你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

oled显示问题

[复制链接]
midfieldmaestro 提问时间:2019-5-8 22:00 /
IMG_20190508_211652.jpg
为什么我的oled第二行显示就把字
  1. #include "oled.h"
  2. #include "stm32f4xx_gpio.h"
  3. #include "oledfont.h"
  4. #include "delay.h"
  5. #include "myiic.h"



  6. void OLED_GPIO_Init(void)
  7. {
  8.         GPIO_Init_Pins(GPIOD,GPIO_Pin_0,GPIO_Mode_OUT);
  9.         GPIO_Init_Pins(GPIOD,GPIO_Pin_1,GPIO_Mode_OUT);
  10.         GPIO_Init_Pins(GPIOD,GPIO_Pin_3,GPIO_Mode_OUT);
  11.         GPIO_Init_Pins(GPIOD,GPIO_Pin_2,GPIO_Mode_OUT);
  12.         GPIO_Init_Pins(GPIOD,GPIO_Pin_4,GPIO_Mode_OUT);
  13. }

  14. void XINGC_Init(void)
  15. {
  16.         GPIO_InitTypeDef GPIO_InitStructure;
  17.        
  18.         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  19.        
  20.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;
  21.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
  22.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  23.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  24.         GPIO_Init(GPIOC,&GPIO_InitStructure);       
  25.        
  26. }


  27. /**
  28.   * @brief  向SSD1106写入一个字节  主要用于寄存器的配置
  29.   *
  30.   * @param  dat:要写入的数据/命令
  31.   * @param  cmd:数据/命令标志 0,表示命令;1,表示数据;
  32.   *     @arg
  33.   * @retval None
  34.   */
  35. void Write_IIC_Data(unsigned char IIC_Data)
  36. {
  37.    IIC_Start();
  38.    IIC_Send_Byte(0x78);                        //D/C#=0; R/W#=0
  39.         IIC_Wait_Ack();       
  40.    IIC_Send_Byte(0x40);                        //write data
  41.         IIC_Wait_Ack();       
  42.    IIC_Send_Byte(IIC_Data);
  43.         IIC_Wait_Ack();       
  44.    IIC_Stop();
  45. }
  46. /**********************************************
  47. // IIC Write Command
  48. **********************************************/
  49. void Write_IIC_Command(unsigned char IIC_Command)
  50. {
  51.    IIC_Start();
  52.    IIC_Send_Byte(0x78);            //Slave address,SA0=0
  53.         if(IIC_Wait_Ack())
  54.         {
  55.                 while(1);
  56.         }
  57.    IIC_Send_Byte(0x00);                        //write command
  58.         IIC_Wait_Ack();       
  59.    IIC_Send_Byte(IIC_Command);
  60.         IIC_Wait_Ack();       
  61.    IIC_Stop();
  62. }
  63. void OLED_WR_Byte(uint8_t dat,uint8_t cmd)  
  64. {       
  65.          
  66.        
  67.         if(cmd)
  68.           Write_IIC_Data(dat);
  69.         else
  70.                  Write_IIC_Command(dat);
  71. }

  72. /**
  73.   * @brief
  74.   *
  75.   * @param
  76.   *     @arg
  77.   * @retval None
  78.   */
  79. void OLED_Set_Pos(uint8_t x, uint8_t y)
  80. {
  81.         OLED_WR_Byte(0xb0+(y & 0x07),OLED_CMD);/* set page start address */
  82.         OLED_WR_Byte(x & 0x0f,OLED_CMD); /* set page start address */
  83.         OLED_WR_Byte(((x & 0xf0)>>4)|0x10,OLED_CMD); /* set higher nibble of the column address */
  84. }             
  85. /**
  86.   * @brief  开启OLED显示   
  87.   *
  88.   * @param
  89.   *
  90.   * @retval None
  91.   */
  92. void OLED_Display_On(void)
  93. {
  94.         OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
  95.         OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
  96.         OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
  97. }

  98. /**
  99.   * @brief  关闭OLED显示   
  100.   *
  101.   * @param
  102.   *
  103.   * @retval None
  104.   */   
  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. /**
  113.   * @brief 清屏函数,清完屏,整个屏幕是黑色的,和没点亮一样
  114.   *
  115.   * @param  None
  116.   *
  117.   * @retval None
  118.   */
  119. void OLED_Clear(void)  
  120. {  
  121.         uint8_t page,x;            
  122.         for(page=0; page<PAGE; page++)  
  123.         {  
  124.                 OLED_WR_Byte (0xb0 + page,OLED_CMD);                                    //设置页地址(0~7)
  125.                 OLED_WR_Byte (0x00,OLED_CMD);                                                              //设置显示位置—列低地址
  126.                 OLED_WR_Byte (0x10,OLED_CMD);                                                              //设置显示位置—列高地址   
  127.                
  128.                 for(x=0; x<X_WIDTH; x++){
  129.                         OLED_WR_Byte(0,OLED_DATA);
  130.                 }
  131.         }

  132. }

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

  177. /**
  178.   * @brief  计算m的n次方
  179.   *
  180.   * @param  底数和指数
  181.   *     
  182.   * @retval 幂的值
  183.   */
  184. u32 oled_pow(u8 m,u8 n)
  185. {
  186.         u32 result=1;         
  187.         while(n--)
  188.         {
  189.                 result *= m;   
  190.         }
  191.         return result;
  192. }                                  
  193.        
  194. /**
  195.   * @brief  显示2个数字
  196.   *
  197.   * @param  x,y :起点坐标          len :数字的位数  size:字体大小 mode:模式        0,填充模式;1,叠加模式 num:数值(0~4294967295);
  198.   *     @arg
  199.   * @retval None
  200.   */
  201. void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len)
  202. {                
  203.         uint8_t t,temp;
  204.         uint8_t enshow=0;                               
  205.        
  206.         for(t=0; t<len; t++){
  207.                 temp=(num/oled_pow(10,len-t-1))%10;//把多位数的数值分出来  从高到低
  208.                
  209.                 if(enshow == 0 && t < (len-1))  //排除最后一位数  第一位
  210.                 {
  211.                         if(temp == 0)
  212.                         {
  213.                                 OLED_ShowChar( x+(SIZEGAP/2)*t, y,'0');//最高位为0则显示为空
  214.                                 continue;
  215.                         }
  216.                         else
  217.                         {
  218.                                 enshow=1;
  219.                         }                          
  220.                 }
  221.                  OLED_ShowChar( x+(SIZEGAP/2)*t, y, temp + '0');
  222.         }
  223. }

  224. /**
  225.   * @brief  显示一个字符串
  226.   *
  227.   * @param        x px,page,以及需要显示的字符串
  228.   *     
  229.   * @retval None
  230.   */
  231. void OLED_ShowString(uint8_t x,uint8_t page,uint8_t *chr)
  232. {
  233.         uint8_t j=0;
  234.         for(j=0; chr[j] != '\0'; j++)
  235.         {
  236.                 OLED_ShowChar(x,page,chr[j]);
  237.                 if(SIZE==8)
  238.                 {
  239.                         x += 6;
  240.                         if(x > 122)  //一行结束,转下一行
  241.                         {
  242.                                 x = 0;
  243.                                 page += 2;
  244.                         }
  245.           }
  246.                 else if(SIZE==16)
  247.                 {
  248.                         x += 8;
  249.                         if(x > 120)
  250.                         {
  251.                                 x = 0;
  252.                                 page += 2;
  253.                         }
  254.           }
  255.                
  256.         }
  257. }

  258. /**
  259.   * @brief  显示一个汉字(在oledfont.h中)   此部分没做修改
  260.   *
  261.   * @param
  262.   *     @arg
  263.   * @retval None
  264.   */
  265. void OLED_ShowCHinese(uint8_t x,uint8_t page,uint8_t no)
  266. {                                  
  267.         uint8_t t,adder=0;
  268.         OLED_Set_Pos(x,page);       
  269.        
  270.         for(t=0; t<16; t++)
  271.         {
  272.                 OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
  273.                 adder+=1;
  274.         }       
  275.        
  276.         OLED_Set_Pos(x,page + 1);       
  277.        
  278.         for(t=0; t<16; t++)
  279.         {       
  280.                 OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
  281.                 adder += 1;
  282.         }                                       
  283. }

  284. /**
  285.   * @brief  显示一个浮点数,小数部分输出3位
  286.   *
  287.   * @param  输出坐标,数字,大小
  288.   *     @arg
  289.   * @retval None
  290.   */
  291. void OLED_FloatNumber(uint8_t x,uint8_t y, double num)
  292. {
  293.         u32 integerPart;
  294.         u8 integerPartNum;
  295.         u8  gap=0;
  296.         if(num <0 ){
  297.                 num = -num;
  298.                 OLED_ShowString(x,y,(uint8_t *)"-");
  299.         }
  300.        
  301.         //让显示效果好一点
  302.         if(SIZE==8)
  303.         {
  304.                 x += 7;
  305.                 if(x > 121)
  306.                 {
  307.                         x = 0;
  308.                         y += 2;
  309.                 }       
  310.         }
  311.        
  312.         if(SIZE==16)
  313.         {
  314.                 x += 10;
  315.                 if(x > 128)
  316.                 {
  317.                         x = 0;
  318.                         y += 2;
  319.                 }       
  320.   }
  321.        
  322.         //计算整数部分  几个数
  323.         for(integerPartNum = 0,integerPart = (u32)num; integerPart != 0; integerPartNum++){
  324.                 integerPart /= 10;
  325.         }
  326.         if(SIZE==8)
  327.                 gap=6;
  328.         else if(SIZE==16)
  329.                 gap=8;
  330.         if(x > 128 - (integerPartNum+4)*gap){
  331.                 x = 0;
  332.                 y += 2;
  333.         }

  334.         OLED_ShowNum(x,y,(int32_t)num,integerPartNum);       
  335.         x += integerPartNum*gap;       
  336.         OLED_ShowString(x,y,(uint8_t *)".");
  337.         x += gap;
  338.         OLED_ShowNum(x,y,(int32_t)((num-integerPart)*100000),5);
  339. }

  340. /**
  341.   * @brief  初始化SSD1306                       
  342.   *
  343.   * @param
  344.   *     @arg
  345.   * @retval None
  346.   */            
  347. void OLED_Init(void)
  348. {        

  349.         delay_ms(500);                                  
  350.         OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
  351.         OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
  352.         OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
  353.        
  354.         OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
  355.        
  356.         OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
  357.         OLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current Brightness
  358.        
  359.         OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
  360.         OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
  361.        
  362.         OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
  363.        
  364.         OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
  365.         OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
  366.        
  367.         OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset        Shift Mapping RAM Counter (0x00~0x3F)
  368.         OLED_WR_Byte(0x00,OLED_CMD);//-not offset
  369.        
  370.         OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
  371.         OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
  372.        
  373.         OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
  374.         OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
  375.        
  376.         OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
  377.         OLED_WR_Byte(0x12,OLED_CMD);
  378.        
  379.         OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
  380.         OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
  381.         OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
  382.         OLED_WR_Byte(0x02,OLED_CMD);//
  383.        
  384.         OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
  385.         OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
  386.        
  387.         OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
  388.         OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
  389.        
  390.         OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel

  391.         OLED_Clear();
  392.         OLED_Set_Pos(0,0);        

  393. }  






  394. void GPIO_Init_Pins(GPIO_TypeDef * GPIOx,uint16_t GPIO_Pin,GPIOMode_TypeDef GPIO_Mode)
  395. {
  396.         GPIO_InitTypeDef GPIO_InitStructure;
  397.           /* Enable GPIOx, clock */  
  398.   switch((uint32_t)GPIOx)
  399.   {
  400.                 case GPIOA_BASE:
  401.     {
  402.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  403.                         break;
  404.     }
  405.                 case GPIOB_BASE:
  406.     {
  407.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  408.                         break;
  409.     }
  410.                 case GPIOC_BASE:
  411.     {
  412.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  413.                         break;
  414.     }
  415.                 case GPIOD_BASE:
  416.     {
  417.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
  418.                         break;
  419.     }
  420.                 case GPIOE_BASE:
  421.     {
  422.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  423.                         break;
  424.     }
  425.                 case GPIOF_BASE:
  426.     {
  427.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
  428.                         break;
  429.     }
  430.                 case GPIOG_BASE:
  431.     {
  432.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);
  433.                         break;
  434.     }
  435.                 case GPIOH_BASE:
  436.     {
  437.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
  438.                         break;
  439.     }
  440.                 case GPIOI_BASE:
  441.     {
  442.                         RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI, ENABLE);
  443.                         break;
  444.     }       
  445.                 default: break;
  446.   }
  447.        
  448.         GPIO_InitStructure.GPIO_Pin=GPIO_Pin;
  449.         GPIO_InitStructure.GPIO_Mode=GPIO_Mode;

  450.         GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
  451.         GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  452.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  453.                
  454.         GPIO_Init(GPIOx,&GPIO_InitStructure);       
  455.         GPIO_SetBits(GPIOx,GPIO_Pin);
  456. }


复制代码

分开了
收藏 1 评论4 发布时间:2019-5-8 22:00

举报

4个回答
milton6799 回答时间:2019-5-9 10:27:02
每一次發生都一樣位置嗎?我之前有發生過但位置每次都不同,原因是瀘波電容Layout放太遠,電源有高頻雜訊(200mhz以上)

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

五哥1 回答时间:2019-5-9 12:19:47
本帖最后由 五哥1 于 2019-5-9 12:27 编辑

你的程序应当是OLED.C的内容,你的主程序MAIN.C的内容没有,你说显示出现问题,问题是第二行文字分开,这要看你的主程序调用了那个显示函数,显示的文字取模是否正常,用分步调试一点一点测试,看看你的问题在哪,这个是I2C的串口屏,有许多种可能造成你的问题,有时候是一个小小的书写错误。你要有耐心,一点一点地看程序,理解内容就好办了,这个弄懂了,其他的就不是事了。第一行显示正常,第一行和第二行的区别是X、Y坐标,怀疑是汉字显示程序的程序里有错误,还有你测试过,用数字显示在第二行了吗,如果用数字没有问题,哪就是汉字显示程序的问题。

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

huangzongwu 回答时间:2019-5-9 15:07:45
milton6799 发表于 2019-5-9 10:27
每一次發生都一樣位置嗎?我之前有發生過但位置每次都不同,原因是瀘波電容Layout放太遠,電源有高頻雜訊(200m ...

对的,我现在手头上有一个类似的项目,也是显示时不时会异常,程序怎么改都没有,所以怀疑是信号干扰
milton6799 回答时间:2019-5-10 11:52:39
huangzongwu 发表于 2019-5-9 15:07
对的,我现在手头上有一个类似的项目,也是显示时不时会异常,程序怎么改都没有,所以怀疑是信号干扰 ...

確認一下電源的狀況,要用更高Mhz的示波器才能量的出來

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版