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

内容摘要本文引用地址:1   前言OLED是非常常用的显示设备,可以由4线、3线的spi驱动,也可以使用2线的IIC来驱动。百问网提供了spi_OLED的驱动例程,这次使用IIC来驱动,并且使用基于面向对象的编程来实现。2   实现步聚1.配置II

本文引用地址:

1   前言

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

2   实现步聚

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

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

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

view plaincopy to clipboardprint?

1.

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

dwSize; i++)

20. {

21. pBuf[i] = 0x00;

22. }

23. ptDispDev- Flush(ptDispDev);

24. HAL_Delay(1);

25. for(uint16_t i=0; idwSize; i++)

26. {

27. pBuf[i] = 0xFF;

28. }

29. ptDispDev- Flush(ptDispDev);

30. HAL_Delay(1);

31.

32. }

33. }

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

3   总结

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

 
举报 收藏 打赏 评论 0
24小时热闻
今日推荐
浙ICP备16017970号-3