|
在STM32G431内部配置有RTC计时器,将它与OLED屏配合即可实现一个电子时钟。 " @8 K7 q: i* G P
实现图1所示效果的主程序为: - int main(void)
, Z5 G% _) i# L) k3 g" n - {1 B6 g @$ W3 B
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */- A& Q9 `0 v2 Q; ^
- HAL_Init();
' @% {+ C( ^/ p, w" E0 x - /* Configure the system clock */+ |; H. t+ [1 k, G/ }
- SystemClock_Config();
" Z' W9 e) c4 t4 y$ f" T g - GPIO_OLED_INIT();
. p" h" P# a6 h' Q" X - OLED_Init();! z4 a4 j N& Y* D+ v+ I$ M D {6 o
- OLED_Clear();' E2 r' O: F) f) H7 d
- OLED_ShowString(18,0,"STM32G431",16);
5 U" B( H$ S' _* `7 l) [ - OLED_ShowString(10,2,"OLED & RTC",16);
* ]; r: V! Z7 r6 ?, x/ F2 z* C" {+ U - /* Initialize all configured peripherals */
% g0 F6 D t, ^( m - MX_RTC_Init();0 b. N. m0 n6 J
- RTCStatus = 1;4 i* M; ^4 b4 e$ T2 L5 T6 @# b
- while (1)
. I$ |) Y# {6 L) _ - {
# s# r3 N- D% S" x! q3 o - /* Display the updated Time and Date */
n! @, L% s2 l8 {- Z- m - RTC_CalendarShow(aShowTime, aShowDate);! q, @, } f" h# \
- Delay(200);# @) U8 x q+ _- H2 p/ F
- }5 n- q" v" G2 }2 Z4 y+ n+ ?* W3 Y
- }
复制代码 图1 RTC电子时钟
: V0 s. @# _ @- u; X5 B9 H+ O9 Z5 @实现RTC显示的函数为: - static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)# j- w n) i2 O+ y
- {6 t* T9 I2 r) d" y& l* `; x+ C
- RTC_DateTypeDef sdatestructureget;/ B1 L4 r& p( k8 x( E1 s3 Z( y/ u# h
- RTC_TimeTypeDef stimestructureget;
* H/ }3 J4 b8 r" d - /* Get the RTC current Time */! U3 {7 L2 k# P. m/ N9 D6 o
- HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);$ U6 _: }. N1 M: l( P! w7 j
- /* Get the RTC current Date */
: ~9 C/ {" b9 ] - HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
+ o2 H1 u; l7 Q4 _ - /* Display time Format : hh:mm:ss */2 W9 G+ T! E2 K) c$ [
- sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
6 ?( C% R6 ?: J+ Y" I; o6 D2 b - OLED_ShowString(26,6,showtime,16);
1 Q `+ U$ ?+ S4 T5 f! A - /* Display date Format : mm-dd-yy */
- Y4 C l5 s- q. ~5 p7 }& B# T1 n - sprintf((char *)showdate, "%2d-%2d-%2d", 2000 + sdatestructureget.Year,sdatestructureget.Month, sdatestructureget.Date);7 u( u% W; z, k0 a3 ?
- OLED_ShowString(10,4,showdate,16);, y l* p' L4 f' H9 {; x$ S* I6 ^
- }
复制代码
! ]' E+ I$ O$ _; R; G! H调用的字符串显示函数为: - void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 Char_Size)
7 T# c: Q. s) ?1 g! h# o! X - {
; \ R0 u9 f7 M* {8 Z - unsigned char j=0; P2 f* B6 }$ }* k+ d
- while (chr[j]!='\0')
4 J" e9 ?5 `9 n- F6 ]5 ]2 o8 F - { OLED_ShowChar(x,y,chr[j],Char_Size);
% p8 s9 e3 C: S! L: C5 p3 I - x+=8;
+ M, T. B2 }$ Z3 R( j - if(x>120){x=0;y+=2;}9 O3 @# M# O) M- N
- j++;
. S% B- j; A) G8 C - }* s& ]$ I$ b' c! G: t2 U
- }
复制代码 , b* t- L$ U" \
由于例程所设置的初始时间是2018年,故需要在函数 MX_RTC_Init()中进行修改,修改后的运行效果如图2所示。 . W" E I+ [' E7 a
图2 校时后的显示效果
. R0 K# |& W3 B3 z |
有空我也玩玩。
计时尚可,长时间的误差可能会明显点儿。
就是11月31日会不会自动进入12月1日,还有闰年修正等。6 C1 T' u8 Q- D( Z6 r& x; [- e+ t
我给你测了下,两者都没有问题。