打印

GD32 驱动 液晶屏幕

[复制链接]
2674|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
junpeng324|  楼主 | 2018-11-30 23:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
IIC 部分
//初始化IIC
void IIC_Init(void)
{                                             
        GPIO_InitPara GPIO_InitStructure;
        RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOA,ENABLE);

    GPIO_InitStructure.GPIO_Pin   = GPIO_PIN_6|GPIO_PIN_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
    GPIO_InitStructure.GPIO_Mode  = GPIO_MODE_OUT_PP;

    GPIO_Init(GPIOA,&GPIO_InitStructure);
}
沙发
junpeng324|  楼主 | 2018-11-30 23:26 | 只看该作者
//产生IIC起始信号
void IIC_Start(void)
{
        SDA_OUT();     //sda线输出
        IIC_SDA=1;                    
        IIC_SCL=1;
        delay_us(4);
        IIC_SDA=0;//START:when CLK is high,DATA change form high to low
        delay_us(4);
        IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
}          

使用特权

评论回复
板凳
junpeng324|  楼主 | 2018-11-30 23:26 | 只看该作者
//产生IIC停止信号
void IIC_Stop(void)
{
        SDA_OUT();//sda线输出
        IIC_SCL=0;
        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
        delay_us(4);
        IIC_SCL=1;
        IIC_SDA=1;//发送I2C总线结束信号
        delay_us(4);                                                                  
}

使用特权

评论回复
地板
junpeng324|  楼主 | 2018-11-30 23:26 | 只看该作者
//等待应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 IIC_Wait_Ack(void)
{
        u8 ucErrTime=0;
        SDA_IN();      //SDA设置为输入  
        IIC_SDA=1;delay_us(1);          
        IIC_SCL=1;delay_us(1);         
        while(READ_SDA)
        {
                ucErrTime++;
                if(ucErrTime>250)
                {
                        IIC_Stop();
                        return 1;
                }
        }
        IIC_SCL=0;//时钟输出0           
        return 0;  
}

使用特权

评论回复
5
junpeng324|  楼主 | 2018-11-30 23:27 | 只看该作者
//产生ACK应答
void IIC_Ack(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=0;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}

使用特权

评论回复
6
junpeng324|  楼主 | 2018-11-30 23:27 | 只看该作者
//不产生ACK应答                    
void IIC_NAck(void)
{
        IIC_SCL=0;
        SDA_OUT();
        IIC_SDA=1;
        delay_us(2);
        IIC_SCL=1;
        delay_us(2);
        IIC_SCL=0;
}                       

使用特权

评论回复
7
junpeng324|  楼主 | 2018-11-30 23:28 | 只看该作者
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答                          
void IIC_Send_Byte(u8 txd)
{                        
    u8 t;   
        SDA_OUT();             
    IIC_SCL=0;//拉低时钟开始数据传输
    for(t=0;t<8;t++)
    {              
        //IIC_SDA=(txd&0x80)>>7;
                if((txd&0x80)>>7)
                        IIC_SDA=1;
                else
                        IIC_SDA=0;
                txd<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                IIC_SCL=1;
                delay_us(2);
                IIC_SCL=0;       
                delay_us(2);
    }         
}          

使用特权

评论回复
8
junpeng324|  楼主 | 2018-11-30 23:28 | 只看该作者
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK   
u8 IIC_Read_Byte(unsigned char ack)
{
        unsigned char i,receive=0;
        SDA_IN();//SDA设置为输入
    for(i=0;i<8;i++ )
        {
        IIC_SCL=0;
        delay_us(2);
                IIC_SCL=1;
        receive<<=1;
        if(READ_SDA)receive++;   
                delay_us(1);
    }                                         
    if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return receive;
}

使用特权

评论回复
9
junpeng324|  楼主 | 2018-11-30 23:29 | 只看该作者
// oled 部分
//更新显存到LCD                 
void OLED_Refresh_Gram(void)
{
        u8 i,n;                    
        for(i=0;i<4;i++)  
        {  
                WriteCmd(0xb0+i);    //设置页地址(0~7)
                WriteCmd(0x00);      //设置显示位置—列低地址
                WriteCmd(0x10);      //设置显示位置—列高地址   
                for(n=0;n<128;n++) WriteDat(OLED_GRAM[n][i]);
        }   
}

使用特权

评论回复
10
junpeng324|  楼主 | 2018-11-30 23:29 | 只看该作者
void I2C_WriteByte(uint8_t addr,uint8_t data)
{
   IIC_Start();  
         IIC_Send_Byte(0x78);            //发送写命令
         IIC_Wait_Ack();
         IIC_Send_Byte(addr);//发送高地址
         
         IIC_Wait_Ack();                                                                                                              
         IIC_Send_Byte(data);     //发送字节                                                          
         IIC_Wait_Ack();                                
   IIC_Stop();//产生一个停止条件
         //delay_ms(2);         
}

使用特权

评论回复
11
junpeng324|  楼主 | 2018-11-30 23:29 | 只看该作者
void WriteCmd(unsigned char I2C_Command)//写命令
{
        I2C_WriteByte(0x00, I2C_Command);
}

使用特权

评论回复
12
junpeng324|  楼主 | 2018-11-30 23:30 | 只看该作者
void WriteDat(unsigned char I2C_Data)//写数据
{
        I2C_WriteByte(0x40, I2C_Data);
}

使用特权

评论回复
13
junpeng324|  楼主 | 2018-11-30 23:30 | 只看该作者
void OLED_Init(void)
{
//        delay_ms(100); //这里的延时很重要
//       
//        WriteCmd(0xAE); //display off
//       
//        WriteCmd(0xd5);        //Set Memory Addressing Mode       
//        WriteCmd(0x10);        //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
//       
//        WriteCmd(0xa8);        //Set Page Start Address for Page Addressing Mode,0-7
//        WriteCmd(0x1f);        //Set COM Output Scan Direction
//       
//        WriteCmd(0xd3); //---set low column address
//        WriteCmd(0x00); //---set high column address
//       
//        WriteCmd(0x40); //--set start line address
//       
//        WriteCmd(0xad); //--set contrast control register
//        WriteCmd(0x8e); //亮度调节 0x00~0xff
//       
//        WriteCmd(0xd8); //--set segment re-map 0 to 127
//        WriteCmd(0x05); //--set normal display
//       
//        WriteCmd(0xa1); //--set multiplex ratio(1 to 64)
//       
//        WriteCmd(0xc8); //
//       
//        WriteCmd(0xda); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
//        WriteCmd(0x12); //-set display offset
//       
//        WriteCmd(0x91); //-not offset
//        WriteCmd(0x3f); //--set display clock divide ratio/oscillator frequency
//        WriteCmd(0x3f); //--set divide ratio
//        WriteCmd(0x3f); //--set pre-charge period
//        WriteCmd(0x3f); //

//       
//        WriteCmd(0x81);
//        WriteCmd(0xef); //--set vcomh
//       
//        WriteCmd(0xd9); //0x20,0.77xVcc
//        WriteCmd(0xd2); //--turn on oled panel
//       
//        WriteCmd(0xdb); //--turn on oled panel
//        WriteCmd(0x08); //--turn on oled panel
//       
//        WriteCmd(0xa4); //--turn on oled panel
//       
//        WriteCmd(0xa6); //--turn on oled panel
//       
//        WriteCmd(0xaf); //--turn on oled panel


//delay_ms(10); //这里的延时很重要
       
         WriteCmd(0xAE ); //关闭显示
         WriteCmd(0xD5 ); //设置时钟分频因子,震荡频率
         WriteCmd(80 );   //[3:0],分频因子;[7:4],震荡频率
         WriteCmd(0xA8 ); //设置驱动路数
         WriteCmd(0x1f );
         WriteCmd(0X3F ); //默认0X3F(1/64)
         WriteCmd(0xD3 ); //设置显示偏移
         WriteCmd(0X00 ); //默认为0

         WriteCmd(0x40 ); //设置显示开始行 [5:0],行数.
                                                                                                            
         WriteCmd(0x8D ); //电荷泵设置
         WriteCmd(0x14 ); //bit2,开启/关闭
         
         WriteCmd(0x20 ); //设置内存地址模式
         WriteCmd(0x02 ); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
         
         WriteCmd(0xA1 ); //段重定义设置,bit0:0,0->0;1,0->127;
         
         WriteCmd(0xC0 ); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
         
         WriteCmd(0xDA ); //设置COM硬件引脚配置   这部分在一开始出现问题  2016.07.10
         WriteCmd(0x00 ); //[5:4]配置
                 
         WriteCmd(0x81 ); //对比度设置
         WriteCmd(0x7f ); //1~255;默认0X7F (亮度设置,越大越亮)
         
        // WriteCmd(0xc2);
         
         WriteCmd(0xD9 ); //设置预充电周期
         WriteCmd(0xf1 ); //[3:0],PHASE 1;[7:4],PHASE 2;
         WriteCmd(0xDB ); //设置VCOMH 电压倍率
         WriteCmd(0x00 ); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;

         WriteCmd(0xA4 ); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
         WriteCmd(0xA6 ); //设置显示方式;bit0:1,反相显示;0,正常显示                                                              
         WriteCmd(0xAF ); //开启显示         
       
       

       
}

使用特权

评论回复
14
junpeng324|  楼主 | 2018-11-30 23:30 | 只看该作者
// Description    : 将OLED从休眠中唤醒
//--------------------------------------------------------------
void OLED_ON(void)
{
        WriteCmd(0X8D);  //设置电荷泵
        WriteCmd(0X14);  //开启电荷泵
        WriteCmd(0XAF);  //OLED唤醒
}

使用特权

评论回复
15
junpeng324|  楼主 | 2018-11-30 23:31 | 只看该作者
// Description    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
//--------------------------------------------------------------
void OLED_OFF(void)
{
        WriteCmd(0X8D);  //设置电荷泵
        WriteCmd(0X10);  //关闭电荷泵
        WriteCmd(0XAE);  //OLED休眠
}

使用特权

评论回复
16
junpeng324|  楼主 | 2018-11-30 23:31 | 只看该作者
void OLED_Clear(void)  
{  
        u8 i,n;  
        for(i=0;i<4;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X0;  
        OLED_Refresh_Gram();//更新显示
}

使用特权

评论回复
17
junpeng324|  楼主 | 2018-11-30 23:33 | 只看该作者
//画点
//x:0~127
//y:0~63
//t:1 填充 0,清空                                  
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
        u8 pos,bx,temp=0;
        if(x>127||y>63)return;//超出范围了.
        pos=7-y/8;
        bx=y%8;
        temp=1<<(7-bx);
        if(t)OLED_GRAM[x][pos]|=temp;
        else OLED_GRAM[x][pos]&=~temp;            
}

使用特权

评论回复
18
junpeng324|  楼主 | 2018-11-30 23:33 | 只看该作者
//m^n函数
u32 mypow(u8 m,u8 n)
{
        u32 result=1;         
        while(n--)result*=m;   
        return result;
}               

使用特权

评论回复
19
junpeng324|  楼主 | 2018-11-30 23:33 | 只看该作者
//显示2个数字
//x,y :起点坐标         
//len :数字的位数
//size:字体大小
//mode:模式        0,填充模式;1,叠加模式
//num:数值(0~4294967295);                           
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
{                
        u8 t,temp;
        u8 enshow=0;                                                  
        for(t=0;t<len;t++)
        {
                temp=(num/mypow(10,len-t-1))%10;
                if(enshow==0&&t<(len-1))
                {
                        if(temp==0)
                        {
                                OLED_ShowChar(x+(size/2)*t,y,' ',size,1);
                                continue;
                        }else enshow=1;
                          
                }
                 OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1);
        }
}

使用特权

评论回复
20
junpeng324|  楼主 | 2018-11-30 23:34 | 只看该作者
//显示字符串
//x,y:起点坐标  
//size:字体大小
//*p:字符串起始地址
void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)
{       
    while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
    {      
        if(x>(128-(size/2))){x=0;y+=size;}
        if(y>(64-size)){y=x=0;OLED_Clear();}
        OLED_ShowChar(x,y,*p,size,1);         
        x+=size/2;
        p++;
    }  
       
}

使用特权

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

本版积分规则

37

主题

1130

帖子

8

粉丝