STM32F103 UART4 DMA接收 终于调试成功,分享一下
2015-11-25 10:39
375 查看
//网上找了老半天也找不到UART4-DMA的程序,自己调试成功了,特地分享一下
</pre><pre name="code" class="cpp"><pre name="code" class="cpp">uint8_t UART4_Rx_buffer[512],UART4_Rx_num;
void UART4_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; DMA_InitTypeDef DMA_InitStructure; //定义DMA初始化结构体DMA_InitStructure // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选择NVIC优先级分组0 RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE); //串口4所使用管脚输出输入定义 //定义UART4 Tx (PC.10)脚为复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //IO口的第2脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //IO口复用推挽输出 GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化串口1输出IO口 //定义 UART4 Rx (PC.11)为悬空输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //IO口的第3脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//IO口悬空输入 GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化串口1输入IO口 //串口4参数初始化定义部分,串口1参数为9600 , 8 ,1 ,N 接收中断方式 USART_InitStructure.USART_BaudRate = 9600; //设定传输速率 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //设定传输数据位数 USART_InitStructure.USART_StopBits = USART_StopBits_1; //设定停止位个数 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(UART4, &USART_InitStructure); //初始化串口4 USART_ITConfig(UART4, USART_IT_IDLE,ENABLE); //使能串口4接收中断 USART_Cmd(UART4, ENABLE); //使能串口4 USART_ClearFlag(UART4, USART_FLAG_TC); // 清标志(后增加) DMA_DeInit(DMA2_Channel3); //重置DMA 2通道配置 DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004C04; //外设地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)UART4_Rx_buffer; //内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //外设作为数据目的地 DMA_InitStructure.DMA_BufferSize = 512; //DMA缓存大小:BufferSize DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte; //内存数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //设置DMA通道优先级为高 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止DMA通道设置为内存至内存传输 DMA_Init(DMA2_Channel3, &DMA_InitStructure); //初始化 DMA_ITConfig(DMA2_Channel3, DMA_IT_TC, ENABLE); DMA_ITConfig(DMA2_Channel3, DMA_IT_TE, ENABLE); USART_DMACmd(UART4, USART_DMAReq_Rx, ENABLE); DMA_Cmd(DMA2_Channel3, ENABLE); //使能串口4中断 NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
void UART4_IRQHandler(void) { <span style="white-space:pre"> </span>uint16_t i; <span style="white-space:pre"> </span>uint16_t Data_Len; <span style="white-space:pre"> </span>if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET) //如果为中断 <span style="white-space:pre"> </span>{ <span style="white-space:pre"> </span>DMA_Cmd(DMA2_Channel3, DISABLE); <span style="white-space:pre"> </span>Data_Len=512-DMA_GetCurrDataCounter(DMA2_Channel3); <span style="white-space:pre"> </span>USART_PutStr(USART1,UART4_Rx_buffer,Data_Len);<span style="white-space:pre"> </span><span style="white-space:pre"> </span> <span style="white-space:pre"> </span>UART4_Rx_num=0; <span style="white-space:pre"> </span>DMA_ClearFlag(DMA2_FLAG_GL3 | DMA2_FLAG_TC3 | DMA2_FLAG_TE3 | DMA2_FLAG_HT3); //清标志 <span style="white-space:pre"> </span>DMA2_Channel3->CNDTR = 512; //重装填 <span style="white-space:pre"> </span>DMA_Cmd(DMA2_Channel3, ENABLE); //处理完,重开DMA <span style="white-space:pre"> </span>//读SR后读DR清除IDLE <span style="white-space:pre"> </span>i = UART4->SR; <span style="white-space:pre"> </span>i = UART4->DR; <span style="white-space:pre"> </span>if(i)<span style="white-space:pre"> </span>i=0; <span style="white-space:pre"> </span>if(Data_Len)<span style="white-space:pre"> </span>Data_Len=0; <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>if(USART_GetITStatus(UART4, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET){ //出错 <span style="white-space:pre"> </span>USART_ClearITPendingBit(UART4, USART_IT_PE | USART_IT_FE | USART_IT_NE); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>USART_ClearITPendingBit(UART4, USART_IT_TC); <span style="white-space:pre"> </span>USART_ClearITPendingBit(UART4, USART_IT_IDLE);<span style="white-space:pre"> </span> }
void DMA2_Channel3_IRQHandler(void) {<pre name="code" class="cpp"><span style="white-space:pre"> </span>USART_PutStr(USART1," DMA23:\r\n",9); <span> </span>DMA_ClearITPendingBit(DMA2_IT_TC3); <span> </span>DMA_ClearITPendingBit(DMA2_IT_TE3); <span> </span>DMA_Cmd(DMA2_Channel3, DISABLE); //关闭DMA,防止处理其间有数据 <span> </span>DMA2_Channel3->CNDTR = 512; //重装填 <span> </span>DMA_Cmd(DMA2_Channel3, ENABLE); //处理完,重开DMA }<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
相关文章推荐
- STM32 IO口双向问题
- 我的 ARM+Linux 学习路线
- 开发学习记录之看门狗驱动
- 时钟+温度+遥控设置,综合时钟例子
- Linux下运行openwebos- -(转)
- Linux下运行openwebos- -(转)
- BusyBox 简化嵌入式 Linux 系统
- EGL 学习
- 嵌入式开发设计方法变化的背景
- 嵌入式人才的发展方向
- 汇编调用c函数为什么要设置栈
- 三角函数的实现
- 嵌入式桌面操作系统使用与制作攻略
- 打开DMA传输方式
- DMA timeout error
- 嵌入式系统烧写uboot/bootloader/kernel的一般方法
- 甲骨文收购Sleepycat 丰富嵌入式产品线
- 嵌入式Linux操作系统学习规划
- 基于嵌入式多芯片模组的微机保护平台
- 嵌入式系统中常用文件系统的制作总结