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

STM32G0-Platformio+libopencm3-串口中断

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

2 H9 q( g! r: `% b3 d
1 新建项目
  • 建立uart项目

    1 q7 C" O* G) @: m% ]% Y
在PIO的Home页面新建项目,项目名称uart,选择开发板为上一次建立的自定义开发板型号 MonkeyPi_STM32_G070RB,开发框架选择libopencm3;
  • 项目建立完成后在src目录下新建main.c主程序文件;
  • 修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:

    , G, ^& o  G+ s% e5 {1 F9 k( f
  1. 1upload_protocol = cmsis-dap
    * @: i# [3 u$ g9 H! O; Y
  2. 2debug_tool = cmsis-dap
复制代码

% z$ }6 u4 A* f
5 v( k9 l# V" a8 `. e2 编写程序
  • 时钟设置

    $ O+ u0 W% A0 s
  1. 1//system clock
    0 O. G3 N# J: _# z$ n8 @
  2. 2rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);8 H* e. f7 s* Z4 }
  3. 3" ~, o9 J7 @% i! A) t
  4. 4//uart pin
    ' ~0 z. u+ t, @1 P( Q+ C
  5. 5rcc_periph_clock_enable(RCC_USART1);" R+ k3 K3 J+ q3 x1 {) L, u
  6. 6rcc_periph_clock_enable(RCC_GPIOB);
复制代码

: w* g/ t1 x# ?: T
+ d* ?- ]- x2 W* S  \' e- X
先设置系统时钟为内部PLL生成64MHz,然后设置串口外设和串口引脚外设的时钟;
  • 引脚复用功能设置

    # @' L# L; B  O& I' g% n
  1. 1gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);# h2 f$ Z6 q) f9 E, V
  2. 2gpio_set_af(GPIOB,GPIO_AF0,GPIO6|GPIO7);
复制代码
' q. ]# b3 S) H* Q

& A3 z2 \) d/ y, `( v% W) C
根据芯片datasheet文档,使用USART1其引脚为PA9\PA10,复用功能AF1为串口功能;

0 X( h3 A9 V4 H) Q* c( [
  • 串口设置

    5 i! V4 L- F4 G$ r+ g
  1. 1usart_set_baudrate(USART1,115200);9 E4 x) ~# j) Q
  2. 2usart_set_databits(USART1,8);: F' w4 G6 N" J# `* T
  3. 3usart_set_stopbits(USART1,USART_STOPBITS_1);7 c! x) B+ T! j1 ]* l- J  ^# L
  4. 4usart_set_parity(USART1,USART_PARITY_NONE);
    ( U) S+ n/ _! `9 E8 t! e# D
  5. 5usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);
    / Q2 d. L9 {/ N6 r- v  J5 O
  6. 6usart_set_mode(USART1,USART_MODE_TX_RX);; u5 _# v- [6 s1 v9 P) `3 T
  7. 7; H5 r- w  w/ M. y
  8. 8//uart isr  n- M; N) [7 Q
  9. 9nvic_enable_irq(NVIC_USART1_IRQ);
      \; G1 `8 Z. Y0 v5 A6 Q
  10. 10
    - O. O, M9 M+ u
  11. 11usart_enable(USART1);
    6 l2 p8 Q( W; i8 E" d# n
  12. 12
    # F+ C7 I" d2 z- x% H3 z
  13. 13usart_enable_rx_interrupt(USART1);
复制代码

9 Q, \/ q& D4 Y* ]
* s) ~" E. U' t. |8 W
先设置串口波特率、数据位数、停止位、校验、流控等设置,再开启串口中断,使能串口和其接收中断;

/ g) M8 s3 L9 q8 T' q: V
  • 串口发送
    7 O" o0 S% c- U4 h& u: \! [# X
  1. 1char buff[32] = "hello, makerinchina.cn\n";
    ! Z. w7 c4 U3 Y% T
  2. 2for(int i=0; i<strlen(buff); i++){2 v& P3 ]5 z2 ?7 E  {7 N
  3. 3    usart_send_blocking(USART1, buff[i]);# `/ g7 c( j* \% I
  4. 4}
复制代码

. o% f6 y% Y! ^) V. e8 ^3 h$ O  }) a! U
发送直接使用 usart_send_blocking 接口发送一个字节数据;

& v) F* l& E7 t
  • 串口接收
    1 H' H: ]' y& d: N
  1. 1/**6 {  J) b! p. }
  2. 2 * @brief uart1 isr function
    , }- g; T9 G4 F! p
  3. 3 *
    . E! v! ~  w7 t+ |3 x! t, b
  4. 4 */4 {9 ~1 k( H1 r2 Z
  5. 5void usart1_isr(void)
    # M( d* w2 q0 {) K$ x1 y
  6. 6{% c; j! ^" X6 U* `
  7. 7    //receive interrupt
    3 |% Z1 ?: O& m- N2 ]. d9 A3 S
  8. 8    if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
    2 d' E: P: C1 P" f0 P2 I! ~9 ~0 z
  9. 9        ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {
    0 H. v3 ?/ r- Z6 Y; A! ?6 {
  10. 10: I5 |: N2 w% q" I1 g% @- A" L8 n
  11. 11        if(recv_index < BUFF_SIZE){% T; z' R7 g: O- w
  12. 12            recv_buff[recv_index++] = usart_recv(USART1);- P4 `1 g8 N( b! o' p# I) o  f
  13. 13        }else{
    2 a) h9 f; _# s4 S
  14. 14            recv_index = 0;
    ; X+ _5 m* e; m
  15. 15        }: R2 ]- s  r. ^) j
  16. 16    }" l0 E2 E4 l* v
  17. 17}
复制代码
5 Y) G% G- w. j

" U3 V4 \4 ]" j, h8 \& C
串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来:
  1. 1#include <libopencm3/stm32/usart.h>0 ?% j. j9 E3 a7 Y0 z) J
  2. 2#include <libopencm3/stm32/rcc.h>2 j  K) H* i* e2 {# V3 G% n
  3. 3#include <libopencm3/stm32/gpio.h>
    4 h5 |" M& {/ q/ v6 B) R. r* E/ ?
  4. 4#include <libopencm3/cm3/nvic.h>
    + u: q, z- {' V5 m: Z% u2 \. n
  5. 53 `/ o+ o9 O, E9 Q  z# e$ B
  6. 6#include <string.h>1 i( |5 O; I+ D  ^% |
  7. 7
      i, {: J( @3 @/ q
  8. 8volatile uint8_t recv_index = 0;' k$ O' F/ K" k4 N4 X$ x
  9. 9volatile uint8_t send_index = 0;
    2 r8 q% C! b9 c5 n) ^3 s% g3 T/ w
  10. 10- Q0 a+ B& w: _9 u' i
  11. 11#define BUFF_SIZE 646 d" n8 t: s+ r3 q
  12. 12uint8_t recv_buff[BUFF_SIZE] = {0};1 F/ |) {) f- T' [/ d+ w  v
  13. 13
    + s2 C/ s: O. r# x+ d* F
  14. 14int main(void)& G$ X" c/ o8 m' P. P9 q+ I
  15. 15{
    ) V1 i3 q- c+ ?) {1 R" b2 D( I7 E
  16. 16    ...
    4 A. _. p, r" ?
  17. 17  `$ T( G7 x" q& I
  18. 18    while (1)
    ; [- D- u: n6 H. A. Q- T: |) ]
  19. 19    {8 `9 c3 z' C( Z) F8 Q1 _0 i
  20. 20) u  Z0 H- |3 [; f% i
  21. 21        if(recv_index != send_index){ # H, a; l# @" c6 P0 U5 z
  22. 22
    % k! u- J. w5 u4 l
  23. 23            if(send_index < BUFF_SIZE){
    ( E% [1 |: R' X& q) x
  24. 24                usart_send_blocking(USART1, recv_buff[send_index++]);
    9 a* S1 s! j1 G- b
  25. 25            }else{
    # \9 t- K8 o: B8 F+ p
  26. 26                send_index = 0;
    & r( p% U( }. h1 U) D
  27. 27            }
    ; |) I. p7 |$ e$ V6 R: q! n; _
  28. 28        }& w3 g6 S$ w  q2 m+ n$ F; C
  29. 29
    - P, ^, t8 V. O7 e! f" _6 O
  30. 30    }
    1 V$ X; u0 s- h, t* R$ X4 k
  31. 31}
复制代码

9 s( Z9 s9 i" E3 烧写测试
点击 platformio:Upload按钮或快捷键 Ctrl+Alt+U即可完成编译、烧写过程,打开串口工具,可以看到发送的数据和接收数据一样;
; q; E. p- x- w. `- D
4 printf使用
如果要使用printf功能,需要定义如下函数,将串口重定向:
  1. 1/*
    9 Q5 K0 F( ?' r3 j) h* |5 W
  2. 2 * Called by libc stdio fwrite functions* d0 s3 h4 P5 ?0 e+ ?
  3. 3 */
    2 v# K3 n9 p2 U0 ^, U: X+ P' T
  4. 4int. a3 H( }! |- f; A! J6 w
  5. 5_write(int fd, char *ptr, int len)3 F# J) {5 v7 ~" R) ^$ z
  6. 6{
    ) ~* W- v9 Q$ ~/ V1 O
  7. 7    int i = 0;
      x4 r6 E0 g& i! S1 P) S; R; c. I
  8. 8
      A7 }8 u- k; k$ ~
  9. 9    /*, y$ q$ E( m4 \5 I
  10. 10     * Write "len" of char from "ptr" to file id "fd"6 U5 d( Q! w! l. S7 B5 c
  11. 11     * Return number of char written.* u# j, \! Y- D" t) Q/ @2 ~
  12. 12     *
    1 W3 ?4 p, H2 P' \* Y
  13. 13     * Only work for STDOUT, STDIN, and STDERR
    - F$ K) U( P$ Q
  14. 14     */
    # \6 Q, h, u( x
  15. 15    if (fd > 2) {
    ) [( k- u, G! e+ k) a5 E; D% O3 z$ f
  16. 16        return -1;
    7 g' y( o4 g+ j! w
  17. 17    }1 j: ^. O& j+ i% e' Q
  18. 18    while (*ptr && (i < len)) {
    ( j# _- p+ z' n. }& p
  19. 19        usart_send_blocking(USART1, *ptr);: q0 ^! A( _2 P4 _
  20. 20        if (*ptr == '\n') {
    # F+ {7 G5 J7 k! n) d! t7 E$ e
  21. 21            usart_send_blocking(USART1, '\r');5 i2 Q% Q: p+ j5 ]  f. L) T
  22. 22        }- ]8 I: G/ L' r* `
  23. 23        i++;; W0 O2 X% r* i% e5 v
  24. 24        ptr++;" Q$ L5 t0 H1 v3 F
  25. 25    }
    9 u2 y/ I2 D. O$ p" A  }
  26. 26    return i;
    + }1 K9 u2 f3 K
  27. 27}
复制代码

  G! ]% N, Q+ z4 B: l$ h' a
现在就可以直接使用printf函数进行打印显示到串口设备;

; F! u3 b) ?  l$ {% T% f
转载自:MakerInChina.cn

  }2 D6 M2 D! w# ^. ?1 `, {( {
收藏 评论0 发布时间:2023-2-23 21:00

举报

0个回答

所属标签

相似分享

官网相关资源

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