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

STM32G0-Platformio+libopencm3-串口中断

[复制链接]
STMCU小助手 发布时间:2023-2-23 21:00
使用Platformio平台的libopencm3开发框架来开发STM32G0,以下为串口中断的使用。

- E4 `- v0 j* A- N3 p+ f' ^+ w
1 新建项目
  • 建立uart项目
    / A% I/ ~* `- l& k9 E) v8 b
在PIO的Home页面新建项目,项目名称uart,选择开发板为上一次建立的自定义开发板型号 MonkeyPi_STM32_G070RB,开发框架选择libopencm3;
  • 项目建立完成后在src目录下新建main.c主程序文件;
  • 修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:

    / _6 d) t: y) }, H- w
  1. 1upload_protocol = cmsis-dap
    4 \( Q/ ~+ x7 M0 l0 X- ^9 j
  2. 2debug_tool = cmsis-dap
复制代码

+ z; Q/ x+ T& d, z- I7 c/ K: y! |2 z
* P* M4 ~* N- B/ b  \' n( B2 编写程序
  • 时钟设置

    $ ?; p( d9 ?) U, H" ~# i9 S7 u
  1. 1//system clock
    8 j0 a$ T( a8 y' X( w- b
  2. 2rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);+ D/ H- r" Z  O+ p/ |8 I4 b+ f
  3. 3
    1 p# q) T1 `7 n0 V
  4. 4//uart pin
    8 E3 K' v5 p' d7 z- X( r
  5. 5rcc_periph_clock_enable(RCC_USART1);3 h9 Q$ ]! K3 D, O" S% m  d" |# {5 H
  6. 6rcc_periph_clock_enable(RCC_GPIOB);
复制代码
9 u, a: N5 n. X8 |5 _! U
! ^7 w! E5 [+ A+ P* v
先设置系统时钟为内部PLL生成64MHz,然后设置串口外设和串口引脚外设的时钟;
  • 引脚复用功能设置
    8 A$ V& h& ^. |
  1. 1gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);
    1 ^, D3 p8 J: f/ N
  2. 2gpio_set_af(GPIOB,GPIO_AF0,GPIO6|GPIO7);
复制代码

. }6 O$ ^$ R5 X9 d! j& Y
0 h9 q& I9 B* |( x
根据芯片datasheet文档,使用USART1其引脚为PA9\PA10,复用功能AF1为串口功能;

2 v% L) [' K; i/ B; P+ r8 R. G+ }
  • 串口设置
    $ M3 L  a( J0 G
  1. 1usart_set_baudrate(USART1,115200);" {# V) l0 ~$ F/ G' F9 ^6 t
  2. 2usart_set_databits(USART1,8);3 ~0 y) l7 D/ @# ^$ t$ g" j
  3. 3usart_set_stopbits(USART1,USART_STOPBITS_1);0 ~- }8 `/ h% X9 z5 l
  4. 4usart_set_parity(USART1,USART_PARITY_NONE);
    # V/ U  G$ R6 I
  5. 5usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);2 v* a( j- O- K, c$ F
  6. 6usart_set_mode(USART1,USART_MODE_TX_RX);- b- p5 ]$ C2 S' L: W( ~2 Z' o9 y/ f7 A
  7. 71 b: I9 X# {3 ^6 p. p: U4 U  a
  8. 8//uart isr
    . |  {9 M6 d; Q& h
  9. 9nvic_enable_irq(NVIC_USART1_IRQ);
    + r5 p' u; D4 T7 p* \* ~
  10. 10, P+ L$ p- x% K  A
  11. 11usart_enable(USART1);
    5 s0 x- I2 i: |  T5 Q4 X
  12. 12
    ! a  e, O6 q$ v6 \# C* c
  13. 13usart_enable_rx_interrupt(USART1);
复制代码
+ G) ~3 k" ^8 d) l/ c1 N
$ y7 G) Q+ }) H
先设置串口波特率、数据位数、停止位、校验、流控等设置,再开启串口中断,使能串口和其接收中断;
; D& I) O1 m! ]% Q# k( R0 D; h
  • 串口发送
    2 n6 L6 s2 ~( O, e$ X
  1. 1char buff[32] = "hello, makerinchina.cn\n";
    9 p1 E+ z: s1 t! L$ h
  2. 2for(int i=0; i<strlen(buff); i++){- F, x8 `% y  O( S, C1 M
  3. 3    usart_send_blocking(USART1, buff[i]);
    ; n8 x# K. p& |  O8 g! N8 j* q% s
  4. 4}
复制代码

" e1 S( y' h# B( N  Z2 @6 ~! k/ I
$ v6 h4 K3 L: U( ?% ?2 S
发送直接使用 usart_send_blocking 接口发送一个字节数据;

& K# i5 S2 s+ C+ g
  • 串口接收
    3 ~/ q( W( ?, Z/ Y( l, r
  1. 1/**/ A  Q. J  B5 f% ?: G
  2. 2 * @brief uart1 isr function
    ) `. n: H; ]6 K! k' ?
  3. 3 *
    7 f( Y- N% ^! }" U& i! e6 ?) R- l
  4. 4 */. D- _  ^8 ?6 }: l# y" j; l
  5. 5void usart1_isr(void)4 ?8 ?/ u* m, J
  6. 6{( r0 S& {( C8 j" j' r2 B& M$ a/ K
  7. 7    //receive interrupt$ z6 c0 k" K' Q' G0 P, H
  8. 8    if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&2 A$ f  R1 A# ?* O0 D/ ]3 Q
  9. 9        ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {0 N. l8 N* a9 L  T2 d$ Q  y/ [" c
  10. 103 S1 d" X- `$ \! }8 i/ P  U; t0 d! n, K
  11. 11        if(recv_index < BUFF_SIZE){
    3 u  _( |; i8 W( @# I
  12. 12            recv_buff[recv_index++] = usart_recv(USART1);* z; J0 ?2 Z/ L9 i- g% P
  13. 13        }else{. E1 @) {9 W4 j
  14. 14            recv_index = 0;! B$ w6 [: q" A8 |! i5 `: C8 R
  15. 15        }6 B. ]- d( U' Z9 |
  16. 16    }
    2 D. i, A7 w/ @) z
  17. 17}
复制代码

5 C( L1 I& M6 Z: U' L/ G9 U" i# }( H  P# I8 E# l9 G
串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来:
  1. 1#include <libopencm3/stm32/usart.h>+ Q* p7 R. ~! i& X: M, l& z
  2. 2#include <libopencm3/stm32/rcc.h>: [8 _3 X- z0 ?5 _3 b
  3. 3#include <libopencm3/stm32/gpio.h>
    ! C: ~* i1 w: ]* W5 y* v8 h0 M
  4. 4#include <libopencm3/cm3/nvic.h>9 a+ Y) A: }) f% |  C
  5. 55 I' W6 Y# s4 Q
  6. 6#include <string.h>( |  }: u* ]' N. i
  7. 7
    9 ]  s* T3 [$ _! {9 k
  8. 8volatile uint8_t recv_index = 0;
    - F- A: K2 F" Z$ p% ~: b
  9. 9volatile uint8_t send_index = 0;" C6 H; y( q3 m
  10. 104 U" j, b( D2 k5 X7 [$ K& K
  11. 11#define BUFF_SIZE 64
    8 x2 n+ ^& x' l, v$ |
  12. 12uint8_t recv_buff[BUFF_SIZE] = {0};
      W4 D1 S% t! l8 ^5 ^7 J- p1 F+ T2 n
  13. 13
    ! h: c( H0 ?! d2 B) R
  14. 14int main(void)" C( h4 V) T( `
  15. 15{
    ! I$ }9 c1 ?" Z! z* e
  16. 16    ...
    9 c  i8 o1 R: R- \
  17. 17/ A6 o9 y1 U( y" U% [& A1 J- ?
  18. 18    while (1)5 g  \- s% j4 U) a0 P, F% z
  19. 19    {
    # Y, ^% {1 U* K% O; R+ V: u" y
  20. 20
    : v0 |& @/ }/ D9 F2 {- ?3 r
  21. 21        if(recv_index != send_index){
    4 f. `/ _2 \+ I  G+ h7 }( C# k
  22. 22
    ' M$ s& u8 h; p
  23. 23            if(send_index < BUFF_SIZE){
    8 J& E5 `" \9 }( N6 w" R
  24. 24                usart_send_blocking(USART1, recv_buff[send_index++]);
    # H- q% e+ G* U# e% e) s
  25. 25            }else{# \3 r5 w2 ~) P4 b( y
  26. 26                send_index = 0;
      a3 U/ F/ W5 y2 N. e! B7 M4 o
  27. 27            }
    $ u, ?) G6 f9 w/ [4 z
  28. 28        }& e9 p3 @, ]& K, A* o/ B
  29. 29" k% N6 g' E* A8 y4 b9 H! ?0 \- `
  30. 30    }
    : u/ M: Z+ p/ l
  31. 31}
复制代码

: D; S1 V: H4 o6 n3 烧写测试
点击 platformio:Upload按钮或快捷键 Ctrl+Alt+U即可完成编译、烧写过程,打开串口工具,可以看到发送的数据和接收数据一样;
$ v% ^" S) `$ @& z, r8 P  ]) u3 B2 L
4 printf使用
如果要使用printf功能,需要定义如下函数,将串口重定向:
  1. 1/*& C; t9 [: g0 C4 X
  2. 2 * Called by libc stdio fwrite functions4 Y7 [& O6 o3 Q' k4 @
  3. 3 */
    9 ^; m* V! ^$ Q$ P" ~1 w+ w
  4. 4int
    5 W  C7 Z5 j7 z  E- C
  5. 5_write(int fd, char *ptr, int len)
    : d0 t8 v: l$ \% p; X: C' `% @) |
  6. 6{
    - F- Z# ^9 u0 U4 F$ K
  7. 7    int i = 0;) L# h) j0 i3 [& Z0 R" s3 z
  8. 8
    + Z/ U& L- c7 `8 Q
  9. 9    /*% a2 N! |. O4 k! W2 L2 Q* a% G) Q9 D8 N
  10. 10     * Write "len" of char from "ptr" to file id "fd"$ W9 F, ~/ |$ N* k- [
  11. 11     * Return number of char written.$ f$ b% I$ E3 P) |
  12. 12     *
    ' c3 U+ a9 c; ]- n" i
  13. 13     * Only work for STDOUT, STDIN, and STDERR' @6 h- Y1 c( E3 K
  14. 14     */
    ; Z6 \; z0 V5 r/ i1 B' U( d# U
  15. 15    if (fd > 2) {6 e' R" i7 h8 ?  s6 }
  16. 16        return -1;
    ' ]5 V& J/ P* N7 @
  17. 17    }- I4 ~1 n- I( S! C3 C) N$ s4 _
  18. 18    while (*ptr && (i < len)) {
    6 C! F5 v, U$ ?1 q
  19. 19        usart_send_blocking(USART1, *ptr);" c& ?; S4 R' h% w& H: t' R! R
  20. 20        if (*ptr == '\n') {
    5 w. }( M% }; f7 F) b; Y: ]; u8 M
  21. 21            usart_send_blocking(USART1, '\r');
    9 q9 E6 q2 [0 m/ D7 A) L
  22. 22        }, I; Z8 i/ E1 N
  23. 23        i++;- h4 Z2 C% p( W5 x& Y
  24. 24        ptr++;
    ; H1 \1 x; }6 e8 H7 i
  25. 25    }7 k. S3 G. Z. R) a# l: F
  26. 26    return i;
    , F- u: [$ _0 R+ C* l' F
  27. 27}
复制代码
) B: S0 S4 x2 K
现在就可以直接使用printf函数进行打印显示到串口设备;
; t, R* j0 l+ k4 r/ B6 p
转载自:MakerInChina.cn

& r9 K0 @# f; R' b
赞 收藏 评论0 发布时间:2023-2-23 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版