在STM32G431内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。 . e' H9 {% l9 V1 {/ P
实现图1所示效果的主程序为: - int main(void)
) C, {, V K; h6 _+ M6 a4 t - {+ `3 N( K2 h) j- C" u% {: K
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */% M' q/ m) B6 j) H0 U- \" [
- HAL_Init();
) o, u' E6 J2 H6 T4 F' e - /* Configure the system clock */
0 B7 p( `* Q) d - SystemClock_Config();' M0 f- I( ]6 C8 I9 w/ F0 l
- GPIO_OLED_INIT();1 b* _9 I0 i) ?8 R: o# B2 u: {0 t
- OLED_Init();
) y* |% _7 ^9 C7 y% d7 V4 T1 x - OLED_Clear();
! e9 B" d, W. g/ v - OLED_ShowString(18,0,"STM32G431",16);
1 ^! k9 J7 e, H7 C& v. s' O - OLED_ShowString(10,2,"OLED & RTC",16);
j6 J6 ]' _+ k4 H - /* Initialize all configured peripherals */
- q& n L! u# @ - MX_RTC_Init();1 W2 ]( A J% I3 y8 s2 O0 D
- RTCStatus = 1;
8 `! k5 N$ O* p) b& }1 `8 t2 t) H - while (1)/ a$ q+ B/ }* D9 r- Q6 S2 u
- {
" A1 B3 Y+ H5 d$ s% \ N8 F - /* Display the updated Time and Date */! X a# z/ F2 P x+ o2 e+ e
- RTC_CalendarShow(aShowTime, aShowDate);
/ ?# Q- r- {0 J, |- H - Delay(200);
( _$ h7 e) x5 a7 t% P - }
R% ? a( J$ r9 n6 z - }
复制代码 图1 RTC电子时钟 , a2 T% [/ g( c; {( F" H
实现RTC显示的函数为: - static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
' c# }: L9 F4 P - {
0 ?* T! P* V- P( G! F - RTC_DateTypeDef sdatestructureget;! }1 a1 c& S( k/ O8 X7 x
- RTC_TimeTypeDef stimestructureget;
2 p3 n5 @& l" ^& m" l - /* Get the RTC current Time */, l$ y( s6 M5 `- D
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
+ X. m9 ^7 S0 N. ]! q5 w - /* Get the RTC current Date */
# i6 c" E7 H, H9 b" q9 ~ - HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
9 R; [- L b; i7 _4 f+ |" ~ - /* Display time Format : hh:mm:ss *// v* ]8 z; O) e' Q# ]
- sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
/ X! H/ `" z: c5 ^" z D- K! d - OLED_ShowString(26,6,showtime,16);
( x2 s4 g+ j' O3 y. o - /* Display date Format : mm-dd-yy */
4 K4 U: [( b5 Q& o - sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);
& P0 W" M7 g) K8 \! Z1 h0 R - OLED_ShowString(10,4,showdate,16);1 A, O9 [% |$ k3 s8 d, f
- }
复制代码
; G/ Y j9 x, D3 l- h a& S调用的字符串显示函数为: - void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size): v1 E% s- x; ? R _
- {
9 l. _: v! s+ u, t' \ - unsigned char j=0;
% Y. S. z/ |( b% G" s - while (chr[j]!='\0')7 ?( P" X& ^" h7 o4 j; z
- { OLED_ShowChar(x,y,chr[j],Char_Size);3 J# a( ]& c. O2 g7 k% ~ j$ F
- x+=8;
+ i* B; h* M/ U6 L* e& Z6 b' o; D - if(x>120){x=0;y+=2;}# b7 R: e% T! q! p1 ?$ i' z' j
- j++;
6 L! N' e! v, G" ]0 f6 ] - }
% R5 T5 i" p4 Z0 m1 K - }
复制代码 ' d+ E g2 b% ?- y
由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。
d2 j+ v/ r: `. [. Q图2 校时后的显示效果 : \8 k/ X( u' x3 I/ i$ I; [0 y& k
|
有空我也玩玩。
计时尚可,长时间的误差可能会明显点儿。
就是11月31日会不会自动进入12月1日,还有闰年修正等。* n$ ?' u+ S; O; q7 I w
我给你测了下,两者都没有问题。