基于LCD屏的电子时钟设计:
由于AG32开发板没有配置相应的显示器件,因此利用手头的LCD屏为其增强了显示功能。
该显示屏采用SPI接口,其显示分辨率为160*80像素点。
为测试对LCD屏的显示驱动能力,它与开发板的连接关系为:
SCLK----PIN_96
SDIN----PIN_95
RST----PIN_92
DC ----PIN_91
CS ----PIN_93
为此在VE文件中建立的映射关系如下:
GPIO4_5 PIN_96
GPIO4_6 PIN_95
GPIO4_7 PIN_92
GPIO4_3 PIN_93
GPIO4_4 PIN_91
为便于向LCD屏提供高低电平的输出,所作的语句定义为:
#define OLED_SCLK_Set GPIO_SetHigh(GPIO4,GPIO_BIT5) //CLK
#define OLED_SCLK_Clr GPIO_SetLow(GPIO4,GPIO_BIT5)
#define OLED_SDIN_Set GPIO_SetHigh(GPIO4,GPIO_BIT6) //DIN
#define OLED_SDIN_Clr GPIO_SetLow(GPIO4,GPIO_BIT6)
#define OLED_RST_Set GPIO_SetHigh(GPIO4,GPIO_BIT7) //RES
#define OLED_RST_Clr GPIO_SetLow(GPIO4,GPIO_BIT7)
#define OLED_DC_Set GPIO_SetHigh(GPIO4,GPIO_BIT4) //DC
#define OLED_DC_Clr GPIO_SetLow(GPIO4,GPIO_BIT4)
#define OLED_CS_Set GPIO_SetHigh(GPIO4,GPIO_BIT3) //CS
#define OLED_CS_Clr GPIO_SetLow(GPIO4,GPIO_BIT3)
对所用引脚的工作模式配置函数为:
void lcd_gpio(void)
{
SYS_EnableAHBClock(APB_MASK_GPIO4);
GPIO_SetOutput(GPIO4,GPIO_BIT5);
GPIO_SetOutput(GPIO4,GPIO_BIT6);
GPIO_SetOutput(GPIO4,GPIO_BIT7);
GPIO_SetOutput(GPIO4,GPIO_BIT3);
GPIO_SetOutput(GPIO4,GPIO_BIT4);
}
所用引脚输出高低电平的语句定义为:
#define OLED_SCLK_Set() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_SET)
#define OLED_SCLK_Clr() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_7, GPIO_PIN_RESET)
#define OLED_SDIN_Set() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_SET)
#define OLED_SDIN_Clr() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8, GPIO_PIN_RESET)
#define OLED_RST_Set() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET)
#define OLED_RST_Clr() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET)
#define OLED_DC_Set() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET)
#define OLED_DC_Clr() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET)
#define OLED_CS_Set() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET)
#define OLED_CS_Clr() HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET)
GPIO口模拟SPI方式字节数据的函数为:
void LCD_Writ_Bus(unsigned char dat)
{
unsigned char i;
OLED_CS_Clr;
for(i=0;i<8;i++)
{
OLED_SCLK_Clr;
if(dat&0x80)
OLED_SDIN_Set;
else
OLED_SDIN_Clr;
OLED_SCLK_Set;
dat<<=1;
}
OLED_CS_Set;
}
实现色彩清屏处理的函数为:
void LCD_Clear(unsigned int Color)
{
unsigned int i,j;
LCD_Address_Set(0,0,LCD_W-1,LCD_H-1);
for(i=0;ifor (j=0;jLCD_WR_DATA(Color);
}
}
}
在进行显示驱动测试时,为通过测试的效率,可在显示屏的初始化之后,直接以色彩清屏函数来测试,若屏幕被指定色彩所填充,则说明显示驱动有效;否则,说明驱动失败。
在配备字库的情况下,其实现字符显示的函数为:
void LCD_ShowChar(unsigned int x,unsigned int y,unsigned char num,unsigned char mode,unsigned int color)
{
unsigned char temp;
unsigned char pos,t;
unsigned int x0=x;
if(x>LCD_W-16||y>LCD_H-16) return;
num=num-' ';
LCD_Address_Set(x,y,x+8-1,y+16-1);
if(!mode)
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(unsigned int)num*16+pos];
for(t=0;t<8;t++)
{
if(temp&0x01) LCD_WR_DATA(color);
else LCD_WR_DATA(RED);
temp>>=1;
x++;
}
x=x0;
y++;
}
}
else
{
for(pos=0;pos<16;pos++)
{
temp=asc2_1608[(unsigned int)num*16+pos];
for(t=0;t<8;t++)
{
if(temp&0x01) LCD_DrawPoint(x+t,y+pos,color);
temp>>=1;
}
}
}
}
实现RTC中断处理的函数为:
void RTC_isr()
{
if (RTC_IsIntActive(RTC_FLAG_SEC)) {
RtcStat();
RTC_ClearInt(RTC_FLAG_SEC);
}
}
实现RTC计时值显示的函数为:
void RtcStat()
{
time_t now = RTC_GetCounter();
struct tm *tm = gmtime(&now);
LCD_ShowNum(20,30,tm->tm_hour,2,WHITE);
LCD_ShowNum(44,30,tm->tm_min,2,WHITE);
LCD_ShowNum(68,30,tm->tm_sec,2,WHITE);
}
实现RTC电子时钟显示效果的程序为:
void TestRTC()
{
lcd_gpio();
Lcd_Init();
LCD_Clear(RED);
LCD_ShowChar(50,10,'R',1,WHITE);
LCD_ShowChar(60,10,'T',1,WHITE);
LCD_ShowChar(70,10,'C',1,WHITE);
LCD_ShowChar(36,30,':',1,WHITE);
LCD_ShowChar(60,30,':',1,WHITE);
RTC_Init(board_rtc_source());
RTC_EnableInt(RTC_FLAG_SEC);
RTC_SetPrescaler(32768);
RTC_SetOutputMode(RTC_OUTPUT_SECOND);
INT_EnableIRQ(RTC_IRQn, RTC_PRIORITY);
time_t now = RTC_GetEpochSeconds(2024, 10, 30, 8, 30, 0);
RTC_SetCounter(now);
RtcStat();
}
经程序的编译于烧录,其测试的效果如图1和图2所示。
图1 色彩清屏效果
图2 电子时钟显示效果