使用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; - 1upload_protocol = cmsis-dap9 l2 Y7 L3 x+ G0 \+ y
- 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//system clock
% Z7 J! p c+ }2 }# i8 p! \" r - 2rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);' d( Y: J- W/ } R! i+ V
- 3& z' C, V4 b% p& f$ w$ M
- 4//uart pin
) v* w& G7 ]0 u j - 5rcc_periph_clock_enable(RCC_USART1);
, r; Y- c1 Z8 Y4 V: G - 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
- 1gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);
; C7 u: Z2 p9 N; P, Q- V - 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
- 1usart_set_baudrate(USART1,115200);
1 Y" _' g) l- l5 J# I; a - 2usart_set_databits(USART1,8);
: d) Y+ \& `* r0 o. u2 m7 C$ }! l - 3usart_set_stopbits(USART1,USART_STOPBITS_1);- n; M( X/ I3 l7 ], W3 S
- 4usart_set_parity(USART1,USART_PARITY_NONE);' Y* O% N! g- k# y9 q: ?
- 5usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);" _4 q. C3 z4 ?/ _, O+ ^2 A9 [
- 6usart_set_mode(USART1,USART_MODE_TX_RX);' F* \7 z( }8 O$ o9 g [! m7 m. v( l' u
- 7$ `! x, Q0 J" W- n* A: p; x! _4 [
- 8//uart isr
, ~1 V [* P" B1 M6 p9 W - 9nvic_enable_irq(NVIC_USART1_IRQ);
' V' e5 e* I; O- Z& ~$ c7 M8 ^ - 10
; [' L/ W$ z" W$ O) h" x9 Y( | - 11usart_enable(USART1);% h1 w6 F! P! Y
- 12+ N1 v5 y' g# `/ g# K
- 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
- 1char buff[32] = "hello, makerinchina.cn\n";
2 `9 W7 S: V7 T, y - 2for(int i=0; i<strlen(buff); i++){
; h4 O6 k. Q- W v! r3 P" r$ J - 3 usart_send_blocking(USART1, buff[i]);
* C" o: n+ D# D3 q& M3 R - 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/**
; j# O- w* g, V! i - 2 * @brief uart1 isr function7 r5 o0 Z- u3 y9 l9 N) Z
- 3 * 1 w+ G3 k) W% @& g
- 4 */6 v: I+ U, |8 u8 p2 r; [" Z
- 5void usart1_isr(void)6 O: U3 c8 o- V$ q5 O8 p9 Q
- 6{
$ u$ v" N6 y' f - 7 //receive interrupt' `2 T, f' ^6 K w9 P) T" O4 I
- 8 if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&; z3 b |: R3 {7 l* W; G( t1 `
- 9 ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {' u: s G6 `' {5 m: R
- 10
, d, K. A/ d, C, R- t/ |) c - 11 if(recv_index < BUFF_SIZE){5 s0 m. r/ X; B% e8 x4 h- S6 @
- 12 recv_buff[recv_index++] = usart_recv(USART1);* N, ^9 X' l& J) I2 J
- 13 }else{4 e7 i" O) i* ?4 ]" ~
- 14 recv_index = 0;0 @- H: } `+ ^$ L7 b& P1 ?( L+ Q
- 15 }
% @( J! R7 M2 i# X$ p1 j& t - 16 }
O2 y0 W- D% k1 Q - 17}
复制代码
2 N8 q; T5 s5 q& Q' N4 A
c# b' d- f" ]: A' |串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来: - 1#include <libopencm3/stm32/usart.h>
2 p, G4 j. u: t# y - 2#include <libopencm3/stm32/rcc.h>9 p: d( [4 B, H, L$ M& O
- 3#include <libopencm3/stm32/gpio.h>) t/ E3 y3 F: `1 ~
- 4#include <libopencm3/cm3/nvic.h>
_2 ]* |1 P& J6 s! F6 W3 b% i - 5
) u1 I: C) e2 x0 m: e - 6#include <string.h>2 ~. Z% N) U3 C
- 7
' j: a! G; M( `( W* k% n - 8volatile uint8_t recv_index = 0;
, y- \( b7 i) q, v4 D4 E - 9volatile uint8_t send_index = 0;
# O1 h' ?/ q2 f# U/ P9 k' r - 10
7 K" \! i2 {" L- G3 R! [6 X - 11#define BUFF_SIZE 64
; Z* W8 q- X. l - 12uint8_t recv_buff[BUFF_SIZE] = {0};
1 o' m* l: }! c3 v - 13
% t7 c6 H% Q2 r1 V - 14int main(void)
$ K) M$ a0 r) a4 x, L; ?8 N: r - 15{
: {7 N4 s8 C% a8 U, Q$ k - 16 ...5 C/ V! z. U7 `$ t: _( I5 \* h' b9 s
- 171 w% U) a6 y2 z# a9 L6 Y. I: t
- 18 while (1)
" Y! h Q5 D. L+ Z! g, F - 19 {
& }8 f& K0 J# F- K! o - 20
9 d0 u: `2 P2 ?: a% h3 C" O - 21 if(recv_index != send_index){
7 Q; s3 d7 M1 i" x5 _1 `2 ?% R2 Z - 226 p5 ^# w3 u' t; G0 z$ y% v
- 23 if(send_index < BUFF_SIZE){
9 K! ?4 p" z# y7 ] - 24 usart_send_blocking(USART1, recv_buff[send_index++]);0 E! z. u V; N" x# U
- 25 }else{
5 H: f5 X+ f; Y" i) H1 } - 26 send_index = 0;
/ U* Z2 H6 S( J; z; x- M - 27 }
( O" R7 U s* D( Z& j$ s3 G$ S - 28 }( G0 H( M* B# o% L; I2 W" c& V. u
- 29
# V6 [& l* _ S) S) U) R {5 D' \ - 30 }
2 e2 d9 T, @" F) h1 U* s8 Z3 G) [ - 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/*& ]. m' r2 v L+ @9 l. [
- 2 * Called by libc stdio fwrite functions
6 J0 [2 ~9 h& s4 y9 ^' Z& ]) q - 3 */
. E( u5 H+ B1 q _. t+ j - 4int& a, c) m. s5 t, C$ X4 w
- 5_write(int fd, char *ptr, int len)
1 | ]# u- {% T8 d5 P1 x( L - 6{: Z; g' n W4 y% [7 F
- 7 int i = 0;/ \* r0 C( {3 t2 ]8 o
- 8# g* W1 D& g- `. E. }0 j6 `/ }
- 9 /*& `$ f8 l) E( ~) J! j
- 10 * Write "len" of char from "ptr" to file id "fd"# u* A" \6 V. \
- 11 * Return number of char written./ J+ j+ I$ q }8 e4 B( |- Q- H
- 12 *! D9 J' K# @4 Q w( B
- 13 * Only work for STDOUT, STDIN, and STDERR0 |4 D" ^. e6 G
- 14 */
2 j( C3 k- r( ~ - 15 if (fd > 2) {
& A0 R4 X2 i) u3 g - 16 return -1;
2 ^$ Y) k, I- Z3 z - 17 }
( o3 Q2 y0 |: A+ z) d$ C8 Y- I+ @. W - 18 while (*ptr && (i < len)) {
} X& M7 o. o) S( \ K* [ - 19 usart_send_blocking(USART1, *ptr);
' m& `% k) z3 B/ a% s - 20 if (*ptr == '\n') {
8 R2 ~* ^( p7 f0 J2 V - 21 usart_send_blocking(USART1, '\r');
% _4 k; M' G1 U2 v" t3 y - 22 }
% e0 U, L, ~- C - 23 i++;
4 R; w0 l, |- f+ } - 24 ptr++;1 a4 W$ d+ y5 z; C+ g* N; g
- 25 }9 k: U( B+ l7 e% u$ D
- 26 return i;& W: ~$ S9 R# F1 ` Q4 ^! r5 D) e
- 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, ` |