1.前言
本来想用他自身的硬件I2C实现的,但是不知道为啥跑demo一点波形都没有,改成推挽也没有波形,只有初始化的电平变化,而且I2C的驱动库好像有点复杂,起始信号结束信号都得单独发的,没有一个全部封装好的库直接往里填数据的就能发的那种,希望后续看看有没有更新啥的,或者大佬分享下经验。
所以本次项目用的软件模拟I2C实现啦,移植性也比较强。直接搬
2.硬件准备
GD32VW553-IOT开发板1个
CH340串口1个
0.96OLED屏幕一个
杜邦线若干
3.代码移植
本次项目是在官方驱动库的硬件I2C库改的,要字库驱动啥的可以评论区留言
main.c
oled屏幕从机的地址上0x78
#include "gd32vw55x.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32vw553h_eval.h"
#include "oled.h"
#include "OLED_Data.h"#define I2C_SLAVE_ADDRESS7 0x78void rcu_config(void)
{/* enable GPIOA clock */rcu_periph_clock_enable(RCU_GPIOA);
}void i2c_gpio_config(void)
{gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_2);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_2);gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3);gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ, GPIO_PIN_3);}int main(void)
{/* configure systick */systick_config();eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);gd_eval_com_init(EVAL_COM0); //初始化串口,上一篇有讲/* 启用外设时钟 */rcu_config();/* 配置I2C GPIO端口 */i2c_gpio_config();/* 初始化OLED */OLED_Init();/*在(0, 0)位置显示字符'A',字体大小为8*16点阵*/OLED_ShowChar(0, 0, 'A', OLED_8X16);/*在(16, 0)位置显示字符串"Hello World!",字体大小为8*16点阵*/OLED_ShowString(16, 0, "Hello World!", OLED_8X16);/*在(0, 18)位置显示字符'A',字体大小为6*8点阵*/OLED_ShowChar(0, 18, 'A', OLED_6X8);/*在(16, 18)位置显示字符串"Hello World!",字体大小为6*8点阵*/OLED_ShowString(16, 18, "Hello World!", OLED_6X8);/*在(0, 28)位置显示数字12345,长度为5,字体大小为6*8点阵*/OLED_ShowNum(0, 28, 12345, 5, OLED_6X8);/*在(40, 28)位置显示有符号数字-66,长度为2,字体大小为6*8点阵*/OLED_ShowSignedNum(40, 28, -66, 2, OLED_6X8);/*在(70, 28)位置显示十六进制数字0xA5A5,长度为4,字体大小为6*8点阵*/OLED_ShowHexNum(70, 28, 0xA5A5, 4, OLED_6X8);/*在(0, 38)位置显示二进制数字0xA5,长度为8,字体大小为6*8点阵*/OLED_ShowBinNum(0, 38, 0xA5, 8, OLED_6X8);/*在(60, 38)位置显示浮点数字123.45,整数部分长度为3,小数部分长度为2,字体大小为6*8点阵*/OLED_ShowFloatNum(60, 38, 123.45, 3, 2, OLED_6X8);/*在(0, 48)位置显示英文和汉字串"Hello,世界。",支持中英文混写*/OLED_ShowString(0, 48, "Hello,世界。", OLED_8X16);/*在(96, 48)位置显示图像,宽16像素,高16像素,图像数据为Diode数组*/OLED_ShowImage(96, 48, 16, 16, Diode);/*在(96, 18)位置打印格式化字符串,字体大小为6*8点阵,格式化字符串为"[%02d]"*/OLED_Printf(96, 18, OLED_6X8, "[%02d]", 6);/*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/OLED_Update();printf("booting\r\n");while(1) {printf("ing\r\n");}
}
oled.c
需要改的地方不多,就是IO口这里,其他照搬代码太多不写了,可以下载江协的代码修改下
这里用的PA2-SCL PA3-SDA硬件I2C也是对的上的
/*** 函 数:OLED写SCL高低电平* 参 数:要写入SCL的电平值,范围:0/1* 返 回 值:无* 说 明:当上层函数需要写SCL时,此函数会被调用* 用户需要根据参数传入的值,将SCL置为高电平或者低电平* 当参数传入0时,置SCL为低电平,当参数传入1时,置SCL为高电平*/
void OLED_W_SCL(uint8_t BitValue)
{/*根据BitValue的值,将SCL置高电平或者低电平*/gpio_bit_write(GPIOA, GPIO_PIN_2, BitValue);/*如果单片机速度过快,可在此添加适量延时,以避免超出I2C通信的最大速度*///...
}/*** 函 数:OLED写SDA高低电平* 参 数:要写入SDA的电平值,范围:0/1* 返 回 值:无* 说 明:当上层函数需要写SDA时,此函数会被调用* 用户需要根据参数传入的值,将SDA置为高电平或者低电平* 当参数传入0时,置SDA为低电平,当参数传入1时,置SDA为高电平*/
void OLED_W_SDA(uint8_t BitValue)
{/*根据BitValue的值,将SDA置高电平或者低电平*/gpio_bit_write(GPIOA, GPIO_PIN_3, BitValue);/*如果单片机速度过快,可在此添加适量延时,以避免超出I2C通信的最大速度*///...
}