完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
stm32f405串口 DMA+空闲中断 不定长数据收发代码
#include "sys.h" #include "usart.h" #include #include "led.h" // // /* //1,串口通信 UART1_TX PA9 DMA2_Stream7 UART1_RX PA10 DMA2_Stream2 UART2_TX PA2 DMA1_Stream6 UART2_RX PA3 DMA1_Stream5 UART3_TX PB10 DMA1_Stream3 UART3_RX PB11 DMA1_Stream1 UART4_TX PC10 DMA1_Stream4 UART4_RX PC11 DMA1_Stream2 UART5_TX PC12 DMA1_Stream7 UART5_RX PD2 DMA1_Stream0 UART6_TX PC6 DMA2_Stream6 UART6_RX PC7 DMA2_Stream1 */ #define DMA2_Stream7_Tx1 DMA2_Stream7 #define DMA2_Stream2_Rx1 DMA2_Stream2 #define DMA1_Stream6_Tx2 DMA1_Stream6 #define DMA1_Stream5_Rx2 DMA1_Stream5 #define DMA1_Stream3_Tx3 DMA1_Stream3 #define DMA1_Stream1_Rx3 DMA1_Stream1 #define DMA1_Stream4_Tx4 DMA1_Stream4 #define DMA1_Stream2_Rx4 DMA1_Stream2 #define DMA1_Stream7_Tx5 DMA1_Stream7 #define DMA1_Stream0_Rx5 DMA1_Stream0 #define DMA2_Stream6_Tx6 DMA2_Stream6 #define DMA2_Stream1_Rx6 DMA2_Stream1 // // //串口1数据 uint8_t g_RxBuffer1[UART_BUF_SIZE1]; //接收缓冲1 uint8_t g_TxBuffer1[UART_BUF_SIZE1]; //发送缓冲1 uint8_t volatile g_UartState1; //UART1工作状态标记 //通讯1数据缓存 u8 Ctr_Rx_Buffer1[UART_BUF_SIZE1]; //通信用缓冲区 u8 Ctr_Tx_Buffer1[UART_BUF_SIZE1]; //通信用缓冲区 uint16_t Ctr_DataLength1; /// /// void DMA_Configuration1(void); void uart1_dma_init(uint16_t BaudRate) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* 1.使能PA口时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); /* 2.管脚映射 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); /* GPIOA9复用为USART2 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); /* GPIOA10复用为USART2 */ /* 4.配置串口1的PA9和PA10管脚 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* TXIO */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* RXIO */ /* 5.配置串口工作模式 */ USART_DeInit(USART1); USART_InitStructure.USART_BaudRate = BaudRate*100;//接电机控制 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(USART1, &USART_InitStructure); /* 6.设置中断 */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* 7.配置串口中断 */ USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // USART_ITConfig(USART1, USART_IT_TC, DISABLE); // USART_ITConfig(USART1, USART_IT_TXE, DISABLE); USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);/* 使能IDLE中断 */ /* 8.使能串口 */ USART_Cmd(USART1, ENABLE);//使能串口 /* 9.DMA配置*/ DMA_Configuration1(); g_UartState1 = UART_IDLE1; } /// //*********************串口1DMA设置********************// //#define DMA2_Stream7_Tx1 DMA2_Stream7 //#define DMA2_Stream2_Rx1 DMA2_Stream2 //uint8_t g_RxBuffer1[UART_BUF_SIZE1]; //接收缓冲1 //uint8_t g_TxBuffer1[UART_BUF_SIZE1]; //发送缓冲1 //uint8_t volatile g_UartState1; //UART1工作状态标记 void DMA_Configuration1(void) { DMA_InitTypeDef DMA_InitStructure; /* 1.使能DMA2时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); /* 2.配置使用DMA发送数据 */ DMA_DeInit(DMA2_Stream7_Tx1); DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置DMA通道 */ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); /* 目的 */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_TxBuffer1; /* 源 雷达的数据*/ DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* 方向 */ DMA_InitStructure.DMA_BufferSize = UART_BUF_SIZE1; /* 长度 */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址是否自增 */ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址是否自增 */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 目的数据带宽 */ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 源数据宽度 */ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 单次传输模式/循环传输模式 */ DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; /* DMA优先级 */ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式/直接模式 */ DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 单次传输 */ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /* 3. 配置DMA */ DMA_Init(DMA2_Stream7_Tx1, &DMA_InitStructure); /* 4.使能DMA中断 */ // DMA_ITConfig(DMA2_Stream7_Tx1, DMA_IT_TC, ENABLE); // DMA_ITConfig(DMA2_Stream7_Tx1, DMA_IT_TE, ENABLE); /* 5.使能串口的DMA发送接口 */ USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); /* 7.不使能DMA */ DMA_Cmd(DMA2_Stream7_Tx1, DISABLE); /* 2.配置使用DMA接收数据 */ DMA_DeInit(DMA2_Stream2_Rx1); DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置DMA通道 */ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); /* 目的 */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)g_RxBuffer1; /* 源 雷达的数据*/ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /* 方向 */ DMA_InitStructure.DMA_BufferSize = UART_BUF_SIZE3; /* 长度 */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址是否自增 */ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址是否自增 */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 目的数据带宽 */ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 源数据宽度 */ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 单次传输模式/循环传输模式 */ DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* DMA优先级 */ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式/直接模式 */ DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 单次传输 */ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /* 3. 配置DMA */ DMA_Init(DMA2_Stream2_Rx1, &DMA_InitStructure); /* 4.使能DMA中断 */ // DMA_ITConfig(DMA2_Stream2_Rx1, DMA_IT_TC, ENABLE); // DMA_ITConfig(DMA2_Stream2_Rx1, DMA_IT_TE, ENABLE); // DMA_ITConfig(DMA2_Stream2_Rx1, DMA_IT_HT, ENABLE); /* 5.使能串口的DMA发送接口 */ USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); /* 7.使能DMA */ DMA_Cmd(DMA2_Stream2_Rx1, ENABLE); } // // extern u32 wcntCK_uartrx_over[6];//接收超时 extern u8 uflagCK_uartrx_over[6];//接收超时 u8 uflagCK_Ctr_Modbus[6];//接收超时 void Ctr_Modbus1(void); //空闲中断 void USART1_IRQHandler(void) { u16 data, i; if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾) { //读SR后读DR清除Idle,下面2行代码不能少,也不能用USART_ClearITPendingBit(USART1, USART_IT_IDLE);来代替 data = USART1->SR; data = USART1->DR; //关闭DMA,防止处理其间有数据 DMA_Cmd(DMA2_Stream2_Rx1, DISABLE); //关闭DMA,防止处理其间有数据 //读数据 Ctr_DataLength1 =UART_BUF_SIZE1 - DMA_GetCurrDataCounter(DMA2_Stream2_Rx1); //处理数据 if (Ctr_DataLength1 > 0) { for (i = 0; i < Ctr_DataLength1; i++) //将数据送DMA存储地址 { Ctr_Rx_Buffer1 = g_RxBuffer1; } } //重新开始接受DMA数据 DMA_Cmd(DMA2_Stream2_Rx1, DISABLE); //改变datasize前先要禁止通道工作 DMA_ClearFlag(DMA2_Stream2_Rx1, DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2); //清除DMA2_Steam7传输完成标志 DMA_SetCurrDataCounter(DMA2_Stream2_Rx1, UART_BUF_SIZE1); DMA_Cmd(DMA2_Stream2_Rx1, ENABLE); g_UartState1 = UART_RECV1; // Ctr_Modbus1();//控制通讯 放入主定时循环里 } } // //#define DMA2_Stream7_Tx1 DMA2_Stream7 //#define DMA2_Stream2_Rx1 DMA2_Stream2 //发送完成中断 void DMA2_Stream7_IRQHandler(void) { u16 data, i; //清除标志 if(DMA_GetFlagStatus(DMA2_Stream7_Tx1, DMA_FLAG_TCIF7) != RESET) //等待DMA2_Steam7传输完成 { DMA_ClearFlag(DMA2_Stream7_Tx1, DMA_FLAG_TCIF7); //清除DMA2_Steam7传输完成标志 } } //接收通道中断 void DMA2_Stream2_IRQHandler(void) { u16 data, i; //清除标志 if(DMA_GetFlagStatus(DMA2_Stream2_Rx1, DMA_FLAG_TCIF2) != RESET) //等待DMA2_Steam7传输完成 { DMA_ClearFlag(DMA2_Stream2_Rx1, DMA_FLAG_TCIF2); //清除DMA2_Steam7传输完成标志 } } // //dma数据发送 //#define DMA2_Stream7_Tx1 DMA2_Stream7 //#define DMA2_Stream2_Rx1 DMA2_Stream2 void uart1_send_dma(uint8_t *buf, uint8_t len) { DMA_InitTypeDef DMA_InitStructure; /* 1.使能DMA1时钟 */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); /* 2.配置使用DMA发送数据 */ DMA_DeInit(DMA2_Stream7_Tx1); DMA_InitStructure.DMA_Channel = DMA_Channel_4; /* 配置DMA通道 */ DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(USART1->DR)); /* 目的 */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buf;//数据 /* 源 雷达的数据*/ DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* 方向 */ DMA_InitStructure.DMA_BufferSize = len;//长度 /* 长度 */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; /* 外设地址是否自增 */ DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; /* 内存地址是否自增 */ DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_Byte; /* 目的数据带宽 */ DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; /* 源数据宽度 */ DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; /* 单次传输模式/循环传输模式 */ DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* DMA优先级 */ DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; /* FIFO模式/直接模式 */ DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; /* FIFO大小 */ DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; /* 单次传输 */ DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream7_Tx1, &DMA_InitStructure); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); DMA_ITConfig(DMA2_Stream7_Tx1, DMA_IT_TC, ENABLE); DMA_Cmd(DMA2_Stream7_Tx1, ENABLE); } // //DMA发送多字节 //开启一次DMA传输 //数据:g_TxBuffer1 //#define DMA2_Stream7_Tx1 DMA2_Stream7 //#define DMA2_Stream2_Rx1 DMA2_Stream2 void uart1_dma_tx(void) { u8 len=50; u8 crc=0x33; u8 i; //******数据发送位****** //包头 g_TxBuffer1[0]=0xBB; g_TxBuffer1[1]=0x66; g_TxBuffer1[2]=0x15; g_TxBuffer1[3]=len; //数据区 //包尾 g_TxBuffer1[49]=crc; //******数据发送****** uart1_send_dma(g_TxBuffer1, len); } // // void Ctr_Modbus1(void) { u8 i; u8 Command = 0; u8 board=0; u8 Cmd_length=0; if (g_UartState1 == UART_RECV1) //接收完成 { i = Ctr_DataLength1;//10长度 /*******包头*****/ if( (Ctr_Rx_Buffer1[0] != 0xBB) || (Ctr_Rx_Buffer1[1] != 0x66)) return ; /*******板子连接类型*****/ board=Ctr_Rx_Buffer1[2];//长度 /*******cmd*****/ Command = Ctr_Rx_Buffer1[3];//指令 Cmd_length=Ctr_Rx_Buffer1[4];//长度 switch (Command) { } } g_UartState1 = UART_IDLE1; } e1 = UART_IDLE1;} |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1632 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1559 浏览 1 评论
985 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
688 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1605 浏览 2 评论
1869浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
652浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
521浏览 3评论
539浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
508浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 09:15 , Processed in 0.713471 second(s), Total 49, Slave 42 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号