测试开发板的I2C通信,驱动OLED显示屏显示字符。
一、硬件部分
开发板预留有I2C接口,正好和OLED显示屏接口定义一样。

二、配置I2C接口
2.1、配置引脚
I2C使用了P100和P101引脚,这里使用的两个端口是SCI复用的I2C功能。

2.2、配置I2C参数
设置i2c从机地址(OLED显示屏)。

三、程序部分
3.1、fun_oled.c
#include "hal_data.h"
#include "oled/fun_oled.h"
#include "oled/codetab.h"
fsp_err_t err = FSP_SUCCESS;
i2c_master_event_t i2c_event = I2C_MASTER_EVENT_ABORTED;
int timeout_ms = 100;
void sci_i2c_master_callback(i2c_master_callback_args_t *p_args)
{
i2c_event = I2C_MASTER_EVENT_ABORTED;
if (NULL != p_args)
{
i2c_event = p_args->event;
}
}
void WriteCmd(unsigned char I2C_Command)
{
uint8_t ii[2]={0x00,0x00};
ii[1]=I2C_Command;
err = R_SCI_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);
assert(FSP_SUCCESS == err);
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)
{
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 100;
}
void WriteDat(unsigned char I2C_Data)
{
uint8_t ii[2]={0x40,0x00};
ii[1]=I2C_Data;
err = R_SCI_I2C_Write(&g_i2c0_ctrl, ii, 0x02, true);
assert(FSP_SUCCESS == err);
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)
{
}
i2c_event = I2C_MASTER_EVENT_ABORTED;
timeout_ms = 100;
}
void OLED_WrCmd(unsigned char IIC_Command)
{
WriteCmd(IIC_Command);
}
void OLED_Init(void)
{
err = R_SCI_I2C_Open(&g_i2c0_ctrl, &g_i2c0_cfg);
assert(FSP_SUCCESS == err);
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
WriteCmd(0xAE);
WriteCmd(0x20);
WriteCmd(0x10);
WriteCmd(0xb0);
WriteCmd(0xc8);
WriteCmd(0x00);
WriteCmd(0x10);
WriteCmd(0x40);
WriteCmd(0x81);
WriteCmd(0xff);
WriteCmd(0xa1);
WriteCmd(0xa6);
WriteCmd(0xa8);
WriteCmd(0x3F);
WriteCmd(0xa4);
WriteCmd(0xd3);
WriteCmd(0x00);
WriteCmd(0xd5);
WriteCmd(0xf0);
WriteCmd(0xd9);
WriteCmd(0x22);
WriteCmd(0xda);
WriteCmd(0x12);
WriteCmd(0xdb);
WriteCmd(0x40);
WriteCmd(0x8d);
WriteCmd(0x14);
WriteCmd(0xaf);
}
void OLED_SetPos(unsigned char x, unsigned char y)
{
WriteCmd(0xb0+y);
WriteCmd(((x&0xf0)>>4)|0x10);
WriteCmd((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_Data)
{
unsigned char m,n;
for(m=0;m<8;m++)
{
WriteCmd(0xb0+m);
WriteCmd(0x00);
WriteCmd(0x10);
for(n=0;n<128;n++)
{
WriteDat(fill_Data);
}
}
}
void OLED_CLS(void)
{
OLED_Fill(0xff);
}
void OLED_ON(void)
{
WriteCmd(0X8D);
WriteCmd(0X14);
WriteCmd(0XAF);
}
void OLED_OFF(void)
{
WriteCmd(0X8D);
WriteCmd(0X10);
WriteCmd(0XAE);
}
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
unsigned char c = 0,i = 0,j = 0;
switch(TextSize)
{
case 1:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 126)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<6;i++)
WriteDat(F6x8[c][i]);
x += 6;
j++;
}
}break;
case 2:
{
while(ch[j] != '\0')
{
c = ch[j] - 32;
if(x > 120)
{
x = 0;
y++;
}
OLED_SetPos(x,y);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
WriteDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
unsigned char wm=0;
unsigned int adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
WriteDat(F16x16[adder]);
adder += 1;
}
}
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_SetPos(x0,y);
for(x=x0;x<x1;x++)
{
WriteDat(BMP[j++]);
}
}
}
3.2、fun_oled.h
#ifndef __FUN_OLED_I2C_H
#define __FUN_OLED_I2C_H
void OLED_Init(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
#endif
3.3、hal_entry.c
#include "hal_data.h"
#include "led/fun_led.h"
#include "uart/fun_uart.h"
#include "adc/fun_adc.h"
#include "oled/fun_oled.h"
FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER
/*******************************************************************************************************************//**
* main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used. This function
* is called by main() when no RTOS is used.
**********************************************************************************************************************/
void hal_entry(void)
{
double adv=0.0;
/* TODO: add your own code here */
init_uart();
init_led();
init_adc();
OLED_Init();
OLED_Fill(0x00);
OLED_ShowStr(0,0,"RA6M4 BOARD",2);
OLED_ShowStr(0,2,"I2C OLED TEST",2);
OLED_ShowStr(0,4,"2025-07-27",2);
while(1)
{
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
led1_on();
led2_off();
led3_on();
R_BSP_SoftwareDelay(100, BSP_DELAY_UNITS_MILLISECONDS);
led1_off();
led2_on();
led3_off();
adv = Read_ADC_Voltage_Value();
printf("adc = %0.1f \r\n",adv);
//printf("RA6M4 Board UART9 TEST!\r\n");
}
#if BSP_TZ_SECURE_BUILD
/* Enter non-secure code */
R_BSP_NonSecureEnter();
#endif
}
/*******************************************************************************************************************//**
* This function is called at various points during the startup process. This implementation uses the event that is
* called right before main() to set up the pins.
*
* @param[in] event Where at in the start up process the code is currently at
**********************************************************************************************************************/
void R_BSP_WarmStart (bsp_warm_start_event_t event)
{
if (BSP_WARM_START_RESET == event)
{
#if BSP_FEATURE_FLASH_LP_VERSION != 0
/* Enable reading from data flash. */
R_FACI_LP->DFLCTL = 1U;
/* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
* C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
}
if (BSP_WARM_START_POST_C == event)
{
/* C runtime environment and system clocks are setup. */
/* Configure pins. */
R_IOPORT_Open(&IOPORT_CFG_CTRL, &IOPORT_CFG_NAME);
#if BSP_CFG_SDRAM_ENABLED
/* Setup SDRAM and initialize it. Must configure pins first. */
R_BSP_SdramInit(true);
#endif
}
}
#if BSP_TZ_SECURE_BUILD
FSP_CPP_HEADER
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();
/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{
}
FSP_CPP_FOOTER
#endif
四、运行结果
下载程序到开发板,OLED显示如下:
