瑞萨单片机william hill官网
直播中

少年阿炳

3年用户 40经验值
擅长:嵌入式技术
私信 关注
[经验]

【瑞萨RA4系列开发板体验】硬件iic点亮oled屏幕

写在前面

  • 此次点亮oled主要是参考了本次开发自带的资料和其他网络资料。
  • 本工程存在bug,直接烧录无法运行,需要在调试模式,全速运行,程序会自动停止,然后再点全速运行才能点亮。
    程序会在下图,38行停止。不知道怎么解决,请路过的朋友帮忙看看,工程压缩包会放在最下方。
  • 图片.png

本次实验现象

1.屏幕显示“瑞萨 电子发烧友”
2.led1灯闪烁

建立工程

本次工程实在之前LED灯闪烁的基础上建立,下面只分享如何配置IIC并移植屏幕驱动。

  1. 打开RASC 选择->Stacks->New stack->Connectivity->I2C_Master(r_iic_master)
    图片.png
  2. 点击g_i2c_master0
    图片.png
  3. iic参数配置
    图片.png
    点击SDA栏,右侧会出现一个箭头,点击箭头配置IIC引脚
    图片.png

图片.png

IIC配置完毕。生成工程即可。

移植OLED驱动

本次移植的驱动来源于stm32,是模拟IIC。

1.将oled相应的所有文件导入到工程,并添加路径。
2.删除在stm32时用到的#include 文件,比如#include“sys.h”
3.删除io口初始化部分,删除模拟IIC部分,比如IIC_Start()这类函数。
4.重新定义IIC写入命令和写入数据的函数

//变量定义
extern fsp_err_t err;
int  timeout_ms;
extern  i2c_master_event_t i2c_event ;

static void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{
    if(cmd)
    {
        Write_IIC_Data(dat);
    }
    else 
    {
        Write_IIC_Command(dat);
    }
}

/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
    uint8_t ii[2]={0x00,0x00};            
    ii[1]=IIC_Command;            
    err = R_IIC_MASTER_Write(&g_i2c_master0_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           = 1000;    
}

/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
    uint8_t ii[2]={0x40,0x00};
    ii[0] = 0x40;
    ii[1]=IIC_Data;
    err = R_IIC_MASTER_Write(&g_i2c_master0_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           = 1000;
}

OLED初始化函数

//初始化SSD1306
void OLED_Init(void)
{
    OLED_WR_Byte(0xAE,OLED_CMD);//--display off
    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
    OLED_WR_Byte(0xB0,OLED_CMD);//--set page address
    OLED_WR_Byte(0x81,OLED_CMD); // contract control
    OLED_WR_Byte(0xFF,OLED_CMD);//--128
    OLED_WR_Byte(0xA1,OLED_CMD);//set segment remap
    OLED_WR_Byte(0xA6,OLED_CMD);//--normal / reverse
    OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
    OLED_WR_Byte(0x3F,OLED_CMD);//--1/32 duty
    OLED_WR_Byte(0xC8,OLED_CMD);//Com scan direction
    OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset
    OLED_WR_Byte(0x00,OLED_CMD);//

    OLED_WR_Byte(0xD5,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(0xD9,OLED_CMD);//Set Pre-Charge Period
    OLED_WR_Byte(0xF1,OLED_CMD);//

    OLED_WR_Byte(0xDA,OLED_CMD);//set com pin configuartion
    OLED_WR_Byte(0x12,OLED_CMD);//

    OLED_WR_Byte(0xDB,OLED_CMD);//set Vcomh
    OLED_WR_Byte(0x30,OLED_CMD);//

    OLED_WR_Byte(0x8D,OLED_CMD);//set charge pump enable
    OLED_WR_Byte(0x14,OLED_CMD);//

    OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panel
}

以上便完成了OLED驱动部分的移植。之后就是hal_entry的函数。

void hal_entry(void)
{


err = R_IIC_MASTER_Open(&g_i2c_master0_ctrl, &g_i2c_master0_cfg);
assert(FSP_SUCCESS == err);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
OLED_Init();//OLED初始化
OLED_Clear();//清屏

//OLED_ShowString(16,1,"RA",16);
OLED_ShowCHinese(32,1,0);//瑞
OLED_ShowCHinese(48,1,1);//萨
OLED_ShowCHinese(0,4,2);//电
OLED_ShowCHinese(16,4,3);//子
OLED_ShowCHinese(32,4,4);//发
OLED_ShowCHinese(48,4,5);//烧
OLED_ShowCHinese(60,4,6);//友

/* TODO: add your own code here */
while(1)
{
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_LOW);
R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT
R_IOPORT_PinWrite(&g_ioport_ctrl, BSP_IO_PORT_04_PIN_15, BSP_IO_LEVEL_HIGH);

}


#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}

变量定义

fsp_err_t err;
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;

IIC的回调函数

void IIC_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;
    }
}

之后便可编译过程,在调试模式按照此贴开头的方式运行。
图片.png

*附件:iic_oled.rar

回帖(2)

lingxin-yuhe

2022-12-2 11:18:07
将变量timeout_ms赋值,再编译运行就可以了。
1 举报

华仔stm32

2022-12-2 12:00:45
我找到原因了:变量timeout_ms 没有赋初值,所以刚运行的时候是0,所以就会卡死。按下面的修改就可以了。
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"

#include "hal_data.h"
extern fsp_err_t err;
int  timeout_ms = 1000;
extern  i2c_master_event_t i2c_event ;
举报

更多回帖

发帖
×
20
完善资料,
赚取积分