您当前的位置: 首页 >> 新品发布/设计应用

瑞萨RA0单片机连载之―面向对象之I2C驱动OLED

作者:蔡柱旺电子交流圈电子网 日期:2025-04-20 点击数:6


1   前言

OLED是非常常用的显示设备,可以由4线、3线的spi驱动,也可以使用2线的IIC来驱动。百问网提供了spi_OLED的驱动例程,这次使用IIC来驱动,并且使用基于面向对象的编程来实现。

2   实现步聚

1.配置IIC,打开RASC后,在栈中增加rau_master_I2C,并设置channel为0b20即通道2,选择SCL为P112与SDA为P110。

1744987216768564.png

【注】我原来设置了为通道0或者通道1,但是都与UART或的外接晶振的IO有冲突,所以只能选择这个通道但是他还是与tx、LED有冲突,如果自己的设计的话还需要考虑到IO的冲突问题。

2.生成代码后,我拷贝drv_oled.h/c 以及driv_spi.h到工程之中。

view plaincopy to clipboardprint?

1. <br>

1744987256301838.png

3.在原来的OLED工程之中,是使用spi来驱动的,同时原来的RA5他的内存与频率相比RA0要高很多,需要进行很多的更改。首先添加回调函数,回调函数中判断接收状态,并更新:

view plaincopy to clipboardprint?

1. void sau_i2c_master_callback(i2c_master_callback_

args_t * p_args)

2. {

3. switch (p_args->event)

4. {

5. c ase I2C_MASTER_EVENT_TX_COMPLETE:

6. {

7. gI2C1TxCplt = true;

8. break;

9. }

10. c aseI2C_MASTER_EVENT_RX_COMPLETE:

11. {

12. gI2C1RxCplt = true;

13. break;

14. }

15. default:

16. {

17. gI2C1TxCplt = gI2C1RxCplt = false;

18. break;

19. }

20. }

21. }

4.接着修改发送等待超时函数,在我们向i2c 总线发送数据结事后,我们需要用这个函数来判断是否发送结束的标志位。

view plaincopy to clipboardprint?

1. static void I2C1WaitTxCplt(void)

2. {

3. uint16_t wTimeOut = 10;

4. while(!gI2C2TxCplt && wTimeOut)

5. {

6. HAL_Delay(1);

7. wTimeOut--;

8. }

9. gI2C2TxCplt = false;

10. }

5.修改向ssd1306 写入一个寄存器的功能函数,在这个函数中,我们要组装一个buff 用于向i2c 总线写入数据的,由于向ssd1306 写入寄存器,第一个字节为

0x00,所以组装为[0x00, cmd]。

view plaincopy to clipboardprint?

1. static void OLEDDrvWriteReg(uint8_t ucData)

2. {

3. uint8_t buff[2]= {0x00,0x00};

4. buff[1] = ucData;

5. fsp_err_t err = R_SAU_I2C_Write(&g_sau_

i2c_master_ctrl, buff, 2, true);

6. if (FSP_SUCCESS != err)

7. {

8. printf(“%s %drn”, __FUNCTION__, __

LINE__);

9. return;

10. }

11. I2C1WaitTxCplt();

12. }

6.组装向ssd1306 发送一整个buff 的命令:

view plaincopy to clipboardprint?

1. static void OLEDDrvWriteBuf(uint8_t* rbuf,

uint16_t wSize)

2. {

3. fsp_err_t err;

4.

5. // err =R_SAU_I2C_Write(&g_sau_i2c_

master_ctrl, 0x40, 1, false);

6. // if(FSP_SUCCESS != err)

7. // printf(“Function:%stLine:%drn”, __

FUNCTION__, __LINE__);

8. rbuf[0] = 0x40;

9. err = R_SAU_I2C_Write(&g_sau_i2c_master_

ctrl, rbuf, 1024, true);

10. if(FSP_SUCCESS != err)

11. printf(“Function:%stLine:%drn”, __

FUNCTION__, __LINE__);

12.

13. I2C1WaitTxCplt();

14. }

【注】这里原来使用malloc 进行了重新的内存申请,但是由于这个MCU 的内存有限,我做了申请,好象一直不成功,先写成这样,其实buf 中的0 位是被清除掉了的,所以会有点问题,在后面我将重新这个驱动,这里先实现基本功能。

7.编写测试函数如下:

view plaincopy to clipboardprint?

1. void led_blink(void)

2. {

3.

4. UartDevicesRegister();

5.

6.

7. DisplayDevice *ptDispDev = OLEDGetDevice();

8. if(ptDispDev == NULL)

9. {

10. printf(“Failed to get OLED Display Device!

rn”);

11. return;

12. }

13.

14. ptDispDev->Init(ptDispDev);

15. uint8_t *pBuf = (uint8_t*)ptDispDev->FBBase;

16. while(1)

17. {

18.

19. for(uint16_t i=0; i<ptDispDev->

dwSize; i++)

20. {

21. pBuf[i] = 0x00;

22. }

23. ptDispDev->Flush(ptDispDev);

24. HAL_Delay(1);

25. for(uint16_t i=0; i<ptDispDev->dwSize; i++)

26. {

27. pBuf[i] = 0xFF;

28. }

29. ptDispDev->Flush(ptDispDev);

30. HAL_Delay(1);

31.

32. }

33. }

其中第一段是向整个屏写入了0x00即全屏为黑色,第二段是写入oxFF 即全白。这样就实现了清屏-》全亮的效果。

3   总结

在面向对象的编程中,对OLED 进行的封装,在使用的过程中,可以实现少量的低层代码的修改即中实现模块化的功能实现。下一步,我将补全字符、图片的功能。

(本文来源于《EEPW》202504

本站所有文章、数据、图片均来自网友原创提供和互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:

标签:202504