本帖最后由 hehung 于 2023-6-12 10:05 编辑
前言
本文讲解如何使用AC7802X的硬件I2C来驱动OLED屏幕。使用了I2C1。
1 硬件连接
查看数据手册,可以知道引脚的复用关系,如下图所示,可以复用为I2C的引脚有多组,我们选择PB6和PB7。
- PB7 - SCL
- PB8 - SDA
关于OLED就不多做介绍了,可以查看相关资料,OLED的7为I2C地址为0x3C。
2 软件编写
2.1 I2C驱动使能
如下图,要正确使用I2C,需要使能I2C外设。
2.2 I2C驱动
驱动代码如下
app_hw_i2c.c
- 初始化I2C相关引脚
- 初始化I2C的通信速率为400K
```c
/*
@hehung
2023-5-22
email: 1398660197@qq.com
wechat: hehung95
reproduced and please indicate the source @hehung
*/
#include "app_hw_i2c.h"
#include "ac780x_gpio.h"
#include <string.h>
/* Initialize for I2c driver */
void I2c_Init(void)
{
I2C_ConfigType i2cConfig;
/*清零结构体变量.*/
memset(&i2cConfig, 0x00, sizeof(i2cConfig));
/*初始化引脚功能为I2C.*/
GPIO_SetFunc(I2C0_SCL_PORT, I2C0_SCL_PIN, GPIO_FUN3);
GPIO_SetFunc(I2C0_SDA_PORT, I2C0_SDA_PIN, GPIO_FUN3);
/*无论是主机还是从机模式都需要配置的参数.*/
i2cConfig.mode = I2C_MASTER; /*设置主机模式.*/
i2cConfig.extAddrEn = DISABLE; /*10bit扩展地址禁能.*/
i2cConfig.interruptEn = DISABLE; /*I2C中断,BND/SAMF/ARBLOST.*/
i2cConfig.nackInterruptEn = DISABLE; /*NACK中断.*/
i2cConfig.ssInterruptEn = DISABLE; /*总线start或stop中断.*/
i2cConfig.i2cEn = ENABLE; /*使能模块.*/
i2cConfig.callBack = NULL; /*中断回调函数.*/
/*主机模式需要配置的参数,配置成从机模式可忽略.*/
/*波特率设置
f = APB时钟/((sampleCnt+1)*(stepCnt+1)*2)
当APB时钟为24M,所需波特率为100Kbps
可配置半脉冲宽度stepCnt为3,每个采样点宽度sampleCnt为4
则波特率 = 16M/((4+1)*(3+1)*2) = 400K
*/
i2cConfig.masterConfig.sampleCnt = 4; /*设置波特率为100Kbps,bandrate=(16M/(5*4*2))=400Kbps.*/
i2cConfig.masterConfig.stepCnt = 3;
i2cConfig.masterConfig.ARBEn = ENABLE; /*设置主机仲裁功能.*/
i2cConfig.masterConfig.SYNCEn = ENABLE; /*设置主机SCL同步功能.*/
I2C_Init(I2C0, &i2cConfig);
}
```
app_hw_i2c.h
- 设置I2C引脚相关宏
- 设置I2C通信地址为0x3C
```c
/*
@hehung
2023-5-22
email: 1398660197@qq.com
wechat: hehung95
reproduced and please indicate the source @hehung
*/
#ifndef APP_HW_I2C_H_
#define APP_HW_I2C_H_
#include "ac780x_i2c.h"
#define I2C0_SCL_PORT (GPIOB)
#define I2C0_SCL_PIN (GPIO_PIN7)
#define I2C0_SDA_PORT (GPIOB)
#define I2C0_SDA_PIN (GPIO_PIN8)
#define I2C0_DATA_LEN (8U)
#define I2C0_SLAVE_ADDR (0x3CU)
extern void I2c_Init(void);
#endif /* APP_HW_I2C_H_ */
```
2.3 OLED写命令和数据
```c
void OLED_WrDat(unsigned char IIC_Data)
{
uint8_t i2c_transmitter[2]={0x40, IIC_Data};
I2C_MasterTransmitPoll(I2C0, I2C0_SLAVE_ADDR, i2c_transmitter, 2, ENABLE);
}
/*********************OLED写命令函数************************************/
void OLED_WrCmd(unsigned char IIC_Command)
{
uint8_t i2c_transmitter[2]={0x00, IIC_Command};
I2C_MasterTransmitPoll(I2C0, I2C0_SLAVE_ADDR, i2c_transmitter, 2, ENABLE);
}
```
2.4 OLED显示
下面的代码为OLED显示,关于OLED的其他相关操作函数实现,参考附件代码。
```c
{
/* initialize the OLED */
OLED_Init();
OLED_ShowString(16, 0, (const uint8_t*)"bbs.21ic.com", 16, 1);
OLED_ShowHzStringRow(32, 16, (const char*)"四维图新", 1);
OLED_ShowHzStringRow(32, 32, (const char*)"杰发科技", 1);
// OLED_ShowString(64, 32, (const uint8_t*)"autochips", 16, 1);
OLED_ShowString(64, 48, (const uint8_t*)"--hehung", 16, 1);
OLED_Refresh_Gram();
```
3 显示效果
如下图,正常显示中英文信息,测试成功。
4 总结
总的来说,AC7802X的I2C驱动代码写的还是很棒的,用户使用起来简单快捷,对于开发过程而言,高效开发是十分喜欢的。
5 附件
下面是OLED的驱动代码,有兴趣的小伙伴可以下载参考。
05_HW_I2C_OLED.zip
(2.63 MB)
注意事项
1. 如需正常显示中文,需要将涉及到显示中文的文件重新编码为UTF-8格式,如果编译不正常,可以重新编码为“带BOM的UTF-8”格式
|