在STM32G431内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。
2 i- J! ^' G" c7 Z7 h* Q5 u实现图1所示效果的主程序为: - int main(void)
# S% |; {1 r7 m+ j, N# x$ f - {4 v% y& A) j% W1 K1 @ i
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
# t' J4 S, ~0 Q0 s* N5 {+ [ - HAL_Init();* P9 `2 w; |( Q, ~5 i4 [7 l
- /* Configure the system clock */
8 s3 B4 N* |# b& j: R3 d - SystemClock_Config();
1 e7 L2 d2 W) d2 }* v - GPIO_OLED_INIT();' `: P5 h; a5 n
- OLED_Init();5 |7 W5 c9 w# m6 w8 K- g: l3 v
- OLED_Clear();
3 w* D3 z! Z8 g) ] - OLED_ShowString(18,0,"STM32G431",16);0 l5 P' P1 b! }- {* Z
- OLED_ShowString(10,2,"OLED & RTC",16);5 H8 I, p; G3 m' A) y
- /* Initialize all configured peripherals */
% Z: X" R( T9 @ q- N& ?) `' c - MX_RTC_Init();3 e2 R, y) S% D6 N4 {1 p5 Q5 W; c+ f# |
- RTCStatus = 1;
" e1 d ? k( {" B - while (1)' S! x6 u& D7 u3 E$ a4 x3 A
- {. s- O$ z: l9 J5 M% a) v+ @2 |
- /* Display the updated Time and Date */
3 ^; O& k4 l1 Q& u. N - RTC_CalendarShow(aShowTime, aShowDate);
5 _: z- M# i0 t( J7 ?0 T - Delay(200);
9 L/ x" f& D* b' [/ w - }' q" W; m+ e% c4 F4 c y P0 `
- }
复制代码 图1 RTC电子时钟
3 G9 t8 a* g- e3 Y( j& {, t实现RTC显示的函数为: - static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)2 h: S( b- }, {
- {
8 Z; c0 Y4 G; g2 D' v! e# V - RTC_DateTypeDef sdatestructureget;# p! D, p" I& N7 q8 _
- RTC_TimeTypeDef stimestructureget;, m4 [2 X: b2 E ~
- /* Get the RTC current Time */( O$ U4 C4 Z2 Y+ z9 f2 [
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
; C$ b5 F; x0 Y, `2 s - /* Get the RTC current Date */+ D4 M" M( w2 P3 Z) H0 W# R
- HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);# K. R& `, {8 Q! r$ Z# q
- /* Display time Format : hh:mm:ss */
% @! O- `, ^% D - sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
) v* A y' G* P4 O8 ^+ } - OLED_ShowString(26,6,showtime,16);& V' D6 G9 r# f: a1 f( t
- /* Display date Format : mm-dd-yy */
5 Y; A0 @6 J1 L' J5 L - sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);# p# I; {2 A* h7 u7 S/ [
- OLED_ShowString(10,4,showdate,16);
! T$ y8 r1 M$ I) |/ \( U - }
复制代码
# \0 H9 g* |+ N% ?% S9 u调用的字符串显示函数为: - void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)8 v" A9 _2 w5 D
- { m# X% l. [4 O3 U* H4 X
- unsigned char j=0;
2 b/ p' }. q3 V+ K9 H - while (chr[j]!='\0')7 ~3 T8 R. B. y9 ?
- { OLED_ShowChar(x,y,chr[j],Char_Size);
3 R: _) z7 g! a8 d$ [/ G. B - x+=8;0 ~7 j4 h& L4 t$ Q; s% W% s% o7 M
- if(x>120){x=0;y+=2;}$ d& `8 y$ v* P& q
- j++;
; ]. r5 g, L# G$ V' R* x - }& g2 j* i5 B6 T; r, Z. z
- }
复制代码
( h- w, j. y1 w" U: K由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。 1 X `. x/ m6 Z( y
图2 校时后的显示效果 ! w/ j& o0 X+ u0 r
|
有空我也玩玩。
计时尚可,长时间的误差可能会明显点儿。
就是11月31日会不会自动进入12月1日,还有闰年修正等。' e* Q; r% l+ j; b+ l
我给你测了下,两者都没有问题。