|
在STM32G431内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。 9 U% i5 N; Z$ _
实现图1所示效果的主程序为: - int main(void)3 I3 J( L1 ?/ z9 d. P
- {: p( c8 ]- |) D6 p- T! y' m) c
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
" V4 z' g' Q+ k h# A$ w - HAL_Init();
5 S$ I X: i: c) {5 R. c - /* Configure the system clock */
$ Z, [. {: H, ?3 z* j* {) P - SystemClock_Config();, d# j- T9 e- n3 y$ z, Y( j
- GPIO_OLED_INIT();* l; J! c+ |% ?" R. W
- OLED_Init();( u# N/ d# W' h
- OLED_Clear();
: Q/ k5 U' d7 p" G - OLED_ShowString(18,0,"STM32G431",16);: Q' P J4 Q' E5 s$ L5 d
- OLED_ShowString(10,2,"OLED & RTC",16);, u& G# ~0 z" ~0 ~6 y8 {
- /* Initialize all configured peripherals */
( s2 j5 h% D+ _: b' r2 t, v9 \9 n2 K - MX_RTC_Init();
& a$ @" m. h3 I: m6 i1 l- ~5 T - RTCStatus = 1;
! {8 t( a) A, ]' y3 } - while (1)
$ M2 o, k N: J: O2 Z - {
; ^, n' a- e" \8 q$ d - /* Display the updated Time and Date */4 }- x! d% C, n& `7 g
- RTC_CalendarShow(aShowTime, aShowDate);
. o5 O/ S% U0 C/ G5 f! Y6 B2 U$ ?; X - Delay(200);
% [$ \& s8 j' P+ U4 v& C* P5 ] - }
8 I& a' K4 h5 X/ A. R+ I, R - }
复制代码 图1 RTC电子时钟
7 ? n3 V0 J% {0 D( H2 L$ H6 ?实现RTC显示的函数为: - static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)& N: t' z9 W: r" ?
- {% a% w5 u& Z3 @7 k( M' X# u
- RTC_DateTypeDef sdatestructureget;
5 u$ u& H) R8 I# A - RTC_TimeTypeDef stimestructureget;5 n5 Q% {/ r" s1 `/ _3 K5 i
- /* Get the RTC current Time */
! \+ R! u* x! m" | - HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);7 f: l" D6 Y9 U5 g! ]
- /* Get the RTC current Date */& J8 k; A4 ^; d/ R: \8 U7 J
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
. P7 d+ l9 E/ K& u, q - /* Display time Format : hh:mm:ss */
o: m& k, s/ M3 ~3 P) v0 S - sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
9 [. Z* q: C1 ]9 x; h5 b! L - OLED_ShowString(26,6,showtime,16);5 `9 p' V( `! X! Q
- /* Display date Format : mm-dd-yy */
; Y8 `7 s& q- [$ f - sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);7 I! K. [5 R& r! x
- OLED_ShowString(10,4,showdate,16);
, G8 B# \2 \) j7 D1 v5 M - }
复制代码
! R* R7 N* R! }7 H6 _7 v: b调用的字符串显示函数为: - void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
& p9 c: s. a( N. A: H( T4 U; S - {" ~ m" @$ k# ]" ~5 l+ I
- unsigned char j=0;
+ A2 s0 W9 k* I# U8 r8 B4 W t - while (chr[j]!='\0')7 w# x( }: ]* ?1 X8 B% e+ \1 y
- { OLED_ShowChar(x,y,chr[j],Char_Size);
2 q' ]8 O8 v" c4 A. K - x+=8;
3 s7 j$ H! h6 \( L H" L - if(x>120){x=0;y+=2;}. ]& Q y3 H- u% v8 J
- j++;
' y2 O8 Y$ Q8 [: e - }2 B) \) o4 @7 ~- A
- }
复制代码
( p) T3 H! P, m由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。
3 g. p- B2 J9 E( O7 [, e& A& p图2 校时后的显示效果 9 M1 t# b& g8 C' s" a" L+ z
|
有空我也玩玩。
计时尚可,长时间的误差可能会明显点儿。
就是11月31日会不会自动进入12月1日,还有闰年修正等。
我给你测了下,两者都没有问题。