瑞萨RA MCU众测宝典 | 手把手搞定瑞萨FPB-RA0E2驱动OLED显示

描述

 

本文介绍了瑞萨FPB-RA0E2开发板实现OLED驱动显示Renesas图标logo以及ADC电压表框架的项目设计。


 

项目介绍


 

硬件连接:依据r_sau_i2c配置,选择目标管脚用以实现开发板与OLED的IIC通信;


 

驱动OLED:配置硬件IIC通信,实现OLED驱动;包括工程创建、代码添加、工程调试等;


 

OLED显示Renesas图标以及ADC电压表框架。


 

硬件连接


 

OLED

RA0E2

SCL

P500(13)

SDA

P502(12)

GND

GND

VCC

3V3


 

示意图

RA


 

工程创建


 

打开e2studio软件,依次选择文件-新建-C/C++-RA项目;


 

设备选择:开发板选择FPB-RA0E2,选择GNU ARM工具链和J-Link调试器,完成工程创建;


 

新建IIC通信堆栈NewStack-Connectivity-I2CMaster(r_sau_i2c);


 

属性配置中,Slave Address设置为0x3c,检查引脚对应关系为SCL00-P500、SDA00-P502;


 

点击Generate Project Content按钮,生成工程代码。


 

工程代码


 

包括hal_entry.c、OLED驱动代码、字模和图片代码等。


 


 

hal_entry.c

在左侧的项目目录中,打开src/hal_entry.c文件,添加如下关键代码:

滑动查看完整内容

  •  

#include"hal_data.h"#include"oled.h"#include"bmp.h"
FSP_CPP_HEADERvoidR_BSP_WarmStart(bsp_warm_start_event_t event);FSP_CPP_FOOTER
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;voidsau_i2c_master_callback(i2c_master_callback_args_t *p_args){    i2c_event = I2C_MASTER_EVENT_ABORTED;    if (NULL != p_args)    {        /* capture callback event for validating the i2c transfer event*/        i2c_event = p_args->event;    }}fsp_err_t err = FSP_SUCCESS;int  timeout_ms = 100;
voidhal_entry(void){    /* TODO: add your own code here */    /* Initialize IIC OLED */            err = R_SAU_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);            assert(FSP_SUCCESS == err);            OLED_Init();            OLED_Clear();            OLED_DrawBMP(0,0,128,8,BMP1,0); // initialized page -> Renesas logo            R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
            /*----------- Frame ------------*/            OLED_Clear();            OLED_ShowString(0,0,"   ADC ",16,1);            OLED_ShowCHinese(56,0,0,1);//电            OLED_ShowCHinese(72,0,1,1);//压            OLED_ShowCHinese(88,0,2,1);//表            OLED_ShowString(104,0,"   ",16,1);
            OLED_ShowString(4,3,"ADC",16,0);            OLED_ShowCHinese(32,3,3,0);//值            OLED_ShowChar(48,3,':',16,0);
            OLED_ShowCHinese(0,6,0,0);//电            OLED_ShowCHinese(16,6,1,0);//压            OLED_ShowCHinese(32,6,3,0);//值            OLED_ShowChar(48,6,':',16,0);            OLED_ShowChar(100,6,'V',16,0);
#if BSP_TZ_SECURE_BUILD    /* Enter non-secure code */    R_BSP_NonSecureEnter();#endif}


 


 

oled.c

在src文件夹下新建OLED驱动源文件,命名为 oled.c,添加如下代码:

滑动查看完整内容

  •  
  •  
  •  

#include"oled.h"#include"oledfont.h"#include"hal_data.h"#include"stdint.h"uint8_t CMD_Data[]={0xAE,0x00,0x10,0x40,0xB0,0x81,0xFF,0xA1,0xA6,0xA8,0x3F,0xC8,0xD3,0x00,0xD5,0x80,0xD8,0x05,0xD9,0xF1,0xDA,0x12,0xD8,0x30,0x8D,0x14,0xAF};      //初始化命令externfsp_err_t err;externint  timeout_ms;extern  i2c_master_event_t i2c_event ;voidWriteCmd(void){    uint8_t i = 0;    uint8_t ii[2]={0x00,0x00};    for(i=0;i<27;i++)    {        ii[1]=CMD_Data[i];    

    //err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);        err = R_SAU_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);        assert(FSP_SUCCESS == err);        /* Since there is nothing else to do, block until Callback triggers*/        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)        {            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);            timeout_ms--;        }        if (I2C_MASTER_EVENT_ABORTED == i2c_event)        {       

     __BKPT(0);        }        /* Read data back from the I2C slave */        i2c_event = I2C_MASTER_EVENT_ABORTED;        timeout_ms           = 100;    }}/** * @function: void OLED_WR_CMD(uint8_t cmd) * @description: 向设备写控制命令 * @param {uint8_t} cmd 芯片手册规定的命令 * @return {*} */voidOLED_WR_CMD(uint8_t cmd){        uint8_t ii[2]={0x00,0x00};        ii[1]=cmd;        //err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);        err = R_SAU_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);        assert(FSP_SUCCESS == err);        /* Since there is nothing else to do, block until Callback triggers*/        //while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)        {            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);          

  timeout_ms--;        }        if (I2C_MASTER_EVENT_ABORTED == i2c_event)        {            __BKPT(0);   

     }        /* Read data back from the I2C slave */        i2c_event = I2C_MASTER_EVENT_ABORTED;        timeout_ms           = 100;}/** * @function: void OLED_WR_DATA(uint8_t data) * @description: 向设备写控制数据 * @param {uint8_t} data 数据 * @return {*} */voidOLED_WR_DATA(uint8_t data){        uint8_t ii[2]={0x40,0x00};        ii[1]=data;        //err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);        err = R_SAU_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);        assert(FSP_SUCCESS == err);        /* Since there is nothing else to do, block until Callback triggers*/        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)        {            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);        

    timeout_ms--;        }        if (I2C_MASTER_EVENT_ABORTED == i2c_event)        {            __BKPT(0);        }        /* Read data back from the I2C slave */        i2c_event = I2C_MASTER_EVENT_ABORTED;        timeout_ms    

       = 100;}/** * @function: void OLED_Init(void) * @description: OLED初始化 * @return {*} */voidOLED_Init(void){    R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);    WriteCmd();}/*** @function: OLED_Clear(void)* @description: 清屏,整个屏幕的像素点都是关闭的* @return {*}*/voidOLED_Clear(void){    uint8_t i,n;    for(i=0;i<8;i++)    {        OLED_WR_CMD(0xb0+i);//设置页地址(0~7)        OLED_WR_CMD (0x00); //设置显示位置—列低地址        OLED_WR_CMD (0x10); //设置显示位置—列高地址        for(n=0;n<132;n++)            OLED_WR_DATA(0);//更新显示    }}/** * @function: void OLED_Display_On(void) * @description: 更新显示 * @return {*} */voidOLED_Display_On(void){    OLED_WR_CMD(0X8D);  //SET DCDC命令    OLED_WR_CMD(0X14);  //DCDC ON    OLED_WR_CMD(0XAF);  //DISPLAY ON}/** * @function: void OLED_Display_Off(void) * @description: 关闭OLED显示 * @return {*} */voidOLED_Display_Off(void){    OLED_WR_CMD(0X8D);  //SET DCDC命令    OLED_WR_CMD(0X10);  //DCDC OFF    OLED_WR_CMD(0XAE);  //DISPLAY OFF}/** * @function: void OLED_Set_Pos(uint8_t x, uint8_t y) * @description: 坐标设置

 * @param {uint8_t} x,y * @return {*} */voidOLED_Set_Pos(uint8_t x, uint8_t y){    OLED_WR_CMD(0xb0+y);    OLED_WR_CMD(((x&0xf0)>>4)|0x10);    OLED_WR_CMD(x&0x0f);}/** * @function: void OLED_On(void) * @description: 更新显示 * @return {*} */voidOLED_On(void){    uint8_t i,n;    for(i=0;i<8;i++)    {        OLED_WR_CMD(0xb0+i);    //设置页地址(0~7)        OLED_WR_CMD(0x00);      //设置显示位置—列低地址        OLED_WR_CMD(0x10);      //设置显示位置—列高地址   

     for(n=0;n<128;n++)            OLED_WR_DATA(1);    } //更新显示}/** * @function: unsigned int oled_pow(uint8_t m,uint8_t n) * @description: m^n函数 * @param {uint8_t} m,n * @return {unsigned int} result */unsignedintoled_pow(uint8_t m,uint8_t n){    unsignedint result=1;  

  while(n--)result*=m;    return result;}/** * @function: void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2, uint8_t mode) * @description: 在OLED12864特定位置开始显示一个整数 * @param {uint8_t} x字符开始显示的横坐标 0~127 * @param {uint8_t} y字符开始显示的纵坐标 0~63 * @param {uint8_t} num 待显示的整数 * @param {uint8_t} len 待显示数字的位数 * @param {uint8_t} size2 待显示数字的大小 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) 

* @return {*} */voidOLED_ShowNum(uint8_t x,uint8_t y,unsignedint num,uint8_t len,uint8_t size2, uint8_t mode){    uint8_t t,temp;    uint8_t enshow=0;    for(t=0;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, mode);                continue;    

        }            else                enshow=1;        }        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2, mode);    }}/** * @function: void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size,uint8_t Color_Turn) * @description: 在OLED12864特定位置开始显示一个字符 

* @param {uint8_t} x字符开始显示的横坐标 0~127 * @param {uint8_t} y字符开始显示的纵坐标 0~63 * @param {uint8_t} chr待显示的字符 * @param {uint8_t} Char_Size待显示字符的字体大小,选择字体 16/12 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size, uint8_t mode){    unsignedchar c=0,i=0;        c=chr-' ';//得到偏移后的值        if(x>128-1)        {            x=0;            y=y+2;        }        if(Char_Size ==16)        {  

          OLED_Set_Pos(x,y);            for(i=0;i<8;i++)            {                //OLED_WR_DATA(F8X16[c*16+i]);                if(mode)                                    OLED_WR_DATA(~F8X16[c*16+i]);                else                                    OLED_WR_DATA(F8X16[c*16+i]);            }            OLED_Set_Pos(x,y+1);            for(i=0;i<8;i++)        

    {                //OLED_WR_DATA(F8X16[c*16+i+8]);                if(mode)                                    OLED_WR_DATA(~F8X16[c*16+i+8]);                else                                    OLED_WR_DATA(F8X16[c*16+i+8]);            }        }        else        {                OLED_Set_Pos(x,y);                for(i=0;i<6;i++)                {                    //OLED_WR_DATA(F6x8[c][i]);                    for(i=0;i<6;i++)           

         {                        if(mode)                                            OLED_WR_DATA(~F6x8[c][i]);                       

 else                                           

 OLED_WR_DATA(F6x8[c][i]);                    }                }        }}/** * @function: void OLED_Showdecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t Color_Turn) * @description: 显示正负浮点数 * @param {uint8_t} x待显示的数字起始横坐标,x:0~126 * @param {uint8_t} y待显示的数字起始纵坐标, y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1

 * @param {float} num:输入的浮点型数据 * @param {uint8_t } z_ len:整数部分的位数 * @param {uint8_t } f_len: 小数部分的位数 * @param {uint8_t} size2:输入的数据大小,选择 16/12,16为8X16,12为6x8 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowDecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t mode){    uint8_t t,temp,i=0;//i为负数标志位    uint8_t enshow;    int z_temp,f_temp;    if(num<0)    {        z_len+=1;        i=1;        num=-num;    }    z_temp=(int)num;    //整数部分  

  for(t=0;t    {        temp=(z_temp/oled_pow(10,z_len-t-1))%10;        if(enshow==0 && t<(z_len-1))      

  {            if(temp==0)            {                OLED_ShowChar(x+(size2/2)*t,y,' ',size2, mode);                continue;            

}            else            enshow=1;        }        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2, mode);    }    //小数点    OLED_ShowChar(x+(size2/2)*(z_len),y,'.',size2, mode);    f_temp=(int)((num-z_temp)*(oled_pow(10,f_len)));  //小数部分    for(t=0;t    {        temp=(f_temp/oled_pow(10,f_len-t-1))%10;        OLED_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2, mode);    }    if(i==1)//如果为负,就将最前的一位赋值

‘-’    {        OLED_ShowChar(x,y,'-',size2, mode);        i=0;    }}/** * @function: void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_tChar_Size, uint8_t Color_Turn) * @description: 在OLED12864特定位置开始显示字符串 * @param {uint8_t} x待显示字符串的开始横坐标x:0~127 * @param {uint8_t} y待显示字符串的开始纵坐标 y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1 * @param {uint8_t} *chr待显示的字符串 * @param {uint8_t} Char_Size待显示字符串的字体大小,选择字体 16/12,16为8X16,12为6x8 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size, uint8_t mode){    uint8_t j=0;    while (chr[j]!='\0')    {        OLED_ShowChar(x,y,chr[j],Char_Size, mode);        if (Char_Size ==12) //6X8的字体列加6,显示下一个字符            x += 6;        else  //8X16的字体列加8,显示下一个字符    

        x += 8;        if (x > 122 && Char_Size==12) //TextSize6x8如果一行不够显示了,从下一行继续显示        {            x = 0;            y++;        }        if (x > 120 && Char_Size== 16) //TextSize8x16如果一行不够显示了,从下一行继续显示      

  {            x = 0;            y+=2;        }        j++;    }}/** * @function: void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t Color_Turn) * @description: 在OLED特定位置开始显示16X16汉字 * @param {uint8_t} x待显示的汉字起始横坐标x: 0~112,两列汉字之间需要间隔16 * @param {uint8_t} y待显示的汉字起始纵坐标 y: 0~6 , 两行汉字之间需要间隔2 * @param {uint8_t} no待显示的汉字编号 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t mode){    uint8_t t=0;    OLED_Set_Pos(x,y);    for(t=0;t<16;t++)    {     

   if (mode)    

        OLED_WR_DATA(~Hzk[2*no][t]); //显示汉字的上半部分        else            OLED_WR_DATA(Hzk[2*no][t]); //显示汉字的上半部分   

 }    OLED_Set_Pos(x,y+1);    for(t=0;t<16;t++)    {        if (mode)            OLED_WR_DATA(~Hzk[2*no+1][t]); //显示汉字的上半部分        else            OLED_WR_DATA(Hzk[2*no+1][t]);//显示汉字的上半部分    }}/** * @function: void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *  BMP,uint8_t Color_Turn) * @description: 在OLED特定区域显示BMP图片 * @param {uint8_t} x0图像开始显示横坐标  x0:0~127 * @param {uint8_t} y0图像开始显示纵坐标  y0:0~7 * @param {uint8_t} x1图像结束显示横坐标  x1:1~128 * @param {uint8_t} y1图像结束显示纵坐标  y1:1~8 * @param {uint8_t} *BMP待显示的图像数据

 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *  BMP, uint8_t mode){   uint32_t j = 0;   uint8_t x = 0, y = 0;  if(y1%8==0)        y = y1/8;  else        y = y1/8 + 1;    for(y=y0;y    {        OLED_Set_Pos(x0,y);    for(x=x0;x   

     {     

       if (mode)         

       OLED_WR_DATA(~BMP[j++]);//显示反相图片            else                OLED_WR_DATA(BMP[j++]);//显示图片   

     }    }}/** * @function: void OLED_DisplayMode(uint8_t mode) * @description: 屏幕内容取反显示 * @param {uint8_t} direction           ON  0xA7  , *                                      OFF 0xA6    默认此模式,设置像素点亮 * @return {*} */voidOLED_DisplayMode(uint8_t mode){    OLED_WR_CMD(mode);}/** * @function: void OLED_IntensityControl(uint8_t intensity) * @description: 屏幕亮度调节 * @param  {uint8_t} intensity  0x00~0xFF,RESET=0x7F * @return {*} */voidOLED_IntensityControl(uint8_t intensity){    OLED_WR_CMD(0x81);    OLED_WR_CMD(intensity);}

 

————————————————版权声明:本文为CSDN博主「无垠的广袤」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_36654593/article/details/149323415


 


 

oled.h

在src文件夹下新建OLED驱动头文件,命名为 oled.h,添加如下代码:

左右滑动查看完整内容

 

#ifndef OLED_H_#define OLED_H_
#include"stdint.h"
voidWriteCmd(void);voidOLED_WR_CMD(uint8_t cmd);voidOLED_WR_DATA(uint8_t data);voidOLED_Init(void);voidOLED_Clear(void);voidOLED_Display_On(void);voidOLED_Display_Off(void);voidOLED_Set_Pos(uint8_t x, uint8_t y);voidOLED_On(void);voidOLED_ShowNum(uint8_t x,uint8_t y,unsignedint num,uint8_t len,uint8_t size2, uint8_t mode);voidOLED_ShowDecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t mode);voidOLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size, uint8_t mode);voidOLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size, uint8_t mode);voidOLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t mode);voidOLED_DrawBMP(unsignedchar x0,unsignedchar y0,unsignedchar x1,unsignedchar y1,unsignedchar BMP[], uint8_t mode);voidOLED_DisplayMode(uint8_t mode);voidOLED_IntensityControl(uint8_t intensity);
#endif/* OLED_H_ */


 


 

oledfont.h

在src文件夹下新建字体驱动头文件,命名为 oledfont.h,添加如下代码

滑动查看完整内容

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

#include"oled.h"#include"oledfont.h"#include"hal_data.h"#include"stdint.h"uint8_t CMD_Data[]={0xAE,0x00,0x10,0x40,0xB0,0x81,0xFF,0xA1,0xA6,0xA8,0x3F,0xC8,0xD3,0x00,0xD5,0x80,0xD8,0x05,0xD9,0xF1,0xDA,0x12,0xD8,0x30,0x8D,0x14,0xAF};      //初始化命令externfsp_err_t err;externint  timeout_ms;extern  i2c_master_event_t i2c_event ;voidWriteCmd(void){    uint8_t i = 0;    uint8_t ii[2]={0x00,0x00};    for(i=0;i<27;i++)    {        ii[1]=CMD_Data[i];        //err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);        err = R_SAU_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);        assert(FSP_SUCCESS == err);        /* Since there is nothing else to do, block until Callback triggers*/        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)        {            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);            timeout_ms--;        }        if (I2C_MASTER_EVENT_ABORTED == i2c_event)        {     

       __BKPT(0);        }        /* Read data back from the I2C slave */        i2c_event = I2C_MASTER_EVENT_ABORTED;        timeout_ms           = 100;    }}/** * @function: void OLED_WR_CMD(uint8_t cmd) * @description: 向设备写控制命令 * @param {uint8_t} cmd 芯片手册规定的命令 * @return {*} */voidOLED_WR_CMD(uint8_t cmd){        uint8_t ii[2]={0x00,0x00};        ii[1]=cmd;        //err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);        err = R_SAU_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);        assert(FSP_SUCCESS == err);        /* Since there is nothing else to do, block until Callback triggers*/        //while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms)        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)        {            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);     

       timeout_ms--;        }        if (I2C_MASTER_EVENT_ABORTED == i2c_event)        {            __BKPT(0);        }        /* Read data back from the I2C slave */        i2c_event = I2C_MASTER_EVENT_ABORTED;        timeout_ms           = 100;}/** * @function: void OLED_WR_DATA(uint8_t data) * @description: 向设备写控制数据 * @param {uint8_t} data 数据 * @return {*} */voidOLED_WR_DATA(uint8_t data){        uint8_t ii[2]={0x40,0x00};        ii[1]=data;        //err = R_IIC_MASTER_Write(&g_i2c_master0_ctrl, ii, 0x02, true);        err = R_SAU_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);        assert(FSP_SUCCESS == err);   

     /* Since there is nothing else to do, block until Callback triggers*/        while ((I2C_MASTER_EVENT_TX_COMPLETE != i2c_event) && timeout_ms>0)        {            R_BSP_SoftwareDelay(1U, BSP_DELAY_UNITS_MICROSECONDS);            timeout_ms--;        }        if (I2C_MASTER_EVENT_ABORTED == i2c_event)        {     

       __BKPT(0);        }    

    /* Read data back from the I2C slave */        i2c_event = I2C_MASTER_EVENT_ABORTED;        timeout_ms           = 100;}/** * @function: void OLED_Init(void) * @description: OLED初始化 * @return {*} */voidOLED_Init(void){    R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);    WriteCmd();}/*** @function: OLED_Clear(void)* @description: 清屏,整个屏幕的像素点都是关闭的* @return {*}*/voidOLED_Clear(void){    uint8_t i,n;    for(i=0;i<8;i++)    {     

   OLED_WR_CMD(0xb0+i);//设置页地址(0~7)        OLED_WR_CMD (0x00); //设置显示位置—列低地址        OLED_WR_CMD (0x10); //设置显示位置—列高地址        for(n=0;n<132;n++)            OLED_WR_DATA(0);//更新显示    }}/** * @function: void OLED_Display_On(void) * @description: 更新显示 * @return {*} */voidOLED_Display_On(void){    OLED_WR_CMD(0X8D);  //SET DCDC命令    OLED_WR_CMD(0X14);  //DCDC ON    OLED_WR_CMD(0XAF);  //DISPLAY ON}/** * @function: void OLED_Display_Off(void) * @description: 关闭OLED显示 * @return {*} */voidOLED_Display_Off(void){    OLED_WR_CMD(0X8D);  //SET DCDC命令    OLED_WR_CMD(0X10);  //DCDC OFF    OLED_WR_CMD(0XAE);  //DISPLAY OFF}/** * @function: void OLED_Set_Pos(uint8_t x, uint8_t y) * @description: 坐标设置 * @param {uint8_t} x,y * @return {*} */voidOLED_Set_Pos(uint8_t x, uint8_t y){ 

   OLED_WR_CMD(0xb0+y);  

  OLED_WR_CMD(((x&0xf0)>>4)|0x10);    OLED_WR_CMD(x&0x0f);}/** * @function: void OLED_On(void) * @description: 更新显示 * @return {*} */voidOLED_On(void){    uint8_t i,n;    for(i=0;i<8;i++)    {        OLED_WR_CMD(0xb0+i);    //设置页地址(0~7)        OLED_WR_CMD(0x00);      //设置显示位置—列低地址   

     OLED_WR_CMD(0x10);      //设置显示位置—列高地址        for(n=0;n<128;n++)            OLED_WR_DATA(1);    } //更新显示}/** * @function: unsigned int oled_pow(uint8_t m,uint8_t n) * @description: m^n函数 * @param {uint8_t} m,n * @return {unsigned int} result */unsignedintoled_pow(uint8_t m,uint8_t n){    unsignedint result=1;    while(n--)result*=m;    return result;}/** * @function: void OLED_ShowNum(uint8_t x,uint8_t y,unsigned int num,uint8_t len,uint8_t size2, uint8_t mode) * @description: 在OLED12864特定位置开始显示一个整数 * @param {uint8_t} x字符开始显示的横坐标 0~127 * @param {uint8_t} y字符开始显示的纵坐标 0~63 * @param {uint8_t} num 待显示的整数 * @param {uint8_t} len 待显示数字的位数 * @param {uint8_t} size2 待显示数字的大小

* @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowNum(uint8_t x,uint8_t y,unsignedint num,uint8_t len,uint8_t size2, uint8_t mode){    uint8_t t,temp;    uint8_t enshow=0;    for(t=0;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, mode);                continue;            }            else        

        enshow=1;        }        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2, mode);    }}/** * @function: void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size,uint8_t Color_Turn) * @description: 在OLED12864特定位置开始显示一个字符 * @param {uint8_t} x字符开始显示的横坐标 0~127 * @param {uint8_t} y字符开始显示的纵坐标 0~63 * @param {uint8_t} chr待显示的字符 * @param {uint8_t} Char_Size待显示字符的字体大小,选择字体 16/12 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size, uint8_t mode){    unsignedchar c=0,i=0;        c=chr-' ';//得到偏移后的值        if(x>128-1)        { 

           x=0;            y=y+2;        }        if(Char_Size ==16)    

    {            OLED_Set_Pos(x,y);            for(i=0;i<8;i++)            {         

       //OLED_WR_DATA(F8X16[c*16+i]);                if(mode)                                    OLED_WR_DATA(~F8X16[c*16+i]);                else                                    OLED_WR_DATA(F8X16[c*16+i]);            }            OLED_Set_Pos(x,y+1);            for(i=0;i<8;i++)            {      

          //OLED_WR_DATA(F8X16[c*16+i+8]);                if(mode)                                    OLED_WR_DATA(~F8X16[c*16+i+8]);                else                                    OLED_WR_DATA(F8X16[c*16+i+8]);            }        }        else        {                OLED_Set_Pos(x,y);                for(i=0;i<6;i++)                {                    //OLED_WR_DATA(F6x8[c][i]);                    for(i=0;i<6;i++)                    {                        if(mode)                                            OLED_WR_DATA(~F6x8[c][i]);                        else                                            OLED_WR_DATA(F6x8[c][i]);                    }                }        }}/** * @function: void OLED_Showdecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t Color_Turn) * @description: 显示正负浮点数 * @param {uint8_t} x待显示的数字起始横坐标,x:0~126 * @param {uint8_t} y待显示的数字起始纵坐标, y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1 * @param {float} num:输入的浮点型数据 * @param {uint8_t } z_ len:整数部分的位数 * @param {uint8_t } f_len: 小数部分的位数 * @param {uint8_t} size2:输入的数据大小,选择 16/12,16为8X16,12为6x8 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) 

* @return {*} */voidOLED_ShowDecimal(uint8_t x,uint8_t y,float num,uint8_t z_len,uint8_t f_len,uint8_t size2, uint8_t mode){    uint8_t t,temp,i=0;//i为负数标志位    uint8_t enshow;    int z_temp,f_temp;    if(num<0)    {        z_len+=1;        i=1;        num=-num;    }    z_temp=(int)num;    //整数部分    for(t=0;t    {        temp=(z_temp/oled_pow(10,z_len-t-1))%10;        if(enshow==0 && t<(z_len-1))        {            if(temp==0)            {                OLED_ShowChar(x+(size2/2)*t,y,' ',size2, mode);         

       continue;            }            else            enshow=1;        }        OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2, mode);    }    //小数点    OLED_ShowChar(x+(size2/2)*(z_len),y,'.',size2, mode);    f_temp=(int)((num-z_temp)*(oled_pow(10,f_len)));  //小数部分    for(t=0;t    {        temp=(f_temp/oled_pow(10,f_len-t-1))%10;        OLED_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2, mode);    }    if(i==1)//如果为负,就将最前的一位赋值‘-’    {        OLED_ShowChar(x,y,'-',size2, mode);        i=0;    }}/** * @function: void OLED_ShowString(uint8_t x, uint8_t y, uint8_t *chr, uint8_tChar_Size, uint8_t Color_Turn) * @description: 在OLED12864特定位置开始显示字符串 * @param {uint8_t} x待显示字符串的开始横坐标x:0~127 * @param {uint8_t} y待显示字符串的开始纵坐标 y:0~7,若选择字体大小为16,则两行数字之间需要间隔2,若选择字体大小为12,间隔1 * @param {uint8_t} *chr待显示的字符串 * @param {uint8_t} Char_Size待显示字符串的字体大小,选择字体 16/12,16为8X16,12为6x8 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size, uint8_t mode){    uint8_t j=0;    while (chr[j]!='\0')    {        OLED_ShowChar(x,y,chr[j],Char_Size, mode);        if (Char_Size ==12) //6X8的字体列加6,显示下一个字符            x += 6;        else  //8X16的字体列加8,显示下一个字符       

     x += 8;        if (x > 122 && Char_Size==12) //TextSize6x8如果一行不够显示了,从下一行继续显示        {            x = 0;            y++;        }        if (x > 120 && Char_Size== 16) //TextSize8x16如果一行不够显示了,从下一行继续显示        {            x = 0;            y+=2;        }        j++;    }}/** * @function: void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t Color_Turn) * @description: 在OLED特定位置开始显示16X16汉字 * @param {uint8_t} x待显示的汉字起始横坐标x: 0~112,两列汉字之间需要间隔16 * @param {uint8_t} y待显示的汉字起始纵坐标 y: 0~6 , 两行汉字之间需要间隔2 * @param {uint8_t} no待显示的汉字编号 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no, uint8_t mode){    uint8_t t=0;    OLED_Set_Pos(x,y);    for(t=0;t<16;t++)    {        if (mode)            OLED_WR_DATA(~Hzk[2*no][t]); //显示汉字的上半部分        else            OLED_WR_DATA(Hzk[2*no][t]); //显示汉字的上半部分    }    OLED_Set_Pos(x,y+1);    for(t=0;t<16;t++)    {        if (mode)            OLED_WR_DATA(~Hzk[2*no+1][t]); //显示汉字的上半部分        else            OLED_WR_DATA(Hzk[2*no+1][t]);//显示汉字的上半部分    }}/** * @function: void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *  BMP,uint8_t Color_Turn) * @description: 在OLED特定区域显示BMP图片 * @param {uint8_t} x0图像开始显示横坐标  x0:0~127 * @param {uint8_t} y0图像开始显示纵坐标  y0:0~7 * @param {uint8_t} x1图像结束显示横坐标  x1:1~128 * @param {uint8_t} y1图像结束显示纵坐标  y1:1~8 * @param {uint8_t} *BMP待显示的图像数据 * @param {uint8_t} mode 是否反相显示(1反相、0不反相) * @return {*} */voidOLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *  BMP, uint8_t mode){   uint32_t j = 0;   uint8_t x = 0, y = 0;  if(y1%8==0)        y = y1/8;  else        y = y1/8 + 1;    for(y=y0;y    {        OLED_Set_Pos(x0,y);    for(x=x0;x        {            if (mode)          

      OLED_WR_DATA(~BMP[j++]);//显示反相图片            else                OLED_WR_DATA(BMP[j++]);//显示图片        }    }}/** * @function: void OLED_DisplayMode(uint8_t mode) * @description: 屏幕内容取反显示 * @param {uint8_t} direction           ON  0xA7  , *                                      OFF 0xA6    默认此模式,设置像素点亮 * @return {*} */voidOLED_DisplayMode(uint8_t mode){    OLED_WR_CMD(mode);}/** * @function: void OLED_IntensityControl(uint8_t intensity) * @description: 屏幕亮度调节 * @param  {uint8_t} intensity  0x00~0xFF,RESET=0x7F * @return {*} */voidOLED_IntensityControl(uint8_t intensity){    OLED_WR_CMD(0x81);    OLED_WR_CMD(intensity);}


 


 

字体和图片取模方案


 

使用Image2LCD软件,将目标图片缩放至OLED屏幕尺寸,并保存为BMP格式;


 

RA


 

将BMP图片导入PCtoLCD软件,模式选择图像模式,点击齿轮图标进入设置界面;


 

RA


 

配置字模选项:


 

RA


 

生成字模即可;


 

同理,切换至字体模式,可生成目标汉字代码。


 

效果


 

按照硬件连接示意图,连接开发板和OLED对应引脚;


 

进入调试模式,或上电复位运行;


 

RA


 

OLED显示Renesas图标logo并延时500毫秒,之后切换至ADC电压表显示框架。


 

总结


 

本文介绍了瑞萨FPB RA0E2开发板实现OLED驱动显示Renesas图标logo以及ADC电压表框架的项目设计,为后续开发和实时显示ADC电压做好铺垫,也为瑞萨相关产品的快速开发和应用提供了参考。


 

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分