|
關于OLED12864用IIC通訊顯示受晶振頻率影響解決方案
采用的單片機機STC8A8K64S4A12,同時STC15系列的也使用,測試過的
之前用軟件模擬IIC驅動OLED12864時,當把單片機晶振頻率調高時,OLED就不能正常顯示了
后來找到了一些IIC程序,采用了一下,得以解決這一問題
問題還是IIC驅動程序沒有寫好,用賣家的例程也不行,還是的自己修改一下
此版程序,通過測試,就算把晶振調到27MHZ,也能正常顯示
附件中有SPI通訊,軟件模擬IIC,基于STC8A8K的硬件IIC,驅動OLED12864
不過STC8的硬件IIC通訊,還是受到晶振頻率的影響,稍微修改了一下,比之前要好一點
貼出來的程序是單片機軟件模擬IIC驅動OLED12864- #include "oled.h"
- #include "Font.h"
- #include "intrins.h"
- void Delay_OLED(u16 t)
- {
- u16 i,j;
- for(j=0;j<t;j++)
- {
- for(i=0;i<1;i++) //根據晶振頻率調整延時
- {
- _nop_();
- //_nop_();_nop_();
- }
- }
- }
- /*********通過IIC寫一字節數據******/
- void IIC_Write_Byte(u8 Byte)
- {
- u8 i;
- for(i=0;i<8;i++)
- {
- OLED_SDA = Byte &0X80; ////改變數據
- OLED_SCL = 1; //傳輸數據
- Delay_OLED(1);
- OLED_SCL = 0;
- Byte<<=1;
- Delay_OLED(1);
- }
- }
- /********起始信號*********/
- void IIC_Start()
- {
- OLED_SDA = 1;
- OLED_SCL = 1;
- Delay_OLED(1);
- OLED_SDA = 0;
- Delay_OLED(1);
- OLED_SCL = 0;
- Delay_OLED(1);
- }
- /********停止信號*********/
- void IIC_Stop()
- {
- OLED_SCL = 0;
- OLED_SDA = 0;
- Delay_OLED(1);
- OLED_SDA = 1;
- Delay_OLED(1);
- OLED_SCL = 1;
- Delay_OLED(1);
- }
- /*********ACK信號********/
- bit IIC_ACK()
- {
- u8 errtime=255;
- OLED_SCL = 0;
- OLED_SDA = 1; //釋放總線
- Delay_OLED(1);
- OLED_SCL = 1;
- Delay_OLED(1);
- while(OLED_SDA) //讀取 SDA上的電平,變為低電平,即有從機回復ACK信號
- {
- errtime--;
- if(!errtime) //超時退出
- {
- OLED_SCL=0;
- return 0;
- }
- }
- OLED_SCL=0;
- return 1;
- }
- /***********向SSD1306寫一字節數據***********
- Dat:要寫入的數據/命令
- Cmd:數據/命令標志 0,表示命令;1,表示數據;
- ********************************************/
- void Write_OLED_Byte(u8 Dat,u8 Cmd)
- {
- IIC_Start();
- IIC_Write_Byte(0X78);
- IIC_ACK();
- if(Cmd ==1) //數據
- IIC_Write_Byte(0X40);
- else //命令
- IIC_Write_Byte(0X00);
- IIC_ACK();
- IIC_Write_Byte(Dat);
- IIC_ACK();
- IIC_Stop();
- }
- /**********IIC_IO口初始化***********/
- void IIC_InitIO()
- {
- OLED_SDA = 1;
- OLED_SCL = 1;
- }
- //---------IIC 通訊----------------------------------------------------------
- /*********設置顯示坐標*********/
- void OLED_Set_PoS(u8 page,u8 column)
- {
- Write_OLED_Byte(0XB0+page,OLED_CMD);
- Write_OLED_Byte( ((column&0XF0)>>4)|0X10,OLED_CMD);
- Write_OLED_Byte( column&0X0F,OLED_CMD);
- }
- ////開啟OLED顯示
- //void OLED_Display_On(void)
- //{
- // Write_OLED_Byte(0X8D,OLED_CMD); //SET DCDC命令
- // Write_OLED_Byte(0X14,OLED_CMD); //DCDC ON
- // Write_OLED_Byte(0XAF,OLED_CMD); //DISPLAY ON
- //}
- ////關閉OLED顯示
- //void OLED_Display_Off(void)
- //{
- // Write_OLED_Byte(0X8D,OLED_CMD); //SET DCDC命令
- // Write_OLED_Byte(0X10,OLED_CMD); //DCDC OFF
- // Write_OLED_Byte(0XAE,OLED_CMD); //DISPLAY OFF
- //}
- /************操作整個屏幕************
- Input: Ins=0 清除整個屏幕
- Ins=0XFF 全部顯示整個屏幕
- *************************************/
- void OLED_Screen_All(u8 Ins)
- {
- u8 page,seg;
- for(page=0;page<8;page++)
- {
- OLED_Set_PoS(page,0);
- for(seg=0;seg<128;seg++)
- {
- Write_OLED_Byte(Ins,OLED_DAT);
- Delay_OLED(1);
- }
- Delay_OLED(1);
- }
- }
- /*********OLED初始化***********/
- void OLED_Init()
- {
- Delay_OLED(2000);
-
- Write_OLED_Byte(0XD5,OLED_CMD); //晶振頻率
- Write_OLED_Byte(0X80,OLED_CMD);
- Write_OLED_Byte(0XD9,OLED_CMD); //
- Write_OLED_Byte(0XF1,OLED_CMD);
- Write_OLED_Byte(0XDB,OLED_CMD); //
- Write_OLED_Byte(0X40,OLED_CMD);
- //--地址設置
- Write_OLED_Byte(0X20,OLED_CMD); //設置尋址模式
- Write_OLED_Byte(0X02,OLED_CMD); //0X00--水平尋址;0X01--垂直尋址;0X02--頁面尋址
- //--硬件設置
- Write_OLED_Byte(0X40,OLED_CMD); //起始行
- Write_OLED_Byte(0XA8,OLED_CMD); //設置顯示比列;
- Write_OLED_Byte(0X3F,OLED_CMD); //1/64
- Write_OLED_Byte(0XD3,OLED_CMD); //設置補償
- Write_OLED_Byte(0X00,OLED_CMD);
- //顯示方向-引腳向上為正方向
- Write_OLED_Byte(0XA1,OLED_CMD); //段尋址,add0-->seg0
- Write_OLED_Byte(0XC8,OLED_CMD); //com掃描方向,com0-com63
- //引腳在下為正方向
- //Write_OLED_Byte(0XA0,OLED_CMD); //段尋址,add127-->seg0
- //Write_OLED_Byte(0XC0,OLED_CMD); //com掃描方向,com63-com0
- Write_OLED_Byte(0X8D,OLED_CMD); //電荷泵設置
- Write_OLED_Byte(0X14,OLED_CMD); //REST=0X10, 0X14才能顯示內容
- //--基本命令
- Write_OLED_Byte(0X81,OLED_CMD); //設置對比度
- Write_OLED_Byte(0XCF,OLED_CMD); //0X00-0XFF,與數值成正比 RES=0X7F
- Write_OLED_Byte(0XA4,OLED_CMD); //整體顯示開啟,可用來測試液晶是否顯示正常
- //0XA4跟隨RAM內容,0XA5不跟隨RAM的內容,一直是白屏全部顯示。
- Write_OLED_Byte(0XA6,OLED_CMD); //設置正顯0XA6,反顯0XA7
- Write_OLED_Byte(0XAF,OLED_CMD); //0XAE顯示關,0XAF顯示開
- Write_OLED_Byte(0X2E,OLED_CMD); //關閉滾屏
- //---清屏
- OLED_Screen_All(0);
- Delay_OLED(100);
- OLED_Screen_All(0XFF);
- Delay_OLED(2000);
- OLED_Screen_All(0);
- Delay_OLED(100);
- }
- ///***********垂直+水平滾屏***************/
- //void Ver_Lev_Screen()
- //{
- ////--垂直+水平滾屏-------------------------------------------------------------------
- // Write_OLED_Byte(0XA3,OLED_CMD); //設置垂直滾動區域
- // Write_OLED_Byte(0X10,OLED_CMD); //固定不動的行數,從頂部開始數
- // Write_OLED_Byte(0X20,OLED_CMD); //垂直滾動的行數,從固定行的下一行開始數
- //
- // Write_OLED_Byte(0X29,OLED_CMD); //垂直+右移///0X2A=垂直+左移
- // Write_OLED_Byte(0X00,OLED_CMD); //空字節
- // Write_OLED_Byte(0X06,OLED_CMD); //水平移動起始頁
- // Write_OLED_Byte(0X05,OLED_CMD); //控制垂直+水平速率
- // Write_OLED_Byte(0X07,OLED_CMD); //水平移動結束頁
- // Write_OLED_Byte(0X02,OLED_CMD); //垂直滾動偏移量,只控制垂直速率,=0只有水平移動
- // Write_OLED_Byte(0X2F,OLED_CMD); //啟動滾屏
- ////---以上效果為,第一行為固定,第二三行垂直滾屏,第四行右移-------------------------
- //}
- /**************水平滾屏*****************/
- void Lev_Screen()
- {
- Write_OLED_Byte(0X26,OLED_CMD); //右移///0X27=左移
- Write_OLED_Byte(0X00,OLED_CMD); //空字節
- Write_OLED_Byte(0X06,OLED_CMD); //水平移動起始頁
- Write_OLED_Byte(0X05,OLED_CMD); //控制垂直+水平速率
- Write_OLED_Byte(0X07,OLED_CMD); //水平移動結束頁
- Write_OLED_Byte(0X00,OLED_CMD); //虛擬字節
- Write_OLED_Byte(0XFF,OLED_CMD); //虛擬字節
- Write_OLED_Byte(0X2F,OLED_CMD); //啟動滾屏
- }
- ///**************清除N個8*16區域**********/
- //void Clear8X16(u8 page, u8 column ,u8 N)
- //{
- // u8 i,j,k;
- // for(k=0;k<N;k++)
- // {
- // for(i=0;i<2;i++)
- // {
- // OLED_Set_PoS(page+i,column+k*8);
- // for(j=8;j>0;j--)
- // Write_OLED_Byte(0X00,OLED_DAT);
- // }
- // }
- //}
- /*****************在(16行/2頁)*Wide列區域寫數據****************
- Input:
- *Buff@點陣數據 Num@字符個數,Wide@字體寬度
- Wide=8時,為寫8*16的數據,字母,符號
- Wide=16時,為寫宋體2號漢字
- **************************************************************/
- void Write_16xWide(u8 page,u8 column ,u8 *Buff,u8 Num,u8 Wide)
- {
- u8 i,j,k;
- for(k=0;k<Num;k++)
- {
- for(i=0;i<2;i++)
- {
- OLED_Set_PoS(page+i,column+k*8);
- for(j=Wide;j>0;j--)
- {
- Write_OLED_Byte(*Buff,OLED_DAT);
- Buff++;
- }
- }
- }
- }
- /**************寫宋體12號漢字 16*Wide ***********
- Input: page@頁 column@列 *CH@字符串
- 可以顯示漢字,數字,字母,符號
- page:0 2 4 6 column:0~15
- ************************************************/
- void Write_GB16X16(u8 page,u8 column ,u8 *CH)
- {
- u8 a,k;
- if( (*CH>=0X20) && (*CH<=0X7E) ) column=column;
- else column*=8;
- while( *CH != '\0')
- {
- if( (*CH>=0X20) && (*CH<=0X7E) ) //數字,字母,符號 一行16個
- {
- k=*CH-0X20;
- for(a=0;a<2;a++)
- {
- Write_16xWide(page,column*8, &ASCII_8X16[k][0],1,8);
- }
- CH+=1;
- column+=1;
- }
- else //漢字,一行 8個
- {
- for(a=0;a<FontNum;a++)
- {
- if( (*CH == GB12Hanzi[a].Index[0]) && (*(CH+1)==GB12Hanzi[a].Index[1]) )
- Write_16xWide(page,column,&GB12Hanzi[a].Msk[0],1,16);
- }
- CH+=2;
- column+=16;
- }
- }
- }
- ///**************在8行/1頁**6列的區域寫字符***************
- //Input:
- // *CH@字符串 能寫21個字符
- // page:0~7 column:0~20
- //*******************************************************/
- //void Write_GB6X8(u8 page,u8 column ,u8 *CH)
- //{
- // u8 j,k;
- // while( *CH != '\0')
- // {
- // if( (*CH>=0X20) && (*CH<=0X7E) ) //數字,字母,符號 一行16個
- // {
- // k=*CH-0X20;
- // OLED_Set_PoS(page,column*6);
- // for(j=0;j<6;j++)
- // Write_OLED_Byte(ASCII_6X8[k][j],OLED_DAT);
- // CH+=1;
- // column+=1;
- // }
- // }
- //}
復制代碼
|
-
OLED12864
-
-
-
D-0.96OLED驅動程序.zip
2020-5-17 13:34 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
141.08 KB, 下載次數: 235, 下載積分: 黑幣 -5
IIC驅動OLED程序
評分
-
查看全部評分
|