本帖最后由 chenqiguang1998 于 2024-6-3 15:11 编辑
#申请原创# 在本次测评中,我们将对 APM32F411V Tiny Board 的 IIC 代码进行测试,并尝试驱动 0.96 寸 IIC 协议的 OLED 蓝黄双色模块。
一、引脚设置
根据 OLED 模块的引脚定义,我们可以将其 SCL 和 SDA 引脚分别连接到 APM32F411V Tiny Board 的 PB3 和 PB10 引脚上。
二、IIC 代码测试
首先,我们需要确保 APM32F411V Tiny Board 上的 IIC 接口已经正确连接。根据参考手册,我们可以使用以下代码来初始化 IIC 接口:
I2C_HandleTypeDef hi2c2;
void MX_I2C2_Init(void) {
hi2c2.Instance = I2C2;
hi2c2.Init.ClockSpeed = 100000;
hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c2.Init.OwnAddress1 = 0;
hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c2.Init.OwnAddress2 = 0;
hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
DAL_I2C_Init(&hi2c2);
}
接下来,我们可以使用以下代码来向 OLED 模块发送数据:
#define OLED_ADDRESS 0x78
// 向 OLED 发送命令
void OLED_SendCommand(uint8_t command) {
DAL_I2C_Master_Transmit(&hi2c2, OLED_ADDRESS, &command, 1, 100);
}
// 向 OLED 发送数据
void OLED_SendData(uint8_t data) {
DAL_I2C_Master_Transmit(&hi2c2, OLED_ADDRESS, &data, 1, 100);
}
// OLED 初始化
void OLED_Init(void) {
OLED_SendCommand(0xAE); // 关闭显示
OLED_SendCommand(0x20); // 设置内存地址模式
OLED_SendCommand(0x02);
OLED_SendCommand(0xB0); // 设置页地址
OLED_SendCommand(0xC8); // 扫描方向反转
OLED_SendCommand(0x00); // 低列起始地址
OLED_SendCommand(0x10); // 高列起始地址
OLED_SendCommand(0x40); // 设置显示起始行
OLED_SendCommand(0x81); // 设置对比度
OLED_SendCommand(0xFF);
OLED_SendCommand(0xA1); // 段重映射
OLED_SendCommand(0xA6); // 正常显示(非反相)
OLED_SendCommand(0xA8); // 设置多路复用比
OLED_SendCommand(0x3F);
OLED_SendCommand(0xA4); // 全局显示开启
OLED_SendCommand(0xD3); // 设置显示偏移
OLED_SendCommand(0x00);
OLED_SendCommand(0xD5); // 设置时钟分频比
OLED_SendCommand(0x80);
OLED_SendCommand(0xD9); // 预充电设置
OLED_SendCommand(0xF1);
OLED_SendCommand(0xDA); // 引脚配置
OLED_SendCommand(0x12);
OLED_SendCommand(0x8D); // 电荷泵设置
OLED_SendCommand(0x14);
OLED_SendCommand(0xAF); // 开启显示
}
// 在指定位置显示一个像素
void OLED_SetPixel(uint8_t x, uint8_t y, uint8_t color) {
uint8_t page = y / 8;
uint8_t col = x;
if (color) {
OLED_SendData(0x01 << (y % 8));
} else {
OLED_SendData(0x00);
}
OLED_SendCommand(0xB0 + page);
OLED_SendCommand((col & 0xF0) >> 4 | 0x10);
OLED_SendCommand(col & 0x0F);
}
// 发送命令函数修改
void OLED_WriteCmd(uint8_t cmd) {
DAL_I2C_Master_Transmit(&hi2c, OLED_ADDRESS, &cmd, 1, 1000);
}
// 发送数据函数修改
void OLED_WriteData(uint8_t data) {
DAL_I2C_Master_Transmit(&hi2c, OLED_ADDRESS, &data, 1, 1000);
}
// 设置光标位置函数修改
void OLED_SetCursor(uint8_t x, uint8_t y) {
OLED_WriteCmd(0xB0 + y);
OLED_WriteCmd(((x & 0xF0) >> 4) | 0x10);
OLED_WriteCmd((x & 0x0F) | 0x01);
}
void OLED_Clear()
{
for (uint8_t i = 0; i < 8; i++)
{
OLED_SetCursor(0, i);
for (uint8_t j = 0; j < 128; j++)
{
OLED_WriteData(0x00);
}
}
}
void OLED_ShowString(uint8_t x, uint8_t y, const char *str)
{
OLED_SetCursor(x, y);
while (*str)
{
OLED_WriteData(*str++);
}
}
typedef enum {
MENU_FUNCTION,
MENU_TEST,
MENU_FUNCTION_SOFT,
MENU_FUNCTION_NORMAL,
MENU_FUNCTION_STRONG,
MENU_TEST_PROGRESSIVE,
MENU_TEST_SENSOR_BASED
} Menu;
Menu current_menu = MENU_FUNCTION;
Menu previous_menu = MENU_FUNCTION_SOFT;
#define OLED_COLOR_BLACK 0x00
void OLED_Fill_Black(uint8_t data) {
for (int page = 0; page < 8; page++) {
// 设置页地址
uint8_t cmd[2] = {0xB0 + page, 0x00};
DAL_I2C_Master_Transmit(&hi2c, OLED_ADDRESS, cmd, 2, 100);
// 逐列填充颜色数据
for (int col = 0; col < 128; col++) {
DAL_I2C_Master_Transmit(&hi2c, OLED_ADDRESS, &data, 1, 100);
}
}
}
void OLED_WriteString(const char *str, uint8_t font, uint8_t color) {
while (*str) {
uint8_t data[2] = {(uint8_t)*str, color};
HAL_I2C_Master_Transmit(&hi2c, OLED_ADDRESS, data, 2, 100);
str++;
}
}
最后进行测试:
int main()
{
DAL_Init();
SystemClock_Config();
MX_I2C2_Init();
OLED_Init();
OLED_Clear();
OLED_ShowString(0, 0, "Hello, World!");
|