久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8981|回復: 13
打印 上一主題 下一主題
收起左側

關于OLED12864用IIC通訊顯示受晶振頻率影響解決方案 附單片機程序

  [復制鏈接]
跳轉到指定樓層
樓主
關于OLED12864用IIC通訊顯示受晶振頻率影響解決方案
采用的單片機機STC8A8K64S4A12,同時STC15系列的也使用,測試過的
之前用軟件模擬IIC驅動OLED12864時,當把單片機晶振頻率調高時,OLED就不能正常顯示了
后來找到了一些IIC程序,采用了一下,得以解決這一問題

問題還是IIC驅動程序沒有寫好,用賣家的例程也不行,還是的自己修改一下

此版程序,通過測試,就算把晶振調到27MHZ,也能正常顯示

附件中有SPI通訊,軟件模擬IIC,基于STC8A8K的硬件IIC,驅動OLED12864
不過STC8的硬件IIC通訊,還是受到晶振頻率的影響,稍微修改了一下,比之前要好一點

貼出來的程序是單片機軟件模擬IIC驅動OLED12864
  1. #include "oled.h"
  2. #include "Font.h"
  3. #include "intrins.h"

  4. void Delay_OLED(u16 t)
  5. {
  6.         u16 i,j;
  7.         for(j=0;j<t;j++)
  8.         {
  9.                 for(i=0;i<1;i++)        //根據晶振頻率調整延時
  10.                 {
  11.                         _nop_();
  12.                         //_nop_();_nop_();
  13.                 }
  14.         }
  15. }

  16. /*********通過IIC寫一字節數據******/
  17. void IIC_Write_Byte(u8 Byte)
  18. {
  19.         u8 i;
  20.         for(i=0;i<8;i++)
  21.         {
  22.                 OLED_SDA = Byte &0X80;        ////改變數據
  23.                 OLED_SCL = 1;        //傳輸數據
  24.                 Delay_OLED(1);
  25.                 OLED_SCL = 0;
  26.                 Byte<<=1;
  27.                 Delay_OLED(1);
  28.         }
  29. }

  30. /********起始信號*********/
  31. void IIC_Start()
  32. {
  33.         OLED_SDA = 1;
  34.         OLED_SCL = 1;
  35.         Delay_OLED(1);
  36.         OLED_SDA = 0;
  37.         Delay_OLED(1);
  38.         OLED_SCL = 0;
  39.         Delay_OLED(1);
  40. }

  41. /********停止信號*********/
  42. void IIC_Stop()
  43. {
  44.         OLED_SCL = 0;
  45.         OLED_SDA = 0;
  46.         Delay_OLED(1);
  47.         OLED_SDA = 1;
  48.         Delay_OLED(1);
  49.         OLED_SCL = 1;
  50.         Delay_OLED(1);
  51. }

  52. /*********ACK信號********/
  53. bit IIC_ACK()
  54. {
  55.         u8 errtime=255;
  56.         OLED_SCL = 0;
  57.         OLED_SDA = 1;        //釋放總線
  58.         Delay_OLED(1);
  59.         OLED_SCL = 1;
  60.         Delay_OLED(1);
  61.         while(OLED_SDA)        //讀取 SDA上的電平,變為低電平,即有從機回復ACK信號
  62.         {
  63.                 errtime--;
  64.                 if(!errtime)        //超時退出
  65.                 {
  66.                         OLED_SCL=0;
  67.                         return 0;
  68.                 }
  69.         }
  70.         OLED_SCL=0;
  71.         return 1;
  72. }

  73. /***********向SSD1306寫一字節數據***********
  74. Dat:要寫入的數據/命令
  75. Cmd:數據/命令標志 0,表示命令;1,表示數據;
  76. ********************************************/
  77. void Write_OLED_Byte(u8 Dat,u8 Cmd)
  78. {
  79.         IIC_Start();
  80.         IIC_Write_Byte(0X78);
  81.         IIC_ACK();
  82.         if(Cmd ==1)        //數據
  83.                 IIC_Write_Byte(0X40);
  84.         else        //命令
  85.                 IIC_Write_Byte(0X00);
  86.         IIC_ACK();
  87.         IIC_Write_Byte(Dat);
  88.         IIC_ACK();
  89.         IIC_Stop();
  90. }

  91. /**********IIC_IO口初始化***********/
  92. void IIC_InitIO()
  93. {
  94.         OLED_SDA = 1;
  95.         OLED_SCL = 1;
  96. }
  97. //---------IIC 通訊----------------------------------------------------------
  98. /*********設置顯示坐標*********/
  99. void OLED_Set_PoS(u8 page,u8 column)
  100. {
  101.         Write_OLED_Byte(0XB0+page,OLED_CMD);
  102.         Write_OLED_Byte( ((column&0XF0)>>4)|0X10,OLED_CMD);
  103.         Write_OLED_Byte( column&0X0F,OLED_CMD);
  104. }

  105. ////開啟OLED顯示   
  106. //void OLED_Display_On(void)
  107. //{
  108. //        Write_OLED_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  109. //        Write_OLED_Byte(0X14,OLED_CMD);  //DCDC ON
  110. //        Write_OLED_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  111. //}


  112. ////關閉OLED顯示     
  113. //void OLED_Display_Off(void)
  114. //{
  115. //        Write_OLED_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  116. //        Write_OLED_Byte(0X10,OLED_CMD);  //DCDC OFF
  117. //        Write_OLED_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
  118. //}

  119. /************操作整個屏幕************
  120. Input: Ins=0        清除整個屏幕
  121.            Ins=0XFF        全部顯示整個屏幕
  122. *************************************/
  123. void OLED_Screen_All(u8 Ins)
  124. {
  125.         u8 page,seg;
  126.         for(page=0;page<8;page++)
  127.         {
  128.                 OLED_Set_PoS(page,0);
  129.                 for(seg=0;seg<128;seg++)
  130.                 {
  131.                         Write_OLED_Byte(Ins,OLED_DAT);
  132.                         Delay_OLED(1);
  133.                 }
  134.                 Delay_OLED(1);
  135.         }
  136. }


  137. /*********OLED初始化***********/
  138. void OLED_Init()
  139. {
  140.         Delay_OLED(2000);  
  141.         
  142.         Write_OLED_Byte(0XD5,OLED_CMD);        //晶振頻率
  143.         Write_OLED_Byte(0X80,OLED_CMD);
  144.         Write_OLED_Byte(0XD9,OLED_CMD);        //
  145.         Write_OLED_Byte(0XF1,OLED_CMD);
  146.         Write_OLED_Byte(0XDB,OLED_CMD);        //
  147.         Write_OLED_Byte(0X40,OLED_CMD);
  148. //--地址設置
  149.         Write_OLED_Byte(0X20,OLED_CMD);        //設置尋址模式
  150.         Write_OLED_Byte(0X02,OLED_CMD);        //0X00--水平尋址;0X01--垂直尋址;0X02--頁面尋址
  151. //--硬件設置
  152.         Write_OLED_Byte(0X40,OLED_CMD);        //起始行
  153.         Write_OLED_Byte(0XA8,OLED_CMD);        //設置顯示比列;
  154.         Write_OLED_Byte(0X3F,OLED_CMD);        //1/64
  155.         Write_OLED_Byte(0XD3,OLED_CMD);        //設置補償
  156.         Write_OLED_Byte(0X00,OLED_CMD);
  157.         //顯示方向-引腳向上為正方向
  158.         Write_OLED_Byte(0XA1,OLED_CMD);        //段尋址,add0-->seg0
  159.         Write_OLED_Byte(0XC8,OLED_CMD);        //com掃描方向,com0-com63
  160.         //引腳在下為正方向
  161.         //Write_OLED_Byte(0XA0,OLED_CMD);        //段尋址,add127-->seg0
  162.         //Write_OLED_Byte(0XC0,OLED_CMD);        //com掃描方向,com63-com0
  163.         Write_OLED_Byte(0X8D,OLED_CMD);        //電荷泵設置
  164.         Write_OLED_Byte(0X14,OLED_CMD);        //REST=0X10,        0X14才能顯示內容
  165. //--基本命令
  166.         Write_OLED_Byte(0X81,OLED_CMD);        //設置對比度
  167.         Write_OLED_Byte(0XCF,OLED_CMD);        //0X00-0XFF,與數值成正比        RES=0X7F
  168.         Write_OLED_Byte(0XA4,OLED_CMD);        //整體顯示開啟,可用來測試液晶是否顯示正常
  169.                                                                         //0XA4跟隨RAM內容,0XA5不跟隨RAM的內容,一直是白屏全部顯示。
  170.         Write_OLED_Byte(0XA6,OLED_CMD);        //設置正顯0XA6,反顯0XA7
  171.         Write_OLED_Byte(0XAF,OLED_CMD);        //0XAE顯示關,0XAF顯示開
  172.         Write_OLED_Byte(0X2E,OLED_CMD);        //關閉滾屏
  173. //---清屏
  174.         OLED_Screen_All(0);        
  175.         Delay_OLED(100);
  176.         OLED_Screen_All(0XFF);        
  177.         Delay_OLED(2000);
  178.         OLED_Screen_All(0);
  179.         Delay_OLED(100);
  180. }

  181. ///***********垂直+水平滾屏***************/
  182. //void Ver_Lev_Screen()
  183. //{
  184. ////--垂直+水平滾屏-------------------------------------------------------------------
  185. //        Write_OLED_Byte(0XA3,OLED_CMD);        //設置垂直滾動區域
  186. //        Write_OLED_Byte(0X10,OLED_CMD);        //固定不動的行數,從頂部開始數
  187. //        Write_OLED_Byte(0X20,OLED_CMD);        //垂直滾動的行數,從固定行的下一行開始數
  188. //        
  189. //        Write_OLED_Byte(0X29,OLED_CMD);        //垂直+右移///0X2A=垂直+左移
  190. //        Write_OLED_Byte(0X00,OLED_CMD);        //空字節
  191. //        Write_OLED_Byte(0X06,OLED_CMD);        //水平移動起始頁
  192. //        Write_OLED_Byte(0X05,OLED_CMD);        //控制垂直+水平速率
  193. //        Write_OLED_Byte(0X07,OLED_CMD);        //水平移動結束頁
  194. //        Write_OLED_Byte(0X02,OLED_CMD);        //垂直滾動偏移量,只控制垂直速率,=0只有水平移動
  195. //        Write_OLED_Byte(0X2F,OLED_CMD);        //啟動滾屏
  196. ////---以上效果為,第一行為固定,第二三行垂直滾屏,第四行右移-------------------------
  197. //}

  198. /**************水平滾屏*****************/
  199. void Lev_Screen()
  200. {
  201.         Write_OLED_Byte(0X26,OLED_CMD);        //右移///0X27=左移
  202.         Write_OLED_Byte(0X00,OLED_CMD);        //空字節
  203.         Write_OLED_Byte(0X06,OLED_CMD);        //水平移動起始頁
  204.         Write_OLED_Byte(0X05,OLED_CMD);        //控制垂直+水平速率
  205.         Write_OLED_Byte(0X07,OLED_CMD);        //水平移動結束頁
  206.         Write_OLED_Byte(0X00,OLED_CMD);        //虛擬字節
  207.         Write_OLED_Byte(0XFF,OLED_CMD);        //虛擬字節
  208.         Write_OLED_Byte(0X2F,OLED_CMD);        //啟動滾屏
  209. }

  210. ///**************清除N個8*16區域**********/
  211. //void Clear8X16(u8 page, u8 column ,u8 N)
  212. //{
  213. //        u8 i,j,k;
  214. //        for(k=0;k<N;k++)
  215. //        {
  216. //                for(i=0;i<2;i++)
  217. //                {
  218. //                        OLED_Set_PoS(page+i,column+k*8);
  219. //                        for(j=8;j>0;j--)
  220. //                                Write_OLED_Byte(0X00,OLED_DAT);
  221. //                }
  222. //        }
  223. //}

  224. /*****************在(16行/2頁)*Wide列區域寫數據****************
  225. Input:        
  226.         *Buff@點陣數據        Num@字符個數,Wide@字體寬度
  227.         Wide=8時,為寫8*16的數據,字母,符號
  228.         Wide=16時,為寫宋體2號漢字
  229. **************************************************************/
  230. void Write_16xWide(u8 page,u8 column ,u8 *Buff,u8 Num,u8 Wide)
  231. {
  232.         u8 i,j,k;
  233.         for(k=0;k<Num;k++)
  234.         {
  235.                 for(i=0;i<2;i++)
  236.                 {
  237.                         OLED_Set_PoS(page+i,column+k*8);
  238.                         for(j=Wide;j>0;j--)
  239.                         {
  240.                                 Write_OLED_Byte(*Buff,OLED_DAT);
  241.                                 Buff++;
  242.                         }
  243.                 }
  244.         }
  245. }

  246. /**************寫宋體12號漢字 16*Wide ***********
  247. Input:        page@頁                column@列        *CH@字符串
  248.         可以顯示漢字,數字,字母,符號
  249.         page:0 2 4 6        column:0~15
  250. ************************************************/
  251. void Write_GB16X16(u8 page,u8 column ,u8 *CH)
  252. {
  253.         u8 a,k;
  254.         if( (*CH>=0X20) && (*CH<=0X7E) )        column=column;
  255.         else column*=8;
  256.         while( *CH != '\0')
  257.         {
  258.                 if( (*CH>=0X20) && (*CH<=0X7E) )        //數字,字母,符號        一行16個
  259.                 {
  260.                         k=*CH-0X20;
  261.                         for(a=0;a<2;a++)
  262.                         {
  263.                                 Write_16xWide(page,column*8, &ASCII_8X16[k][0],1,8);
  264.                         }
  265.                         CH+=1;
  266.                         column+=1;
  267.                 }        
  268.                 else        //漢字,一行 8個
  269.                 {
  270.                         for(a=0;a<FontNum;a++)
  271.                         {
  272.                                 if( (*CH == GB12Hanzi[a].Index[0]) && (*(CH+1)==GB12Hanzi[a].Index[1]) )
  273.                                         Write_16xWide(page,column,&GB12Hanzi[a].Msk[0],1,16);
  274.                         }
  275.                         CH+=2;
  276.                         column+=16;
  277.                 }
  278.         }
  279. }

  280. ///**************在8行/1頁**6列的區域寫字符***************
  281. //Input:        
  282. //        *CH@字符串        能寫21個字符
  283. //        page:0~7        column:0~20
  284. //*******************************************************/
  285. //void Write_GB6X8(u8 page,u8 column ,u8 *CH)
  286. //{
  287. //        u8 j,k;
  288. //        while( *CH != '\0')
  289. //        {
  290. //                if( (*CH>=0X20) && (*CH<=0X7E) )        //數字,字母,符號        一行16個
  291. //                {
  292. //                        k=*CH-0X20;
  293. //                        OLED_Set_PoS(page,column*6);
  294. //                        for(j=0;j<6;j++)
  295. //                                Write_OLED_Byte(ASCII_6X8[k][j],OLED_DAT);
  296. //                        CH+=1;
  297. //                        column+=1;
  298. //                }
  299. //        }
  300. //}


復制代碼

KI]R2]RX~Z6](54P1%~KJWJ.jpg (218.14 KB, 下載次數: 156)

OLED12864

OLED12864

Z%%CJ_LKS2YH_G7S850E4S9.png (7.43 KB, 下載次數: 142)

Z%%CJ_LKS2YH_G7S850E4S9.png

D-0.96OLED驅動程序.zip

141.08 KB, 下載次數: 235, 下載積分: 黑幣 -5

IIC驅動OLED程序

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏9 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:446175 發表于 2021-4-14 22:22 | 只看該作者
用樓主的程序直接點亮屏了,哈哈,謝謝
回復

使用道具 舉報

板凳
ID:94330 發表于 2021-4-19 08:55 | 只看該作者
感謝樓主分享,測試成功
回復

使用道具 舉報

地板
ID:963221 發表于 2021-9-2 16:06 | 只看該作者
還是受速度影響.比如27M時候容易卡死,得斷電才可以不管怎么復位都不行
回復

使用道具 舉報

5#
ID:137590 發表于 2021-10-9 21:29 | 只看該作者
跟著芯片手冊驅動IIC OLED屏幕
回復

使用道具 舉報

6#
ID:965325 發表于 2021-10-10 12:42 | 只看該作者
沒啥特殊的,就是讀寫OLED的底層函數中加了延時。

回復

使用道具 舉報

7#
ID:90718 發表于 2021-11-22 00:59 | 只看該作者
有參考價值,非常感謝!
回復

使用道具 舉報

8#
ID:1013122 發表于 2022-3-28 21:01 | 只看該作者
謝謝。一直在找,非常棒的資源。
回復

使用道具 舉報

9#
ID:630338 發表于 2022-4-5 16:13 | 只看該作者
非常好的資源
回復

使用道具 舉報

10#
ID:471636 發表于 2022-4-8 17:09 | 只看該作者
對于軟件模擬I2C通訊來說,讀寫的延時很重要,更換單片機或者更改頻率,都會影響延時函數的實際運行值,可能會引起I2C通訊故障,樓主所謂的解決方案只是對某種單片機的某些頻率段試驗可行,并不能徹底解決問題。
5、6樓說的都對,其實就是按照手冊調延時。
回復

使用道具 舉報

11#
ID:297903 發表于 2022-4-9 09:34 | 只看該作者
要用I/O摸似II2C,只能自己調整延時來適應不的CPU頻率!!
回復

使用道具 舉報

12#
ID:744744 發表于 2022-5-22 22:42 來自手機 | 只看該作者
單片機運行時間不一樣,時序要調整,這個是正常的。
回復

使用道具 舉報

13#
ID:1135948 發表于 2024-11-9 10:13 | 只看該作者
學習一下
不知道能否點亮OLED
回復

使用道具 舉報

14#
ID:961114 發表于 2024-11-12 14:55 | 只看該作者
過年新玩具get√ ^o^ 第一次玩彩色的OLED,跟TFT彩屏的用法幾乎一樣_嗶哩嗶哩_bilibili  https://www.bilibili.com/video/B ... 229259e6d079df11d14
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 秋霞电影一区二区 | 色www精品视频在线观看 | 欧美片网站免费 | 成人久草 | 国产精品久久久久久久久久久免费看 | 无码一区二区三区视频 | 欧美成人在线影院 | 国产一区二区免费 | 久久久久久久久久久成人 | 欧美日韩国产不卡 | 欧洲视频一区二区 | 日本三级全黄三级三级三级口周 | 欧美成人精品在线观看 | 国产一区视频在线 | 天天久久 | 成人综合一区 | 中文久久| 涩涩视频网 | 国产一区亚洲 | 欧美成人a∨高清免费观看 老司机午夜性大片 | 亚洲色图插插插 | 国产亚洲精品久久情网 | 亚洲免费在线观看 | 日韩一区二区不卡 | 亚洲国产精品一区二区久久 | 羞羞视频在线网站观看 | 99亚洲精品视频 | 国产精品区二区三区日本 | 日韩中文一区二区三区 | 69av片| 亚洲国产视频一区二区 | 午夜免费在线电影 | 一区二区三区国产精品 | 久久99精品久久久久久国产越南 | 狠狠草视频 | 国产剧情一区二区三区 | 国产成人精品一区二区三区视频 | 日韩欧美一区二区三区四区 | 波多野吉衣在线播放 | 国产高清免费 | 久草在线在线精品观看 |