找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6915|回复: 11
收起左侧

stc 8a 8f单片机硬件iic驱动0.96oled 源程序

  [复制链接]
ID:499469 发表于 2020-4-10 23:39 | 显示全部楼层 |阅读模式
stc  8a或8f硬件iic驱动0.96oled
图片就不上了  通过stc8f2k16s2实验(晶振22.1184) 驱动正常
scl接P32,sda接P33(P_SW2 = 0xb0;)
寄存器P_SW2 可更改io口
程序有问题欢迎留言

单片机源程序如下:
  1. #include "STC8A.h"
  2. #include "oled.h"
  3. #include "oledfont.h"         
  4. #include "intrins.h"

  5. void iicInit()
  6. {
  7.           P_SW2 = 0xb0;   // SCL(3.2) SDA(3.3)
  8.     I2CCFG = 0xe0;  //开启iic 主机模式 最高速度
  9.           I2CMSST = 0x00; //关中断 待机模式
  10. }
  11. void delay_ms(unsigned int ms) //晶振22.1184
  12. {                        
  13.         while(ms)
  14.         {
  15.         unsigned char i=29, j=183;
  16.         do
  17.         {while (--j);}
  18.         while (--i);
  19.                 ms--;
  20.         }
  21.         return;
  22. }

  23. void Wait()  //等待
  24. {
  25.     while (!(I2CMSST & 0x40));
  26.     I2CMSST &= ~0x40;
  27. }
  28. void IIC_Start()
  29. {
  30.     I2CMSCR = 0x01;     //发送START命令
  31.     Wait();
  32. }

  33. void IIC_Stop()
  34. {
  35.     I2CMSCR = 0x06;     //发送STOP命令
  36.     Wait();
  37. }

  38. void IIC_Wait_Ack()
  39. {
  40.     I2CMSST = 0x00;                             //设置ACK信号
  41.     I2CMSCR = 0x05;                             //发送ACK命令
  42.     Wait();
  43. }

  44. void Write_IIC_Byte(unsigned char dat)
  45. {
  46.     I2CTXD = dat;         //写数据到数据缓冲区
  47.     I2CMSCR = 0x02;       //发送SEND命令
  48.     Wait();
  49. }

  50. void Write_IIC_Command(unsigned char IIC_Command)
  51. {
  52.    IIC_Start();
  53.    Write_IIC_Byte(0x78);            //Slave address,SA0=0
  54.         IIC_Wait_Ack();        
  55.    Write_IIC_Byte(0x00);                        //write command
  56.         IIC_Wait_Ack();        
  57.    Write_IIC_Byte(IIC_Command);
  58.         IIC_Wait_Ack();        
  59.    IIC_Stop();
  60. }

  61. void Write_IIC_Data(unsigned char IIC_Data)
  62. {
  63.    IIC_Start();
  64.    Write_IIC_Byte(0x78);                        //D/C#=0; R/W#=0
  65.         IIC_Wait_Ack();        
  66.    Write_IIC_Byte(0x40);                        //write data
  67.         IIC_Wait_Ack();        
  68.    Write_IIC_Byte(IIC_Data);
  69.         IIC_Wait_Ack();        
  70.    IIC_Stop();
  71. }
  72. void OLED_WR_Byte(unsigned dat,unsigned cmd)
  73. {
  74.         if(cmd)
  75.                         {

  76.    Write_IIC_Data(dat);
  77.    
  78.                 }
  79.         else {
  80.    Write_IIC_Command(dat);
  81.                
  82.         }


  83. }

  84. /********************************************
  85. // fill_Picture
  86. ********************************************/
  87. //void fill_picture(unsigned char fill_Data)
  88. //{
  89. //        unsigned char m,n;
  90. //        for(m=0;m<8;m++)
  91. //        {
  92. //                OLED_WR_Byte(0xb0+m,0);                //page0-page1
  93. //                OLED_WR_Byte(0x00,0);                //low column start address
  94. //                OLED_WR_Byte(0x10,0);                //high column start address
  95. //                for(n=0;n<128;n++)
  96. //                        {
  97. //                                OLED_WR_Byte(fill_Data,1);
  98. //                        }
  99. //        }
  100. //}


  101. ///***********************Delay****************************************/
  102. //void Delay_50ms(unsigned int Del_50ms)
  103. //{
  104. //        unsigned int m;
  105. //        for(;Del_50ms>0;Del_50ms--)
  106. //                for(m=6245;m>0;m--);
  107. //}

  108. //void Delay_1ms(unsigned int Del_1ms)
  109. //{
  110. //        unsigned char j;
  111. //        while(Del_1ms--)
  112. //        {        
  113. //                for(j=0;j<123;j++);
  114. //        }
  115. //}

  116. //坐标设置

  117.         void OLED_Set_Pos(unsigned char x, unsigned char y)
  118. {         OLED_WR_Byte(0xb0+y,OLED_CMD);
  119.         OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  120.         OLED_WR_Byte((x&0x0f),OLED_CMD);
  121. }            
  122. ////开启OLED显示   
  123. //void OLED_Display_On(void)
  124. //{
  125. //        OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  126. //        OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
  127. //        OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  128. //}
  129. ////关闭OLED显示     
  130. //void OLED_Display_Off(void)
  131. //{
  132. //        OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  133. //        OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
  134. //        OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
  135. //}                                            
  136. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!         
  137. void OLED_Clear(void)  
  138. {  
  139.         u8 i,n;                    
  140.         for(i=0;i<8;i++)  
  141.         {  
  142.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  143.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
  144.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
  145.                 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  146.         } //更新显示
  147. }
  148. //void OLED_On(void)  
  149. //{  
  150. //        u8 i,n;                    
  151. //        for(i=0;i<8;i++)  
  152. //        {  
  153. //                OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  154. //                OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
  155. //                OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
  156. //                for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
  157. //        } //更新显示
  158. //}
  159. //在指定位置显示一个字符,包括部分字符
  160. //x:0~127
  161. //y:0~63
  162. //mode:0,反白显示;1,正常显示                                 
  163. //size:选择字体 16/12
  164. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
  165. {              
  166.         unsigned char c=0,i=0;        
  167.                 c=chr-' ';//得到偏移后的值                        
  168.                 if(x>Max_Column-1){x=0;y=y+2;}
  169.                 if(Char_Size ==16)
  170.                         {
  171.                         OLED_Set_Pos(x,y);        
  172.                         for(i=0;i<8;i++)
  173.                         OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
  174.                         OLED_Set_Pos(x,y+1);
  175.                         for(i=0;i<8;i++)
  176.                         OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
  177.                         }
  178.                         else {        
  179.                                 OLED_Set_Pos(x,y);
  180.                                 for(i=0;i<6;i++)
  181.                                 OLED_WR_Byte(F6x8[c][i],OLED_DATA);
  182.                                 
  183.                         }
  184. }

  185. //显示单个数字
  186. void OLED_Showm(u8 x,u8 y,u32 num,u8 size2)
  187. {  
  188.         u8 i,f,g;
  189.         if(num>>15)//负温度
  190.         {
  191.                 num=num&0x7fff;//高位清零
  192.           i=num/100;
  193.           f=num%100/10;
  194.           g=num%10;
  195.           OLED_ShowChar(x,y,'-',size2);
  196.                 OLED_ShowChar(x+size2/2,y,f+'0',size2);
  197.           OLED_ShowChar(x+size2,y,'.',size2);
  198.           OLED_ShowChar(x+size2+4,y,g+'0',size2);
  199. }
  200. else
  201. {
  202.    i=num/100;
  203.         f=num%100/10;
  204.         g=num%10;
  205.           OLED_ShowChar(x,y,i+'0',size2);
  206.                 OLED_ShowChar(x+size2/2,y,f+'0',size2);
  207.         OLED_ShowChar(x+size2,y,'.',size2);
  208.          OLED_ShowChar(x+size2+4,y,g+'0',size2);


  209. }}
  210. //m^n函数
  211. //u32 oled_pow(u8 m,u8 n)
  212. //{
  213. //        u32 result=1;         
  214. //        while(n--)result*=m;   
  215. //        return result;
  216. //}                                 
  217. //显示2个数字
  218. //x,y :起点坐标         
  219. //len :数字的位数
  220. //size:字体大小
  221. //mode:模式        0,填充模式;1,叠加模式
  222. //num:数值(0~4294967295);                           
  223. //void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
  224. //{                 
  225. //        u8 t,temp;
  226. //        u8 enshow=0;                                                   
  227. //        for(t=0;t<len;t++)
  228. //        {
  229. //                temp=(num/oled_pow(10,len-t-1))%10;
  230. //                if(enshow==0&&t<(len-1))
  231. //                {
  232. //                        if(temp==0)
  233. //                        {
  234. //                                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
  235. //                                continue;
  236. //                        }else enshow=1;
  237. //                          
  238. //                }
  239. //                 OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
  240. //        }
  241. //}
  242. //显示一个字符号串
  243. void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
  244. {
  245.         unsigned char j=0;
  246.         while (chr[j]!='\0')
  247.         {                OLED_ShowChar(x,y,chr[j],Char_Size);
  248.                         x+=8;
  249.                 if(x>120){x=0;y+=2;}
  250.                         j++;
  251.         }
  252. }
  253. //显示汉字
  254. void OLED_ShowCHinese(u8 x,u8 y,u8 no)
  255. {                                 
  256.         u8 t,adder=0;
  257.         OLED_Set_Pos(x,y);        
  258.     for(t=0;t<16;t++)
  259.                 {
  260.                                 OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
  261.                                 adder+=1;
  262.      }        
  263.                 OLED_Set_Pos(x,y+1);        
  264.     for(t=0;t<16;t++)
  265.                         {        
  266.                                 OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
  267.                                 adder+=1;
  268.       }                                       
  269. }
  270. /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
  271. //void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
  272. //{         
  273. // unsigned int j=0;
  274. // unsigned char x,y;
  275. //  
  276. //  if(y1%8==0) y=y1/8;      
  277. //  else y=y1/8+1;
  278. //        for(y=y0;y<y1;y++)
  279. //        {
  280. //                OLED_Set_Pos(x0,y);
  281. //    for(x=x0;x<x1;x++)
  282. //            {      
  283. //                    OLED_WR_Byte(BMP[j++],OLED_DATA);                    
  284. //            }
  285. //        }
  286. //}

  287. //初始化SSD1306                                            
  288. void OLED_Init(void)
  289. ……………………

  290. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

程序如果不好用,请看2楼和4楼的修改方案:
0.96OLED硬件iic.zip (113.51 KB, 下载次数: 228)
回复

使用道具 举报

ID:748788 发表于 2021-8-21 16:28 | 显示全部楼层
测试了楼主的程序,开始屏幕不亮,对比stc的有关范例,加了一句:P_SW2 = 0x80; 就能正常显示了。还是要感谢楼主的奉献

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:963221 发表于 2021-9-1 17:34 | 显示全部楼层
为什么我就不对呢?请指教一下
回复

使用道具 举报

ID:504289 发表于 2021-9-20 16:36 | 显示全部楼层
需要对GPIO进行初始化上拉配置 才能使用
/******************** IO口配置 ********************/
void        GPIO_config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                                //结构定义

        GPIO_InitStructure.Pin  = GPIO_Pin_All;                        //指定要初始化的IO, GPIO_Pin_0 ~ GPIO_Pin_7, 或操作
        GPIO_InitStructure.Mode = GPIO_PullUp;                        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
        P3=0xFF;
}

0.96OLED硬件iic完美例子!!.zip

257.55 KB, 下载次数: 106, 下载积分: 黑币 -5

评分

参与人数 1黑币 +30 收起 理由
admin + 30 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:66287 发表于 2022-1-14 09:02 | 显示全部楼层
5d36424903b6db20b904398f44d8c09.jpg
下载了楼上的附件,用压缩包里的EXE文件烧录,工作正常。
但自己编译一下,生成的EXE文件烧录就不能工作。
回复

使用道具 举报

ID:66287 发表于 2022-1-14 09:09 | 显示全部楼层
我用的芯片是STC8G1K08A,用压缩包里的EXE文件烧录工作正常。
回复

使用道具 举报

ID:912806 发表于 2022-1-14 11:07 | 显示全部楼层
https://github.com/IOsetting/FwL ... er/demo/i2c/ssd1306

STC8H 的 SSD1306 驱动演示, STC8G没测, 应该也支持
回复

使用道具 举报

ID:66287 发表于 2022-1-20 11:09 | 显示全部楼层
折腾了几天,找到了问题所在。
楼上的定义了一个GPIO_config();
void        GPIO_config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;                                //结构定义
        GPIO_InitStructure.Pin  = GPIO_Pin_All;                        //指定要初始化的IO, GPIO_Pin_0 ~   GPIO_Pin_7, 或操作
        GPIO_InitStructure.Mode = GPIO_PullUp;                        //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
        GPIO_Inilize(GPIO_P3,&GPIO_InitStructure);        //初始化
        P3=0xFF;
}
但不能正常运行,所以一直不能运行。
本人在主程序中加入一句端口初始化语句,完美解决。
main()
{
   P3M1 = 0;   
   P3M0 = 0;   //P3设置为准双向口
   IIC_Init(); //硬件iic初始化       
   OLED_Init();//初始化OLED
   ……
   ……
}
回复

使用道具 举报

ID:228723 发表于 2022-6-24 10:41 | 显示全部楼层
我的还是不显示
回复

使用道具 举报

ID:921294 发表于 2022-9-27 20:13 | 显示全部楼层
int main(void)
{        u8 t;
        //GPIO_config();
         P3M1 = 0;   
         P3M0 = 0;   //P3设置为准双向口
         iicInit();  //硬件iic初始化
搞了好久,把//GPIO_config();注释掉,增加 P3M1 = 0;P3M0 = 0;   //P3设置为准双向口,就可以显示了,我用的芯片是STC8G1K08A SOP8
回复

使用道具 举报

ID:400910 发表于 2022-10-31 11:47 | 显示全部楼层
楼主这个地方的最高速度不应该是MSSPEED[5:0]=0时才是最高速度吗?你这个I2CCFG = 0xe0;的 [MSSPEED]=32,怎么都不是最高速度啊?不太懂,希望大佬能解释下
回复

使用道具 举报

ID:1088283 发表于 2023-7-12 21:31 | 显示全部楼层
bhjyqjs 发表于 2022-1-14 09:09
我用的芯片是STC8G1K08A,用压缩包里的EXE文件烧录工作正常。

使用config.h做头文件,修改起来应该会比较方便
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表