[MM32软件] 【EV Board (MM32L0136C7P)测评】+GPIO口使用及OLED屏驱动

[复制链接]
 楼主| jinglixixi 发表于 2022-12-1 11:05 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2022-12-1 11:07 编辑

尽管开发板上配置了LCD屏,并具有能耗低、显示规格比较大的特点,但相对来讲它毕竟是靠笔段来显示信息,因此显示的符号会受到很大的限制,且显示的信息量也比较少,最重要的是占用引脚资源太严重。
为此,从掌握GPIO口使用的角度,还是从GPIO口的使用开始,并以模拟I2C接口的方式来驱动OLED屏。
1GPIO口使用
以按键控制小风扇的转动,其控制效果如图1和图2所示。
1.jpg
1 静止状态
2.jpg
2 转动状态

实现该控制的程序如下:
  1. int main(void)
  2. {
  3.     BOARD_Init();
  4.     while (1)
  5.     {
  6.         if ( GPIO_ReadInDataBit(BOARD_KEY0_GPIO_PORT, BOARD_KEY0_GPIO_PIN) )
  7.         {
  8.               GPIO_WriteBit(BOARD_ FAN _GPIO_PORT, BOARD_ FAN _GPIO_PIN, 0u);
  9.         }
  10.         else
  11.         {
  12.               GPIO_WriteBit(BOARD_ FAN _GPIO_PORT, BOARD_ FAN _GPIO_PIN, 1u);
  13.         }
  14.     }
  15. }

其中,小风扇被连接到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屏的初始化函数为:
  1. void OLED_Init(void)
  2. {
  3.     OLED_WR_Byte(0xAE,OLED_CMD);l
  4.     OLED_WR_Byte(0x02,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(0xff,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_WR_Byte(0xAF,OLED_CMD);
  31.     OLED_WR_Byte(0xAF,OLED_CMD);
  32.     OLED_Clear();
  33.     OLED_Set_Pos(0,0);
  34. }

模拟I2C方式字节数据的函数为:
  1. void Write_IIC_Byte(unsigned char IIC_Byte)
  2. {
  3.     unsigned char i;
  4.     unsigned char m,da;
  5.     da=IIC_Byte;
  6.     SCL_low;
  7.     for(i=0;i<8;i++)
  8.     {
  9.         m=da;
  10.         m=m&0x80;
  11.         if(m==0x80)
  12.         {
  13.             SDA_high;
  14.         }
  15.         else  SDA_low;
  16.         da=da<<1;
  17.         del_t(20);
  18.         SCL_high;
  19.         del_t(20);
  20.         SCL_low;
  21.         del_t(20);
  22.      }
  23. }

实现字符串显示的函数为:
  1. void OLED_ShowString(uint8_t x,uint8_t y,uint8_t *chr,uint8_t Char_Size)
  2. {
  3.     unsigned char j=0;
  4.     while (chr[j]!='\0')
  5.     {       OLED_ShowChar(x,y,chr[j],Char_Size);
  6.             x+=8;
  7.             if(x>120){x=0;y+=2;}
  8.             j++;
  9.     }
  10. }

实现图3所示显示效果的主程序为:
  1. int main(void)
  2. {
  3.     BOARD_Init();
  4.     gpio_init.Pins  = GPIO_PIN_5;
  5.     gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;
  6.     gpio_init.Speed = GPIO_Speed_50MHz;
  7.     GPIO_Init(GPIOD, &gpio_init);
  8.     GPIO_PinAFConf(GPIOD, gpio_init.Pins, GPIO_AF_15);
  9.         
  10.     gpio_init.Pins  = GPIO_PIN_8;
  11.     gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;
  12.     gpio_init.Speed = GPIO_Speed_50MHz;
  13.     GPIO_Init(GPIOA, &gpio_init);
  14.     GPIO_PinAFConf(GPIOA, gpio_init.Pins, GPIO_AF_15);
  15.         
  16.     OLED_Init();
  17.     OLED_Clear();
  18.     OLED_ShowString(20,0,"EVB-L0136",16);
  19.     OLED_ShowString(20,2,"MM32L0136C7P",16);
  20.     OLED_ShowString(20,6,"jinglixixi",16);
  21.     while (1);
  22. }

3.jpg
3 显示效果


掌握了GPIO口的使用,还可以对其它的I2C设备或SPI设备进行驱动。



caigang13 发表于 2022-12-2 01:18 来自手机 | 显示全部楼层
GPIO能直接驱动?
 楼主| jinglixixi 发表于 2022-12-2 11:59 | 显示全部楼层

没问题
gaoyang9992006 发表于 2022-12-3 16:10 | 显示全部楼层
用I2C驱动效率更高。
 楼主| jinglixixi 发表于 2022-12-3 23:16 | 显示全部楼层
gaoyang9992006 发表于 2022-12-3 16:10
用I2C驱动效率更高。

费事,灵活性差!
tpgf 发表于 2023-1-1 12:44 | 显示全部楼层
一般来说使用GPIO口驱动OLED屏 需要使用哪种模式呢
aoyi 发表于 2023-1-1 12:56 | 显示全部楼层
为什么说这种使用方式的灵活性比较差呢
nawu 发表于 2023-1-1 13:04 | 显示全部楼层
jinglixixi 发表于 2022-12-3 23:16
费事,灵活性差!

感觉是不是iic的速度应该能快一点呢 但是我觉得不是很好调试
zljiu 发表于 2023-1-1 13:15 | 显示全部楼层
直接使用io口进行oled屏幕的控制 一般需要多少个引脚呢
gwsan 发表于 2023-1-1 13:24 | 显示全部楼层
OLED屏驱动需要的是并口驱动还是串口啊
tfqi 发表于 2023-1-1 13:32 | 显示全部楼层
做这种屏幕的驱动  一般最小的数据需求量是多少啊
 楼主| jinglixixi 发表于 2023-1-1 23:59 | 显示全部楼层
tpgf 发表于 2023-1-1 12:44
一般来说使用GPIO口驱动OLED屏 需要使用哪种模式呢

只用输出模式即可
 楼主| jinglixixi 发表于 2023-1-2 00:00 | 显示全部楼层
tfqi 发表于 2023-1-1 13:32
做这种屏幕的驱动  一般最小的数据需求量是多少啊

除程序占用的空间外,就是字库所需的空间。
 楼主| jinglixixi 发表于 2023-1-2 00:03 | 显示全部楼层
aoyi 发表于 2023-1-1 12:56
为什么说这种使用方式的灵活性比较差呢

一般I2C所分配的引脚是相对固定的,而使用GPIO口则几乎没有限制。
 楼主| jinglixixi 发表于 2023-1-2 00:05 | 显示全部楼层
gwsan 发表于 2023-1-1 13:24
OLED屏驱动需要的是并口驱动还是串口啊

严格将是I2C接口,可以看做串口的方式。
 楼主| jinglixixi 发表于 2023-1-2 00:05 | 显示全部楼层
zljiu 发表于 2023-1-1 13:15
直接使用io口进行oled屏幕的控制 一般需要多少个引脚呢

2个
Jacquetry 发表于 2023-1-5 17:17 | 显示全部楼层
使用GPIO口驱动OLED屏输出模式就行
您需要登录后才可以回帖 登录 | 注册

本版积分规则

515

主题

2929

帖子

39

粉丝
快速回复 返回顶部 返回列表