创客神器NanoPi
直播中

zpzdd

11年用户 486经验值
擅长:可编程逻辑 电源/新能源 模拟技术 测量仪表 嵌入式技术 控制/MCU RF/无线
私信 关注
[经验]

【NanoPi K1 Plus试用体验】IIC调试之OLED

`
上次帖子里有提到,wiringPI已经写好了IICSPI等外设的驱动,接下来的实验从IIC开始吧

QQ截图20180727162212.png
之前已经用单片机驱动过OLED,底层IIC函数如下:
  1. void WriteCmd(unsigned char I2C_Command)//写命令
  2. {
  3.         I2C_WriteByte(0x00, I2C_Command);
  4. }

  5. void WriteDat(unsigned char I2C_Data)//写数据
  6. {
  7.         I2C_WriteByte(0x40, I2C_Data);
  8. }
屏幕的所有操作都是通过这两个函数控制的,所以这里我们只要把这两个函数改成nanoPi的就可以了
  1. void WriteCmd(unsigned char I2C_Command)//写命令
  2. {
  3.   // I2C_WriteByte(0x00, I2C_Command);
  4.   wiringPiI2CWriteReg8(fd, 0x00, I2C_Command);
  5. }

  6. void WriteDat(unsigned char I2C_Data)//写数据
  7. {
  8.   // I2C_WriteByte(0x40, I2C_Data);
  9.   wiringPiI2CWriteReg8(fd, 0x40, I2C_Data);
  10. }
wiringPiI2CWriteReg8函数在wiringPiI2C.c中可以找到;

剩下的就是普通OLED的寄存器操作了

完整代码:
  1. /***
  2.   Copyright (c) 2018
  3.   All rights reserved.

  4.   File name           :oled_iic_main.c
  5.   file identification :
  6.   Subject             :Say something about the file

  7.   Current Version     :V1.0.0
  8.   Author              :Hacker
  9.   Date                :

  10.   Instead Version     :
  11.   Author              :Hacker
  12.   Date                :
  13. ***/
  14. #include
  15. #include
  16. #include "wiringPiI2C.h"

  17. #include "codetab.h"
  18. #include "pcf8574.h"

  19. // LED Pin - wiringPi pin 0 is BCM_GPIO 17.

  20. #define OLED_ADDRESS  0x3C //通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78
  21. int fd = 0;

  22. void WriteCmd(unsigned char I2C_Command)//写命令
  23. {
  24.   // I2C_WriteByte(0x00, I2C_Command);
  25.   wiringPiI2CWriteReg8(fd, 0x00, I2C_Command);
  26. }

  27. void WriteDat(unsigned char I2C_Data)//写数据
  28. {
  29.   // I2C_WriteByte(0x40, I2C_Data);
  30.   wiringPiI2CWriteReg8(fd, 0x40, I2C_Data);
  31. }

  32. void OLED_Init(void)
  33. {
  34.   delay(100); //这里的延时很重要
  35.   
  36.   WriteCmd(0xAE); //display off
  37.   WriteCmd(0x20); //Set Memory Addressing Mode  
  38.   WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
  39.   WriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7
  40.   WriteCmd(0xc8); //Set COM Output Scan Direction
  41.   WriteCmd(0x00); //---set low column address
  42.   WriteCmd(0x10); //---set high column address
  43.   WriteCmd(0x40); //--set start line address
  44.   WriteCmd(0x81); //--set contrast control register
  45.   WriteCmd(0xff); //亮度调节 0x00~0xff
  46.   WriteCmd(0xa1); //--set segment re-map 0 to 127
  47.   WriteCmd(0xa6); //--set normal display
  48.   WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
  49.   WriteCmd(0x3F); //
  50.   WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
  51.   WriteCmd(0xd3); //-set display offset
  52.   WriteCmd(0x00); //-not offset
  53.   WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
  54.   WriteCmd(0xf0); //--set divide ratio
  55.   WriteCmd(0xd9); //--set pre-charge period
  56.   WriteCmd(0x22); //
  57.   WriteCmd(0xda); //--set com pins hardware configuration
  58.   WriteCmd(0x12);
  59.   WriteCmd(0xdb); //--set vcomh
  60.   WriteCmd(0x20); //0x20,0.77xVcc
  61.   WriteCmd(0x8d); //--set DC-DC enable
  62.   WriteCmd(0x14); //
  63.   WriteCmd(0xaf); //--turn on oled panel
  64. }

  65. void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
  66. {
  67.   WriteCmd(0xb0+y);
  68.   WriteCmd(((x&0xf0)>>4)|0x10);
  69.   WriteCmd((x&0x0f)|0x01);
  70. }

  71. void OLED_Fill(unsigned char fill_Data)//全屏填充
  72. {
  73.   unsigned char m,n;
  74.   for(m=0;m<8;m++)
  75.   {
  76.     WriteCmd(0xb0+m);   //page0-page1
  77.     WriteCmd(0x00);   //low column start address
  78.     WriteCmd(0x10);   //high column start address
  79.     for(n=0;n<128;n++)
  80.       {
  81.         WriteDat(fill_Data);
  82.       }
  83.   }
  84. }

  85. void OLED_CLS(void)//清屏
  86. {
  87.   OLED_Fill(0x00);
  88. }

  89. //--------------------------------------------------------------
  90. // Prototype      : void OLED_ON(void)
  91. // Calls          :
  92. // Parameters     : none
  93. // Description    : 将OLED从休眠中唤醒
  94. //--------------------------------------------------------------
  95. void OLED_ON(void)
  96. {
  97.   WriteCmd(0X8D);  //设置电荷泵
  98.   WriteCmd(0X14);  //开启电荷泵
  99.   WriteCmd(0XAF);  //OLED唤醒
  100. }

  101. //--------------------------------------------------------------
  102. // Prototype      : void OLED_OFF(void)
  103. // Calls          :
  104. // Parameters     : none
  105. // Description    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
  106. //--------------------------------------------------------------
  107. void OLED_OFF(void)
  108. {
  109.   WriteCmd(0X8D);  //设置电荷泵
  110.   WriteCmd(0X10);  //关闭电荷泵
  111.   WriteCmd(0XAE);  //OLED休眠
  112. }

  113. //--------------------------------------------------------------
  114. // Prototype      : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
  115. // Calls          :
  116. // Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
  117. // Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
  118. //--------------------------------------------------------------
  119. void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
  120. {
  121.   unsigned char c = 0,i = 0,j = 0;
  122.   switch(TextSize)
  123.   {
  124.     case 1:
  125.     {
  126.       while(ch[j] != '\0')
  127.       {
  128.         c = ch[j] - 32;
  129.         if(x > 126)
  130.         {
  131.           x = 0;
  132.           y++;
  133.         }
  134.         OLED_SetPos(x,y);
  135.         for(i=0;i<6;i++)
  136.           WriteDat(F6x8[c][i]);
  137.         x += 6;
  138.         j++;
  139.       }
  140.     }break;
  141.     case 2:
  142.     {
  143.       while(ch[j] != '\0')
  144.       {
  145.         c = ch[j] - 32;
  146.         if(x > 120)
  147.         {
  148.           x = 0;
  149.           y++;
  150.         }
  151.         OLED_SetPos(x,y);
  152.         for(i=0;i<8;i++)
  153.           WriteDat(F8X16[c*16+i]);
  154.         OLED_SetPos(x,y+1);
  155.         for(i=0;i<8;i++)
  156.           WriteDat(F8X16[c*16+i+8]);
  157.         x += 8;
  158.         j++;
  159.       }
  160.     }break;
  161.   }
  162. }

  163. //--------------------------------------------------------------
  164. // Prototype      : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
  165. // Calls          :
  166. // Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
  167. // Description    : 显示codetab.h中的汉字,16*16点阵
  168. //--------------------------------------------------------------
  169. void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
  170. {
  171.   unsigned char wm=0;
  172.   unsigned int  adder=32*N;
  173.   OLED_SetPos(x , y);
  174.   for(wm = 0;wm < 16;wm++)
  175.   {
  176.     WriteDat(F16x16[adder]);
  177.     adder += 1;
  178.   }
  179.   OLED_SetPos(x,y + 1);
  180.   for(wm = 0;wm < 16;wm++)
  181.   {
  182.     WriteDat(F16x16[adder]);
  183.     adder += 1;
  184.   }
  185. }

  186. //--------------------------------------------------------------
  187. // Prototype      : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
  188. // Calls          :
  189. // Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
  190. // Description    : 显示BMP位图
  191. //--------------------------------------------------------------
  192. void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
  193. {
  194.   unsigned int j=0;
  195.   unsigned char x,y;

  196.   if(y1%8==0)
  197.     y = y1/8;
  198.   else
  199.     y = y1/8 + 1;
  200.   for(y=y0;y
  201.   {
  202.     OLED_SetPos(x0,y);
  203.     for(x=x0;x
  204.     {
  205.       WriteDat(BMP[j++]);
  206.     }
  207.   }
  208. }


  209. int main (void)
  210. {
  211.   printf ("nanoPi oled
  212. ") ;
  213.   fd = wiringPiI2CSetup(OLED_ADDRESS);

  214.   printf ("fd = %d
  215. ", fd) ;

  216.   OLED_Init();
  217.   delay(100);
  218.   
  219.   OLED_Fill(0xa0);
  220.   delay(500);

  221.   OLED_Fill(0x60);
  222.   delay(500);

  223.   OLED_Fill(0);
  224.   delay(500);

  225.   OLED_ShowStr(10, 2, "Haha, nanoPi", 1);
  226.   OLED_ShowStr(10, 3, "Haha, nanoPi", 2);

  227.   printf ("test end
  228. ") ;

  229.   return 0 ;
  230. }

保存好之后,执行编译
  1. gcc -g -o oled_iic_main oled_iic_main.c -lwiringPi -lpthread
执行
  1. sudo ./oled_iic_main

=======================================================

实验难度不大,不过过程却并不简单,实现这个需要很多准本工作
1、首先需要使能IIC,在npi-config中操作
2、由于库函数不同单片机中IIC设备地址是8位,然而本库函数是7位
设备地址的问题排查花了不少时间,这里采用了I2C-tools,经过i2c-tetect检测到设备地址,显示0x3C
,根据这个修改了程序中的设备地址,问题解决了

实验过程比实验结果精彩很多


` oled_hah.jpg
oled.rar (5.95 KB)
(下载次数: 21, 2018-7-27 17:13 上传)

回帖(1)

宋威

2020-10-15 17:29:29
嗯,
sudo -i
cd wiringPi # the directory where you downloaded it
./build
exit
代码可以顺利编译使用
举报

更多回帖

发帖
×
20
完善资料,
赚取积分