你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C0评测】C071:GPIO+定时器+串口

[复制链接]
戈壁滩上的辉煌 发布时间:2025-5-10 23:38
       我们板子第一次上电的时候看到的就是LED的闪烁实验,而且还可以通过按键来调整闪烁的频率,这个板载demo的效果,两个LED交替闪烁,一般板载的demo都是通过延时的方式实现的。这次我们将通过定时的方式实现两个LED的同频闪烁,通过外部中断的方式采集按键,调整同频闪烁的频率。2 D& P, B# A2 u/ ?5 H% a, F+ u  s# s
       我们先看一下需要使用的硬件资源:1 ]" N% r0 _; K( t
       LED:
- a& N4 ~2 n# J* [/ c; l( Q
1.png 6 o% R8 f4 n, Y+ @3 \

+ L7 P2 `$ W( s0 @# l+ J* e( h       按键:
- f( U: h+ m1 m* l
2.png   g9 y; N# Y5 }( s: v( |0 z
3 `; O* p8 ~0 M$ t) ]
       GPIO的功能专注于具体引脚的实现,涵盖输入与输出两大核心方面。输入功能主要用于采集外部器件的状态信息(例如按键状态),而输出功能则实现对外部器件的有效控制(LED的控制)。本开发板装备了两个LED灯作为可操控的外部器件实例,同时配备一个用户按键,用于输入信号的检测。简单分析一下原理图,LD1事业绿灯,想要点亮需要PA5输出高电平,LD2为蓝灯,要点亮需要PC9输出低电平。按键按下的时候另一端是地,也就是低电平,所以对应PC13引脚的初始状态要为高电平,不过硬件中R34并没有连接,我们需要通过引脚配置内部上拉。
3 {' K# j: M. D" A1 H       定时器是MCU的内部模块,通过精准计数进行计时,这就涉及到时钟的配置来计算定时器参数。
) D0 w" L2 ?; u$ F3 ~       接下来我们基于板卡创建工程:% B' Z$ q) s: R; v1 X
3.png 8 J# ?5 {$ ~4 N  T* y, k

; w2 w7 |- z  {4 c6 P       我们先看一下基于STM32Cube的模块配置,由于引脚的多样性,我们可以在引脚上直接操作:  E8 Q( ?8 E. O: ^9 @1 ?/ ]
4.png   t$ L9 }! y0 V; i

9 W4 j8 R/ S$ ]  F7 S       接下来配置三个引脚,一个按键,两个LED:4 I+ a8 R: M8 h1 g  @+ y) A
5.png
$ Q* M, z  |" v2 `2 {

% H4 D5 P% }9 [/ C- n2 B$ X' k       配置定时器模块前先看一下时钟配置,并修改为24M,最大支持48M:) }0 V8 H3 l- b2 f% T- X+ {) r
6.png
; p. n& Q0 m/ A- _

: D1 ?2 a/ |- R8 P! v" ]       接下来配置定时器,我们选用的是定时器14,是一个普通定时器,配置的参数也比较少,定时1ms:
9 N( U& n0 y& |- w
7.png & B+ z2 F% w$ _7 y

( d- X) s6 I9 v' O/ g" E$ J. @       接下来是中断配置,实际上我们在上面的具体模块配置的时候就可以进行中断配置,也可以统一开启:
% p5 ~) ^1 z/ z% `+ n/ j% i* b! G
8.png
9 U- [1 [/ b0 T% N0 f6 w( U
3 i/ J) u- X* {/ T: t
       到这里硬件方面的配置已经基本完成,我们开始软件方面的操作,实际上我们实现的功能也是非常基础了,初始化和定时处理部分都已经添加了:6 ?( U- _9 z- \4 O. n
9.png
# }5 O0 f, O9 i  e/ L
       我们创建两个变量:( o. j- v" d; C! W$ f1 n, m
9 O; w4 L; U9 R- v) r- r* L
  1. uint16_t LED_TimeCnt_limit = 0;
    ) |% ?# w1 L  ]: e! H' V( \. i8 e
  2. uint16_t TimeCnt = 0;
复制代码
      LED的闪烁就是通过判断TimeCnt是否等于或者大于LED_TimeCnt_limit进行LED的状态翻转。
3 ^) n7 ]: Q( m! A+ m  w  L5 E4 ~       我们需要做的就是编写对应的回调函数:
0 ~1 B! D6 N* _: z4 ^# M
  1. void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
    ! E7 ?2 v& z& K0 _
  2. {
    7 N" d, O( ^3 i& H
  3.      if(GPIO_Pin == GPIO_PIN_13)
    . `0 B4 ]7 b& G
  4.      {
    9 f- [, r6 @9 p' F4 h
  5.                 LED_TimeCnt_limit += 500;; f. Z9 w$ m3 V) v' c7 b
  6.                 TimeCnt = 0;) _' a7 Y, Z0 ?- u" z9 H. {( M
  7.                 if(LED_TimeCnt_limit > 1500 )- q- ]1 D( i* v$ t5 ^6 t# G
  8.                     LED_TimeCnt_limit = 500;
    5 K( L! }5 O7 \+ F
  9.      }
    # ~8 D( @# A7 W7 A3 \$ A& h0 [
  10. }
    8 ^& i7 R# x  _4 V9 C7 ~3 w2 ^( }

  11. 2 H3 R! O8 Z3 i4 X% T
  12. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    - p! N/ Q" B9 `0 U% N9 V
  13. {+ |+ J+ r) f& ^! K9 p4 o. r  V
  14.   if (htim->Instance == TIM14) {
    ; }" u. N( h- Z" M7 B% D3 D; d+ C
  15.     HAL_IncTick();: n+ o/ W, ~# b6 j5 K
  16.         TimeCnt++;" N) H, {" |9 X" h1 w
  17.         if(TimeCnt > LED_TimeCnt_limit)
    , j9 F( d4 e+ u; S0 x
  18.         {/ `  n0 U7 S4 P
  19.             HAL_GPIO_TogglePin(LD1_GPIO_Port, LD1_Pin);2 k9 s' \6 V8 V; B; e2 t
  20.             HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);  w  U9 u5 O- w# j  P
  21.             TimeCnt = 0;
    3 M& x$ d; [, |, p9 i& S
  22.         }
    $ r- a6 X/ q: q5 r: j+ [: @9 N
  23.   }
    & o! j" j' h6 n% \
  24. }
复制代码
      这样我们就通过定时器实现的了LED的翻转控制,这个时候我们加入串口的控制,实在是串口和这种多模式的控制太搭了,我们可以通过串口实现同样的翻转控制命令,同时也可以通过串口打印当前状态,我们试一下加入模式变量,因为要实现同步控制,必须按键和串口命令控制的对象是同一个。
4 k* G9 l  }9 Q, K. b+ k       配置串口2模块:: Z- y0 }& z3 n6 K
10.png " Z% B+ B  A8 c. ]8 [
0 f9 i" `/ v) {" [) z
       实际上在生成工程的的时候这个模块就配置了,估计当成必备选项了,行为这个串口连接的STlink:5 o6 Y' G  W; p- k- m" D
11.png
. f6 [% n" o& O  e7 [1 m6 a
+ l( Z5 r1 O6 g" P
       我们先实现一下printf打印功能,加入一下代码即可:' o$ ?" F  `3 L8 N. D- L% M
  1. #if defined(__ICCARM__)
    7 l! n6 V6 [0 Z/ V$ J& b
  2. __ATTRIBUTES size_t __write(int, const unsigned char *, size_t);+ G& L! v: [1 E2 R; R+ M5 A# d# ~
  3. #endif /* __ICCARM__ */
    # t7 V# q, X: ?

  4. , g# j$ I" m1 r8 f+ u: \- g
  5. #if defined(__ICCARM__)
    ( U& f. k) i' F  D! P/ C
  6. /* New definition from EWARM V9, compatible with EWARM8 */
    / _8 g' A9 q- e) k7 g) b' x9 S
  7. int iar_fputc(int ch);
    2 @  G" j7 c5 W; w  m
  8. #define PUTCHAR_PROTOTYPE int iar_fputc(int ch)
    7 _2 h, L2 L+ e: }9 B
  9. #elif defined ( __CC_ARM ) || defined(__ARMCC_VERSION)
    + L8 ~5 @4 J7 b/ u
  10. /* ARM Compiler 5/6*/
    2 t- V! L7 ^: p2 d5 e- N# ~5 U2 n- Z
  11. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)2 S5 ?2 e( ~& N$ I% t9 A: Q
  12. #elif defined(__GNUC__)
    0 c0 G- ~/ P0 ]$ V6 `  ^1 S2 k
  13. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
      G& w0 x) z2 h2 X  @4 O
  14. #endif /* __ICCARM__ */
复制代码
      然后将printf与串口2关联:, E! Z0 B  y; c  |& |
  1. PUTCHAR_PROTOTYPE5 q9 J* k. N1 s6 W  M
  2. {
    " C* L9 t# T+ l+ Y9 [5 ]" o. t
  3.   /* Place your implementation of fputc here */
      k6 r) l5 L; H
  4.   /* e.g. write a character to the USART3 and Loop until the end of transmission */
    * Z4 P% ~8 @6 ?% R7 B* R
  5.   HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);. z; L; X/ J! S: p

  6. # O- p9 N# Z5 y1 d
  7.   return ch;
    / ~5 [! A/ N% A5 |# M& ?7 q4 {1 q6 u
  8. }
复制代码
      这个时候我们就可以用使用printf打印功能了。
1 D' }) ~; _( B" p2 _8 W4 B       串口的接收依然使用的是回调函数的方式,同时修改按键控制内容:7 |, ]4 F$ ~; k3 {. e1 W+ m
  1. void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)
    4 h2 S) G8 l4 R6 \' e
  2. {
    0 K6 K  Y; O* e: P
  3.      if(GPIO_Pin == GPIO_PIN_13)
    % u* G& U( W9 |. a
  4.      {
    9 B" h' a2 S- s1 Y! t7 A$ `
  5.                 LED_Mode++;4 A" d+ m) z: J( X; D. W0 ?
  6. ) S$ q+ Y( F9 m2 T5 _- c
  7.                 LED_TimeCnt_limit = 500+500*LED_Mode;) O$ N7 C2 j% j8 x
  8.                 TimeCnt = 0;
      w, H  ~9 K/ x, H" H+ L, |
  9.                 if(LED_TimeCnt_limit > 1500 )5 {  H- U9 T9 v  F
  10.                 {9 ?  c% g+ ~, Z" O2 ?: y; `' ^: u
  11.                     LED_Mode = 0;: g6 q0 q: H$ U& [+ o$ E. p: L
  12.                     LED_TimeCnt_limit = 500;
    + y. S6 @( C3 U
  13.                 }. a+ C: ~2 q1 j& O& P
  14.                 printf("New Mode:    %d\n\r",LED_Mode);: o0 `% h  ~3 g4 G0 O9 |& h: H
  15.      }0 r' I% x3 g( C4 E3 I- Y7 V
  16. }3 {% Y# Y$ w9 E; M8 d5 `
  17. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)2 T, P6 p' Z" ?6 g/ y
  18. {# ^, r+ b( Q+ k/ Y; v2 C7 u
  19.     if(huart->Instance==USART2)
    / H% x6 Q! A. P  x; s# r
  20.   {
    ) Q0 ^2 q, r8 }: z2 @
  21.             if(UART2_RXData == 0x00||UART2_RXData == 0x01 || UART2_RXData == 0x02)+ z/ k/ `, g* `- j1 X# d! s
  22.             {4 {# L( s8 W1 c9 N6 M8 B
  23.                 LED_Mode = UART2_RXData;
    - _  J# n: B) |" ~; _7 C
  24.                 printf("New Mode:    %d\n\r",LED_Mode);
    : a* O; d1 N+ @* O% g
  25.                 LED_TimeCnt_limit = 500+500*LED_Mode;- G( `% R* k+ `9 o6 L
  26.                 TimeCnt = 0;
    4 Y1 W' c/ q, H0 A. R& I
  27.             }- C& h( G7 A; n2 Y/ w  n& B
  28.             HAL_UART_Receive_IT(&huart2, &UART2_RXData, 1);& i( s0 u$ [" Y" h3 j6 f3 _
  29.   }) L5 ?. ]& p0 W- F; h9 _
  30. }
复制代码
      整体的效果如下,我们将操作过程和串口控制过程通过动图的方式进行展示:2 V- {* G2 }- h7 I& |' c7 V, f
74502b93f6b77b2dc011d0d08f253a74 (1).gif : h% ^  Y# s- ]% Z

& g) A4 K1 y  M8 {$ \       整个对应的串口反应:
$ f# d; d- `, b7 x
12.png
* a- }9 o3 b1 F5 ^# W: t

6 v% `" @3 N; u* [2 N+ c$ D" ^& Z5 S
$ m* m* p5 n" c6 ~3 b5 m5 L1 i: S( ]6 O/ h1 n: K* d6 c8 S

- X) G, L2 \! p! L+ z8 X! u1 [+ p5 u+ h# O- [4 M4 |

% j) H' v  `! |& w/ ?; b# [( i; \

6 p- }" s/ d- z  C/ H. k$ B
+ S8 X4 @) `  E8 w
( G, I* ?3 G/ I4 @3 ?- v( R
# d0 b$ X) L7 C; W% m
2 C  \; s) [. B8 t$ b. U' t: B* |# c5 ~: B1 ]% e" u( C8 T. R6 u. q  \3 r
4 G! b5 C# {3 Q* f0 w
' {$ E$ Y0 H$ p( X/ ?

  I: R: z2 i$ c" F. P# h; F2 O! L+ y
收藏 评论0 发布时间:2025-5-10 23:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版