[AT32M412] 【AT-START-M412测评】+硬件方式驱动OLED屏

[复制链接]
 楼主| jinglixixi 发表于 2025-6-1 12:55 | 显示全部楼层 |阅读模式
#申请原创#

在AT32M412开发板的例程中提供了I2C的相关示例,通过对它们的学习可以完成对OLED屏的显示驱动。
为使用 I2C1来驱动OLED屏,对I2C的相关定义如下:
#define I2Cx_PORT                       I2C1
#define I2Cx_CLK                         CRM_I2C1_PERIPH_CLOCK
#define I2Cx_DMA                        DMA1
#define I2Cx_DMA_CLK                    CRM_DMA1_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SCL_GPIO_PIN                GPIO_PINS_6
#define I2Cx_SCL_GPIO_PinsSource         GPIO_PINS_SOURCE6
#define I2Cx_SCL_GPIO_PORT              GPIOB
#define I2Cx_SCL_GPIO_MUX               GPIO_MUX_4
#define I2Cx_SDA_GPIO_CLK                CRM_GPIOB_PERIPH_CLOCK
#define I2Cx_SDA_GPIO_PIN                GPIO_PINS_7
#define I2Cx_SDA_GPIO_PinsSource         GPIO_PINS_SOURCE7
#define I2Cx_SDA_GPIO_PORT              GPIOB
#define I2Cx_SDA_GPIO_MUX               GPIO_MUX_4
进行I2C初始化的函数为:
  1. void i2c_lowlevel_init(i2c_handle_type* hi2c)
  2. {
  3. gpio_init_type gpio_init_structure;
  4. if(hi2c->i2cx == I2Cx_PORT)
  5. {
  6. crm_periph_clock_enable(I2Cx_CLK, TRUE);
  7. crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
  8. crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
  9. gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
  10. gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
  11. gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  12. gpio_init_structure.gpio_mode = GPIO_MODE_MUX;
  13. gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
  14. gpio_init_structure.gpio_pull = GPIO_PULL_UP;
  15. gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN;
  16. gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);
  17. gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN;
  18. gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);
  19. i2c_init(hi2c->i2cx, 0x0F, I2Cx_CLKCTRL);
  20. i2c_own_address1_set(hi2c->i2cx, I2C_ADDRESS_MODE_7BIT, I2Cx_ADDRESS);
  21. }
  22. }

OLED屏所使用的接口为J1,见图1所示。
5c15052d80578c48001c4207ef3e9de4
图1 所用接口

相较于软件方式,硬件方式省去了字节数据发送函数及相关辅助函数的构建。
此时,只需调用函数 i2c_master_transmit()即可构建相应的指令发送函数和数据发送函数,其内容如下:
  1. void Write_IIC_Command(unsigned char IIC_Command)
  2. {
  3. unsigned char Data[2]={0x00,0x00};
  4. Data[1]=IIC_Command;
  5. hi2cx.i2cx = I2C1;
  6. i2c_master_transmit(&hi2cx, 0x78, Data, 2, I2C_TIMEOUT);
  7. }

  8. void Write_IIC_Data(unsigned char IIC_Data)
  9. {
  10. unsigned char Data[2]={0x40,0x00};
  11. Data[1]=IIC_Data;
  12. hi2cx.i2cx = I2C1;
  13. i2c_master_transmit(&hi2cx, 0x78, Data, 2, I2C_TIMEOUT);
  14. }

  15. void OLED_WR_Byte(unsigned dat,unsigned cmd)
  16. {
  17. if(cmd)
  18. {
  19. Write_IIC_Data(dat);
  20. }
  21. else
  22. {
  23. Write_IIC_Command(dat);
  24. }
  25. }

在此基础上,就可以直接与OLED的功能函数实现对接。
对于单色的OLED屏来说其参数化函数为:
  1. void OLED_0_96D_Init(void)
  2. {
  3. OLED_WR_Byte(0xAE,OLED_CMD);
  4. OLED_WR_Byte(0x00,OLED_CMD);
  5. OLED_WR_Byte(0x10,OLED_CMD);
  6. OLED_WR_Byte(0x40,OLED_CMD);
  7. OLED_WR_Byte(0x81,OLED_CMD);
  8. OLED_WR_Byte(0xCF,OLED_CMD);
  9. OLED_WR_Byte(0xA1,OLED_CMD);
  10. OLED_WR_Byte(0xC8,OLED_CMD);
  11. OLED_WR_Byte(0xA6,OLED_CMD);
  12. OLED_WR_Byte(0xA8,OLED_CMD);
  13. OLED_WR_Byte(0x3f,OLED_CMD);
  14. OLED_WR_Byte(0xD3,OLED_CMD);
  15. OLED_WR_Byte(0x00,OLED_CMD);
  16. OLED_WR_Byte(0xd5,OLED_CMD);
  17. OLED_WR_Byte(0x80,OLED_CMD);
  18. OLED_WR_Byte(0xD9,OLED_CMD);
  19. OLED_WR_Byte(0xF1,OLED_CMD);
  20. OLED_WR_Byte(0xDA,OLED_CMD);
  21. OLED_WR_Byte(0x12,OLED_CMD);
  22. OLED_WR_Byte(0xDB,OLED_CMD);
  23. OLED_WR_Byte(0x40,OLED_CMD);
  24. OLED_WR_Byte(0x20,OLED_CMD);
  25. OLED_WR_Byte(0x02,OLED_CMD);
  26. OLED_WR_Byte(0x8D,OLED_CMD);
  27. OLED_WR_Byte(0x14,OLED_CMD);
  28. OLED_WR_Byte(0xA4,OLED_CMD);
  29. OLED_WR_Byte(0xA6,OLED_CMD);
  30. OLED_Clear();
  31. OLED_WR_Byte(0xAF,OLED_CMD);
  32. }

测试OLED屏的主程序为:
  1. int main(void)
  2. {
  3. i2c_status_type i2c_status;
  4. system_clock_config();
  5. hi2cx.i2cx = I2Cx_PORT;
  6. i2c_config(&hi2cx);
  7. OLED_0_96D_Init();
  8. OLED_ShowString(8,0,"AT32m412",16);
  9. OLED_ShowString(8,3, "0.96' OLED!",16);
  10. while(1);
  11. }

经程序的编译和下载,其测试效果如图2所示。
5195abe1625de995162f5421a2e82338
图2   0.91寸屏显示效果

75e4a97ffe49806b5833cb4cb845e7e1
图3   0.96寸屏显示效果


caigang13 发表于 2025-6-2 09:57 来自手机 | 显示全部楼层
古老的OLED显示屏又派上用场了
xionghaoyun 发表于 2025-6-2 11:23 | 显示全部楼层
接线图 代码分享不
 楼主| jinglixixi 发表于 2025-6-2 12:05 | 显示全部楼层
caigang13 发表于 2025-6-2 09:57
古老的OLED显示屏又派上用场了

没错,相对来讲单色屏较双色屏要好驱动。
 楼主| jinglixixi 发表于 2025-6-2 12:09 | 显示全部楼层
xionghaoyun 发表于 2025-6-2 11:23
接线图 代码分享不

SCL连接PB6,SDA连接PB7即可。
代码关键部分已介绍,其他代码参照器件的源程序的功能函数即可。
NightfallBallad 发表于 2025-6-16 10:28 | 显示全部楼层
楼主头像不是ST **么,硬件驱动的话 应该是I2C驱动。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

518

主题

2933

帖子

39

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