本帖最后由 jinglixixi 于 2022-12-1 11:07 编辑
尽管开发板上配置了LCD屏,并具有能耗低、显示规格比较大的特点,但相对来讲它毕竟是靠笔段来显示信息,因此显示的符号会受到很大的限制,且显示的信息量也比较少,最重要的是占用引脚资源太严重。 为此,从掌握GPIO口使用的角度,还是从GPIO口的使用开始,并以模拟I2C接口的方式来驱动OLED屏。 1)GPIO口使用 以按键控制小风扇的转动,其控制效果如图1和图2所示。 图1 静止状态 图2 转动状态
实现该控制的程序如下: int main(void)
{
BOARD_Init();
while (1)
{
if ( GPIO_ReadInDataBit(BOARD_KEY0_GPIO_PORT, BOARD_KEY0_GPIO_PIN) )
{
GPIO_WriteBit(BOARD_ FAN _GPIO_PORT, BOARD_ FAN _GPIO_PIN, 0u);
}
else
{
GPIO_WriteBit(BOARD_ FAN _GPIO_PORT, BOARD_ FAN _GPIO_PIN, 1u);
}
}
}
其中,小风扇被连接到PB10,其定义如下: #define BOARD_FAN_GPIO_PORT GPIOB #define BOARD_FAN_GPIO_PIN GPIO_PIN_10 对该引脚的初始化程序为: gpio_init.Pins = GPIO_PIN_10; gpio_init.PinMode = GPIO_PinMode_Out_PushPull; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &gpio_init); GPIO_PinAFConf(GPIOB, gpio_init.Pins,GPIO_AF_15); 按键使用板上K2键,所使用的引脚为PD5,它的初始化程序为: gpio_init.Pins = GPIO_PIN_5; gpio_init.PinMode = GPIO_PinMode_In_PullUp; gpio_init.Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOD, &gpio_init); GPIO_PinAFConf(GPIOD, gpio_init.Pins,GPIO_AF_15); 2)驱动OLED屏 这里使用的是一款0.96寸的双色OLED屏,其分辨率为128*64,驱动方式为I2C。 该显示屏与开发板的连接关系为: SCL---D5 SDA---A8 模拟I2C输出高低电平的语句定义为: #define SCL_high GPIO_WriteBit(GPIOD, GPIO_PIN_5, 1u) #define SCL_low GPIO_WriteBit(GPIOD, GPIO_PIN_5, 0u); #define SDA_high GPIO_WriteBit(GPIOA, GPIO_PIN_8, 1u); #define SDA_low GPIO_WriteBit(GPIOA, GPIO_PIN_8, 0u);
OLED屏的初始化函数为: void OLED_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD);l
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x81,OLED_CMD);
OLED_WR_Byte(0xff,OLED_CMD);
OLED_WR_Byte(0xA1,OLED_CMD);
OLED_WR_Byte(0xC8,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xA8,OLED_CMD);
OLED_WR_Byte(0x3f,OLED_CMD);
OLED_WR_Byte(0xD3,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0xd5,OLED_CMD);
OLED_WR_Byte(0x80,OLED_CMD);
OLED_WR_Byte(0xD9,OLED_CMD);
OLED_WR_Byte(0xF1,OLED_CMD);
OLED_WR_Byte(0xDA,OLED_CMD);
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);
OLED_WR_Byte(0x40,OLED_CMD);
OLED_WR_Byte(0x20,OLED_CMD);
OLED_WR_Byte(0x02,OLED_CMD);
OLED_WR_Byte(0x8D,OLED_CMD);
OLED_WR_Byte(0x14,OLED_CMD);
OLED_WR_Byte(0xA4,OLED_CMD);
OLED_WR_Byte(0xA6,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_WR_Byte(0xAF,OLED_CMD);
OLED_Clear();
OLED_Set_Pos(0,0);
}
模拟I2C方式字节数据的函数为: void Write_IIC_Byte(unsigned char IIC_Byte)
{
unsigned char i;
unsigned char m,da;
da=IIC_Byte;
SCL_low;
for(i=0;i<8;i++)
{
m=da;
m=m&0x80;
if(m==0x80)
{
SDA_high;
}
else SDA_low;
da=da<<1;
del_t(20);
SCL_high;
del_t(20);
SCL_low;
del_t(20);
}
}
实现字符串显示的函数为: void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
{
unsigned char j=0;
while (chr[j]!='\0')
{ OLED_ShowChar(x,y,chr[j],Char_Size);
x+=8;
if(x>120){x=0;y+=2;}
j++;
}
}
实现图3所示显示效果的主程序为: int main(void)
{
BOARD_Init();
gpio_init.Pins = GPIO_PIN_5;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &gpio_init);
GPIO_PinAFConf(GPIOD, gpio_init.Pins, GPIO_AF_15);
gpio_init.Pins = GPIO_PIN_8;
gpio_init.PinMode = GPIO_PinMode_Out_PushPull;
gpio_init.Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpio_init);
GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_15);
OLED_Init();
OLED_Clear();
OLED_ShowString(20,0,"EVB-L0136",16);
OLED_ShowString(20,2,"MM32L0136C7P",16);
OLED_ShowString(20,6,"jinglixixi",16);
while (1);
}
图3 显示效果
掌握了GPIO口的使用,还可以对其它的I2C设备或SPI设备进行驱动。
|