|
STM32电机培训online,大佬带你玩电机 ! A' d' g3 ?7 D$ s D #include "stm32f10x.h" #include "stm32f10x_usart.h" #include "stm32f10x_dma.h"0 K( Z* y {; y uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};' `! G0 a% g& d1 G! j1 A0 H& @. B uint8_t USART2_DMA_TX_Buf[1024]; uint8_t Flag_USART2_DMA_TX_Finished = 1;4 ^6 U$ P& q' ^4 T5 }/ H0 v uint8_t Flag_USART2_Send = 0;2 @' V) A( }; A3 F& { /** * Function Name : USART2_Config4 ~/ i& F5 X5 w! ?& S" k: G) Q- u7 `6 Z * Description : None3 t0 o# S4 J7 @ * Input : None * Output : None * Return : None& W" N1 |7 E5 Y4 ~ O */! j4 Y; T! r/ Z. o% m+ n void USART2_Config(void) { GPIO_InitTypeDef GPIO_InitStructure;; |% z9 I8 D- x5 e3 w7 @+ @- t( d" W$ Z USART_InitTypeDef USART_InitStructure; DMA_InitTypeDef DMA_InitStructure;( h6 ~& Q) w) [5 ^; G8 K NVIC_InitTypeDef NVIC_InitStructure; /* config USART2 clock */) D. L" k! q* i; B. `9 Z4 B RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);1 S: T& R/ L/ V /* *********************USART2 GPIO config **********************/ /* Configure USART1 Tx (PA.02) as alternate function push-pull */) B0 T" i% z+ }/ w# I/ A GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; ) h# s5 Z' l8 G0 k- D- J GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); : {" ^* y( L, w$ U /* Configure USART2 Rx (PA.03) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;5 R; }- f2 \1 {/ a GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;' n9 a7 r6 t; B# V$ ?* x GPIO_Init(GPIOA, &GPIO_InitStructure); & x/ I5 E4 t% H% k9 M /* USART2 mode config 115200 8-N-1*/4 J# E/ G# ^* N; P8 j% j USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b;7 v3 B5 b, C. z$ }9 i) b& M2 u USART_InitStructure.USART_StopBits = USART_StopBits_1;% g, }) Y2 T, f3 K6 Y) Q USART_InitStructure.USART_Parity = USART_Parity_No ;7 p ~- M3 }! T8 W( ?3 R! [ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;' P M0 }9 I6 I& a USART_Init(USART2, &USART_InitStructure); : G/ w5 K3 t% G t0 _; ? USART_Cmd(USART2, ENABLE);" `3 o- L9 N! C( I, N8 k ; ]8 j! V/ {6 s0 O9 a$ P USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); /* Enable USART2 DMA TX request */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);1 K: a4 M; b/ ]6 Q* t V4 Y# ]3 y0 _) P! j# `' `5 W, G DMA_DeInit(DMA1_Channel7); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR);/ o( J/ [) F+ W1 I) P7 ` DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;$ ?1 A1 ?5 d4 T5 q1 r1 D DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = 0; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;+ x4 j' L! p2 O$ V8 k5 ? DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;" H( N1 }$ Z+ a3 n6 _ O DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;2 F/ e0 s- D* L DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel7, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE); 4 l& Y7 S5 k8 N+ w/ j% k- @ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* Enable USART2 DMA TX Finish Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;; s0 f& ]5 m" _" @, R NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;- d+ x2 p: Y7 U5 W* R. `: y NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;0 |# x$ Z% {+ k NVIC_Init(&NVIC_InitStructure);; p1 [- d- s5 t. }( f+ P /* Enable USART2 Interrupt */2 y: |: m+ J* E NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;* j& H6 a7 ?$ _% J7 S: o/ ^' f NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;/ n+ i' x$ W$ y# s6 X7 ]/ E5 K NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;/ W2 j4 {5 j G0 h$ k2 Z NVIC_Init(&NVIC_InitStructure); } /** * Function Name : USART2_Data_Load9 r) ]) E8 S- N: u9 L% ~) n3 r) G * Description : None9 A8 D' ~$ v9 k. v7 R/ y * Input : None * Output : None' P3 W) N9 s/ V" h0 l" o8 ]# y9 M * Return : None# h0 u; s, c& T @# `( Y, |* K */; ]) B, `8 n% v$ A void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){- U& d/ O) r* ] USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4]; USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F]; USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4];) e/ K6 ]8 e) ~; G5 t1 O USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F]; USART2_DMA_TX_Buf[4] = 0x20;: `- j' R+ p' Y) W: {" c USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];- ]2 e$ {4 |0 k! f* {: U6 t; m USART2_DMA_TX_Buf[6] = 0x0D;$ J5 H* `& m, r8 N% q USART2_DMA_TX_Buf[7] = 0x0A; Flag_USART2_Send = 1;. _7 h0 S% j/ [; c4 t }% ?7 v0 O. u/ r) u( J4 }0 u /** * Function Name : USART2_Data_Send- X' w- }0 x& e * Description : None * Input : None * Output : None, y; [! G# k; U2 f * Return : None( W- X# H; P+ l% k" R! M */, R: ~% e! U8 B/ ]* d' t- x' E void USART2_Data_Send(uint16_t len) { if(Flag_USART2_Send){ if(Flag_USART2_DMA_TX_Finished == 1){, n+ Y- `0 e* J% {7 n Flag_USART2_DMA_TX_Finished = 0;( [6 }, O- a& ~# B7 q2 }/ g DMA1_Channel7->CMAR = (uint32_t)&USART2_DMA_TX_Buf[0];4 d* v3 K$ k# |1 N; I DMA1_Channel7->CNDTR = 8; // len DMA_Cmd(DMA1_Channel7, ENABLE);1 \8 m! f" D9 t& @+ X- Y Flag_USART2_Send = 0; }6 [6 ^- B" c; E } }# ^2 C+ ^7 x: n9 d2 x /** * Function Name : USART2_IRQHandler * Description : This function handles USART2 global interrupt request.& y! P% B6 H- i+ D' [: K- B * Input : None$ B# m! h2 |& l; A3 \) C4 m: v * Output : None * Return : None; i g1 q% g6 p5 g+ @9 f */ void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {! U& B( l- u$ `! H5 f1 q (void)USART_ReceiveData(USART2);. i2 `2 P- |$ ~3 X! g3 i. K: s, y } if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) { /* Disable the USART2 Transmit Complete interrupt */) r1 k" u/ w* U) N' N+ g/ a# U USART_ITConfig(USART2, USART_IT_TC, DISABLE); Flag_USART2_DMA_TX_Finished = 1; } # r, H, L8 g g9 s# v( j /* If overrun condition occurs, clear the ORE flag a.nd recover communication */ 4 L0 b, l4 N3 q if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {! u9 K" y" u+ B# Y (void)USART_ReceiveData(USART2);8 P9 m( C) w' W3 w }0 }7 g8 n( \9 e* v, U% {5 S } /**& y* @ ^3 U9 B& K2 K U2 B) A * Function Name : DMA1_Channel7_IRQHandler! C& I6 b* t) O! Z+ A * Description : This function handles DMA1 Channel 7 interrupt request.4 Q6 ?/ e% l# _6 x * Input : None * Output : None6 O2 H8 l$ `% U u6 f * Return : None2 R0 Q2 h3 M" _ y- e* V; n- z' ?' D */ void DMA1_Channel7_IRQHandler(void)" q4 M/ A6 h Y8 y9 y { if(DMA_GetITStatus(DMA1_IT_TC7)) {, _) E; Q5 E! p /* USART2 DMA 传输完成 */( I! \' t$ l* z2 n1 v. x DMA_ClearITPendingBit(DMA1_IT_TC7);6 T G& _) U! [, m, U DMA_Cmd(DMA1_Channel7, DISABLE);) ?4 B2 {( J! V+ r- {0 g4 R /* Enable USART2 Transmit complete interrupt */; Z' Q9 o* J8 v- f$ ] USART_ITConfig(USART2, USART_IT_TC, ENABLE); }; r( f: X' J c4 N3 t! q5 P" ` }; K4 o' W2 }" R# V4 D% s |
DMA 原理从 0 到 1:为什么它能解放 CPU?一文讲透 DMA 的工作流程
【福利三:雨露均沾·逢7狂欢】之五:STM32系统时钟PLL故障排除1例
【福利三:雨露均沾·逢7狂欢】之三:AI帮我查BUG
福利三:雨露均沾·逢7狂欢】之二:STM32F407VG串口通信乱码故障的排除
基于STM32F103的I2C主从机通信
OpenBLT移植到STM32F103战舰开发板上适用于所有STM32F103系列的Bootloader
TFT LCD 与 FSMC 的硬件连接大容量 STM32F10xxx FSMC 接口
单片机:初学者该了解的STM32F103基础知识
2025软件工具兔哥知道
STM32之继电器模块
微信公众号
手机版
所谓STM32F103串口数据的DMA发送,其本质流程如下:
1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。
2. STM32串口DMA发送和DSP相比的优势。. t: j- X8 k5 x$ \( ?1 d, C
启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,0 }2 j1 J+ [9 l
自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。
和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过: h. v2 ]. r. ~8 g& L9 w- K! G: ~* G
FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。: B9 H# _4 Q6 ^- c6 T
而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。
3. 发送结束的一些事务处理5 U" U- W; h' H0 \1 ]1 K8 m, i
DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了" ?7 m, g# I/ w8 ?" `
DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,
此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,$ o& E# S* H& V
也可以操作GPIO, 进行RS485的换向动作。0 |, \5 S# I' z+ y) W
; V# ?( T7 @8 w+ j; `: s7 Z, ~4 \! g/ x
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够," @0 F2 n. i" g2 c# Z. \
但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,
又保证标准外设驱动库的灵活性。7 t% q' p/ P6 I6 a5 a$ P
7 v' e" c5 M B3 k- ^4 v) K