CH57x,CH582,CH592模拟I2C主机控制OLED屏幕
OLED驱动源码来自B站UP:江协科技
视频链接:https://www.bilibili.com/video/BV1th411z7sn?p=10&vd_source=d1b8b6d61c97078bb35a07cbc2e6608a
I2C通讯一般采用开漏输出的IO配置,可以降低总线上挂载的IIC从机设备的数据冲突风险。
而CH582等低功耗蓝牙芯片的GPIO不支持开漏输出模式,了解到开漏输出的特性为:IO输出高时为高阻态(由外部上拉或者下拉电阻决定最终电平),IO输出低时为低电平,因此可以模拟开漏:
1、当GPIO要输出高电平时,将GPIO配置为上拉输入模式,由芯片内部上拉电阻将总线拉至高电平;芯片内部上/下拉电阻阻值默认为50K ,如需加快电平转换速度,可外接阻值更小的上下拉电阻;
2、当GPIO要输出低电平时,将GPIO配置为输出模式,默认输出低电平。
具体配置为:
#define IIC_SCL_PIN GPIO_Pin_5//PB5-SCL
#define IIC_SDA_PIN GPIO_Pin_4//PB4-SDA
#define IIC_SCL_H() R32_PB_DIR &= ~IIC_SCL_PIN
#define IIC_SCL_L() R32_PB_DIR |= IIC_SCL_PIN
#define IIC_SDA_H() R32_PB_DIR &= ~IIC_SDA_PIN
#define IIC_SDA_L() R32_PB_DIR |= IIC_SDA_PIN
void IIC_Init()
{
GPIOB_ModeCfg(IIC_SCL_PIN,GPIO_ModeIN_PU );//初始化为上拉输入
GPIOB_ModeCfg(IIC_SDA_PIN,GPIO_ModeIN_PU );//初始化为上拉输入
GPIOB_ResetBits(IIC_SCL_PIN|IIC_SDA_PIN);//配置默认输出低电平,保证在切换IO引脚为输出方向时能够及时输出低电平
IIC_SCL_H();//SCL拉高
IIC_SDA_H();//SDA拉高
}
void IIC_START()//开始信号:SCL为高电平时,SDA由高电平转变为低电平
{
IIC_SDA_H();
IIC_SCL_H();
IIC_SDA_L();
IIC_SCL_L();
}
void IIC_STOP()//结束信号:SCL为高电平时,SDA由低电平转变为高电平
{
IIC_SDA_L();
IIC_SCL_H();
IIC_SDA_H();
}
/**
* @brief I2C发送一个字节
* @param Byte 要发送的一个字节
* @retval 无
*/
void OLED_IIC_SendByte(uint8_t Byte)
{
uint8_t i;
for(i = 0;i < 8;i++)
{
if(Byte & (0x80 >> i))
{
IIC_SDA_H();
}
else
{
IIC_SDA_L();
}
IIC_SCL_H();
IIC_SCL_L();
}
IIC_SCL_H();
IIC_SCL_L();
}
/**
* @brief OLED写命令
* @param Command 要写入的命令
* @retval 无
*/
void OLED_WriteCommand(uint8_t Command)
{
IIC_START();
OLED_IIC_SendByte(0x78);
OLED_IIC_SendByte(0x00);
OLED_IIC_SendByte(Command);
IIC_STOP();
}
/**
* @brief OLED写数据
* @param Data 要写入的数据
* @retval 无
*/
void OLED_WriteData(uint8_t Data)
{
IIC_START();
OLED_IIC_SendByte(0x78); //从机地址
OLED_IIC_SendByte(0x40); //写数据
OLED_IIC_SendByte(Data);
IIC_STOP();
}
void OLED_Init(void)//OLED屏幕按照手册进行初始化
{
IIC_Init(); //端口初始化
OLED_WriteCommand(0xAE); //关闭显示
OLED_WriteCommand(0xD5); //设置显示时钟分频比/振荡器频率
OLED_WriteCommand(0x80);
OLED_WriteCommand(0xA8); //设置多路复用率
OLED_WriteCommand(0x3F);
OLED_WriteCommand(0xD3); //设置显示偏移
OLED_WriteCommand(0x00);
OLED_WriteCommand(0x40); //设置显示开始行
OLED_WriteCommand(0xA1); //设置左右方向,0xA1正常 0xA0左右反置
OLED_WriteCommand(0xC8); //设置上下方向,0xC8正常 0xC0上下反置
OLED_WriteCommand(0xDA); //设置COM引脚硬件配置
OLED_WriteCommand(0x12);
OLED_WriteCommand(0x81); //设置对比度控制
OLED_WriteCommand(0xCF);
OLED_WriteCommand(0xD9); //设置预充电周期
OLED_WriteCommand(0xF1);
OLED_WriteCommand(0xDB); //设置VCOMH取消选择级别
OLED_WriteCommand(0x30);
OLED_WriteCommand(0xA4); //设置整个显示打开/关闭
OLED_WriteCommand(0xA6); //设置正常/倒转显示
OLED_WriteCommand(0x8D); //设置充电泵
OLED_WriteCommand(0x14);
OLED_WriteCommand(0xAF); //开启显示
OLED_Clear(); //OLED清屏
}
应用到main.c中运行查看效果
int main()
{
SetSysClock(CLK_SOURCE_PLL_60MHz);
GPIOA_SetBits(GPIO_Pin_9);
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
OLED_Init();
char Data = '!';
for(uint8_t i=1;i<5;i++)
{
for(uint8_t j=1;j<17;j++)
{
OLED_ShowChar(i,j,Data);
Data++;
}
}
while(1);
}
显示效果如下:
工程链接(自取):
链接:https://pan.baidu.com/s/17BEm1VFW-zDocnlxwPNs1Q?pwd=q6wc
提取码:q6wc