|
STM32电机培训online,大佬带你玩电机 #include "stm32f10x.h" #include "stm32f10x_usart.h" #include "stm32f10x_dma.h"5 z0 ^! s( L1 o7 f6 \9 K) m5 ?9 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];1 w4 _0 |- _, u6 [% O3 ?4 S* a uint8_t Flag_USART2_DMA_TX_Finished = 1;. N1 |( A) s: O6 H uint8_t Flag_USART2_Send = 0; /**& S) r% q" q- R) O9 { * Function Name : USART2_Config * Description : None * Input : None4 f) W' N( [; c, T# h/ a * Output : None * Return : None, m% _5 R9 I8 D' n' D. F */ void USART2_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; DMA_InitTypeDef DMA_InitStructure;, L4 P! S9 B) a) m! {' B6 @$ j NVIC_InitTypeDef NVIC_InitStructure; & J$ x! k1 u( b4 A /* config USART2 clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);# ~2 a" m+ j5 I7 D* i3 D RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);& q0 R% M; |: C+ [/ T $ ~% G' K" y5 f* ]4 x /* *********************USART2 GPIO config **********************/. x- T3 t/ @' l8 ~ /* 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); 7 ]) @8 b+ v4 x6 \: B$ ` /* Configure USART2 Rx (PA.03) as input floating */( @% ], d' f4 H/ U7 ? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;2 W! L& m' a: d7 } GPIO_Init(GPIOA, &GPIO_InitStructure); ! L8 j6 ^. S7 t/ i4 i# A /* USART2 mode config 115200 8-N-1*/9 {0 [% U8 {% h USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b;. V$ }1 y5 C; |# I( ]5 X/ } USART_InitStructure.USART_StopBits = USART_StopBits_1;* N# Z5 S' J9 h: a USART_InitStructure.USART_Parity = USART_Parity_No ;! s7 v7 v- Z' | Y9 r6 X USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;' S1 E/ C. \" Q" p6 b USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure); USART_Cmd(USART2, ENABLE);% R; Y) `3 ?( [0 G: y- a3 ~9 u ' j" d6 Y9 u5 s. R USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE); /* Enable USART2 DMA TX request */% a0 {6 K, Z; G' ^; d RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);& E( b9 _5 Y9 q h/ Z$ W6 @2 e DMA_DeInit(DMA1_Channel7); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DR); DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_DMA_TX_Buf;& O6 _" ~4 A3 J* X$ V% r4 `3 D DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;3 d* y' v& M$ ~! N 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; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;+ y0 K( W" s' @1 G6 n. r8 P DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;2 i/ i0 N6 [; k DMA_Init(DMA1_Channel7, &DMA_InitStructure); DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE); 8 n( S# A/ h( I2 P NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);1 P% C7 m. ~: {2 z: y /* Enable USART2 DMA TX Finish Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;- ~: e5 }; S% p( M; o NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;. [% n; h# t* H2 a+ h NVIC_Init(&NVIC_InitStructure); S+ I; ]2 r/ ^$ I( |# _& _% E /* Enable USART2 Interrupt */7 o4 q. K) e+ d% S NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;0 x$ a7 \" {; F {! b+ H2 F NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStructure);& B, P: j' Y# M$ R }; j; Z3 I' `! B9 ^% | /**% [3 E1 q& d7 t% Q1 |# ]: Z3 R * Function Name : USART2_Data_Load * Description : None* g' k; s# |, t * Input : None * Output : None * Return : None */ void USART2_Data_Load(uint16_t temp1, uint16_t temp2, uint8_t temp3){ USART2_DMA_TX_Buf[0] = HEX_CODE[temp1 >> 4]; USART2_DMA_TX_Buf[1] = HEX_CODE[temp1 & 0x0F];! r/ n" p" |* d2 ^" ? USART2_DMA_TX_Buf[2] = HEX_CODE[temp2 >> 4]; USART2_DMA_TX_Buf[3] = HEX_CODE[temp2 & 0x0F]; y# G, R4 {* {# P. l+ y. K. o USART2_DMA_TX_Buf[4] = 0x20;1 u+ |% v3 }7 g: ]4 S USART2_DMA_TX_Buf[5] = HEX_CODE[temp3];8 B5 B5 ]' v+ H6 v# W! l @ USART2_DMA_TX_Buf[6] = 0x0D;7 u) M2 d4 K1 i; o2 s9 F5 D* V USART2_DMA_TX_Buf[7] = 0x0A; Flag_USART2_Send = 1;' ~, p0 X" _; U3 Y1 [4 L } /**- a' t9 Q& [4 k9 k/ P1 D- s2 ?) M * Function Name : USART2_Data_Send! h0 U5 ]% S2 R- } * Description : None& T" g. u; I- E! f3 |8 K5 O- ?) K0 F$ z% | * Input : None * Output : None6 z9 J; L1 m) Z$ X) O' B: b * Return : None8 K7 [' P$ t9 j4 k# \8 g */ void USART2_Data_Send(uint16_t len) { if(Flag_USART2_Send){ if(Flag_USART2_DMA_TX_Finished == 1){) K% |1 n# D0 o( C3 |* f Flag_USART2_DMA_TX_Finished = 0;9 w2 @9 b5 O3 V" T+ M# { DMA1_Channel7->CMAR = (uint32_t)&USART2_DMA_TX_Buf[0];* [' z3 c% E2 @ DMA1_Channel7->CNDTR = 8; // len! f( G2 O- T2 u b* P- z/ b DMA_Cmd(DMA1_Channel7, ENABLE);/ @9 E: G& V, ]7 o4 L0 K: p Flag_USART2_Send = 0; } }% M& h; l. [- U/ U: T } /** Y5 {$ g) h! g1 h1 v7 W * Function Name : USART2_IRQHandler) A0 I5 M7 I' T! |( P4 L * Description : This function handles USART2 global interrupt request. * Input : None I3 H3 \/ k3 W7 O * Output : None * Return : None8 i! t( Q* b( A& t$ D" E */ void USART2_IRQHandler(void) {' b0 y( Y* \' v. K if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET) { (void)USART_ReceiveData(USART2);8 \( h6 }8 `0 t; K" a( P }, i: Y5 u# U! y# w if (USART_GetITStatus(USART2, USART_IT_TC) != RESET) { /* Disable the USART2 Transmit Complete interrupt *// i8 _$ }6 f+ _- I" Z+ b) s USART_ITConfig(USART2, USART_IT_TC, DISABLE); Flag_USART2_DMA_TX_Finished = 1;8 Z! h" @- z' {& T. E } /* If overrun condition occurs, clear the ORE flag a.nd recover communication */ 7 o" K3 a6 S& @) S! E# z if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) != RESET) {( |% o- W' U: u; ^" t- V3 z (void)USART_ReceiveData(USART2); }4 Q `# V5 ]5 j5 {+ q. F6 L5 y i t } /**' I% Z0 @4 t# z& ]. e * Function Name : DMA1_Channel7_IRQHandler * Description : This function handles DMA1 Channel 7 interrupt request. * Input : None( I. c1 ~. p3 A& p# l: ^6 _1 W * Output : None4 J2 \. a3 I1 T/ [& \/ }$ i! U0 n * Return : None( n+ R! B' w: x* A */2 {9 ~/ Q5 I/ k, d \$ G void DMA1_Channel7_IRQHandler(void)) o2 W/ F9 D' U: r& C Q { if(DMA_GetITStatus(DMA1_IT_TC7)) { /* USART2 DMA 传输完成 */ DMA_ClearITPendingBit(DMA1_IT_TC7); DMA_Cmd(DMA1_Channel7, DISABLE); /* Enable USART2 Transmit complete interrupt */ USART_ITConfig(USART2, USART_IT_TC, ENABLE); , L( v, p# Q7 w* w" f }9 u& U: h2 q; a: n* t7 f }; } R& o* C/ H `) v ) T" _. s5 u% O @ |
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之继电器模块
微信公众号
手机版
! m* r4 L# N$ v, H0 c
所谓STM32F103串口数据的DMA发送,其本质流程如下:
1. 要发送的数据放在USART2_DMA_TX_Buf缓冲。
2. STM32串口DMA发送和DSP相比的优势。 n% t9 p5 ~* \
启动DMA传输后,USART2_DMA_TX_Buf缓冲中的数据通过DMA1_Channel7通道,
自动传输到USART2->DR寄存器,这个工作不需要CPU干预,可以极大的节省CPU的资源。
和DSP的FIFO相比,这优势很大,因为DSP的FIFO只有16字节,这意味着DSP的串口通过
FIFO发送数据时,如果FIFO缓冲为空,可以迅速填入16个字节,然后去处理其它的事务。
而STM32的DMA发送则没有此种限制。更具体的说,如果DSP发送的数据超过16字节,( ^. Z1 ]6 [4 c! |) e6 Z
则必须等待前16个字节数据发送完毕,然后再继续发送后续的数据,需要第二次甚至
第N次处理。而STM32启动一次DMA就搞定(DMA最大传输65535个数据)。$ b# I+ n" N2 u
3. 发送结束的一些事务处理
DMA传输完毕,数据全部通过DMA1_Channel7通道依次传入USART2-DR,这里开启了7 l7 f3 E2 A2 R1 G G
DMA传输完毕中断,进这个中断时,USART2-DR寄存器是最后一个要发送的数据,
此时打开USART2发送完毕中断,进入USART2发送完毕中断后,可以设定标识,: w% H. J( O. i' M) F
也可以操作GPIO, 进行RS485的换向动作。
; R$ R- L9 [5 z* ~
最新的STM32F103的HAL库,几乎所有的通信,都可以启用DMA,HAL库函数抽象层次过高,灵活性不够,
但比较适合使用操作系统的场合。可以把HAL库的宏定义拷贝过来使用,以提高标准外设驱动库的效率,
又保证标准外设驱动库的灵活性。) _, R( b/ b6 A$ U6 \" W: O
6 ` \% }1 Q" t: \
! G, h8 p. A2 Z' f