在信息显示方面对显示的要求比较强,为此在STM32F407开发板上提供了OLED屏和TFT屏的接口。而就OLED屏接口来讲,其接口如图1所示,是一款并行方式的接口。
图1 OLED屏接口
从使用的方便性出发,这里为其配置一款I2C方式工作的OLED屏,其显示分辨率为128*64,是一款准双色屏,是采用TFT屏接口来进行连接。
该OLED屏与开发板的连接关系为:
SCL---PB2
SDA---PB1
图2 TFT屏接口
在以GPIO口模拟I2C的情况下,其引脚输出高低电平的语句定义为:
#define SCL_high HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET)
#define SCL_low
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET)
#define SDA_high
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET)
#define SDA_low
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET)
OLED屏的初始化函数为:
void OLEDA_Init(void)
{
OLED_WR_Byte(0xAE,OLED_CMD);
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);
}
清屏函数为:
void OLED_Clear(void)
{
uint8_t i,n;
for(i=0;i<8;i++)
{
OLED_WR_Byte(0xb0+i,OLED_CMD);
OLED_WR_Byte(0x00,OLED_CMD);
OLED_WR_Byte(0x10,OLED_CMD);
for(n=0;n<128;n++)
OLED_WR_Byte(0x00,OLED_DATA);
}
}
字符显示函数为:
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size)
{
unsigned char c=0,i=0;
c=chr-' ';
if(Char_Size ==16)
{
OLED_Set_Pos(x,y);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);
OLED_Set_Pos(x,y+1);
for(i=0;i<8;i++)
OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);
}
}
数值显示函数为:
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size2)
{
uint8_t t,temp;
uint8_t enshow=0;
for(t=0;t<len;t++)
{
temp=(num/oled_pow(10,len-t-1))%10;
if(enshow==0&&t<(len-1))
{
if(temp==0)
{
OLED_ShowChar(x+(size2/2)*t,y,'',size2);
continue;
}
else enshow=1;
}
OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2);
}
}
在RTC计时函数的配合下,实现电子时钟显示效果的主程序为:
int main(void)
{
uint8_t hour, min, sec, ampm;
uint8_t year, month, date, week;
uint8_t t = 0;
HAL_Init();
sys_stm32_clock_init(336, 8, 2, 7);
delay_init(168);
usart_init(115200);
usmart_dev.init(84);
led_init();
oled_init();
rtc_init();
rtc_set_wakeup(RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0);
OLEDA_Init();
OLED_Clear();
OLED_ShowString(16,0,"STM32F407",16);
OLED_ShowString(16,2,"RTC TEST",16);
OLED_ShowString(16,4," : :",16);
OLED_ShowString(16,6," - -",16);
while (1)
{
t++;
if ((t
{
rtc_get_time(&hour, &min,&sec, &m);
OLED_ShowNum(16,4,hour,2,16);
OLED_ShowNum(40,4,min,2,16);
OLED_ShowNum(64,4,sec,2,16);
rtc_get_date(&year, &month,&date, &week);
OLED_ShowNum(16,6,year,2,16);
OLED_ShowNum(40,6,month,2,16);
OLED_ShowNum(64,6,date,2,16);
}
if ((t
{
LED0_TOGGLE();
}
delay_ms(10);
}
}
经编译和下载,其显示效果如图3所示。
图3 计时效果
由于开发板上以安装了纽扣电池,为调整RTC的初始值需要在函数rtc_set_time() 中进行设置和调整,其形式为:
if ((bkpflag != 0x5050) && (bkpflag != 0x5051))
{
rtc_set_time(6, 59, 56, RTC_HOURFORMAT12_AM);
rtc_set_date(23, 4, 22, 3);
}
此外,由于开发板上载有蜂鸣器,还可通过时间的设置来实现闹钟提示功能。
视频演示: