使用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; - 1upload_protocol = cmsis-dap
* @: i# [3 u$ g9 H! O; Y - 2debug_tool = cmsis-dap
复制代码
% z$ }6 u4 A* f
5 v( k9 l# V" a8 `. e2 编写程序- 1//system clock
0 O. G3 N# J: _# z$ n8 @ - 2rcc_clock_setup(&rcc_clock_config[RCC_CLOCK_CONFIG_HSI_PLL_64MHZ]);8 H* e. f7 s* Z4 }
- 3" ~, o9 J7 @% i! A) t
- 4//uart pin
' ~0 z. u+ t, @1 P( Q+ C - 5rcc_periph_clock_enable(RCC_USART1);" R+ k3 K3 J+ q3 x1 {) L, u
- 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
- 1gpio_mode_setup(GPIOB,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO6|GPIO7);# h2 f$ Z6 q) f9 E, V
- 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
- 1usart_set_baudrate(USART1,115200);9 E4 x) ~# j) Q
- 2usart_set_databits(USART1,8);: F' w4 G6 N" J# `* T
- 3usart_set_stopbits(USART1,USART_STOPBITS_1);7 c! x) B+ T! j1 ]* l- J ^# L
- 4usart_set_parity(USART1,USART_PARITY_NONE);
( U) S+ n/ _! `9 E8 t! e# D - 5usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);
/ Q2 d. L9 {/ N6 r- v J5 O - 6usart_set_mode(USART1,USART_MODE_TX_RX);; u5 _# v- [6 s1 v9 P) `3 T
- 7; H5 r- w w/ M. y
- 8//uart isr n- M; N) [7 Q
- 9nvic_enable_irq(NVIC_USART1_IRQ);
\; G1 `8 Z. Y0 v5 A6 Q - 10
- O. O, M9 M+ u - 11usart_enable(USART1);
6 l2 p8 Q( W; i8 E" d# n - 12
# F+ C7 I" d2 z- x% H3 z - 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
- 1char buff[32] = "hello, makerinchina.cn\n";
! Z. w7 c4 U3 Y% T - 2for(int i=0; i<strlen(buff); i++){2 v& P3 ]5 z2 ?7 E {7 N
- 3 usart_send_blocking(USART1, buff[i]);# `/ g7 c( j* \% I
- 4}
复制代码
. o% f6 y% Y! ^) V. e8 ^3 h$ O }) a! U
发送直接使用 usart_send_blocking 接口发送一个字节数据;
& v) F* l& E7 t
- 1/**6 { J) b! p. }
- 2 * @brief uart1 isr function
, }- g; T9 G4 F! p - 3 *
. E! v! ~ w7 t+ |3 x! t, b - 4 */4 {9 ~1 k( H1 r2 Z
- 5void usart1_isr(void)
# M( d* w2 q0 {) K$ x1 y - 6{% c; j! ^" X6 U* `
- 7 //receive interrupt
3 |% Z1 ?: O& m- N2 ]. d9 A3 S - 8 if (((USART_CR1(USART1) & USART_CR1_RXNEIE) != 0) &&
2 d' E: P: C1 P" f0 P2 I! ~9 ~0 z - 9 ((USART_ISR(USART1) & USART_ISR_RXNE) != 0)) {
0 H. v3 ?/ r- Z6 Y; A! ?6 { - 10: I5 |: N2 w% q" I1 g% @- A" L8 n
- 11 if(recv_index < BUFF_SIZE){% T; z' R7 g: O- w
- 12 recv_buff[recv_index++] = usart_recv(USART1);- P4 `1 g8 N( b! o' p# I) o f
- 13 }else{
2 a) h9 f; _# s4 S - 14 recv_index = 0;
; X+ _5 m* e; m - 15 }: R2 ]- s r. ^) j
- 16 }" l0 E2 E4 l* v
- 17}
复制代码 5 Y) G% G- w. j
" U3 V4 \4 ]" j, h8 \& C串口接收使用中断方式,接收到数据后将其存放的buff中,然后主程序中取出打印显示出来: - 1#include <libopencm3/stm32/usart.h>0 ?% j. j9 E3 a7 Y0 z) J
- 2#include <libopencm3/stm32/rcc.h>2 j K) H* i* e2 {# V3 G% n
- 3#include <libopencm3/stm32/gpio.h>
4 h5 |" M& {/ q/ v6 B) R. r* E/ ? - 4#include <libopencm3/cm3/nvic.h>
+ u: q, z- {' V5 m: Z% u2 \. n - 53 `/ o+ o9 O, E9 Q z# e$ B
- 6#include <string.h>1 i( |5 O; I+ D ^% |
- 7
i, {: J( @3 @/ q - 8volatile uint8_t recv_index = 0;' k$ O' F/ K" k4 N4 X$ x
- 9volatile uint8_t send_index = 0;
2 r8 q% C! b9 c5 n) ^3 s% g3 T/ w - 10- Q0 a+ B& w: _9 u' i
- 11#define BUFF_SIZE 646 d" n8 t: s+ r3 q
- 12uint8_t recv_buff[BUFF_SIZE] = {0};1 F/ |) {) f- T' [/ d+ w v
- 13
+ s2 C/ s: O. r# x+ d* F - 14int main(void)& G$ X" c/ o8 m' P. P9 q+ I
- 15{
) V1 i3 q- c+ ?) {1 R" b2 D( I7 E - 16 ...
4 A. _. p, r" ? - 17 `$ T( G7 x" q& I
- 18 while (1)
; [- D- u: n6 H. A. Q- T: |) ] - 19 {8 `9 c3 z' C( Z) F8 Q1 _0 i
- 20) u Z0 H- |3 [; f% i
- 21 if(recv_index != send_index){ # H, a; l# @" c6 P0 U5 z
- 22
% k! u- J. w5 u4 l - 23 if(send_index < BUFF_SIZE){
( E% [1 |: R' X& q) x - 24 usart_send_blocking(USART1, recv_buff[send_index++]);
9 a* S1 s! j1 G- b - 25 }else{
# \9 t- K8 o: B8 F+ p - 26 send_index = 0;
& r( p% U( }. h1 U) D - 27 }
; |) I. p7 |$ e$ V6 R: q! n; _ - 28 }& w3 g6 S$ w q2 m+ n$ F; C
- 29
- P, ^, t8 V. O7 e! f" _6 O - 30 }
1 V$ X; u0 s- h, t* R$ X4 k - 31}
复制代码
9 s( Z9 s9 i" E3 烧写测试点击 platformio:Upload按钮或快捷键 Ctrl+Alt+U即可完成编译、烧写过程,打开串口工具,可以看到发送的数据和接收数据一样; ; q; E. p- x- w. `- D
4 printf使用如果要使用printf功能,需要定义如下函数,将串口重定向: - 1/*
9 Q5 K0 F( ?' r3 j) h* |5 W - 2 * Called by libc stdio fwrite functions* d0 s3 h4 P5 ?0 e+ ?
- 3 */
2 v# K3 n9 p2 U0 ^, U: X+ P' T - 4int. a3 H( }! |- f; A! J6 w
- 5_write(int fd, char *ptr, int len)3 F# J) {5 v7 ~" R) ^$ z
- 6{
) ~* W- v9 Q$ ~/ V1 O - 7 int i = 0;
x4 r6 E0 g& i! S1 P) S; R; c. I - 8
A7 }8 u- k; k$ ~ - 9 /*, y$ q$ E( m4 \5 I
- 10 * Write "len" of char from "ptr" to file id "fd"6 U5 d( Q! w! l. S7 B5 c
- 11 * Return number of char written.* u# j, \! Y- D" t) Q/ @2 ~
- 12 *
1 W3 ?4 p, H2 P' \* Y - 13 * Only work for STDOUT, STDIN, and STDERR
- F$ K) U( P$ Q - 14 */
# \6 Q, h, u( x - 15 if (fd > 2) {
) [( k- u, G! e+ k) a5 E; D% O3 z$ f - 16 return -1;
7 g' y( o4 g+ j! w - 17 }1 j: ^. O& j+ i% e' Q
- 18 while (*ptr && (i < len)) {
( j# _- p+ z' n. }& p - 19 usart_send_blocking(USART1, *ptr);: q0 ^! A( _2 P4 _
- 20 if (*ptr == '\n') {
# F+ {7 G5 J7 k! n) d! t7 E$ e - 21 usart_send_blocking(USART1, '\r');5 i2 Q% Q: p+ j5 ] f. L) T
- 22 }- ]8 I: G/ L' r* `
- 23 i++;; W0 O2 X% r* i% e5 v
- 24 ptr++;" Q$ L5 t0 H1 v3 F
- 25 }
9 u2 y/ I2 D. O$ p" A } - 26 return i;
+ }1 K9 u2 f3 K - 27}
复制代码
G! ]% N, Q+ z4 B: l$ h' a现在就可以直接使用printf函数进行打印显示到串口设备;
; F! u3 b) ? l$ {% T% f
转载自:MakerInChina.cn
}2 D6 M2 D! w# ^. ?1 `, {( { |