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

STM32G0-Platformio+libopencm3-串口中断

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

* i8 p  a4 k: v* V/ S  Y3 p+ z* o
1 新建项目
  • 建立uart项目
    / d/ C6 l% t7 a' O; ^/ E  T/ q
在PIO的Home页面新建项目,项目名称uart,选择开发板为上一次建立的自定义开发板型号 MonkeyPi_STM32_G070RB,开发框架选择libopencm3;
  • 项目建立完成后在src目录下新建main.c主程序文件;
  • 修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:

    2 w5 P' M) F. A
  1. 1upload_protocol = cmsis-dap9 l2 Y7 L3 x+ G0 \+ y
  2. 2debug_tool = cmsis-dap
复制代码
% I' N. g; C4 s  b, q. a

% b3 e/ p7 d: n" h' C1 ^2 编写程序
  • 时钟设置

    : M- i) X/ x: U; Z% x, O
  1. 1//system clock
    % Z7 J! p  c+ }2 }# i8 p! \" r
  2. 2rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);' d( Y: J- W/ }  R! i+ V
  3. 3& z' C, V4 b% p& f$ w$ M
  4. 4//uart pin
    ) v* w& G7 ]0 u  j
  5. 5rcc_periph_clock_enable(RCC_USART1);
    , r; Y- c1 Z8 Y4 V: G
  6. 6rcc_periph_clock_enable(RCC_GPIOB);
复制代码
+ u  A& l& q3 K

; V" f2 @+ n- d. M" o% ~
先设置系统时钟为内部PLL生成64MHz,然后设置串口外设和串口引脚外设的时钟;
  • 引脚复用功能设置
    ( m: m& z& f( d! ^- K" |* d: Q
  1. 1gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);
    ; C7 u: Z2 p9 N; P, Q- V
  2. 2gpio_set_af(GPIOB,GPIO_AF0,GPIO6|GPIO7);
复制代码
; E- y! }3 E; T" E; D( ?, z1 Q  g! }
% N$ G4 d0 ^( B" c: o1 A
根据芯片datasheet文档,使用USART1其引脚为PA9\PA10,复用功能AF1为串口功能;
- z3 u( Q  v& W3 E$ S. q* J
  • 串口设置

    ) z0 {5 E! }# ?) ]1 H$ O
  1. 1usart_set_baudrate(USART1,115200);
    1 Y" _' g) l- l5 J# I; a
  2. 2usart_set_databits(USART1,8);
    : d) Y+ \& `* r0 o. u2 m7 C$ }! l
  3. 3usart_set_stopbits(USART1,USART_STOPBITS_1);- n; M( X/ I3 l7 ], W3 S
  4. 4usart_set_parity(USART1,USART_PARITY_NONE);' Y* O% N! g- k# y9 q: ?
  5. 5usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);" _4 q. C3 z4 ?/ _, O+ ^2 A9 [
  6. 6usart_set_mode(USART1,USART_MODE_TX_RX);' F* \7 z( }8 O$ o9 g  [! m7 m. v( l' u
  7. 7$ `! x, Q0 J" W- n* A: p; x! _4 [
  8. 8//uart isr
    , ~1 V  [* P" B1 M6 p9 W
  9. 9nvic_enable_irq(NVIC_USART1_IRQ);
    ' V' e5 e* I; O- Z& ~$ c7 M8 ^
  10. 10
    ; [' L/ W$ z" W$ O) h" x9 Y( |
  11. 11usart_enable(USART1);% h1 w6 F! P! Y
  12. 12+ N1 v5 y' g# `/ g# K
  13. 13usart_enable_rx_interrupt(USART1);
复制代码
" f) I6 J! `, A

- v8 S2 x' M6 c1 A' _7 r
先设置串口波特率、数据位数、停止位、校验、流控等设置,再开启串口中断,使能串口和其接收中断;

: a- E3 A" A# a
  • 串口发送
    $ `; h$ F9 x; [9 T$ E
  1. 1char buff[32] = "hello, makerinchina.cn\n";
    2 `9 W7 S: V7 T, y
  2. 2for(int i=0; i<strlen(buff); i++){
    ; h4 O6 k. Q- W  v! r3 P" r$ J
  3. 3    usart_send_blocking(USART1, buff[i]);
    * C" o: n+ D# D3 q& M3 R
  4. 4}
复制代码

! z7 X5 Q( C) w) d+ z
) d" R; O6 z7 h$ ]
发送直接使用 usart_send_blocking 接口发送一个字节数据;
: m, V6 _' k' B/ E" X/ _
  • 串口接收

    : I; [5 D: `  z# d4 y4 A+ f/ U
  1. 1/**
    ; j# O- w* g, V! i
  2. 2 * @brief uart1 isr function7 r5 o0 Z- u3 y9 l9 N) Z
  3. 3 * 1 w+ G3 k) W% @& g
  4. 4 */6 v: I+ U, |8 u8 p2 r; [" Z
  5. 5void usart1_isr(void)6 O: U3 c8 o- V$ q5 O8 p9 Q
  6. 6{
    $ u$ v" N6 y' f
  7. 7    //receive interrupt' `2 T, f' ^6 K  w9 P) T" O4 I
  8. 8    if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&; z3 b  |: R3 {7 l* W; G( t1 `
  9. 9        ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {' u: s  G6 `' {5 m: R
  10. 10
    , d, K. A/ d, C, R- t/ |) c
  11. 11        if(recv_index < BUFF_SIZE){5 s0 m. r/ X; B% e8 x4 h- S6 @
  12. 12            recv_buff[recv_index++] = usart_recv(USART1);* N, ^9 X' l& J) I2 J
  13. 13        }else{4 e7 i" O) i* ?4 ]" ~
  14. 14            recv_index = 0;0 @- H: }  `+ ^$ L7 b& P1 ?( L+ Q
  15. 15        }
    % @( J! R7 M2 i# X$ p1 j& t
  16. 16    }
      O2 y0 W- D% k1 Q
  17. 17}
复制代码

2 N8 q; T5 s5 q& Q' N4 A
  c# b' d- f" ]: A' |
串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来:
  1. 1#include <libopencm3/stm32/usart.h>
    2 p, G4 j. u: t# y
  2. 2#include <libopencm3/stm32/rcc.h>9 p: d( [4 B, H, L$ M& O
  3. 3#include <libopencm3/stm32/gpio.h>) t/ E3 y3 F: `1 ~
  4. 4#include <libopencm3/cm3/nvic.h>
      _2 ]* |1 P& J6 s! F6 W3 b% i
  5. 5
    ) u1 I: C) e2 x0 m: e
  6. 6#include <string.h>2 ~. Z% N) U3 C
  7. 7
    ' j: a! G; M( `( W* k% n
  8. 8volatile uint8_t recv_index = 0;
    , y- \( b7 i) q, v4 D4 E
  9. 9volatile uint8_t send_index = 0;
    # O1 h' ?/ q2 f# U/ P9 k' r
  10. 10
    7 K" \! i2 {" L- G3 R! [6 X
  11. 11#define BUFF_SIZE 64
    ; Z* W8 q- X. l
  12. 12uint8_t recv_buff[BUFF_SIZE] = {0};
    1 o' m* l: }! c3 v
  13. 13
    % t7 c6 H% Q2 r1 V
  14. 14int main(void)
    $ K) M$ a0 r) a4 x, L; ?8 N: r
  15. 15{
    : {7 N4 s8 C% a8 U, Q$ k
  16. 16    ...5 C/ V! z. U7 `$ t: _( I5 \* h' b9 s
  17. 171 w% U) a6 y2 z# a9 L6 Y. I: t
  18. 18    while (1)
    " Y! h  Q5 D. L+ Z! g, F
  19. 19    {
    & }8 f& K0 J# F- K! o
  20. 20
    9 d0 u: `2 P2 ?: a% h3 C" O
  21. 21        if(recv_index != send_index){
    7 Q; s3 d7 M1 i" x5 _1 `2 ?% R2 Z
  22. 226 p5 ^# w3 u' t; G0 z$ y% v
  23. 23            if(send_index < BUFF_SIZE){
    9 K! ?4 p" z# y7 ]
  24. 24                usart_send_blocking(USART1, recv_buff[send_index++]);0 E! z. u  V; N" x# U
  25. 25            }else{
    5 H: f5 X+ f; Y" i) H1 }
  26. 26                send_index = 0;
    / U* Z2 H6 S( J; z; x- M
  27. 27            }
    ( O" R7 U  s* D( Z& j$ s3 G$ S
  28. 28        }( G0 H( M* B# o% L; I2 W" c& V. u
  29. 29
    # V6 [& l* _  S) S) U) R  {5 D' \
  30. 30    }
    2 e2 d9 T, @" F) h1 U* s8 Z3 G) [
  31. 31}
复制代码
( ~9 b5 J' k1 Q4 V7 L
3 烧写测试
点击 platformio:Upload按钮或快捷键 Ctrl+Alt+U即可完成编译、烧写过程,打开串口工具,可以看到发送的数据和接收数据一样;

- \& G5 F) U- B1 q$ W+ x
4 printf使用
如果要使用printf功能,需要定义如下函数,将串口重定向:
  1. 1/*& ]. m' r2 v  L+ @9 l. [
  2. 2 * Called by libc stdio fwrite functions
    6 J0 [2 ~9 h& s4 y9 ^' Z& ]) q
  3. 3 */
    . E( u5 H+ B1 q  _. t+ j
  4. 4int& a, c) m. s5 t, C$ X4 w
  5. 5_write(int fd, char *ptr, int len)
    1 |  ]# u- {% T8 d5 P1 x( L
  6. 6{: Z; g' n  W4 y% [7 F
  7. 7    int i = 0;/ \* r0 C( {3 t2 ]8 o
  8. 8# g* W1 D& g- `. E. }0 j6 `/ }
  9. 9    /*& `$ f8 l) E( ~) J! j
  10. 10     * Write "len" of char from "ptr" to file id "fd"# u* A" \6 V. \
  11. 11     * Return number of char written./ J+ j+ I$ q  }8 e4 B( |- Q- H
  12. 12     *! D9 J' K# @4 Q  w( B
  13. 13     * Only work for STDOUT, STDIN, and STDERR0 |4 D" ^. e6 G
  14. 14     */
    2 j( C3 k- r( ~
  15. 15    if (fd > 2) {
    & A0 R4 X2 i) u3 g
  16. 16        return -1;
    2 ^$ Y) k, I- Z3 z
  17. 17    }
    ( o3 Q2 y0 |: A+ z) d$ C8 Y- I+ @. W
  18. 18    while (*ptr && (i < len)) {
      }  X& M7 o. o) S( \  K* [
  19. 19        usart_send_blocking(USART1, *ptr);
    ' m& `% k) z3 B/ a% s
  20. 20        if (*ptr == '\n') {
    8 R2 ~* ^( p7 f0 J2 V
  21. 21            usart_send_blocking(USART1, '\r');
    % _4 k; M' G1 U2 v" t3 y
  22. 22        }
    % e0 U, L, ~- C
  23. 23        i++;
    4 R; w0 l, |- f+ }
  24. 24        ptr++;1 a4 W$ d+ y5 z; C+ g* N; g
  25. 25    }9 k: U( B+ l7 e% u$ D
  26. 26    return i;& W: ~$ S9 R# F1 `  Q4 ^! r5 D) e
  27. 27}
复制代码
  S. {  x7 D: B7 I9 Z8 C0 y4 r" ~
现在就可以直接使用printf函数进行打印显示到串口设备;
% B  z* l4 B! u' x: V
转载自:MakerInChina.cn

0 ~' u& i1 g7 Y- M, `
收藏 评论0 发布时间:2023-2-23 21:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版