在STM32G431内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。
0 ^" S2 T+ q- X5 a, x6 o实现图1所示效果的主程序为: - int main(void)) v9 {3 E" g# Z3 D1 j/ O' L
- {
k+ k1 x/ f" q9 J1 L3 f - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
! f5 w9 R; K1 {% P# Q) H - HAL_Init();
" f7 J$ `( u2 @ - /* Configure the system clock */: i; {; ~ b! q4 Z t4 X" A: c
- SystemClock_Config();
" U z$ B% L6 y4 H9 e - GPIO_OLED_INIT();2 i* V0 e( t1 t! U9 y# \7 I* h
- OLED_Init();
6 V- ^# a' I& `, |" E8 w - OLED_Clear();
) b5 c1 m6 K ~# K x5 R1 I - OLED_ShowString(18,0,"STM32G431",16);
* N6 d- U- u( u6 C S - OLED_ShowString(10,2,"OLED & RTC",16);5 E% `5 ~6 i! {. o! E
- /* Initialize all configured peripherals */+ R3 i" O" T0 i1 ^& X) @
- MX_RTC_Init();- E2 d3 ]# Y* w. c
- RTCStatus = 1;
; T1 c O9 ^) f G( o7 z - while (1)% K5 H T9 w$ `( q/ d
- {
! S. b0 u2 T* w; s. l - /* Display the updated Time and Date */
+ b* T1 K! r* s, O, w - RTC_CalendarShow(aShowTime, aShowDate);# R" n' D8 Z- T, G" y( }8 e
- Delay(200);/ m1 K7 u% M. U3 _2 w1 R
- }
& f E7 _5 s% ~5 {, H - }
复制代码 图1 RTC电子时钟 1 p7 J2 p2 x0 T: x- ^/ ]$ o8 X- K
实现RTC显示的函数为: - static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)8 m) y& z+ K# H3 J4 h7 S. U( J
- {
3 j/ `- A6 K- B7 h. s - RTC_DateTypeDef sdatestructureget;
/ c4 }/ c, D( M6 V) d2 x - RTC_TimeTypeDef stimestructureget;" y7 t: X# ^: s" F
- /* Get the RTC current Time */0 G n8 S. U# a6 E7 @8 W' Q
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
; W$ |! ?+ S! {3 l2 t: Y( }6 G - /* Get the RTC current Date */
6 b, n8 S8 V+ l - HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);8 a4 c! R7 e1 g; [/ s2 s2 t
- /* Display time Format : hh:mm:ss */& j/ z C- _ f0 K, Z; W
- sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);$ T" e! N1 T( p" R2 U( w9 f; X. S
- OLED_ShowString(26,6,showtime,16);0 m: q- ^% V( E
- /* Display date Format : mm-dd-yy */- z3 L, Q4 @$ M5 x, q4 O/ m
- sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);
3 B' E- S0 P5 p+ S/ S - OLED_ShowString(10,4,showdate,16);
$ M# T3 l( P7 F$ k - }
复制代码
$ y5 L/ a- v8 Y7 y+ ^- D2 Q1 D- H" J6 ~调用的字符串显示函数为: - void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)! @9 J, ^& O, O9 K5 a0 ~ R! `
- {
& k, j- {$ X2 I4 Z/ j- a - unsigned char j=0;
7 F- t: I) V0 d - while (chr[j]!='\0')
; e; _0 J9 f& C4 A# ]6 D - { OLED_ShowChar(x,y,chr[j],Char_Size);
! J! `5 w/ p! }6 A - x+=8;
9 g, y3 j7 J( V6 E7 E - if(x>120){x=0;y+=2;}
& C8 R; N3 V: W$ _# e - j++;* P8 |" P [4 _: Z) S+ L$ z
- }; M% k8 K! J. Z# H
- }
复制代码 / V1 S3 _1 q& {% [) w
由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。 8 [7 Q. b" g' |! s4 T* t7 a
图2 校时后的显示效果
; P2 Y) ?; I0 U2 }( S! L |
有空我也玩玩。
计时尚可,长时间的误差可能会明显点儿。
就是11月31日会不会自动进入12月1日,还有闰年修正等。7 t3 z4 R: R4 h, h( D
我给你测了下,两者都没有问题。