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

STM32G0-Platformio+libopencm3-串口中断

[复制链接]
STMCU小助手 发布时间:2023-2-23 21:00
使用Platformio平台的libopencm3开发框架来开发STM32G0,以下为串口中断的使用。
/ u9 Q7 C- a7 F: D
1 新建项目
  • 建立uart项目

    ( c* g$ \  K, `+ x
在PIO的Home页面新建项目,项目名称uart,选择开发板为上一次建立的自定义开发板型号 MonkeyPi_STM32_G070RB,开发框架选择libopencm3;
  • 项目建立完成后在src目录下新建main.c主程序文件;
  • 修改下载和调试方式,这里开发板使用的是DAPLink仿真器,因此修改platformio.ini文件如下:

    4 M, w# u. n# J5 m+ B
  1. 1upload_protocol = cmsis-dap( S7 O# C' c/ J9 n8 J
  2. 2debug_tool = cmsis-dap
复制代码

9 @9 b$ N* K1 E* H- R
( Y) \/ U- F4 ]% V2 编写程序
  • 时钟设置
    ) B$ j4 V/ a* S, T# [) z3 ~
  1. 1//system clock- ^3 j$ }, m4 S. Q
  2. 2rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);
    9 _7 P, T& C1 V0 ^) c: T1 T3 v* T
  3. 39 ^; \6 r, A* h" ]
  4. 4//uart pin
    / ^! F( t. S1 j9 k/ [3 O
  5. 5rcc_periph_clock_enable(RCC_USART1);
    1 i: x7 Z( f! M! ]& @6 e% o7 R% E' L
  6. 6rcc_periph_clock_enable(RCC_GPIOB);
复制代码
+ O. ^. {1 D2 Z9 W6 O8 X+ L0 I/ w
5 r. `1 E- n$ U. s, P+ |
先设置系统时钟为内部PLL生成64MHz,然后设置串口外设和串口引脚外设的时钟;
  • 引脚复用功能设置
    * c1 @% z+ W; \) s- G2 `( s
  1. 1gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);2 J5 \) R  @" S8 R5 n1 o2 n" n: M
  2. 2gpio_set_af(GPIOB,GPIO_AF0,GPIO6|GPIO7);
复制代码

2 r- x7 H8 W* I8 M+ o
2 n2 E4 {8 K  E0 D+ G- z( y8 \
根据芯片datasheet文档,使用USART1其引脚为PA9\PA10,复用功能AF1为串口功能;

9 \8 j6 ^$ x; ^% }$ W
  • 串口设置
    ' r# v, i( S  H$ t
  1. 1usart_set_baudrate(USART1,115200);. E) R6 q0 i: ]- S/ T" |# ?# x6 b
  2. 2usart_set_databits(USART1,8);- o) c3 _3 m% Y) C
  3. 3usart_set_stopbits(USART1,USART_STOPBITS_1);* l$ j0 ?5 C- s  e+ d! p9 L* d
  4. 4usart_set_parity(USART1,USART_PARITY_NONE);4 w% Q# [1 T0 v9 f: r: x- S
  5. 5usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);- a/ L0 g  g& L; F& L% F
  6. 6usart_set_mode(USART1,USART_MODE_TX_RX);* ^# Q* H. B" k8 H' I+ N* U
  7. 7
    1 s/ R# s/ @/ _4 G$ N' m2 d
  8. 8//uart isr. h6 L/ r2 B, k+ I) _1 V! N7 i
  9. 9nvic_enable_irq(NVIC_USART1_IRQ);
    ( \! |/ S- o9 Z& U: N  y& t
  10. 109 J* r6 G! v( M4 H
  11. 11usart_enable(USART1);
    $ i9 I; I* H4 X) z1 S2 L
  12. 12
    0 r7 c$ @1 a( B$ [
  13. 13usart_enable_rx_interrupt(USART1);
复制代码
. B1 P7 q8 z8 \, q" z5 @

9 I/ R. {) Z+ f% Z* h/ S- D! k
先设置串口波特率、数据位数、停止位、校验、流控等设置,再开启串口中断,使能串口和其接收中断;
* Q# T. K: c# I: u/ x
  • 串口发送

    2 O5 R7 g* _3 ~4 h  \
  1. 1char buff[32] = "hello, makerinchina.cn\n";
    9 w& H" }5 p& u& T& h, C- U
  2. 2for(int i=0; i<strlen(buff); i++){
    ( k$ Q( a9 f: [% p% y
  3. 3    usart_send_blocking(USART1, buff[i]);
    * x( K7 l! I4 u* w8 Z
  4. 4}
复制代码

& D) D1 n+ `/ h- [# ]5 p( ?2 f
! U$ u! n9 y* n% [
发送直接使用 usart_send_blocking 接口发送一个字节数据;
& Z6 j3 v& _  P2 K) P' D
  • 串口接收

    5 L# H+ T- Y2 D
  1. 1/**- \$ Z! _1 L* I: Y- I0 W
  2. 2 * @brief uart1 isr function0 U8 j" q3 h3 l2 [; Z2 n
  3. 3 * & m) D; F1 E* K7 y+ `: Y
  4. 4 */
    5 {7 X6 X+ ]6 n3 ~7 J1 s
  5. 5void usart1_isr(void)0 y5 D( Q5 A* C3 h& Z% \+ u
  6. 6{
    5 p5 \- O- |" L, }
  7. 7    //receive interrupt
    4 O9 l& k) I, r7 ~% b* E
  8. 8    if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
      v3 l" s5 K5 @( C
  9. 9        ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {
    ; H2 Y8 A% r! \0 p  B; n9 q& `
  10. 10
    1 h) x4 L& d4 ]  B3 m- b
  11. 11        if(recv_index < BUFF_SIZE){
    " v+ L) Y7 e* q: D( N" @/ `
  12. 12            recv_buff[recv_index++] = usart_recv(USART1);$ C* _4 A5 @5 P& v0 x- X
  13. 13        }else{- p* _0 {" G+ n% i% Y1 m- C- |6 x
  14. 14            recv_index = 0;& R9 r! a, k& \; l  |! k2 q* C
  15. 15        }5 H6 B$ o/ s& |
  16. 16    }
    1 f- z; V$ Z+ @4 O* V) C9 U
  17. 17}
复制代码

* H# g& L* A; a2 w( b% |# R4 w6 F' ^
串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来:
  1. 1#include <libopencm3/stm32/usart.h>/ u2 u9 B; b( a
  2. 2#include <libopencm3/stm32/rcc.h>
    " z6 p# A7 U& F; K) m) j
  3. 3#include <libopencm3/stm32/gpio.h>
    7 p2 M2 f  s! k/ x
  4. 4#include <libopencm3/cm3/nvic.h>; K3 w. B# I, [! I5 @% t
  5. 5
    3 e* T' w: C0 C; [& Q9 |# U
  6. 6#include <string.h>$ y3 T1 \5 Y: D+ F+ {
  7. 7
    9 z* V  S, x# h9 Y) g. e
  8. 8volatile uint8_t recv_index = 0;& r, N- C6 l# A( Q5 x
  9. 9volatile uint8_t send_index = 0;
    ' m1 e. J( D! }2 h0 q5 p- {& g  j
  10. 10' {$ }& B1 E  l5 C4 r' x( h) m
  11. 11#define BUFF_SIZE 64% A* V: \' V+ j
  12. 12uint8_t recv_buff[BUFF_SIZE] = {0};4 I% {2 B0 s% d
  13. 13
    $ G7 v& [. V  i* M& b& u* z: h4 v
  14. 14int main(void)  B- e6 n2 Z6 S( E+ y: A
  15. 15{
    ; T3 V5 V- D# c# q& X: \6 `
  16. 16    ...4 k& ]4 C" q  E0 E+ v" h
  17. 17
    # F) r9 T$ P, C, J
  18. 18    while (1)
    " v. \8 ^/ \' l  ]
  19. 19    {! b8 N, i2 t4 N
  20. 20
    $ E* V# E0 `: F- g! M- c
  21. 21        if(recv_index != send_index){
    7 S6 m% q$ Q& A( U, e
  22. 22" n( n& O3 d8 G' p# w
  23. 23            if(send_index < BUFF_SIZE){& L8 r5 ?3 i3 \; Q
  24. 24                usart_send_blocking(USART1, recv_buff[send_index++]);
    7 t: K  F" d" T) b) s% A, s4 m
  25. 25            }else{; `1 l8 l  _3 B! s
  26. 26                send_index = 0;
    ; U* l. m+ g; j6 O9 ~
  27. 27            }
    . Y1 ]1 {5 T! n  P) Y  d. |
  28. 28        }3 Z3 l5 e" a9 g' W& E, y
  29. 29  }, `) G& C* z9 n
  30. 30    }. m0 y6 w9 M; Z& W: S8 H
  31. 31}
复制代码
3 K$ j' `$ s& P; ^5 L9 X3 ~# }. q" Q4 P
3 烧写测试
点击 platformio:Upload按钮或快捷键 Ctrl+Alt+U即可完成编译、烧写过程,打开串口工具,可以看到发送的数据和接收数据一样;

* R, |# N% Y; l, B; ^+ e
4 printf使用
如果要使用printf功能,需要定义如下函数,将串口重定向:
  1. 1/*
    2 A( ~9 u3 x' M8 F! L% z& O8 n
  2. 2 * Called by libc stdio fwrite functions2 L2 U6 ~" l  x. z
  3. 3 */
    7 [" l/ F4 L" J9 u* t' T
  4. 4int
      Z. y# N+ E4 J( W/ Y. J
  5. 5_write(int fd, char *ptr, int len)
    * X$ }! e/ q* g/ g# ~: o
  6. 6{6 c$ D% F5 \6 q9 M& a& y
  7. 7    int i = 0;! W3 e: S! s. {0 V
  8. 8
    # [# }9 F4 G# _; {5 T. `7 T+ Z
  9. 9    /*
    * O& S/ R% ~$ D) m: p0 D
  10. 10     * Write "len" of char from "ptr" to file id "fd"% s  y' l+ l3 H5 l: y2 R' i9 H
  11. 11     * Return number of char written.
    $ ~5 N; L3 W+ A- s2 ^& X  V
  12. 12     *8 G4 n: l0 d! B( M9 _8 Y4 K5 b
  13. 13     * Only work for STDOUT, STDIN, and STDERR
    ) ~* ~0 t9 x  M* W
  14. 14     */
    , ?* \5 b' f8 I- K  i
  15. 15    if (fd > 2) {
    * k) ?; y0 R/ o! V- x1 K$ K- b
  16. 16        return -1;
    & U& C5 F$ \9 n9 b8 A" C0 H
  17. 17    }
      t/ {) a6 [2 Z( U8 C
  18. 18    while (*ptr && (i < len)) {! Y, s2 a2 o) I* N. m4 B5 g/ p0 I# e
  19. 19        usart_send_blocking(USART1, *ptr);
    9 c5 }6 I0 H/ f4 o3 g, s8 \
  20. 20        if (*ptr == '\n') {
    - N1 c6 u$ Z6 H# N) v
  21. 21            usart_send_blocking(USART1, '\r');( h" M  p' o) k
  22. 22        }
    ! O: l, p5 E/ x6 c* X7 [% E
  23. 23        i++;
    & G; k: ~$ D) p& @
  24. 24        ptr++;
    0 F* p0 a% b% Z! H3 {& V, [# d
  25. 25    }
    ; U; E3 V3 Q& `  N6 u3 Y1 V
  26. 26    return i;1 @# h: a$ P! J- n7 P. j
  27. 27}
复制代码
( n$ I3 \' f2 u3 T
现在就可以直接使用printf函数进行打印显示到串口设备;
, b" r- A# q9 A! V8 l6 ]3 S1 Y
转载自:MakerInChina.cn

+ k" Y5 y' \' _) \) c
赞 收藏 评论0 发布时间:2023-2-23 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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