在STM32G431内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。
4 O5 ?: N) d* y; T' \; g( H* E实现图1所示效果的主程序为: - int main(void)
5 p$ }/ i7 {" o, X - {
6 {1 S; \+ F7 u) P2 A( F+ ^7 _+ {* M - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */" V5 A x9 q0 o
- HAL_Init();, v" m1 m1 J: T9 @ n/ R
- /* Configure the system clock */
" r+ }+ p4 V* i2 p' ~. J% W - SystemClock_Config();2 ]& v8 I" S4 ?
- GPIO_OLED_INIT();( D x ]8 r0 M7 A+ l
- OLED_Init();
) k5 W# Y' _8 K, }, h8 ?$ F( t( D t - OLED_Clear(); ^* F7 e* P" _; M* _; J
- OLED_ShowString(18,0,"STM32G431",16);
1 ~: J$ c& X9 R& J - OLED_ShowString(10,2,"OLED & RTC",16);2 i: r, f1 B5 A, E6 d9 ]
- /* Initialize all configured peripherals */
~! m7 c+ L6 H: X* V5 b/ I - MX_RTC_Init();3 U( y) `7 x3 k6 Q* d
- RTCStatus = 1;
+ y/ m$ L( ]8 H! p8 Q - while (1)
; @- k3 T+ l+ j6 x+ A - {
4 ? U5 D6 `+ N0 p9 ^+ q# @1 i4 J - /* Display the updated Time and Date */
. U8 H% _3 ^6 ^ - RTC_CalendarShow(aShowTime, aShowDate);! e* n+ j3 N+ Y& ~+ x
- Delay(200);
& v' V( Q/ p. x% L& Z# X - }
F$ e9 S' x- {( r4 B - }
复制代码 图1 RTC电子时钟 $ O# ?" C$ B! O! n/ X+ E
实现RTC显示的函数为: - static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
7 `! R# A9 q7 D7 B. s( | - {# U- a; F2 A: m. t) M
- RTC_DateTypeDef sdatestructureget;
5 m' @5 ~& N9 E6 w/ t - RTC_TimeTypeDef stimestructureget;
5 z3 T0 {% m G% @0 Z9 W - /* Get the RTC current Time */: }0 _5 U' p- v! \( ^* g
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
: ~; u2 \2 G5 A - /* Get the RTC current Date */1 s8 B* w4 O5 v; f
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);2 j" q" q, B; o
- /* Display time Format : hh:mm:ss */
- }8 h( L5 M: [4 {; K5 [ - sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);; s* s1 @3 X" @7 ~8 ^
- OLED_ShowString(26,6,showtime,16);
" v. } ~/ h# F, V7 ]3 ? - /* Display date Format : mm-dd-yy */
; v" |% o, |+ e2 H) f - sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);; w4 s+ R% B9 ?% R# ?! s
- OLED_ShowString(10,4,showdate,16);
$ W0 G0 e5 r- { | - }
复制代码
( Q( O, Y$ R( Z5 T0 Z调用的字符串显示函数为: - void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
4 H$ s- d! a9 S5 S0 [ - {' w5 ?3 k" Z2 F/ V$ m4 P
- unsigned char j=0;3 d% v0 u; y- r
- while (chr[j]!='\0')' p; P* b! F9 ^% n# _6 C9 b- }
- { OLED_ShowChar(x,y,chr[j],Char_Size);
. q& l0 O6 J8 {: [- \ - x+=8;
7 U+ A$ H& C8 f; y Q# H. b - if(x>120){x=0;y+=2;}
6 u) F/ r5 S% F" N" G+ ] - j++;5 M; F- `$ o% o" P: p
- }: _! H4 C v- Q, O! c: q/ q
- }
复制代码
$ `& `) w& @6 D$ ~由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。 & d$ v2 Y K" g& j- ]
图2 校时后的显示效果
3 j; w, A) G5 \3 s |
有空我也玩玩。
计时尚可,长时间的误差可能会明显点儿。
就是11月31日会不会自动进入12月1日,还有闰年修正等。4 ^- N. j8 J6 Q3 |; {+ Z
我给你测了下,两者都没有问题。