基于昊芯DSC28034+四针OLED屏 显示文字及数字

基于昊芯DSC28034+四针OLED屏 显示文字及数字,第1张

/******************************************************************

 

编  译  器:Haawking IDE V0.1.2

 

  D  S  P:dsc28034湖人板

 

电 脑 配 置:Windows10 专业版; 64 位 *** 作系统

 

仿  真  器:HX100v2

 

使  用  库:无

 

作         用:在OLED屏上显示文字及数字

 

说         明:无

 

版         本:V0.0.1

 

******************************************************************/

 

OLED资料

 

链接:https://pan.baidu.com/s/1sQlrV6J09XKWtcQlFHXdXQ 

提取码:8034

 

四针的OLED屏用IIC来写,原理在资料中 ,再结合以下例程,定能够轻松上手:

 

IIC_OLED.c、

//GPIO配置

 

void I2C_GPIO_Config_OLED(void)

{

    EALLOW;

    GpioCtrlRegs.GPAPUD.bit.GPIO14 = 0;

    GpioCtrlRegs.GPAPUD.bit.GPIO15 = 0;

 

    GpioCtrlRegs.GPAQSEL1.bit.GPIO14 = 3;

    GpioCtrlRegs.GPAQSEL1.bit.GPIO15 = 3;

 

    GpioCtrlRegs.GPADIR.bit.GPIO14 = 1;

    GpioCtrlRegs.GPADIR.bit.GPIO15 = 1;

 

    GpioCtrlRegs.GPAMUX1.bit.GPIO14 = 0; 

    GpioCtrlRegs.GPAMUX1.bit.GPIO15 = 0;

 

    GpioDataRegs.GPASET.bit.GPIO14 = 1;

    GpioDataRegs.GPASET.bit.GPIO15 = 1;

 

    EDIS;

}

 

//得到输入数字的长度

 

 int Data_len(int data)

{

        int n=0;

        if(data==0)

        return ++n;

    while(data!=0)

    {

        n++;

        data/=10;

    }

    return n;

}

 

//延时

 

void I2C_OLED_delay(void)   //延时函数

{

    int i =50;

    while(i)

    {

        i--;

    }

}

 

//延时

 

void I2C_OLED_delay_more(void)

{

    int i =200;

    while(i)

    {

        i--;

    }

}

 

//以GPIO14为SCL,GPIO15为SDA向OLED模块传送起始位

 

bool I2C_OLED_start(void)//IIC起始位

{

    SDA1_H;

    SCL1_H;

    I2C_OLED_delay();

    if(!SDA1_read)//SDA线为低电平,总线忙,退出

    {

        return 0;

    }

    SDA1_L;

    I2C_OLED_delay();

    if(SDA1_read)//SDA线为高电平则总线出错,退出

    {

        return 0;

    }

    SDA1_L;

    I2C_OLED_delay();

    return 1;

}

 

//以GPIO14为SCL,GPIO15为SDA向OLED模块传送停止位

 

void I2C_OLED_stop(void)

{

    SCL1_L;

    I2C_OLED_delay();

    SDA1_L;

    I2C_OLED_delay();

    SCL1_H;

    I2C_OLED_delay();

    SDA1_H;

}

 

//以GPIO14为SCL,GPIO15为SDA向OLED模块传送响应位

 

void I2C_OLED_ack(void)

{

    SCL1_L;

    I2C_OLED_delay();

    SDA1_L;

    I2C_OLED_delay();

    SCL1_H;

    I2C_OLED_delay();

    SCL1_L;

    I2C_OLED_delay();

}

 

//以GPIO14为SCL,GPIO15为SDA向OLED模块传送不响应位

 

void I2C_OLED_noack(void)//不响应位

{

    SCL1_L;

    I2C_OLED_delay();

    SDA1_H;

    I2C_OLED_delay();

    SCL1_H;

    I2C_OLED_delay();

    SCL1_L;

    I2C_OLED_delay();

}

 

//接受ACK,有返回1,无返回0

 

bool I2C_OLED_WaitAck(void)//0无ACK,1有ACK

{

    EALLOW;

    GpioCtrlRegs.GPADIR.bit.GPIO15 = 0;            //配置GPIO15(SDA)为输入模式

    SCL1_L;

    I2C_OLED_delay();

    SDA1_H;

    I2C_OLED_delay();

    SCL1_H;

    I2C_OLED_delay();

    if(SDA1_read)

    {

      SCL1_L;

      I2C_OLED_delay();

      return 0;

    }

    SCL1_L;

    I2C_OLED_delay();

    GpioCtrlRegs.GPADIR.bit.GPIO15 = 1;        //配置GPIO15为输出模式

    EDIS;

    return 1;

}

 

//判断是否有ACK,有返回1,无返回0

 

bool Juge_ACK_OLED(void)//判断有无ACK

{

     if(!I2C_OLED_WaitAck())

        {

         I2C_OLED_stop();

            return 0;

        }

     return 1;

}

 

//用IIC协议写数据SendByte

 

void I2C_OLED_SendByte(uint8 SendByte)   //写入

{

    uint8 i=8;

    while(i--)

    {

        SCL1_L;

        I2C_OLED_delay();

      if(SendByte&0x80)

        SDA1_H;

      else

        SDA1_L;

        SendByte=SendByte<<1;

        I2C_OLED_delay();

        SCL1_H;

        I2C_OLED_delay();

    }

    SCL1_L;

}

 

//向OLED模块传送写命令的要求,0x00,写命令IIC_Command(OLED模块的写时序)

 

bool Write_IIC_OLED_Command(uint8 IIC_Command)//写命令

{

    if(!I2C_OLED_start())

    {

        return 0;//总线忙或出错

    }

    I2C_OLED_SendByte(OLED_addr);            //Slave address,SA0=0

    if(!Juge_ACK_OLED())

        return 0;

    I2C_OLED_SendByte(0x00);    //write command

    if(!Juge_ACK_OLED())

        return 0;

    I2C_OLED_SendByte(IIC_Command);

    if(!Juge_ACK_OLED())

        return 0;

    I2C_OLED_stop();

    return 1;

}

 

//向OLED模块传送写数据的要求,0x40,写数据IIC_Data(OLED模块的写时序)

 

bool Write_IIC_OLED_Data(uint8 IIC_Data)//写数据

{

    if(!I2C_OLED_start())

    {

        return 0;//总线忙或出错

    }

    I2C_OLED_SendByte(OLED_addr);             //D/C#=0; R/W#=0

    if(!Juge_ACK_OLED())

        return 0;

    I2C_OLED_SendByte(0x40);            //write data

    if(!Juge_ACK_OLED())

        return 0;

    I2C_OLED_SendByte(IIC_Data);

    if(!Juge_ACK_OLED())

        return 0;

    I2C_OLED_stop();

    return 1;

}

 

//选择是写数据还是写命令,cmd==1则写数据,否则写命令

 

void OLED_WR_Byte(uint8 dat,int cmd)//写数据或命令

{

    if(cmd)

    {

        Write_IIC_OLED_Data(dat);

    }

    else

    {

        Write_IIC_OLED_Command(dat);

    }

}

 

//写入fill_Data整个OLED屏幕

 

void fill_picture(uint8 fill_Data)

{

    uint8 m,n;

    for(m=0;m<8;m++)

    {

        OLED_WR_Byte(page_address+m,0); 

        OLED_WR_Byte(low_column_address,0);    

        OLED_WR_Byte(high_column_address,0);        

        for(n=0;n<128;n++)

            {

                OLED_WR_Byte(fill_Data,1);

            }

    }

}

 

//坐标设置,y为页地址设置,x为列地址设置

 

void OLED_Set_Pos(int x,int y)//y>=0,y<=7,x>=0,x<=127

{

    OLED_WR_Byte(page_address+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(SET_DCDC,OLED_CMD);  //SET DCDC命令

    OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON

    OLED_WR_Byte(display_on,OLED_CMD);  //DISPLAY ON

}

 

//关闭OLED显示

 

void OLED_Display_Off(void)

{

    OLED_WR_Byte(SET_DCDC,OLED_CMD);  //SET DCDC命令

    OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF

    OLED_WR_Byte(display_off,OLED_CMD);  //DISPLAY OFF

}

 

 

//清屏

 

void OLED_Clear(void)

{

    uint8 i,n;

    for(i=0;i<8;i++)

    {

        OLED_WR_Byte (page_address+i,OLED_CMD);    //设置页地址(0~7)

        OLED_WR_Byte (low_column_address,OLED_CMD);      //设置显示位置—列低地址

        OLED_WR_Byte (high_column_address,OLED_CMD);      //设置显示位置—列高地址

        for(n=0;n<128;n++)

        {

            OLED_WR_Byte(0,OLED_DATA);

            I2C_OLED_delay_more();

        }

    }

}

 

//全亮,将屏幕全变亮

 

void OLED_On(void)

{

    uint8 i,n;

    for(i=0;i<8;i++)

    {

        OLED_WR_Byte (page_address+i,OLED_CMD);    //设置页地址(0~7)

        OLED_WR_Byte (low_column_address,OLED_CMD);      //设置显示位置—列低地址

        OLED_WR_Byte (high_column_address,OLED_CMD);      //设置显示位置—列高地址

        for(n=0;n<128;n++)

        {

            OLED_WR_Byte(0xff,OLED_DATA);

            I2C_OLED_delay_more();

        }

    } 

}

 

//在指定位置显示一个字符

 

void OLED_ShowChar(int x,int y,uint8 chr,int 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);

                I2C_OLED_delay_more();

            }

            OLED_Set_Pos(x,y+1);

            for(i=0;i<8;i++)

            {

                OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);

                I2C_OLED_delay_more();

            }

        }

        else

        {

            OLED_Set_Pos(x,y);

            for(i=0;i<6;i++)

                OLED_WR_Byte(F6x8[c][i],OLED_DATA);

        }

}

 

//指数函数,m^n

 

uint32 oled_pow(int m,int n)

{

    uint32 result=1;

    while(n--)

        result*=m;

    return result;

}

 

//在指定位置(x,y)显示一串数字

 

void OLED_ShowNum(int x,int y,uint32 num,int len,int size2)

{

    int t,temp;

    int enshow=0;

    for(t=0;t;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,0,size2);

                I2C_OLED_delay_more();

                conTInue;

            }else enshow=1;

        }

         OLED_ShowChar(x+(size2/2)*t,y,temp,size2);

        I2C_OLED_delay_more();

    }

}

 

//在指定位置(x,y)显示汉字

 

void OLED_ShowCHinese(int x,int y,uint8 no)

{

    uint8 t;

    OLED_Set_Pos(x,y);

    for(t=0;t<16;t++)

    {

        OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);

        I2C_OLED_delay_more();

    }

    OLED_Set_Pos(x,y+1);

    for(t=0;t<16;t++)

    {

        OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);

        I2C_OLED_delay_more();

    }

}

 

//初始化OLED屏芯片,对OLED寄存器设置初始化

 

void OLED_Init(void)

{

    OLED_WR_Byte(display_off,OLED_CMD);//--display off

    OLED_WR_Byte(low_column_address,OLED_CMD);//---set low column address

    OLED_WR_Byte(high_column_address,OLED_CMD);//---set high column address

    OLED_WR_Byte(start_line,OLED_CMD);//--set start line address

    OLED_WR_Byte(page_address,OLED_CMD);//--set page address

    OLED_WR_Byte(contract_control,OLED_CMD); // contract control

    OLED_WR_Byte(0xFF,OLED_CMD);//--128

    OLED_WR_Byte(segment_remap,OLED_CMD);//--set segment remap

    OLED_WR_Byte(normal_dispaly,OLED_CMD);//--normal / reverse

    OLED_WR_Byte(mulTIplex_raTIo,OLED_CMD);//--set mulTIplex ratio(1 to 64)

    OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty

    OLED_WR_Byte(scan_direction,OLED_CMD);//Com scan direction

    OLED_WR_Byte(display_offset,OLED_CMD);//-set display offset

    OLED_WR_Byte(0x00,OLED_CMD);//复位

 

    OLED_WR_Byte(clock_division,OLED_CMD);//set osc division

    OLED_WR_Byte(0x80,OLED_CMD);//

 

    OLED_WR_Byte(0xD8,OLED_CMD);//set area color mode off

    OLED_WR_Byte(0x05,OLED_CMD);//

 

    OLED_WR_Byte(Pre_Charge_Period,OLED_CMD);//Set Pre-Charge Period

    OLED_WR_Byte(0xF1,OLED_CMD);//

 

    OLED_WR_Byte(pin_configuartion,OLED_CMD);//set com pin configuartion

    OLED_WR_Byte(0x12,OLED_CMD);//复位

 

    OLED_WR_Byte(0x20,OLED_CMD);

    OLED_WR_Byte(0x02,OLED_CMD);

 

    OLED_WR_Byte(Vcomh,OLED_CMD);//set Vcomh

    OLED_WR_Byte(0x30,OLED_CMD);//复位

 

    OLED_WR_Byte(SET_DCDC,OLED_CMD);//set charge pump enable

    OLED_WR_Byte(0x14,OLED_CMD);//DCDC ON

 

    OLED_WR_Byte(display_on,OLED_CMD);//--turn on oled panel

}

 

IIC_OLED.h

#define OLED_CMD  0    //写命令

#define OLED_DATA 1    //写数据

 

#define OLED_addr 0x78

#define display_off    0xAE//关显示

#define low_column_address 0x00//列低地址

#define high_column_address 0x10 //设置列高地址

#define start_line 0x40 //设置起始行

#define page_address 0xB0 //起始页

#define contract_control 0x81 //对比度设置

#define segment_remap  0xA1

#define normal_dispaly 0xA6 //普通显示

#define multiplex_ratio 0xA8

#define scan_direction 0xC8   //扫描

#define display_offset 0xD3

#define clock_division 0xD5

#define Pre_Charge_Period 0xD9

#define pin_configuartion 0xDA

#define Vcomh 0xDB

#define display_on 0xAF

#define SET_DCDC 0X8D

 

#define SCL1_H GpioDataRegs.GPASET.bit.GPIO14=1

#define SCL1_L GpioDataRegs.GPACLEAR.bit.GPIO14=1

#define SDA1_H     GpioDataRegs.GPASET.bit.GPIO15=1

#define SDA1_L  GpioDataRegs.GPACLEAR.bit.GPIO15=1

 

#define SCL1_read     GpioDataRegs.GPADAT.bit.GPIO14

#define SDA1_read     GpioDataRegs.GPADAT.bit.GPIO15

 

#define SIZE 16

#define Max_Column    128

#define Max_Row        64

 

void I2C_GPIO_Config_OLED(void);

int Data_len(int data);

void I2C_OLED_delay(void);

void I2C_OLED_delay_more(void);

bool I2C_OLED_start(void);

void I2C_OLED_stop(void);

void I2C_OLED_ack(void);

void I2C_OLED_noack(void);

bool I2C_OLED_WaitAck(void);

bool Juge_ACK_OLED(void);

void I2C_OLED_SendByte(uint8 SendByte);

bool Write_IIC_OLED_Command(uint8 IIC_Command);

bool Write_IIC_OLED_Data(uint8 IIC_Data);

void OLED_WR_Byte(uint8 dat,int cmd);

void fill_picture(uint8 fill_Data);

void OLED_Set_Pos(int x,int y);

void OLED_Display_On(void);

void OLED_Display_Off(void);

void OLED_Clear(void);

void OLED_On(void);

void OLED_ShowChar(int x,int y,uint8 chr,int Char_Size);

uint32 oled_pow(int m,int n);

void OLED_ShowNum(int x,int y,uint32 num,int len,int size2);

void OLED_ShowCHinese(int x,int y,uint8 no);

void OLED_Init(void);

 

main.c

int main(void)

{

    int data;

    EALLOW;

    P_SysCtrlRegs->INTOSC1TRIM.bit.COARSETRIM = 0;

    P_SysCtrlRegs->INTOSC2TRIM.bit.COARSETRIM= 0;

    EDIS;

    InitSysCtrl();

    DINT;

    InitPieCtrl();

    IER_DISABLE(0xffff);

    IFR_DISABLE(0xffff);

    InitPieVectTable();

    I2C_GPIO_Config_OLED();

    OLED_Init();

    EINT;

    OLED_Clear();

    OLED_ShowCHinese(28,0,0);

    OLED_ShowCHinese(44,0,1);

    OLED_ShowCHinese(60,0,2);

    OLED_ShowCHinese(76,0,3);

    OLED_ShowChar(16,4,16,16);

    OLED_ShowChar(24,4,17,16);

    OLED_ShowChar(32,4,16,16);

    OLED_ShowChar(40,4,13,16);

    OLED_ShowChar(48,4,22,16);

    OLED_ShowChar(56,4,17,16);

    OLED_ShowChar(64,4,25,16);

    OLED_ShowChar(72,4,19,16);

    OLED_ShowChar(80,4,20,16);

    OLED_ShowChar(88,4,21,16);

    OLED_ShowChar(96,4,22,16);

    OLED_ShowChar(104,4,17,16);

    while(1){}

    return 0;

}

 

接线以及显示效果:

 

基于昊芯DSC28034+四针OLED屏 显示文字及数字,微信图片_20210827105558.jpg,第2张

基于昊芯DSC28034+四针OLED屏 显示文字及数字,微信图片_20210827105551.jpg,第3张

 

 

详细例程请参考

 

链接:https://pan.baidu.com/s/1C8I7OSgjKifGP8UX-U6Tmg 

提取码:8034

————————————————

特别鸣谢 原创作者  博主「晟逸轩」

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/dianzi/2434171.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-02
下一篇 2022-08-02

发表评论

登录后才能评论

评论列表(0条)

保存