|
STM32电机培训online,大佬带你玩电机 ! d& s; Y R n o$ s ' c% Y2 |8 }' n" l #include "stm32f10x.h" #include "stm32f10x_usart.h" #include "stm32f10x_dma.h"* [+ F, I' X S6 m- e' A 2 h$ s* `4 Z+ M# b7 z7 J uint8_t HEX_CODE[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; uint8_t USART2_DMA_TX_Buf[1024]; uint8_t Flag_USART2_DMA_TX_Finished = 1;! L" X& N5 f, t7 g uint8_t Flag_USART2_Send = 0;/ o! f, A. R* O /** * Function Name : USART2_Config * Description : None9 K' ?: k- T C! R * Input : None * Output : None * Return : None */ void USART2_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure;2 H$ s# |* w C$ D* c( M DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; ) K% |; Y x* T4 \9 r /* config USART2 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);; z! }& Z& N" G! J /* *********************USART2 GPIO config **********************/+ {- m% l2 D/ X& f- q" w /* Configure USART1 Tx (PA.02) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ; v0 `+ q9 X, a3 P5 L" \ /* Configure USART2 Rx (PA.03) as input floating */" p* O% U8 v% B# I GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;) j3 h0 T; J- t6 n GPIO_Init(GPIOA, &GPIO_InitStructure); /* USART2 mode config 115200 8-N-1*/ USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1;5 |1 h# E% o# `; I5 E3 |' i5 U USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure); ' \* k3 g1 h7 I: i+ f7 P& j USART_Cmd(USART2, ENABLE); USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);1 n3 S w4 c$ t8 ^; k8 _: R9 ^ /* Enable USART2 DMA TX request */# j# l% W* R0 q" c RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);* G9 @4 x* C. n% ?' D/ U9 v9 [ G DMA_DeInit(DMA1_Channel7);- N- {) _6 w9 F DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;6 t k) [5 A) ?/ {: l DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;/ |2 e- o8 @+ h1 D3 I DMA_InitStructure.DMA_BufferSize = 0;' K- R9 p2 G& R! o0 h DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;, |* `8 W. l! G6 x! I DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;0 \# Y- p6 s( [$ W5 S! M DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;7 ~# H1 v. s! F" @0 ? F# U% [. U/ c DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel7, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);; o6 f2 d7 {. {1 f / D* R `3 w \3 U2 \$ r& w NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);0 b+ Y0 l: k/ H5 d& N' I0 S7 e /* Enable USART2 DMA TX Finish Interrupt */6 ]' y* D; F( Y7 J& _; j6 e NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;0 m% h! C. p3 s- D NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);" r' S2 J; G) K9 \ * `0 k7 a; O8 r' Q1 b /* Enable USART2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;8 a& t2 e$ t0 C& `9 a NVIC_Init(&NVIC_InitStructure);' ?: u, g' |" J3 }! P } /** * Function Name : USART2_Data_Load: g8 ^7 N6 P3 P0 T0 }+ \* ~ * Description : None * Input : None * Output : None3 D" Q) y, x$ _5 J/ J5 Q * Return : None) O. M% z. u9 q. g. `) i( l* | C0 ~6 j */. l f! F, }7 L" N- y7 |5 `- h7 s void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){ USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4];: E5 M2 ~8 @; \* T! n r+ ] USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F]; USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4]; USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F]; USART2_DMA_TX_Buf[4] = 0x20; USART2_DMA_TX_Buf[5] = HEX_CODE[temp3]; USART2_DMA_TX_Buf[6] = 0x0D; USART2_DMA_TX_Buf[7] = 0x0A; Flag_USART2_Send = 1;8 \" h4 G9 U6 r1 Q. d. ^ }/ q8 r- M0 U: @ N" L% G /**2 ~% W- ~4 D8 @/ P4 Q( Q9 D * Function Name : USART2_Data_Send6 Q% z5 _6 L/ a7 v- s! t * Description : None; Z6 N% Y9 o5 |& d * Input : None * Output : None& D- f7 o D9 _; ~. v * Return : None */ void USART2_Data_Send(uint16_t len) {: X' ?8 E9 M: v* N; H% Y6 N if(Flag_USART2_Send){ if(Flag_USART2_DMA_TX_Finished == 1){ Flag_USART2_DMA_TX_Finished = 0; DMA1_Channel7->CMAR = (uint32_t)&USART2_DMA_TX_Buf[0];! d7 I# B2 e% _* N' U, ^4 p( v DMA1_Channel7->CNDTR = 8; // len9 w, ~3 Y7 a2 Y DMA_Cmd(DMA1_Channel7, ENABLE); Flag_USART2_Send = 0;1 Z5 o+ O7 z0 e- ^$ y- w }* T* }$ K' R$ H! a& c }1 P" c5 _9 f* V+ m: P" Y8 I } a* i$ F8 G. a3 Q3 D /** * Function Name : USART2_IRQHandler * Description : This function handles USART2 global interrupt request.* o6 L/ N% K; [% I) O * Input : None& {- y: A; B3 v * Output : None7 I5 k6 f: B! m * Return : None */: b+ G* S* F; t) x& y void USART2_IRQHandler(void) {* [" y" j1 _3 w7 a/ o4 { if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) {1 {: v# `! M! j% h+ p (void)USART_ReceiveData(USART2); }2 \( ]. |- R& Q+ f if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) { /* Disable the USART2 Transmit Complete interrupt */- m7 K+ y$ A9 |5 R# o5 G USART_ITConfig(USART2, USART_IT_TC, DISABLE);1 D' r, L2 i" u; I1 Q1 j+ | Flag_USART2_DMA_TX_Finished = 1;# `) I3 \1 I) b1 j$ ?& V" W } /* If overrun condition occurs, clear the ORE flag a.nd recover communication */ if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {. q; C5 u# T9 Q+ p (void)USART_ReceiveData(USART2);0 Y1 U- e: U. L* r } }; n& H) T* G3 a /** * Function Name : DMA1_Channel7_IRQHandler) G" W! y, p0 A$ w. @ * Description : This function handles DMA1 Channel 7 interrupt request. * Input : None * Output : None * Return : None */ void DMA1_Channel7_IRQHandler(void) {/ h8 A! C5 H$ g! R$ F+ J if(DMA_GetITStatus(DMA1_IT_TC7)) { /* USART2 DMA 传输完成 */# x3 c& m. ^3 ?' K* m9 s. Z2 h DMA_ClearITPendingBit(DMA1_IT_TC7); DMA_Cmd(DMA1_Channel7, DISABLE);+ q: t" j) g3 `4 V% Y& b# { /* Enable USART2 Transmit complete interrupt */! x4 ?2 o8 U9 t- f% U! s3 r. ? USART_ITConfig(USART2, USART_IT_TC, ENABLE); }0 Y( M2 s# I3 i7 M; m& J } |
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缓冲。# k; W) ~0 g G1 D! S3 b0 F
2. STM32串口DMA发送和DSP相比的优势。
启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,
自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。
和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过
FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。6 {9 y' q/ J/ B" X
而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,
则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至 ]4 O- @6 b2 G
第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。
3. 发送结束的一些事务处理
DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了: c n# S& y4 @8 Q6 R( ~
DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,; K9 Q9 h+ ^1 ^3 h
此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,) U6 @0 Q- A4 V7 t5 C
也可以操作GPIO, 进行RS485的换向动作。0 I5 I$ s" Y; u- V$ _) S! h
9 F, `% O" c4 q8 {% ~, u
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,1 v$ S% |" Y- y) u7 j0 ?
又保证标准外设驱动库的灵活性。1 @+ c$ N+ K! Z' L( C. {
6 U# V: {# K, J, o
0 {; R5 A1 {8 |9 P