1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
#include "sys.h"
#include "usart.h" #include "string.h" #include "stdio.h" #include "stdlib.h" //蓝牙 // uart_find uart1s;//定义串口一的接受处理结构体 //局部定义以便实现模块化 //USART #define USART USART1 #define USART_CLK RCC_APB2Periph_USART1 #define USART_CLK_SET RCC_APB2PeriphClockCmd #define USART_GPIO_CLK_SET RCC_APB2PeriphClockCmd #define USART_RX_GPIO_PORT GPIOA #define USART_RX_GPIO_CLK RCC_APB2Periph_GPIOA #define USART_RX_PIN GPIO_Pin_10 #define USART_RX_IRQ USART1_IRQn #define USART_RX_IRQ_HANDLER USART1_IRQHandler //USART3_IRQHandler #define USART_TX_GPIO_PORT GPIOA #define USART_TX_GPIO_CLK RCC_APB2Periph_GPIOA #define USART_TX_PIN GPIO_Pin_9 #define USART_BAUDRATE 115200 //DMA tx #define USART_DR_BASE (USART1_BASE+0x04) // 0x40013800 + 0x04 = 0x40013804,串口数据寄存器地址 #define SEND_BUFF_SIZE 128 //发送的数据量,SEND_BUFF_SIZE * DMA_MemoryDataSize #define USART_TX_DMA_CLK RCC_AHBPeriph_DMA1 #define USART_TX_DMA_CHANNEL DMA1_Channel4 #define USART_TX_DMA_IRQ DMA1_Channel4_IRQn//中断接口 #define USART_TX_DMA_IRQ_HANDLER DMA1_Channel4_IRQHandler//中断接口 #define USART_Tx_DMA_FLAG DMA1_FLAG_GL4 //错误标志 #define USART_Tx_ERR_DMA_FLAG DMA1_FLAG_GL4 //DMA rx #define USART_DR_BASE (USART1_BASE+0x04) // 0x40013800 + 0x04 = 0x40013804,串口数据寄存器地址 #define REC_BUFF_SIZE 128 //发送的数据量,SEND_BUFF_SIZE * DMA_MemoryDataSize #define USART_RX_DMA_CLK RCC_AHBPeriph_DMA1 #define USART_RX_DMA_CHANNEL DMA1_Channel5 #define USART_RX_DMA_IRQ DMA1_Channel5_IRQn//中断接口 #define USART_RX_DMA_IRQ_HANDLER DMA1_Channel5_IRQHandler//中断接口 #define USART_Rx_DMA_FLAG DMA1_FLAG_GL5 //错误标志 #define USART_Rx_ERR_DMA_FLAG DMA1_FLAG_GL5 static uint8_t SendBuff[SEND_BUFF_SIZE];//发送测试缓冲 static uint8_t rec_by=0;//缓冲位置 static uint8_t recBuff[REC_BUFF_SIZE]; //接受测试缓冲 临时缓冲 static uint8_t recBuff1[REC_BUFF_SIZE]; //接受测试缓冲 static uint8_t recBuff2[REC_BUFF_SIZE]; //接受测试缓冲 static u16 rec_counter=0; //static uint8_t *send_buff = SendBuff; //锁定发送地址 //static uint8_t *rec_buff1 = recBuff1; //锁定接收地址1 //static uint8_t *rec_buff2 = recBuff2; //锁定接收地址2 static void uart_dma_send(u8 *buff,u8 len); static void USART_DMA_Config(void); static void user_heander(void); static void USART_Config(void); /********************************** 定义函数接口 ************************************/ void blue_uart_int(void) { uart1s.uart_send = uart_dma_send; uart1s.uart_rxbuf_len = &rec_counter; uart1s.uart_init = USART_Config; //初始化 uart1s.uart_init(); uart1s.uart_rxbuf1 = recBuff1; uart1s.uart_rxbuf2 = recBuff2; } /** * @brief USART GPIO 配置,工作模式配置。115200 8-N-1 * @param 无 * @retval 无 */ static void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /*配置使用DMA模式*/ USART_DMA_Config(); USART_GPIO_CLK_SET( USART_RX_GPIO_CLK|USART_TX_GPIO_CLK, ENABLE); /* Enable UART clock */ USART_CLK_SET(USART_CLK, ENABLE); //时钟将会出现大问题 USART_DeInit(USART); //复位串口 /* Configure USART Tx as alternate function */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Pin = USART_TX_PIN ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(USART_TX_GPIO_PORT, &GPIO_InitStructure); /* Configure USART Rx as alternate function */ GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(USART_RX_GPIO_PORT, &GPIO_InitStructure); // /* Enable the DMA Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART_RX_IRQ; // 发送DMA通道的中断配置 满中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; // 优先级设置 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* USART mode config */ USART_InitStructure.USART_BaudRate = USART_BAUDRATE; 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(USART, &USART_InitStructure); USART_Cmd(USART, ENABLE); // USART_ITConfig(USART, USART_IT_RXNE, ENABLE);//开启中断 // USART_ITConfig(USART, USART_IT_IDLE, ENABLE); // 开启 串口空闲IDEL 中断 /* Enable USARTy DMA TX request */ USART_ITConfig(USART,USART_IT_TC,DISABLE); // USART_DMACmd(USART, USART_DMAReq_Tx, ENABLE); // 开启串口DMA发送 这两个不能随便开启 开启就是发送 USART_DMACmd(USART, USART_DMAReq_Rx, ENABLE); // 开启串口DMA接收 接受可以提前开启 USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE); // 开启串口DMA发送 printf("串口2初始化rn"); } /** * @brief USART1 TX DMA 配置,内存到外设(USART1->DR) * @param 无 * @retval 无 */ static DMA_InitTypeDef DMA_InitStructure1; static void USART_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; /*usart1 tx对应dma2,通道4,数据流7*/ /*开启DMA时钟*/ RCC_AHBPeriphClockCmd(USART_TX_DMA_CLK, ENABLE); DMA_Cmd(USART_TX_DMA_CHANNEL, DISABLE); // 关DMA通道 DMA_DeInit(USART_TX_DMA_CHANNEL); // 恢复缺省值 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART->DR);// 设置串口发送数据寄存器 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SendBuff; // 设置发送缓冲区首地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; // 设置外设位目标,内存缓冲区 -> 外设寄存器 DMA_InitStructure.DMA_BufferSize = uart1s.uart_txbuf_len; // 需要发送的字节数,这里其实可以设置为0,因为在实际要发送的时候,会重新设置次值 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不做增加调整,调整不调整是DMA自动实现的 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存缓冲区地址增加调整 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8位,1个字节 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 单次传输模式 DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; // 优先级设置 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; // 关闭内存到内存的DMA模式 DMA_Init(USART_TX_DMA_CHANNEL, &DMA_InitStructure); // 写入配置 DMA_ClearFlag(USART_Tx_DMA_FLAG); // 清除DMA所有标志 DMA_Cmd(USART_TX_DMA_CHANNEL, DISABLE); // 关闭DMA DMA_ITConfig(USART_TX_DMA_CHANNEL, DMA_IT_TC, ENABLE); //中断配置 DMA_ITConfig(USART_TX_DMA_CHANNEL, DMA_IT_TC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; /* Enable the DMA Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART_TX_DMA_IRQ; // 发送DMA通道的中断配置 满中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; // 优先级设置 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /**************************************************************/ //****************************配置接收 /*--- LUMMOD_UART_Rx_DMA_Channel DMA Config ---*/ //启动DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_Cmd(USART_RX_DMA_CHANNEL, DISABLE); // 关DMA通道 DMA_DeInit(USART_RX_DMA_CHANNEL); // 恢复缺省值 DMA_InitStructure1.DMA_PeripheralBaseAddr = (uint32_t)(&USART->DR);// 设置串口接收数据寄存器 DMA_InitStructure1.DMA_MemoryBaseAddr = (uint32_t)recBuff1; // 设置接收缓冲区首地址 DMA_InitStructure1.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置外设为数据源,外设寄存器 -> 内存缓冲区 DMA_InitStructure1.DMA_BufferSize = *uart1s.uart_rxbuf_len; // 需要最大可能接收到的字节数 不能为零 DMA_InitStructure1.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不做增加调整,调整不调整是DMA自 动实现的 DMA_InitStructure1.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存缓冲区地址增加调整 DMA_InitStructure1.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设数据宽度8位,1个字节 DMA_InitStructure1.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存数据宽度8位,1个字节 DMA_InitStructure1.DMA_Mode = DMA_Mode_Normal; // 单次传输模式 DMA_InitStructure1.DMA_Priority = DMA_Priority_VeryHigh; // 优先级设置 DMA_InitStructure1.DMA_M2M = DMA_M2M_Disable; // 关闭内存到内存的DMA模式 DMA_Init(USART_RX_DMA_CHANNEL, &DMA_InitStructure1); // 写入配置 DMA_ClearFlag(USART_Rx_DMA_FLAG); // 清除DMA所有标志 DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE); // 开启接收DMA通道,等待接收数据 //DMA_ITConfig(LUMMOD_UART_Rx_DMA_Channel, DMA_IT_TC, ENABLE); // 开启接收完成DMA通道中断 /* Enable the DMA Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART_RX_DMA_IRQ; // 发送DMA通道的中断配置 满中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; // 优先级设置 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /********************************* dma 发送 ***********************************/ static void uart_dma_send(u8 *buff,u8 len) { memset(SendBuff,0,SEND_BUFF_SIZE); memcpy(SendBuff,buff,len); DMA_SetCurrDataCounter(USART_TX_DMA_CHANNEL,len); //数据传输量 DMA_Cmd(USART_TX_DMA_CHANNEL, ENABLE); //开启DMA传输 /* USART1 向 DMA发出TX请求 */ USART_DMACmd(USART, USART_DMAReq_Tx, ENABLE);//开始发送 } /*********************************************END OF FILE**********************/ /*下面代码我们直接把中断控制逻辑写在中断服务函数内部。*/ //DMA传输接收完成中断 void USART_RX_DMA_IRQ_HANDLER(void) { if(DMA_GetITStatus(USART_Rx_DMA_FLAG) != RESET) { DMA_ClearITPendingBit(USART_Rx_DMA_FLAG); // Dma_FreeBuf_Ok = 1;//有准备好的数据了 //数据溢出会出现在这里 } else { DMA_ClearFlag(USART_Rx_ERR_DMA_FLAG); } } /********************* 参数说明: dma串口通道切换 **********************/ static void buf_chn2(void) { if(rec_by==0) { rec_by=1; DMA_InitStructure1.DMA_MemoryBaseAddr = (uint32_t)recBuff2; // 设置接收缓冲区首地址 DMA_Init(USART_RX_DMA_CHANNEL, &DMA_InitStructure1); // 写入配置 } else { rec_by=0; DMA_InitStructure1.DMA_MemoryBaseAddr = (uint32_t)recBuff1; // 设置接收缓冲区首地址 DMA_Init(USART_RX_DMA_CHANNEL, &DMA_InitStructure1); // 写入配置 } DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE); } //串口1中断服务程序 void USART_RX_IRQ_HANDLER(void) { u8 res; if(USART_GetITStatus(USART, USART_IT_RXNE) != RESET)//接收到数据 { res=USART->DR; //读取就是清空 // // while((USART1->SR&0X40)==0);//等待发送结束 // USART1->DR=res; } else if(USART_GetITStatus(USART, USART_IT_IDLE) != RESET)//空闲中断 { u8 clear; clear=USART->SR;//读SR寄存器 clear=USART->DR;//读DR寄存器 清空数据 /*******************************/ DMA_Cmd(USART_RX_DMA_CHANNEL, DISABLE); // 关闭DMA ,防止干扰 DMA_ClearFlag( USART_Rx_ERR_DMA_FLAG ); // 清DMA标志位 rec_counter = REC_BUFF_SIZE - DMA_GetCurrDataCounter(USART_RX_DMA_CHANNEL); //获得接收到的字节数 USART_RX_DMA_CHANNEL->CNDTR = REC_BUFF_SIZE; // 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目 //开始切换buff buf_chn2(); // printf("当前是通道二:%srn",recBuff1); DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE); //数据转移 memset(recBuff,0,REC_BUFF_SIZE); if(rec_by==1) { memcpy(recBuff,recBuff1,REC_BUFF_SIZE); memset(recBuff1,0,REC_BUFF_SIZE); } else { memcpy(recBuff,recBuff2,REC_BUFF_SIZE); memset(recBuff2,0,REC_BUFF_SIZE); } user_heander(); //cc3200_rec(); //some things doing /* DMA 开启,等待数据。注意,如果中断发送数据帧的速率很快,MCU来不及处理此次接收到的数据,中断又发来数据的话,这里不能开启,否则数据会被覆盖。有2种方式解决。 1. 在重新开启接收DMA通道之前,将LumMod_Rx_Buf缓冲区里面的数据复制到另外一个数组中,然后再开启DMA,然后马上处理复制出来的数据。 2. 建立双缓冲,在LumMod_Uart_DMA_Rx_Data函数中,重新配置DMA_MemoryBaseAddr 的缓冲区地址,那么下次接收到的数据就会保存到新的缓冲区中,不至于被覆盖。*/ //注意双缓冲:只需要重新配置,数据地址即可 } } //dma2 7 tx 发送完成中断实验 void USART_TX_DMA_IRQ_HANDLER(void) { if(DMA_GetITStatus(USART_Tx_DMA_FLAG)!=RESET) { DMA_ClearFlag(USART_Tx_DMA_FLAG); // 清除标志 DMA_Cmd(USART_TX_DMA_CHANNEL, DISABLE); // 关闭DMA通道 } else { DMA_ClearFlag(USART_Tx_ERR_DMA_FLAG); // 清除所有错误标志 } } /******************************** 用户处理程序 **********************************/ static void user_heander(void) { // your code //rest printf("your printf : %s",recBuff); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1936浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
729浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
569浏览 3评论
594浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
552浏览 3评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 22:54 , Processed in 0.811949 second(s), Total 76, Slave 60 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号