打印
[其他ST产品]

stm32驱动oled代码,点不亮屏幕,怀疑是时序问题(转发解答)

[复制链接]
295|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
stm32驱动oled代码,点不亮屏幕,怀疑是时序问题oled.c

#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"      
#include "delay.h"
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127   
//[1]0 1 2 3 ... 127   
//[2]0 1 2 3 ... 127   
//[3]0 1 2 3 ... 127   
//[4]0 1 2 3 ... 127   
//[5]0 1 2 3 ... 127   
//[6]0 1 2 3 ... 127   
//[7]0 1 2 3 ... 127               
/**********************************************
//IIC Start
**********************************************/
/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
    OLED_SCLK_Set() ;
    OLED_SDIN_Set();
    OLED_SDIN_Clr();
    OLED_SCLK_Clr();
}
/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
    OLED_SCLK_Set() ;
//    OLED_SCLK_Clr();
    OLED_SDIN_Clr();
    OLED_SDIN_Set();
   
}
void IIC_Wait_Ack()
{
    //GPIOB->CRH &= 0XFFF0FFFF;    //设置PB12为上拉输入模式
    //GPIOB->CRH |= 0x00080000;
//    OLED_SDA = 1;
//    delay_us(1);
    //OLED_SCL = 1;
    //delay_us(50000);
/*    while(1)
    {
        if(!OLED_SDA)                //判断是否接收到OLED 应答信号
        {
            //GPIOB->CRH &= 0XFFF0FFFF;    //设置PB12为通用推免输出模式
            //GPIOB->CRH |= 0x00030000;
            return;
        }
    }
*/
    OLED_SCLK_Set() ;
    OLED_SCLK_Clr();
}
/**********************************************
// IIC Write byte
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
    unsigned char i;
    unsigned char m,da;
    da=IIC_Byte;
//    OLED_SCLK_Clr();
    for(i=0;i<8;i++)        
    {
        m=da;
        OLED_SCLK_Clr();
        m=m&0x80;
        if(m==0x80)
        {OLED_SDIN_Set();}
        else OLED_SDIN_Clr();
        OLED_SCLK_Set();
        OLED_SCLK_Clr();
        da=da<<1;
    }
}
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
    IIC_Start();
    Write_IIC_Byte(0x78);            //Slave address,SA0=0
    IIC_Wait_Ack();   
    Write_IIC_Byte(0x00);            //write command
    IIC_Wait_Ack();   
    Write_IIC_Byte(IIC_Command);
    IIC_Wait_Ack();   
    IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
    IIC_Start();
    Write_IIC_Byte(0x78);            //D/C#=0; R/W#=0
    IIC_Wait_Ack();   
    Write_IIC_Byte(0x40);            //write data
    IIC_Wait_Ack();   
    Write_IIC_Byte(IIC_Data);
    IIC_Wait_Ack();   
    IIC_Stop();
}
void OLED_WR_Byte(unsigned dat,unsigned cmd)
{
    if(cmd)
    {
        Write_IIC_Data(dat);
    }
    else
    {
        Write_IIC_Command(dat);
    }
}
/********************************************
// fill_Picture
********************************************/
void fill_picture(unsigned char fill_Data)
{
    unsigned char m,n;
    for(m=0;m<8;m++)
    {
        OLED_WR_Byte(0xb0+m,0);        //page0-page1
        OLED_WR_Byte(0x00,0);        //low column start address
        OLED_WR_Byte(0x10,0);        //high column start address
        for(n=0;n<128;n++)
        {
            OLED_WR_Byte(fill_Data,1);
        }
    }
}
/***********************Delay****************************************/
void Delay_50ms(unsigned int Del_50ms)
{
    unsigned int m;
    for(;Del_50ms>0;Del_50ms--)
        for(m=6245;m>0;m--);
}
void Delay_1ms(unsigned int Del_1ms)
{
    unsigned char j;
    while(Del_1ms--)
    {   
        for(j=0;j<123;j++);
    }
}
//坐标设置
void OLED_Set_Pos(unsigned char x, unsigned char y)
{     OLED_WR_Byte(0xb0+y,OLED_CMD);
    OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);
    OLED_WR_Byte((x&0x0f),OLED_CMD);
}         
//开启OLED显示   
void OLED_Display_On(void)
{
    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
    OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示     
void OLED_Display_Off(void)
{
    OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
    OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}                        
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!      
//void OLED_Refresh(void)
//{
//    u8 i,n;
//    for(i=0;i<8;i++)
//    {
//       OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
//       OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
//       OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
//       for(n=0;n<128;n++)
//         OLED_WR_Byte(OLED_GRAM[n],OLED_DATA);
//  }
//}
void OLED_Clear(void)  
{  
    u8 i,n;            
    for(i=0;i<8;i++)  
    {  
        OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
        OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
        OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
        for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA);
    } //更新显示
}
void OLED_On(void)  
{  
    u8 i,n;            
    for(i=0;i<8;i++)  
    {  
        OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
        OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
        OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
        for(n=0;n<128;n++)OLED_WR_Byte(1,OLED_DATA);
    } //更新显示
}
//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示                 
//size:选择字体 16/12
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{         
    unsigned char c=0,i=0;   
    c=chr-' ';//得到偏移后的值            
    if(x>Max_Column-1){x=0;y=y+2;}
    if(Char_Size ==16)
    {
        OLED_Set_Pos(x,y);   
        for(i=0;i<8;i++)
        OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
        OLED_Set_Pos(x,y+1);
        for(i=0;i<8;i++)
        OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
    }
    else
    {   
        OLED_Set_Pos(x,y);
        for(i=0;i<6;i++)
        OLED_WR_Byte(F6x8[c],OLED_DATA);   
    }
}
//m^n函数
u32 oled_pow(u8 m,u8 n)
{
    u32 result=1;     
    while(n--)result*=m;   
    return result;
}                  
//显示2个数字
//x,y :起点坐标     
//len :数字的位数
//size:字体大小
//mode:模式    0,填充模式;1,叠加模式
//num:数值(0~4294967295);               
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{            
    u8 t,temp;
    u8 enshow=0;                           
    for(t=0;t<len;t++)
    {
        temp=(num/oled_pow(10,len-t-1))%10;
        if(enshow==0&&t<(len-1))
        {
            if(temp==0)
            {
                OLED_ShowChar(x+(size2/2)*t,y,' ',size2);
                continue;
            }
            else enshow=1;
              
        }
         OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
    }
}
//显示一个字符号串
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
{
    unsigned char j=0;
    while (chr[j]!='\0')
    {        
        OLED_ShowChar(x,y,chr[j],Char_Size);
        x+=8;
        if(x>120){x=0;y+=2;}
        j++;
    }
}
//显示汉字
void OLED_ShowCHinese(u8 x,u8 y,u8 no)
{                     
    u8 t,adder=0;
    OLED_Set_Pos(x,y);   
    for(t=0;t<16;t++)
    {
        OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);
        adder+=1;
    }   
    OLED_Set_Pos(x,y+1);   
    for(t=0;t<16;t++)
    {   
        OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);
        adder+=1;
    }                    
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{     
    unsigned int j=0;
    unsigned char x,y;
    if(y1%8==0) y=y1/8;      
    else y=y1/8+1;
    for(y=y0;y<y1;y++)
    {
        OLED_Set_Pos(x0,y);
        for(x=x0;x<x1;x++)
        {      
            OLED_WR_Byte(BMP[j++],OLED_DATA);            
        }
    }
}
//初始化SSD1306                        
void OLED_Init(void)
{     
    GPIO_InitTypeDef  GPIO_InitStructure;
   
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);     //使能A端口时钟
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6;     
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz
     GPIO_Init(GPIOC, &GPIO_InitStructure);      //初始化GPIOD3,6
     GPIO_SetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_6);   
   
   
   
    OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
    OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
    OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
    OLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
    OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
    OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
    OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
    OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
    OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
    OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
    OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
    OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset    Shift Mapping RAM Counter (0x00~0x3F)
    OLED_WR_Byte(0x00,OLED_CMD);//-not offset
    OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
    OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
    OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
    OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
    OLED_WR_Byte(0x12,OLED_CMD);
    OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
    OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
    OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
    OLED_WR_Byte(0x02,OLED_CMD);//
    OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
    OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
    OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
    OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
    OLED_WR_Byte(0xAF,OLED_CMD);
    OLED_Clear();
   
   
}





oled.h


<font color="#000000">#ifndef __OLED_H
#define __OLED_H                  
#include "stm32f10x.h"
//#include "stdlib.h"            
#define OLED_MODE 0
#define SIZE 8
#define XLevelL        0x00
#define XLevelH        0x10
#define Max_Column    128
#define Max_Row        64
#define    Brightness    0xFF
#define X_WIDTH     128
#define Y_WIDTH     64                                 
//-----------------OLED IIC端口定义----------------                        

#define OLED_SCLK_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_6)//SCL
#define OLED_SCLK_Set() GPIO_SetBits(GPIOC,GPIO_Pin_6)

#define OLED_SDIN_Clr() GPIO_ResetBits(GPIOC,GPIO_Pin_7)//SDA
#define OLED_SDIN_Set() GPIO_SetBits(GPIOC,GPIO_Pin_7)

              
#define OLED_CMD  0    //写命令
#define OLED_DATA 1    //写数据


//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);  
void OLED_Display_On(void);
void OLED_Display_Off(void);                                                  
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);
void OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size);     
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(u8 x,u8 y,u8 no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
void Delay_50ms(unsigned int Del_50ms);
void Delay_1ms(unsigned int Del_1ms);
void fill_picture(unsigned char fill_Data);
void OLED_On(void);
void OLED_Refresh(void);
void Write_IIC_Command(unsigned char IIC_Command);
void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Byte(unsigned char IIC_Byte);


#endif  

</font>


使用特权

评论回复
沙发
感觉很反感mva|  楼主 | 2024-2-26 16:28 | 只看该作者
头文件中定义了一些OLED控制用的函数和宏,以及一些宏定义和全局变量。头文件来看,这是一份用于控制OLED显示的驱动程序的头文件。对头文件中一些关键部分的简要解释:

宏定义:

OLED_MODE: 定义OLED的模式,这里设为0。
SIZE: 定义字体的大小,这里设为8。
XLevelL和XLevelH: 定义X轴的起始地址。
Max_Column和Max_Row: 定义OLED的最大列数和最大行数。
Brightness: 定义亮度,这里设为0xFF。
X_WIDTH和Y_WIDTH: 定义OLED的宽度和高度。
OLED端口定义:

OLED_SCLK_Clr(), OLED_SCLK_Set(), OLED_SDIN_Clr(), OLED_SDIN_Set(): 定义了控制OLED的SCL(时钟线)和SDA(数据线)的宏,分别用于清零和置位。
OLED控制函数:

OLED_WR_Byte(unsigned dat,unsigned cmd): 写一个字节到OLED,可用于写数据或命令。
OLED_Display_On(), OLED_Display_Off(): 控制OLED的开关。
OLED_Init(): 初始化OLED。
OLED_Clear(): 清屏。
OLED_DrawPoint(u8 x,u8 y,u8 t): 在指定位置画一个点。
OLED_Fill(u8 x1,u8 y1,u8 x2,u8 y2,u8 dot): 画一个矩形。
OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size): 在指定位置显示一个字符。
OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size): 在指定位置显示一个数字。
OLED_ShowString(u8 x,u8 y, u8 *p,u8 Char_Size): 在指定位置显示一个字符串。
OLED_Set_Pos(unsigned char x, unsigned char y): 设置OLED显示的位置。
OLED_ShowCHinese(u8 x,u8 y,u8 no): 在指定位置显示一个汉字。
OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]): 在指定位置显示BMP图片。
Delay_50ms(unsigned int Del_50ms), Delay_1ms(unsigned int Del_1ms): 延时函数。
fill_picture(unsigned char fill_Data): 用指定数据填充整个屏幕。
OLED_On(): 打开OLED显示。
OLED_Refresh(): 刷新OLED显示。
Write_IIC_Command(unsigned char IIC_Command), Write_IIC_Data(unsigned char IIC_Data), Write_IIC_Byte(unsigned char IIC_Byte): IIC通信相关的函数。
这份头文件涵盖了一些常见的OLED控制功能,可以在你的项目中使用这些函数来控制OLED的显示。

使用特权

评论回复
板凳
感觉很反感mva|  楼主 | 2024-2-26 16:30 | 只看该作者
有一些可能导致OLED显示不亮的问题。

1.时钟配置: 确保你的OLED_SCLK和OLED_SDIN引脚的时钟配置是正确的。你可以在初始化代码的时钟配置部分检查一下是否正确。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); // 使能A端口时钟


确保OLED_SCLK和OLED_SDIN引脚的端口和引脚号设置正确。


使用特权

评论回复
地板
感觉很反感mva|  楼主 | 2024-2-26 16:31 | 只看该作者
引脚电平状态: 确保在初始化时,OLED_SDIN引脚处于高电平状态。你的初始化代码中有以下部分:

GPIO_SetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_6);

这应该确保OLED_SDIN引脚处于高电平状态。检查一下这部分的逻辑。

使用特权

评论回复
5
感觉很反感mva|  楼主 | 2024-2-26 16:31 | 只看该作者
I2C通信问题: 你的代码中使用了I2C通信,确保I2C通信的物理连接和逻辑配置是正确的。如果I2C通信不正常,可能导致OLED无法正常工作。

使用特权

评论回复
6
感觉很反感mva|  楼主 | 2024-2-26 16:32 | 只看该作者
初始化流程: 确保OLED初始化的流程正确。你的初始化代码中有一系列的设置命令,确保这些命令的顺序和参数是正确的。

OLED_WR_Byte(0xAE,OLED_CMD);  // 关闭OLED显示
// ... 其他初始化命令 ...
OLED_WR_Byte(0xAF,OLED_CMD);  // 打开OLED显示

检查一下这些命令的顺序和参数是否符合OLED的要求。

使用特权

评论回复
7
感觉很反感mva|  楼主 | 2024-2-26 16:32 | 只看该作者
电源问题: 确保OLED模块的电源正常。有些OLED模块可能需要外部电源,确保电源电压符合OLED的要求。

硬件问题: 如果以上步骤都正常,可以考虑硬件问题。检查一下OLED模块的连接是否正确,确保没有短路或者其他硬件问题。

在排查问题时,可以逐步调试,先确认每个部分的基本功能是否正常。可以使用示波器或者逻辑分析仪来观察时钟和数据线的波形,以确定通信是否正常。另外,确保OLED模块本身是正常的,可以尝试使用其他的例程或者示例代码来验证OLED模块是否工作正常。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

37

帖子

0

粉丝