HC32F460内部配有RTC功能,这里我们为它配上OLED屏显示,这样它就构成一个RTC电子时钟。
所用的OLED屏就是随板子自带的,该OLED屏的原理图见图1所示。
image.png
1  OLED屏原理图

本想以I2C通讯来驱动OLED屏,但将其移到RTC的程序中,比较难协调,最终还是以模拟I2C的方式来轻松地将两者结合在一起。
由于SDASCL 仍占用原位置,故定义其输出高低电平的语句如下:
#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);
  • }
  • }
  • 复制代码
    进行RTC时间设置的函数为:
    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");
  • }
  • }
  • 复制代码
    实现图1和图2显示效果的主程序如下:
    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);
  • }
  • }
  • }
  • }
  • 复制代码
    image.png

    image.png