在HC32F460内部配有RTC功能,这里我们为它配上OLED屏显示,这样它就构成一个RTC电子时钟。
所用的OLED屏就是随板子自带的,该OLED屏的原理图见图1所示。
图1 OLED屏原理图
本想以I2C通讯来驱动OLED屏,但将其移到RTC的程序中,比较难协调,最终还是以模拟I2C的方式来轻松地将两者结合在一起。
由于SDA和SCL 仍占用原位置,故定义其输出高低电平的语句如下:
#define OLED_SCLK_Set() PORT_SetBits(PortD, Pin00)#define OLED_SCLK_Clr() PORT_ResetBits(PortD, Pin00) #define OLED_SDIN_Set() PORT_SetBits(PortD, Pin01) #define OLED_SDIN_Clr() PORT_ResetBits(PortD, Pin01)
复制代码所用的字符显示函数为:
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++; } }
复制代码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); } }
复制代码static void Rtc_CalendarConfig(void){ stc_rtc_date_time_t stcRtcDateTimeCfg; MEM_ZERO_STRUCT(stcRtcDateTimeCfg); stcRtcDateTimeCfg.u8Year = 20u; stcRtcDateTimeCfg.u8Month = 9; stcRtcDateTimeCfg.u8Day = 27u; stcRtcDateTimeCfg.u8Weekday = RtcWeekdaySunday; stcRtcDateTimeCfg.u8Hour = 12u; stcRtcDateTimeCfg.u8Minute = 23u; stcRtcDateTimeCfg.u8Second = 01u; if (RTC_SetDateTime(RtcDataFormatDec, &stcRtcDateTimeCfg, Enable, Enable) != Ok) { printf("write calendar failed!\r\n"); } }
复制代码int32_t main(void){ stc_port_init_t stcPortInit; stc_rtc_date_time_t stcCurrDateTime; MEM_ZERO_STRUCT(stcPortInit); MEM_ZERO_STRUCT(stcCurrDateTime); LED0_OFF(); stcPortInit.enPinMode = Pin_Mode_Out; PORT_Init(LED0_PORT, LED0_PIN, &stcPortInit); stcPortInit.enPinMode = Pin_Mode_Out; PORT_Init(PortD, Pin00, &stcPortInit); PORT_Init(PortD, Pin01, &stcPortInit); Xtal32_ClockConfig(); Ddl_UartInit(); Rtc_Config(); OLED_Init(); OLED_Clear(); OLED_ShowString(0,0,"HC32F460 TEST",16); OLED_ShowString(0,2,"OLED & RTC",16); Ddl_Delay1ms(1000u); OLED_Clear(); OLED_ShowString(0,0,"20 - -",16); OLED_ShowString(0,2," : :",16); while (1) { if (1u == u8SecIntFlag) { u8SecIntFlag = 0u; LED0_TOGGLE(); if (RTC_GetDateTime(RtcDataFormatDec, &stcCurrDateTime) = Ok) { OLED_ShowNum(16,0,stcCurrDateTime.u8Year,2,16); OLED_ShowNum(40,0,stcCurrDateTime.u8Month,2,16); OLED_ShowNum(64,0,stcCurrDateTime.u8Day,2,16); OLED_ShowNum(16,2,stcCurrDateTime.u8Hour,2,16); OLED_ShowNum(40,2,stcCurrDateTime.u8Minute,2,16); OLED_ShowNum(64,2,stcCurrDateTime.u8Second,2,16); } } } }
复制代码