标签:sub mod public 复用 flow 来源 isa 输出 一个
内容来源于:http://blog.sina.com.cn/s/blog_777668c30102x4hz.html
1、DMA做所周知这个是好的东西,对于跑裸机的开发者来说是一个福音。但是很多工程师还是按照以前的方式来设计串口,本人看到了真的急的不行。多么好的东西就这样子暴遣天物!可能很多开发者会说DMA是定长的我收发的数据都是不定长的有什么用?如果听到这句话我保证该位同事没有好好研究过DMA。今天把自己DMA不定长发送接收程序贴上来。希望大家在开发的过程少受罪。
1 void Usart1RccEnable( void ) 2 { 3 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); //使能串口1时钟 4 RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1, ENABLE); //使能串口1时钟 5 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA时钟 6 } 7 8 void Usart1GpioConfig( void ) 9 { 10 GPIO_InitTypeDef GPIO_InitStructure; 11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX 12 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 14 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口 15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX 16 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入 17 GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口 18 } 19 20 void Usart1DmaConfig( void ) 21 { 22 DMA_InitTypeDef DMA_InitStructure; 23 DMA_DeInit(DMA1_Channel5); 24 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; 25 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Usart1_Module_Struct.S_usart_dma_rx_buffer;//这是初始化时候配置,可以根据程序运行重新设置。 26 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 27 DMA_InitStructure.DMA_BufferSize = UART1_TX_RX_MAX_SIZE; 28 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 29 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 30 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 31 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 32 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 33 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 34 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 35 DMA_Init(DMA1_Channel5, &DMA_InitStructure); 36 DMA_Cmd(DMA1_Channel5, ENABLE); 37 USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); 38 } 39 40 void Usart1Config(void) 41 { 42 USART_InitTypeDef USART_InitStructure; 43 USART_InitStructure.USART_BaudRate = BAUD_RATE; //速率115200bps 44 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位 45 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位 46 USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位 47 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控 48 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 49 USART_Init(USART1, &USART_InitStructure); //配置串口参数函数 50 USART_ITConfig(USART1,USART_IT_TC,DISABLE); //串口中断使能 51 USART_ITConfig(USART1,USART_IT_RXNE,DISABLE); //串口接收中断使能 52 USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //串口空闲中断使能 53 USART_Cmd(USART1, ENABLE); 54 USART_ClearFlag(USART1,USART_FLAG_TC); 55 } 56 57 void Usart1NvicConfig( void ) 58 { 59 NVIC_InitTypeDef NVIC_InitStructure; 60 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 61 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; // 串口中断配置 62 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 63 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 64 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 65 NVIC_Init(&NVIC_InitStructure); 66 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); 67 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; // 串口中断配置 68 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 69 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 70 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 71 NVIC_Init(&NVIC_InitStructure); 72 } 73 74 void Usart1DmaStructInit( void ) 75 { 76 Usart1_Module_Struct.S_rx_idle_flag = DISABLE; //初始化IDLE为0,没有数据发来 77 Usart1_Module_Struct.S_dma_send_usart_flag = ENABLE; //初始化DMA状态设置位1,才能启动第一次发送。 78 } 79 80 void Usart1Init( void ) 81 { 82 Usart1RccEnable(); 83 Usart1GpioConfig(); 84 Usart1Config(); 85 Usart1NvicConfig(); 86 Usart1DmaConfig(); 87 Usart1DmaStructInit(); 88 } 89 90 void Usart1SendData(uint8_t *Usart_TxBuffer, uint32_t Length) 91 { 92 DMA_InitTypeDef DMA_InitStructure; 93 while(Usart1_Module_Struct.S_dma_send_usart_flag == DISABLE); 94 Usart1_Module_Struct.S_dma_send_usart_flag = DISABLE; 95 DMA_DeInit(DMA1_Channel4); 96 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); 97 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; 98 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)Usart_TxBuffer; 99 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; 100 DMA_InitStructure.DMA_BufferSize = Length; 101 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 102 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 103 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; 104 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; 105 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 106 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 107 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 108 DMA_Init(DMA1_Channel4, &DMA_InitStructure); 109 DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); 110 DMA_Cmd(DMA1_Channel4, ENABLE); 111 USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); 112 } 113 114 void USART1_IRQHandler(void) 115 { 116 if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) 117 { 118 Usart1_Module_Struct.S_dma_rx_usart_size = USART1->SR; 119 Usart1_Module_Struct.S_dma_rx_usart_size = USART1->DR; 120 DMA_Cmd(DMA1_Channel5,DISABLE); 121 Usart1_Module_Struct.S_dma_rx_usart_size = UART1_TX_RX_MAX_SIZE - DMA_GetCurrDataCounter(DMA1_Channel5); 122 DMA_SetCurrDataCounter(DMA1_Channel5,UART1_TX_RX_MAX_SIZE); 123 DMA_Cmd(DMA1_Channel5,ENABLE); 124 Usart1_Module_Struct.S_rx_idle_flag = 1; 125 } 126 } 127 128 129 130 131 void DMA1_Channel4_IRQHandler(void) 132 { 133 if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET) 134 { 135 DMA_ClearFlag(DMA1_FLAG_TC4); 136 DMA_Cmd(DMA1_Channel4,DISABLE); 137 Usart1_Module_Struct.S_dma_send_usart_flag = ENABLE; 138 } 139 } 140 141 unsigned char GetUsart1DmaTxFlag( void ) 142 { 143 return Usart1_Module_Struct.S_dma_send_usart_flag; 144 } 145 146 unsigned char GetUsart1DmaRxFlag( void ) 147 { 148 return Usart1_Module_Struct.S_rx_idle_flag; 149 } 150 151 void SetUsart1DmaTxFlag( unsigned char status ) 152 { 153 Usart1_Module_Struct.S_dma_send_usart_flag = status; 154 } 155 156 void SetUsart1DmaRxFlag( unsigned char status ) 157 { 158 Usart1_Module_Struct.S_rx_idle_flag = status; 159 } 160 161 unsigned int GetUsart1DmaRxSize( void ) 162 { 163 return Usart1_Module_Struct.S_dma_rx_usart_size; 164 } 165 166 void SetUsart1DmaRxSize( void ) 167 { 168 Usart1_Module_Struct.S_dma_rx_usart_size = 0; 169 }
以下是.h文件
1 #ifndef _usart1_h 2 #define _usart1_h 3 #include "public.h" 4 #ifdef _usart1_C 5 #define _usart1_ext 6 #else 7 #define _usart1_ext extern 8 #endif 9 10 #define BAUD_RATE 115200 11 #define UART1_TX_RX_MAX_SIZE 1460 12 13 typedef struct 14 { 15 unsigned char __IO S_dma_send_usart_flag; //该状态表示DMA发送结束标志,如果该标志为否DMA资源占用用请勿使用。 16 unsigned int __IO S_dma_rx_usart_size; //接收到一帧数据结束,获取该帧长度 17 unsigned char __IO S_rx_idle_flag; //接收一帧结束标志位 18 unsigned char S_usart_dma_tx_buffer[UART1_TX_RX_MAX_SIZE];//发送缓冲Buffer 19 unsigned char S_usart_dma_rx_buffer[UART1_TX_RX_MAX_SIZE];//接收缓冲Buffer 20 } Usart_p; 21 22 _usart1_ext Usart_p Usart1_Module_Struct; 23 24 _usart1_ext void Usart1Init( void ); 25 _usart1_ext void Usart1SendData(uint8_t *Usart_TxBuffer, uint32_t Length); 26 _usart1_ext unsigned char GetUsart1DmaTxFlag( void ); 27 _usart1_ext unsigned char GetUsart1DmaRxFlag( void ); 28 _usart1_ext void SetUsart1DmaTxFlag( unsigned char status ); 29 _usart1_ext void SetUsart1DmaRxFlag( unsigned char status ); 30 _usart1_ext unsigned int GetUsart1DmaRxSize( void ); 31 _usart1_ext void SetUsart1DmaRxSize( void ); 32 33 #endif 34 35 36 //用户应用: 37 int main( void ) 38 { 39 SystemInit(); 40 Usart1Init(); 41 while(1) 42 { 43 if(GetUsart1DmaRxFlag()==TRUE) 44 { 45 SetUsart1DmaRxFlag(FALSE); 46 Usart1SendData(Usart1_Module_Struct.S_usart_dma_rx_buffer,GetUsart1DmaRxSize()); 47 } 48 } 49 }
标签:sub mod public 复用 flow 来源 isa 输出 一个
原文地址:https://www.cnblogs.com/better-day/p/12600351.html