[PIC®/AVR®/dsPIC®产品] 【CuriosityNano测评报告】+驱动oled12864

[复制链接]
1713|3
 楼主| dql2015 发表于 2021-6-5 15:49 | 显示全部楼层 |阅读模式
oled12864是一种常见的液晶显示设备。本测试使用的i2c接口的ssd1306。使用MCC配置RC4和RC5作为驱动IO。


驱动oled.h文件

  1. #ifndef __OLED_H
  2. #define __OLED_H                                   

  3. #include "stdlib.h"         
  4. #include "mcc_generated_files/mcc.h"

  5. #define OLED_MODE 0
  6. #define SIZE 8
  7. #define XLevelL                0x00
  8. #define XLevelH                0x10
  9. #define Max_Column        128
  10. #define Max_Row                64
  11. #define        Brightness        0xFF
  12. #define X_WIDTH         128
  13. #define Y_WIDTH         64                                                              
  14. //-----------------OLED IIC端口定义----------------                                            

  15. #define OLED_SCLK_Clr() IO_RC3_SCL_SetLow()
  16. #define OLED_SCLK_Set() IO_RC3_SCL_SetHigh()  

  17. #define OLED_SDIN_Clr() IO_RC4_SDA_SetLow()
  18. #define OLED_SDIN_Set() IO_RC4_SDA_SetHigh()

  19.                      
  20. #define OLED_CMD  0        //写命令
  21. #define OLED_DATA 1        //写数据

  22. #define u8 unsigned char
  23. #define u32 unsigned int       


  24. //OLED控制用函数
  25. static void OLED_WR_Byte(unsigned dat,unsigned cmd);  

  26. void OLED_Display_On(void);
  27. void OLED_Display_Off(void);                                                                                          
  28. void OLED_Init(void);
  29. void OLED_Clear(void);
  30. void OLED_DrawPoint(u8 x,u8 y,u8 t);
  31. void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
  32. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
  33. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
  34. void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);         
  35. void OLED_Set_Pos(unsigned char x, unsigned char y);
  36. void OLED_ShowCHinese(u8 x,u8 y,u8 no);
  37. void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
  38. void Delay_50ms(unsigned int Del_50ms);
  39. void Delay_1ms(unsigned int Del_1ms);
  40. void fill_picture(unsigned char fill_Data);

  41. //void Picture();
  42. static void IIC_Start(void);
  43. static void IIC_Stop(void);
  44. static void Write_IIC_Command(unsigned char IIC_Command);
  45. static void Write_IIC_Data(unsigned char IIC_Data);
  46. static void Write_IIC_Byte(unsigned char IIC_Byte);
  47. static void IIC_Wait_Ack(void);

  48. #endif  
  49.          



驱动oled.c文件

  1. #include "oled.h"
  2. #include "stdlib.h"
  3. #include "oledfont.h"           
  4. //OLED的显存
  5. //存放格式如下.
  6. //[0]0 1 2 3 ... 127       
  7. //[1]0 1 2 3 ... 127       
  8. //[2]0 1 2 3 ... 127       
  9. //[3]0 1 2 3 ... 127       
  10. //[4]0 1 2 3 ... 127       
  11. //[5]0 1 2 3 ... 127       
  12. //[6]0 1 2 3 ... 127       
  13. //[7]0 1 2 3 ... 127                           
  14. /**********************************************
  15. //IIC Start
  16. **********************************************/
  17. /**********************************************
  18. //IIC Start
  19. **********************************************/
  20. static void IIC_Start(void)
  21. {
  22.         OLED_SCLK_Set() ;
  23.         OLED_SDIN_Set();
  24.         OLED_SDIN_Clr();
  25.         OLED_SCLK_Clr();
  26. }

  27. /**********************************************
  28. //IIC Stop
  29. **********************************************/
  30. static void IIC_Stop(void)
  31. {
  32.     OLED_SCLK_Set() ;
  33.         //OLED_SCLK_Clr();
  34.         OLED_SDIN_Clr();
  35.         OLED_SDIN_Set();
  36.        
  37. }

  38. static void IIC_Wait_Ack(void)
  39. {

  40.         //GPIOB->CRH &= 0XFFF0FFFF;        //设置PB12为上拉输入模式
  41.         //GPIOB->CRH |= 0x00080000;
  42. //        OLED_SDA = 1;
  43. //        delay_us(1);
  44.         //OLED_SCL = 1;
  45.         //delay_us(50000);
  46. /*        while(1)
  47.         {
  48.                 if(!OLED_SDA)                                //判断是否接收到OLED 应答信号
  49.                 {
  50.                         //GPIOB->CRH &= 0XFFF0FFFF;        //设置PB12为通用推免输出模式
  51.                         //GPIOB->CRH |= 0x00030000;
  52.                         return;
  53.                 }
  54.         }
  55. */
  56.         OLED_SCLK_Set() ;
  57.         OLED_SCLK_Clr();
  58. }
  59. /**********************************************
  60. // IIC Write byte
  61. **********************************************/

  62. static void Write_IIC_Byte(unsigned char IIC_Byte)
  63. {
  64.         unsigned char i;
  65.         unsigned char m,da;
  66.         da=IIC_Byte;
  67.         OLED_SCLK_Clr();
  68.         for(i=0;i<8;i++)               
  69.         {
  70.                         m=da;
  71.                 //        OLED_SCLK_Clr();
  72.                 m=m&0x80;
  73.                 if(m==0x80)
  74.                 {OLED_SDIN_Set();}
  75.                 else OLED_SDIN_Clr();
  76.                         da=da<<1;
  77.                 OLED_SCLK_Set();
  78.                 OLED_SCLK_Clr();
  79.                 }


  80. }
  81. /**********************************************
  82. // IIC Write Command
  83. **********************************************/
  84. static void Write_IIC_Command(unsigned char IIC_Command)
  85. {
  86.    IIC_Start();
  87.    Write_IIC_Byte(0x78);            //Slave address,SA0=0
  88.         IIC_Wait_Ack();       
  89.    Write_IIC_Byte(0x00);                        //write command
  90.         IIC_Wait_Ack();       
  91.    Write_IIC_Byte(IIC_Command);
  92.         IIC_Wait_Ack();       
  93.    IIC_Stop();
  94. }
  95. /**********************************************
  96. // IIC Write Data
  97. **********************************************/
  98. static void Write_IIC_Data(unsigned char IIC_Data)
  99. {
  100.    IIC_Start();
  101.    Write_IIC_Byte(0x78);                        //D/C#=0; R/W#=0
  102.         IIC_Wait_Ack();       
  103.    Write_IIC_Byte(0x40);                        //write data
  104.         IIC_Wait_Ack();       
  105.    Write_IIC_Byte(IIC_Data);
  106.         IIC_Wait_Ack();       
  107.    IIC_Stop();
  108. }
  109. static void OLED_WR_Byte(unsigned dat,unsigned cmd)
  110. {
  111.         if(cmd)
  112.                         {

  113.    Write_IIC_Data(dat);
  114.    
  115.                 }
  116.         else {
  117.    Write_IIC_Command(dat);
  118.                
  119.         }


  120. }


  121. /********************************************
  122. // fill_Picture
  123. ********************************************/
  124. void fill_picture(unsigned char fill_Data)
  125. {
  126.         unsigned char m,n;
  127.         for(m=0;m<8;m++)
  128.         {
  129.                 OLED_WR_Byte(0xb0+m,0);                //page0-page1
  130.                 OLED_WR_Byte(0x00,0);                //low column start address
  131.                 OLED_WR_Byte(0x10,0);                //high column start address
  132.                 for(n=0;n<128;n++)
  133.                         {
  134.                                 OLED_WR_Byte(fill_Data,1);
  135.                         }
  136.         }
  137. }


  138. /***********************Delay****************************************/
  139. void Delay_50ms(unsigned int Del_50ms)
  140. {
  141.     DELAY_milliseconds(50);
  142. }

  143. void Delay_1ms(unsigned int Del_1ms)
  144. {
  145.     DELAY_milliseconds(1);
  146. }

  147. //坐标设置
  148. void OLED_Set_Pos(unsigned char x, unsigned char y)
  149. {         OLED_WR_Byte(0xb0+y,OLED_CMD);
  150.         OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
  151.         OLED_WR_Byte((x&0x0f),OLED_CMD);
  152. }             
  153. //开启OLED显示   
  154. void OLED_Display_On(void)
  155. {
  156.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  157.         OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
  158.         OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  159. }
  160. //关闭OLED显示     
  161. void OLED_Display_Off(void)
  162. {
  163.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  164.         OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
  165.         OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
  166. }                                            
  167. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!          
  168. void OLED_Clear(void)  
  169. {  
  170.         u8 i,n;                    
  171.         for(i=0;i<8;i++)  
  172.         {  
  173.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  174.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置―列低地址
  175.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置―列高地址   
  176.                 for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
  177.         } //更新显示
  178. }
  179. void OLED_On(void)  
  180. {  
  181.         u8 i,n;                    
  182.         for(i=0;i<8;i++)  
  183.         {  
  184.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  185.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置―列低地址
  186.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置―列高地址   
  187.                 for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
  188.         } //更新显示
  189. }
  190. //在指定位置显示一个字符,包括部分字符
  191. //x:0~127
  192. //y:0~63
  193. //mode:0,反白显示;1,正常显示                                 
  194. //size:选择字体 16/12
  195. void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
  196. {             
  197.         unsigned char c=0,i=0;       
  198.                 c=chr-' ';//得到偏移后的值                       
  199.                 if(x>Max_Column-1){x=0;y=y+2;}
  200.                 if(Char_Size ==16)
  201.                         {
  202.                         OLED_Set_Pos(x,y);       
  203.                         for(i=0;i<8;i++)
  204.                         OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
  205.                         OLED_Set_Pos(x,y+1);
  206.                         for(i=0;i<8;i++)
  207.                         OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
  208.                         }
  209.                         else {       
  210.                                 OLED_Set_Pos(x,y);
  211.                                 for(i=0;i<6;i++)
  212.                                 OLED_WR_Byte(F6x8[c][i],OLED_DATA);
  213.                                
  214.                         }
  215. }
  216. //m^n函数
  217. u32 oled_pow(u8 m,u8 n)
  218. {
  219.         u32 result=1;         
  220.         while(n--)result*=m;   
  221.         return result;
  222. }                                  
  223. //显示2个数字
  224. //x,y :起点坐标         
  225. //len :数字的位数
  226. //size:字体大小
  227. //mode:模式        0,填充模式;1,叠加模式
  228. //num:数值(0~4294967295);                           
  229. void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
  230. {                
  231.         u8 t,temp;
  232.         u8 enshow=0;                                                  
  233.         for(t=0;t<len;t++)
  234.         {
  235.                 temp=(num/oled_pow(10,len-t-1))%10;
  236.                 if(enshow==0&&t<(len-1))
  237.                 {
  238.                         if(temp==0)
  239.                         {
  240.                                 OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
  241.                                 continue;
  242.                         }else enshow=1;
  243.                           
  244.                 }
  245.                  OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
  246.         }
  247. }
  248. //显示一个字符号串
  249. void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
  250. {
  251.         unsigned char j=0;
  252.         while (chr[j]!='\0')
  253.         {                OLED_ShowChar(x,y,chr[j],Char_Size);
  254.                         x+=8;
  255.                 if(x>120){x=0;y+=1;}
  256.                         j++;
  257.         }
  258. }
  259. //显示汉字
  260. void OLED_ShowCHinese(u8 x,u8 y,u8 no)
  261. {                                  
  262.         u8 t,adder=0;
  263.         OLED_Set_Pos(x,y);       
  264.     for(t=0;t<16;t++)
  265.                 {
  266.                                 OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
  267.                                 adder+=1;
  268.      }       
  269.                 OLED_Set_Pos(x,y+1);       
  270.     for(t=0;t<16;t++)
  271.                         {       
  272.                                 OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
  273.                                 adder+=1;
  274.       }                                       
  275. }
  276. /***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
  277. void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
  278. {        
  279. unsigned int j=0;
  280. unsigned char x,y;
  281.   
  282.   if(y1%8==0) y=y1/8;      
  283.   else y=y1/8+1;
  284.         for(y=y0;y<y1;y++)
  285.         {
  286.                 OLED_Set_Pos(x0,y);
  287.     for(x=x0;x<x1;x++)
  288.             {      
  289.                     OLED_WR_Byte(BMP[j++],OLED_DATA);                   
  290.             }
  291.         }
  292. }

  293. //初始化SSD1306                                            
  294. void OLED_Init(void)
  295. {        
  296.     IO_RC3_SCL_SetDigitalOutput();
  297.     IO_RC4_SDA_SetDigitalOutput();
  298.         DELAY_milliseconds(800);
  299.         OLED_WR_Byte(0xAE,OLED_CMD);//--display off
  300.         OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  301.         OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  302.         OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  
  303.         OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
  304.         OLED_WR_Byte(0x81,OLED_CMD); // contract control
  305.         OLED_WR_Byte(0xFF,OLED_CMD);//--128   
  306.         OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
  307.         OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
  308.         OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  309.         OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
  310.         OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
  311.         OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
  312.         OLED_WR_Byte(0x00,OLED_CMD);//
  313.        
  314.         OLED_WR_Byte(0xD5,OLED_CMD);//set osc division
  315.         OLED_WR_Byte(0x80,OLED_CMD);//
  316.        
  317.         OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off
  318.         OLED_WR_Byte(0x05,OLED_CMD);//
  319.        
  320.         OLED_WR_Byte(0xD9,OLED_CMD);//Set Pre-Charge Period
  321.         OLED_WR_Byte(0xF1,OLED_CMD);//
  322.        
  323.         OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
  324.         OLED_WR_Byte(0x12,OLED_CMD);//
  325.        
  326.         OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
  327.         OLED_WR_Byte(0x30,OLED_CMD);//
  328.        
  329.         OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
  330.         OLED_WR_Byte(0x14,OLED_CMD);//
  331.        
  332.         OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
  333. }  






测试工程:




本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
734774645 发表于 2021-6-6 20:22 | 显示全部楼层
大家更喜欢用IO模拟IIC,这样就不用自己完成配置和时序了。哈哈。
xinpian101 发表于 2021-6-6 22:02 | 显示全部楼层
移植是很容易。
 楼主| dql2015 发表于 2021-6-7 17:20 | 显示全部楼层
734774645 发表于 2021-6-6 20:22
大家更喜欢用IO模拟IIC,这样就不用自己完成配置和时序了。哈哈。

简单,配置两个IO输出,一个ms延时就搞定
您需要登录后才可以回帖 登录 | 注册

本版积分规则

104

主题

384

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部