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

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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版