[学习笔记] 【AutoChips MCU评测报告】五、I2C

[复制链接]
1023|1
 楼主| lisingch 发表于 2020-6-13 15:37 | 显示全部楼层 |阅读模式
本帖最后由 lisingch 于 2020-6-13 15:43 编辑

      对于I2C通信平时使用软件方式比较多,因为其使用比较灵活、移植方便。本次实验使用AC7811QBGE微控制器片上的硬件I2C资源驱动一块0.69寸96*16分辨率的OLED。工程依然使用了“AutoGen Studio”创建。下面是实验过程:

一、实验资源
1、AC7811-MINI开发板;
2、AutoGen Studio 1.2.0;
3、KEIL 5.28.0.0;
4、0.69寸OLED(自制模块)

二、资源简介
       AC7811QBGE微控制器片上有两个I2C模块,支持主、从模式, 支持I2C标准模式和快速模式,支持DMA,具有可编程输入毛刺过滤器、传输比特率等。
2020-06-13_132858.png
2020-06-13_133007.png

      对于I2C的各种操作模式参考手册中结合寄存器给出了非常细致的描述,通过对手册的学习对I2C协议的学习具有积极的指导作用。在本次实验中只是对OLED设备写数据,AC7811QBGE的I2C模块只充当了主机发送器。如下:
2020-06-13_143939.png
2020-06-13_144007.png

I2C通信中还有一个速率的重要参数需要考虑,实验中具体的配置在下一节中描述。如下图:
2020-06-13_144100.png

三、代码实现
      上节图中的公式:fSCL=fbclk/(((SAMPLE_CNT_DIV+1)*(STEP_CNT_DIV+1))*2),其中的主要参数均可在“AutoGen Studio”进行相应配置,
Fbclk=48MHz;SAMPLE_CNT_DIV=14;STEP_CNT_DIV=14,根据配置参数可以计算fSCL=48MHz/((14+1)*(14+1)*2)=106.6KHz,当然也可以根据需要配置更高的通信速率,比如400KHz。
2020-06-13_152823.png
2020-06-13_152839.png

由“AutoGen Studio”生成的I2C初始化代码如下:
  1. /* I2C1 init function */
  2. void ATC_I2C1_Init(void)
  3. {
  4.     I2C_ConfigType config;

  5.     MSP_I2C_Init(I2C1);
  6.     config.sampleCNT = 14;
  7.     config.stepCNT = 14;
  8.     config.sclAdj = 0;
  9.     config.setting.i2cEn = 1;
  10.     config.setting.intEn = 0;
  11.     config.setting.master = 1;
  12.     config.setting.wakeUpEn = 0;
  13.     config.setting.swRst = 0;
  14.     config.setting.gcaEn = 0;
  15.     config.setting.addressExt = 0;
  16.     config.setting.syncEn = 1;
  17.     config.setting.arbEn = 0;
  18.     config.setting.strEn = 0;
  19.     config.setting.mntEn = 0;
  20.     config.setting.mntIE = 0;
  21.     config.setting.dmaRxEn = 0;
  22.     config.setting.dmaTxEn = 0;
  23.     config.setting.SSIE = 0;
  24.     config.setting.rxOFIntEn = 0;
  25.     config.setting.txUFIntEn = 0;
  26.     config.setting.nackIntEn = 0;
  27.     config.addr1 = 127;
  28.     I2C_Initialize(I2C1, &config);

  29. }

实验中使用的这个OLED模块当时制作时引出了"RES"复位脚,其实直接将其接高电平也可以工作,实验中还是使用这个引脚:
  1. /**
  2.   * @函数名: OLED_RES_Init
  3.   * @功  能: 对OLED069的RES引脚初始化
  4.   * @参  数: 无
  5.   * @返回值: 无
  6.   */
  7. static void OLED_RES_Init(void)
  8. {
  9.   OLED069_RES_HIGH();
  10.   mdelay(100);
  11.   OLED069_RES_LOW();
  12.   mdelay(100);
  13.   OLED069_RES_HIGH();
  14. }

对于这个OLED器件的操作无非就是向器件地址上写命令各数据,I2C主机“写”函数套用了DEMO:
  1. #define OLED069_ADDS                 0X78        //OLED069器件地址
  2. #define OLED069_WRITE_CMD                        0X00        //写命令
  3. #define OLED069_WRITE_DAT     0X40                                //写数据

  4. /**
  5.   * [url=home.php?mod=space&uid=247401]@brief[/url]  WriteDat,向OLED写入数据
  6.   * @param  I2C_Data:数据
  7.   * @retval 无
  8.   */
  9. void WriteDat(uint8_t I2C_Data)//写数据
  10. {
  11.         uint32_t errorStatus = 0;
  12.         I2C_Start(I2C1);
  13.         errorStatus = I2C_WriteOneByte(I2C1, OLED069_ADDS);
  14.         if (errorStatus == I2C_ERROR_NULL)
  15.         {
  16.                 I2C_WriteOneByte(I2C1, OLED069_WRITE_DAT);
  17.         }
  18.         if (errorStatus == I2C_ERROR_NULL)
  19.         {
  20.                 I2C_WriteOneByte(I2C1, I2C_Data);
  21.         }
  22.         I2C_Stop(I2C1);
  23. }


  24. void WriteCmd(uint8_t I2C_Command)//写命令
  25. {
  26.         uint32_t errorStatus = 0;
  27.         I2C_Start(I2C1);
  28.         errorStatus = I2C_WriteOneByte(I2C1, OLED069_ADDS);      
  29.         if(errorStatus == I2C_ERROR_NULL)
  30.         {
  31.                 errorStatus = I2C_WriteOneByte(I2C1, OLED069_WRITE_CMD);  
  32.         }
  33.         if(errorStatus == I2C_ERROR_NULL)
  34.         {
  35.                 errorStatus = I2C_WriteOneByte(I2C1, I2C_Command);
  36.         }
  37.         I2C_Stop(I2C1);
  38. }

OLED的分辨率为96*16,主函数中直接向OLED分三屏送显8*16的ASCII数据:
  1. OLED_ShowStr(12, 0, "AutoChips", 2);
  2.                         mdelay(1000);
  3.                         OLED_CLS();//清屏
  4.                         
  5.                         OLED_ShowStr(8, 0, "AC7811QBGE", 2);
  6.                         mdelay(1000);
  7.                         OLED_CLS();
  8.                         
  9.                         OLED_ShowStr(0, 0, "I2C OLED OK!", 2);
  10.                         mdelay(1000);
  11.                         OLED_CLS();

四、实验结果
微信图片_20200613013544.jpg
微信图片_20200613013548.jpg
微信图片_20200613013552.jpg

五、实验总结
      通过本次实验对AC781X系列微控制器的片上I2C资源的主机发送器模式有了一些认识,对于其他各种工作模式还要进一步学习。


zeshoufx 发表于 2020-6-15 08:35 | 显示全部楼层
谢谢分享,,,,,,,,,,,,,
您需要登录后才可以回帖 登录 | 注册

本版积分规则

99

主题

15005

帖子

19

粉丝
快速回复 在线客服 返回列表 返回顶部