[开发工具] 【APM32F107VC-MINI开发板测评】OLED

[复制链接]
2490|30
 楼主| 比神乐 发表于 2023-3-9 12:03 | 显示全部楼层 |阅读模式
今天搞了一下OLED。模拟I2C时序。
PC0接SCL,PC1接SDA。
代码:
  1. #include "main.h"
  2. #include "oled.h"
  3. /** @addtogroup Examples
  4.   @{
  5. */


  6. uint8_t temp;
  7. uint8_t txBuffer[50];
  8. uint8_t rxBuffer[10];
  9. uint8_t cord_h,cord_l;//???????
  10. volatile uint32_t nBytesRead = 0;
  11. //volatile bool txThresholdEventReceived = false;
  12. //volatile bool rxThresholdEventReceived = false;

  13. /** @addtogroup USART_Printf
  14.   @{
  15. */

  16. /** @addtogroup USART_Printf_Variables Variables
  17.   @{
  18. */

  19. volatile uint32_t tick = 0;
  20. uint8_t txBuf[] = "Key Value = :   \r\n";

  21. /**@} end of group USART_Printf_Variables */
  22. void DelayMs(uint16_t nms)
  23. {
  24.         uint16_t i,j;                  
  25.         for(i=0;i<nms;i++)
  26.        for(j=0;j<200;j++);
  27. }
  28. /** @addtogroup USART_Printf_Functions Functions
  29.   @{
  30. */
  31. //void PORT_Initialize1(void)
  32. //{
  33. //   /************************** GROUP 0 Initialization *************************/
  34. //         GPIO_Config_T GPIO_ConfigStruct;

  35. //   /************************** GROUP 1 Initialization *************************/
  36. //   RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_GPIOC);
  37. //         
  38. //                GPIO_ConfigStruct.mode = GPIO_MODE_OUT_PP;
  39. //                GPIO_ConfigStruct.pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
  40. //                GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
  41. //                GPIO_Config(GPIOC, &GPIO_ConfigStruct);

  42. //                GPIO_ConfigStruct.mode = GPIO_MODE_IN_PU;
  43. //                GPIO_ConfigStruct.pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
  44. //                GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
  45. //                GPIO_Config(GPIOA, &GPIO_ConfigStruct);
  46. //}
  47. //void PORT_Initialize2(void)
  48. //{
  49. //   GPIO_Config_T GPIO_ConfigStruct;

  50. //   /************************** GROUP 1 Initialization *************************/
  51. //   RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA  | RCM_APB2_PERIPH_GPIOC);
  52. //         
  53. //                GPIO_ConfigStruct.mode = GPIO_MODE_OUT_PP;
  54. //                GPIO_ConfigStruct.pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
  55. //                GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
  56. //                GPIO_Config(GPIOA, &GPIO_ConfigStruct);

  57. //                GPIO_ConfigStruct.mode = GPIO_MODE_IN_PU;
  58. //                GPIO_ConfigStruct.pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3;
  59. //                GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
  60. //                GPIO_Config(GPIOC, &GPIO_ConfigStruct);

  61. //}


  62. /*!
  63. * [url=home.php?mod=space&uid=247401]@brief[/url]       Main program
  64. *
  65. * @param       None
  66. *
  67. * @retval      None
  68. *
  69. */
  70. int main(void)
  71. {
  72.     uint8_t i;

  73.     GPIO_Config_T GPIO_ConfigStruct;
  74.     USART_Config_T USART_ConfigStruct;

  75.     APM_MINI_LEDInit(LED2);

  76.     RCM_EnableAPB2PeriphClock((RCM_APB2_PERIPH_T)(RCM_APB2_PERIPH_GPIOA | RCM_APB2_PERIPH_USART1));

  77.     GPIO_ConfigStruct.mode = GPIO_MODE_AF_PP;
  78.     GPIO_ConfigStruct.pin = GPIO_PIN_9;
  79.     GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
  80.     GPIO_Config(GPIOA, &GPIO_ConfigStruct);

  81.     USART_ConfigStruct.baudRate = 115200;
  82.     USART_ConfigStruct.hardwareFlow = USART_HARDWARE_FLOW_NONE;
  83.     USART_ConfigStruct.mode = USART_MODE_TX;
  84.     USART_ConfigStruct.parity = USART_PARITY_NONE;
  85.     USART_ConfigStruct.stopBits = USART_STOP_BIT_1;
  86.     USART_ConfigStruct.wordLength = USART_WORD_LEN_8B;
  87.     USART_Config(USART1, &USART_ConfigStruct);

  88.     USART_Enable(USART1);

  89.     SysTick_Config(SystemCoreClock / 1000);
  90.                 I2C_Init();
  91.                 OLED_Init();
  92.    // OLED_ShowChar(0,0,'1',16);
  93.     //OLED_ShowNum(0,2,123,3,16);
  94.     OLED_ShowString(10,0,"21ic",16);
  95.     OLED_ShowCHinese(10,2,0);
  96.                 OLED_ShowCHinese(26,2,1);
  97.                 OLED_ShowCHinese(42,2,2);
  98.                 OLED_ShowCHinese(58,2,3);
  99.                 OLED_ShowCHinese(74,2,4);
  100.                
  101.                
  102.     while(1)
  103.     {

  104.                                
  105.                                                 for(i = 0; i < sizeof(txBuf); i++)
  106.                                                 {
  107.                                                                 while(USART_ReadStatusFlag(USART1, USART_FLAG_TXBE) == RESET);
  108.                                                                 USART_TxData(USART1, txBuf[i]);
  109.                                                 }
  110.         
  111.     }
  112. }

  113. /*!
  114. * @brief       Delay
  115. *
  116. * @param       None
  117. *
  118. * @retval      None
  119. *
  120. */
  121. void Delay(void)
  122. {
  123.     tick = 0;

  124.     while(tick < 500);
  125. }

  126. /**@} end of group USART_Printf_Functions */
  127. /**@} end of group USART_Printf */
  128. /**@} end of group Examples */
OLED.C程序:
  1. #include "oled.h"


  2. //OLED的显存
  3. //存放格式如下.
  4. //[0]0 1 2 3 ... 127       
  5. //[1]0 1 2 3 ... 127       
  6. //[2]0 1 2 3 ... 127       
  7. //[3]0 1 2 3 ... 127       
  8. //[4]0 1 2 3 ... 127       
  9. //[5]0 1 2 3 ... 127       
  10. //[6]0 1 2 3 ... 127       
  11. //[7]0 1 2 3 ... 127                           

  12. /**
  13.   * @brief  Write_I2C_Data 向OLED写入数据
  14.   * @param  I2C_Data:数据
  15.   * @retval 无
  16.   */
  17. /**********************************************************************************************************
  18. *   函 数 名: AT24Cxx_WriteOneByte
  19. *   功能说明: AT24Cxx_WriteOneByte  写一个字节
  20. *   形    参:无
  21. *   返 回 值: 无
  22. **********************************************************************************************************/
  23. void WriteOneByte1(u8 dt)
  24. {
  25.     I2C_Start();

  26.    
  27.      I2C_Send_Byte(0x78);//器件地址+数据地址
  28.    

  29.     I2C_Wait_Ack();
  30.     I2C_Send_Byte(0x40);//双字节是数据地址低位               
  31.                                                     //单字节是数据地址低位
  32.     I2C_Wait_Ack();

  33.     I2C_Send_Byte(dt);
  34.     I2C_Wait_Ack();
  35.     I2C_Stop();

  36.     //delay_ms(10);
  37. }
  38. void WriteOneByte2(u8 dt)
  39. {
  40.     I2C_Start();

  41.    
  42.      I2C_Send_Byte(0x78);//器件地址+数据地址
  43.    

  44.     I2C_Wait_Ack();
  45.     I2C_Send_Byte(0x00);//双字节是数据地址低位               
  46.                                                     //单字节是数据地址低位
  47.     I2C_Wait_Ack();

  48.     I2C_Send_Byte(dt);
  49.     I2C_Wait_Ack();
  50.     I2C_Stop();

  51.     //delay_ms(10);
  52. }
  53. static void Write_I2C_Data(uint8_t I2C_Data)//写数据
  54. {
  55.     WriteOneByte1(I2C_Data);                               
  56. }

  57. /**
  58.   * @brief  Write_I2C_Command,向OLED写入命令
  59.   * @param  I2C_Command
  60.   * @retval 无
  61.   */
  62. static void Write_I2C_Command(uint8_t I2C_Command)//写命令
  63. {
  64.     WriteOneByte2(I2C_Command);
  65. }


  66. void OLED_WR_Byte(unsigned dat,unsigned cmd)
  67. {
  68.         if(cmd)
  69.                 Write_I2C_Data(dat);
  70.         else
  71.                 Write_I2C_Command(dat);
  72. }

  73. /********************************************
  74. // fill_Picture
  75. ********************************************/
  76. void fill_picture(uint8_t fill_Data)
  77. {
  78.         uint8_t m,n;
  79.         for(m=0; m<8; m++)
  80.         {
  81.                 OLED_WR_Byte(0xb0+m,0);                //page0-page1
  82.                 OLED_WR_Byte(0x00,0);                //low column start address
  83.                 OLED_WR_Byte(0x10,0);                //high column start address
  84.                 for(n=0; n<128; n++)
  85.                 {
  86.                         OLED_WR_Byte(fill_Data,1);
  87.                 }
  88.         }
  89. }


  90. //坐标设置
  91. void OLED_Set_Pos(uint8_t x, uint8_t y)
  92. {        
  93.         OLED_WR_Byte(0xb0+y, OLED_CMD);
  94.         OLED_WR_Byte(((x&0xf0)>>4)|0x10, OLED_CMD);
  95.         OLED_WR_Byte((x&0x0f), OLED_CMD);
  96. }             


  97. //开启OLED显示   
  98. void OLED_Display_On(void)
  99. {
  100.         OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDC命令
  101.         OLED_WR_Byte(0X14, OLED_CMD);  //DCDC ON
  102.         OLED_WR_Byte(0XAF, OLED_CMD);  //DISPLAY ON
  103. }


  104. //关闭OLED显示     
  105. void OLED_Display_Off(void)
  106. {
  107.         OLED_WR_Byte(0X8D, OLED_CMD);  //SET DCDC命令
  108.         OLED_WR_Byte(0X10, OLED_CMD);  //DCDC OFF
  109.         OLED_WR_Byte(0XAE, OLED_CMD);  //DISPLAY OFF
  110. }       


  111. //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!          
  112. void OLED_Clear(void)  
  113. {  
  114.         uint8_t i,n;                    
  115.         for(i=0; i<8; i++)  
  116.         {  
  117.                 OLED_WR_Byte (0xb0+i, OLED_CMD);    //设置页地址(0~7)
  118.                 OLED_WR_Byte (0x00,   OLED_CMD);      //设置显示位置—列低地址
  119.                 OLED_WR_Byte (0x10,   OLED_CMD);      //设置显示位置—列高地址   
  120.                 for(n=0; n<128; n++)
  121.                         OLED_WR_Byte(0, OLED_DATA);
  122.         }
  123. }


  124. void OLED_ON(void)  
  125. {  
  126.         uint8_t i,n;                    
  127.         for(i=0; i<8; i++)  
  128.         {  
  129.                 OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
  130.                 OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
  131.                 OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
  132.                 for(n=0; n<128; n++)
  133.                         OLED_WR_Byte(1, OLED_DATA);
  134.         }
  135. }


  136. //在指定位置显示一个字符,包括部分字符
  137. //x:0~127
  138. //y:0~63
  139. //mode:0,反白显示;1,正常显示                                 
  140. //size:选择字体 16/12
  141. void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
  142. {             
  143.         uint8_t c=0,i=0;       
  144.         c=chr-' ';//得到偏移后的值                       
  145.         if(x>Max_Column-1)
  146.         {
  147.                 x = 0;
  148.                 y = y+2;
  149.         }
  150.         if(Char_Size == 16)
  151.         {
  152.                 OLED_Set_Pos(x, y);       
  153.                 for(i=0; i<8; i++)
  154.                         OLED_WR_Byte(F8X16[c*16 + i], OLED_DATA);
  155.                
  156.                 OLED_Set_Pos(x, y+1);
  157.                 for(i=0; i<8; i++)
  158.                         OLED_WR_Byte(F8X16[c*16 + i + 8], OLED_DATA);
  159.         }
  160.         else
  161.         {       
  162.                 OLED_Set_Pos(x, y);
  163.                 for(i=0; i<6; i++)
  164.                         OLED_WR_Byte(F6x8[c][i], OLED_DATA);
  165.         }
  166. }


  167. //m^n函数
  168. uint32_t OLED_pow(uint8_t m, uint8_t n)
  169. {
  170.         uint32_t result = 1;         
  171.         while(n--)
  172.                 result *= m;   
  173.        
  174.         return result;
  175. }                                  


  176. //显示2个数字
  177. //x,y :起点坐标         
  178. //len :数字的位数
  179. //size:字体大小
  180. //mode:模式        0,填充模式;1,叠加模式
  181. //num:数值(0~4294967295);                           
  182. void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2)
  183. {                
  184.         uint8_t t,temp;
  185.         uint8_t enshow = 0;                                                  
  186.         for(t=0; t<len; t++)
  187.         {
  188.                 temp = (num/OLED_pow(10, len-t-1)) %10;
  189.                 if(enshow == 0 && t<(len-1))
  190.                 {
  191.                         if(temp == 0)
  192.                         {
  193.                                 OLED_ShowChar(x+(size2/2)*t, y, ' ', size2);
  194.                                 continue;
  195.                         }
  196.                         else
  197.                                 enshow = 1;                           
  198.                 }
  199.                  OLED_ShowChar(x+(size2/2)*t, y, temp+'0', size2);
  200.         }
  201. }


  202. //显示一个字符号串
  203. void OLED_ShowString(uint8_t x, uint8_t y, char *chr, uint8_t Char_Size)
  204. {
  205.         uint8_t j=0;
  206.         while (chr[j] != '\0')
  207.         {               
  208.                 OLED_ShowChar(x, y, chr[j], Char_Size);
  209.                 x += 8;
  210.                 if(x>120)
  211.                 {
  212.                         x=0;
  213.                         y+=2;
  214.                 }
  215.                 j++;
  216.         }
  217. }


  218. //显示汉字
  219. void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no)
  220. {                                  
  221.         uint8_t t,adder=0;
  222.         OLED_Set_Pos(x,y);       
  223.         for(t=0;t<16;t++)
  224.         {
  225.                 OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
  226.                 adder+=1;
  227.         }       
  228.         OLED_Set_Pos(x,y+1);       
  229.         for(t=0;t<16;t++)
  230.         {       
  231.                 OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
  232.                 adder+=1;
  233.         }                                       
  234. }
  235. /***********功能描述:
  236. 显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7
  237. *****************/
  238. void OLED_DrawBMP(uint8_t x0, uint8_t y0,uint8_t x1, uint8_t y1, uint8_t BMP[])
  239. {        
  240.         unsigned int j=0;
  241.         uint8_t x,y;

  242.         if(y1%8 == 0)
  243.                 y = y1/8;      
  244.         else
  245.                 y = y1/8 + 1;
  246.         for(y=y0; y<y1; y++)
  247.         {
  248.                 OLED_Set_Pos(x0, y);
  249.                 for(x=x0; x<x1; x++)
  250.                 {      
  251.                         OLED_WR_Byte(BMP[j++], OLED_DATA);                   
  252.                 }
  253.         }
  254. }

  255. //初始化SSD1306                                            
  256. void OLED_Init(void)
  257. {        
  258.   long int i;
  259.     for(i=0;i<20000;i++);
  260.         //Ddl_Delay1ms(100);
  261.         OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示
  262.        
  263.         OLED_WR_Byte(0x40,OLED_CMD);//---set low column address
  264.         OLED_WR_Byte(0xB0,OLED_CMD);//---set high column address

  265.         OLED_WR_Byte(0xC8,OLED_CMD);//-not offset

  266.         OLED_WR_Byte(0x81,OLED_CMD);//设置对比度
  267.         OLED_WR_Byte(0xff,OLED_CMD);

  268.         OLED_WR_Byte(0xa1,OLED_CMD);//段重定向设置

  269.         OLED_WR_Byte(0xa6,OLED_CMD);//
  270.        
  271.         OLED_WR_Byte(0xa8,OLED_CMD);//设置驱动路数
  272.         OLED_WR_Byte(0x1f,OLED_CMD);
  273.        
  274.         OLED_WR_Byte(0xd3,OLED_CMD);
  275.         OLED_WR_Byte(0x00,OLED_CMD);
  276.        
  277.         OLED_WR_Byte(0xd5,OLED_CMD);
  278.         OLED_WR_Byte(0xf0,OLED_CMD);
  279.        
  280.         OLED_WR_Byte(0xd9,OLED_CMD);
  281.         OLED_WR_Byte(0x22,OLED_CMD);
  282.        
  283.         OLED_WR_Byte(0xda,OLED_CMD);
  284.         OLED_WR_Byte(0x02,OLED_CMD);
  285.        
  286.         OLED_WR_Byte(0xdb,OLED_CMD);
  287.         OLED_WR_Byte(0x49,OLED_CMD);
  288.        
  289.         OLED_WR_Byte(0x8d,OLED_CMD);
  290.         OLED_WR_Byte(0x14,OLED_CMD);
  291.        
  292.         OLED_WR_Byte(0xaf,OLED_CMD);
  293.         OLED_Clear();
  294. }  

效果图:
2.jpg


3.jpg


nawu 发表于 2023-4-4 16:46 | 显示全部楼层
是不是感觉模拟的iic比自带的模块要运行稳定点呢
 楼主| 比神乐 发表于 2023-4-5 09:44 | 显示全部楼层
nawu 发表于 2023-4-4 16:46
是不是感觉模拟的iic比自带的模块要运行稳定点呢

硬件i2c不好搞
tpgf 发表于 2023-4-6 08:40 | 显示全部楼层
主要是时序这块要求的比较高 需要反复调整
aoyi 发表于 2023-4-6 11:28 | 显示全部楼层
我比较好奇的是 因为iic可以带好多设备 那么设备名称如何批量写入呢
zljiu 发表于 2023-4-6 13:29 | 显示全部楼层
一般来说一条总线上可以带多少个从设备呢
gwsan 发表于 2023-4-6 14:00 | 显示全部楼层
zljiu 发表于 2023-4-6 13:29
一般来说一条总线上可以带多少个从设备呢

不是255就是256个设备,不过很少有真的带这么多设备的吧
tfqi 发表于 2023-4-6 14:27 | 显示全部楼层
gwsan 发表于 2023-4-6 14:00
不是255就是256个设备,不过很少有真的带这么多设备的吧

一条总线的带载能力和什么参数有关系呢
uptown 发表于 2023-4-8 21:43 | 显示全部楼层
电流居然在900uA左右。               
youtome 发表于 2023-4-8 21:47 | 显示全部楼层
用oled和lcd显示有什么不同  
1988020566 发表于 2023-4-8 22:14 | 显示全部楼层
调试OLED液晶,显示不稳定,需要多次复位才可以
mikewalpole 发表于 2023-4-8 22:23 | 显示全部楼层
驱动oled要上拉吗               
 楼主| 比神乐 发表于 2023-4-9 10:36 | 显示全部楼层
youtome 发表于 2023-4-8 21:47
用oled和lcd显示有什么不同

我这个OLED是I2C接口的
sdlls 发表于 2023-4-9 13:48 | 显示全部楼层
彩色的oled的驱动代码有吗?              
minzisc 发表于 2023-4-9 13:57 | 显示全部楼层
APM32F107VC怎么连接oled12864
wangdezhi 发表于 2023-4-9 14:05 | 显示全部楼层
如何显示一个数组呢              
iyoum 发表于 2023-4-9 14:11 | 显示全部楼层
0.96寸OLED显示屏,怎么显示字符串变量?
xiaoyaodz 发表于 2023-4-9 14:21 | 显示全部楼层
APM32F107VC的性能不错。
1988020566 发表于 2023-4-9 14:26 | 显示全部楼层
驱动oled如何实现反色显示表示选中功能
pixhw 发表于 2023-4-9 14:32 | 显示全部楼层
写OLED的代码内存不够怎么办  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

470

主题

3537

帖子

7

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