IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F407VET6串口6+DMA发送队列和DMA接收队列 -> 正文阅读

[嵌入式]STM32F407VET6串口6+DMA发送队列和DMA接收队列

定义的变量:

#define USART_DMA_USING?? ??? ?1
#define USART_DMA_IDLE?? ??? ?0 ? ? ? ? //空闲标志

#define USART6_RX_BUF_MAX ? ? ? ? ? 1024
#define USART6_TX_BUF_MAX ? ? ? ? ? 1024

#define UART_QUEUE_BUF_MAX ? ? ? ? ?1024

#define UART_UPPER_QUEUE_MAX ? ? ? ?20 ? ? ? ? ? ?//队列长度

u8 Usart6RxBuf[USART6_RX_BUF_MAX];
u8 Usart6TxBuf[USART6_TX_BUF_MAX];

u16 Usart6RxNum;
u16 Usart6TxLen;
u16 Usart6RxNum;
u8 ?SendingFlagUart;

typedef enum?
{
?? ?kUART_QUEUE_IDLE = 0, ? ? ? ? ? ? ?//没有要处理的数据
?? ?kUART_QUEUE_FLAG, ? ? ? ? ? ? ? ? ?//有要处理的数据
}UART_QUEUE_CMD;

typedef struct ?_usartQueueBuffer
{
?? ?u8 ?uartQueueBuf[UART_QUEUE_BUF_MAX]; ? ? ? ?//发送BUF
?? ?u16 uartQueueLen; ? ? ? ? ? ? ? ? ? ? ? ? ? ?//发送数据长度
? UART_QUEUE_CMD uartQueueCmdFlag; ? ? ? ? ? ? //是否要处理
?? ?
}UsartQueueBuffer;


UsartQueueBuffer ?UsartUpperRxBuf[UART_UPPER_QUEUE_MAX]; ? //发送数据队列
UsartQueueBuffer ?UsartUpperTxBuf[UART_UPPER_QUEUE_MAX]; ? //接收数据队列
u8 ? UsartTxQueueOrder; ?
u8 ? UsartRxQueueOrder;


u8 ComUpperRxDataBufRcv[UART_QUEUE_BUF_MAX]; ? //接收数据BUFfalo

1.初始化串口
void UsartInit(void)
{
?? ??? ?GPIO_InitTypeDef GPIO_InitStructure;
?? ??? ?USART_InitTypeDef USART_InitStructure;
?? ??? ?//?? ?NVIC_InitTypeDef NVIC_InitStructure;

?? ??? ?RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); ?? ??? ??? ?//使能GPIOC时钟
?? ??? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);?? ??? ??? ?//使能USART6时钟

?? ??? ?//串口6对应引脚复用映射
?? ??? ?GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6); ?? ??? ?//GPIOC6复用为USART6
?? ??? ?GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6); ?? ??? ?//GPIOC7复用为USART6

?? ??? ?GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; ?? ??? ??? ?//GPIOC6与GPIOC7
?? ??? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;?? ??? ??? ??? ??? ?//复用功能
?? ??? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;?? ??? ??? ??? ?//速度50MHz
?? ??? ?GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; ?? ??? ??? ??? ??? ?//推挽复用输出
?? ??? ?GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; ?? ??? ??? ??? ??? ?//上拉
?? ??? ?GPIO_Init(GPIOC,&GPIO_InitStructure); ?? ??? ??? ??? ??? ??? ??? ?//初始化PC6,PC7

?? ??? ?/* ?配置串口硬件参数 */
?? ??? ?USART_InitStructure.USART_BaudRate = 115200;?? ??? ?//波特率设置
?? ??? ?USART_InitStructure.USART_WordLength = USART_WordLength_8b;?? ??? ?//字长为8位数据格式
?? ??? ?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(USART6, &USART_InitStructure); ?? ??? ??? ??? ??? ??? ?//初始化串口6

?? ??? ?//?? ?USART_ClearFlag(USART6, USART_FLAG_RXNE);
?? ??? ?//?? ?USART_ClearFlag(USART6, USART_FLAG_TC);
?? ??? ?//?? ?USART_ITConfig(USART6, USART_IT_RXNE, ENABLE);?? ??? ??? ??? ??? ?// 使能接收中断?? ?
?? ??? ?//用于判断是否接收完一包数据.
?? ??? ?USART_ITConfig(USART6, USART_IT_IDLE, ENABLE);?? ??? ??? ??? ??? ?// 使能串口空闲中断

?? ??? ?USART_Cmd(USART6, ENABLE); ?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?// 串口使能
?? ??? ?// 初始化相应串口接收和发送缓存
?? ??? ?DriveUartBuffClearInit(Usart6RxBuf,USART6_RX_BUF_MAX);?? ??? ??? ??? ?
?? ??? ?DriveUartBuffClearInit(Usart6TxBuf,USART6_TX_BUF_MAX);?

?? ??? ?NVIC_EnableIRQ(USART6_IRQn);?? ??? ??? ??? ??? ??? ??? ??? ??? ?// 使能串口中断
?? ??? ?USART_DMACmd(USART6,USART_DMAReq_Tx,ENABLE); ?//使能串口1的DMA发送 ??
?? ??? ?USART_DMACmd(USART6,USART_DMAReq_Rx,ENABLE); ?//使能串口1的DMA接收?

?? ??? ?// 串口DMA初始化
?? ??? ?dma2_Stream2_init();
?? ??? ?dma2_Stream6_init();
}

2.初始化发送DMA

void dma2_Stream6_init(void)
{ ?
?? ??? ?DMA_InitTypeDef ?DMA_InitStructure;
?? ??? ?NVIC_InitTypeDef NVIC_InitStructure;

?? ??? ?RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能

?? ??? ?while (DMA_GetCmdStatus(DMA2_Stream6) != DISABLE)
?? ??? ?{
?? ??? ?;
?? ??? ?}//等待DMA2_Stream6可配置?

?? ??? ?DMA_DeInit(DMA2_Stream6);?
?? ??? ?/* 配置 DMA Stream */
?? ??? ?DMA_InitStructure.DMA_Channel = DMA_Channel_5; ?//通道4
?? ??? ?DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART6->DR; ? ? ? ? ? //DMA 对应的外设USART4->DR地址
?? ??? ?DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Usart6TxBuf; ? ? ? // 内存存储基地址

?? ??? ?DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
?? ??? ?DMA_InitStructure.DMA_BufferSize = USART6_TX_BUF_MAX;//数据传输量
?? ??? ?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_MemoryDataSize_Byte;//存储器数据长度 8位
?? ??? ?DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 循环模式
?? ??? ?DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//中等优先级
?? ??? ?DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //FIFO模式不开启?
?? ??? ?DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;?? ?
?? ??? ?DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
?? ??? ?DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
?? ??? ?DMA_Init(DMA2_Stream6, &DMA_InitStructure);//初始化DMA Stream

?? ??? ?//?? ?DMA_Cmd(DMA2_Stream6, ENABLE); ? ? ? ? ? ? ? ? ?/* DMA2_Stream6 enable */ // 在发送的时候才开启DMA
?? ??? ?//DMA NVIC ?
?? ??? ?NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream6_IRQn; ? ?
?? ??? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ?
?? ??? ?NVIC_Init(&NVIC_InitStructure); ?
?? ??? ?DMA_ITConfig(DMA2_Stream6,DMA_IT_TC,ENABLE);
}

3.初始化接收DMA

void dma2_Stream2_init(void)
{ ?
?? ??? ?DMA_InitTypeDef ?DMA_InitStructure;
?? ??? ?NVIC_InitTypeDef NVIC_InitStructure;

?? ??? ?RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA1时钟使能

?? ??? ?while (DMA_GetCmdStatus(DMA2_Stream2) != DISABLE)
?? ??? ?{
?? ??? ?;
?? ??? ?}//等待DMA2_Stream2可配置?

?? ??? ?DMA_DeInit(DMA2_Stream2);?
?? ??? ?/* 配置 DMA Stream */
?? ??? ?DMA_InitStructure.DMA_Channel = DMA_Channel_5; ?//通道4
?? ??? ?DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART6->DR; ? ? ? ? ? //DMA 对应的外设USART1->DR地址
?? ??? ?DMA_InitStructure.DMA_Memory0BaseAddr = (u32)Usart6RxBuf; ? ? ? // 内存存储基地址

?? ??? ?DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory ;//外设到存储器模式
?? ??? ?DMA_InitStructure.DMA_BufferSize = USART6_RX_BUF_MAX;//数据传输量
?? ??? ?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_MemoryDataSize_Byte;//存储器数据长度 8位
?? ??? ?DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// 循环模式
?? ??? ?DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//高优先级
?? ??? ?DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //FIFO模式不开启 ?
?? ??? ?DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; ? ?
?? ??? ?DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输
?? ??? ?DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输
?? ??? ?DMA_Init(DMA2_Stream2, &DMA_InitStructure);//初始化DMA Stream

?? ??? ?DMA_Cmd(DMA2_Stream2, ENABLE); ? ? ? ? ? ? ? ? ?/* DMA2_Stream2 enable */
?? ??? ?//DMA NVIC ?
?? ??? ?NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream2_IRQn; ? ?
?? ??? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ?
?? ??? ?NVIC_Init(&NVIC_InitStructure); ?
?? ??? ?DMA_ITConfig(DMA2_Stream2,DMA_IT_TC,ENABLE);
}

4.中断处理

//串口6 中断函数
void USART6_IRQHandler(void)
{?? ?
?? ?u8 clear;
?? ?//用于判断是否接收完一包数据.
?? ?if (USART_GetITStatus(USART6, USART_IT_IDLE)==SET)
?? ?{
?? ??? ?USART_ClearITPendingBit(USART6, USART_IT_IDLE);
?? ??? ?clear = USART6->SR;
?? ??? ?clear = USART6->DR;
?? ??? ?clear = clear;//无任何作用 去除编译告警
?? ??? ?
?? ??? ?DMA_Cmd(DMA2_Stream2, DISABLE); //关闭DMA,防止处理期间有数据
?? ??? ?Usart6RxNum = USART6_RX_BUF_MAX - DMA_GetCurrDataCounter(DMA2_Stream2);
?? ??? ?
?? ??? ?UsartUpperRxBuf[UsartRxQueueOrder].uartQueueLen = Usart6RxNum;
?? ??? ?DriveUsartGetRecvData(UsartUpperRxBuf[UsartRxQueueOrder].uartQueueBuf,Usart6RxNum);
?? ??? ?UsartUpperRxBuf[UsartRxQueueOrder].uartQueueCmdFlag = USART_DMA_USING;
? ? UsartRxQueueOrder++;
?? ??? ?if(UsartRxQueueOrder >= UART_UPPER_QUEUE_MAX)
?? ??? ?{
?? ??? ??? ?UsartRxQueueOrder = 0;
?? ??? ?}
?? ??? ?
?? ??? ?DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2);//清除DMA1_Steam0传输完成标志
?? ??? ?DMA_Cmd(DMA2_Stream2, ENABLE); ? ? //打开DMA,?? ??? ?
?? ?}
?? ?
?? ?if(USART_GetFlagStatus(USART6,USART_FLAG_ORE) == SET) //溢出?
?? ?{
?? ??? ?USART_ClearFlag(USART6,USART_FLAG_ORE); //读SR ??
?? ??? ?USART_ReceiveData(USART6); //读DR ?? ??? ?
?? ?}?
?? ?
}


?
void DMA2_Stream2_IRQHandler(void)
{
?? ?//清除标志
?? ?if(DMA_GetFlagStatus(DMA2_Stream2,DMA_FLAG_TCIF2)!=RESET)//等待DMA2_Steam2传输完成
?? ?{?
?? ??? ?DMA_Cmd(DMA2_Stream2, DISABLE); //关闭DMA,防止处理期间有数据
?? ??? ?Usart6RxNum = 0;?? ??? ?
?? ??? ?DMA_ClearFlag(DMA2_Stream2,DMA_FLAG_TCIF2 | DMA_FLAG_FEIF2 | DMA_FLAG_DMEIF2 | DMA_FLAG_TEIF2 | DMA_FLAG_HTIF2);//清除DMA1_Steam1传输完成标志
?? ??? ?DMA_SetCurrDataCounter(DMA2_Stream2, USART6_RX_BUF_MAX);
?? ??? ?DMA_Cmd(DMA2_Stream2, ENABLE); ? ? //打开DMA,
?? ?}
}


//串口6发送完成中断
void DMA2_Stream6_IRQHandler(void)
{
?? ?//清除标志
?? ?if(DMA_GetFlagStatus(DMA2_Stream6,DMA_FLAG_TCIF6)!=RESET)//等待DMA1_Steam3传输完成
?? ?{?
?? ??? ?SendingFlagUart = USART_DMA_IDLE;
?? ??? ?DMA_ClearFlag(DMA2_Stream6,DMA_FLAG_TCIF6);//清除DMA1_Steam3传输完成标志
?? ?}
}
?

5.接收数据处理

void ComUpperRxDataHandle(void)
{
?? ?static u8 rxUpperOrder = 0;
?? ?if(UsartRxQueueOrder != rxUpperOrder)//接受一包数据中断标志位
?? ?{
?? ??? ?memcpy(ComUpperRxDataBufRcv,UsartUpperRxBuf[rxUpperOrder].uartQueueBuf,UsartUpperRxBuf[rxUpperOrder].uartQueueLen);
?? ??? ?memset(UsartUpperRxBuf[rxUpperOrder].uartQueueBuf, 0, UsartUpperRxBuf[rxUpperOrder].uartQueueLen);
?? ??? ?UsartUpperRxBuf[rxUpperOrder].uartQueueLen = 0;
?? ??? ?UsartUpperRxBuf[rxUpperOrder].uartQueueCmdFlag = USART_DMA_IDLE;
?? ??? ?rxUpperOrder++;
?? ??? ?if(rxUpperOrder >= UART_UPPER_QUEUE_MAX)
?? ??? ?{
?? ??? ??? ?rxUpperOrder = 0;
?? ??? ?}
?? ? ?//在这里对ComUpperRxDataBufRcv进行解析
?? ??? ?if((ComUpperRxDataBufRcv[0] == 0xAA) && (ComUpperRxDataBufRcv[0] == 0x55))
?? ??? ?{
?? ??? ?
?? ??? ?}
?? ?}
}

6.main函数

int main(void)
{?
? u8 i;
?? ?UsartInit();
??
?? ?//测试发送数据,发送10包数据,每包数据从0~19
?? ?for(i = 0; i < 20; i++)
?? ?{
?? ??? ?sendTest[i] = i;
?? ?}
?? ?
?? ?for(i = 0 ; i < 10 ; i++)
?? ?{
?? ??? ?UsartSendData(sendTest,20);
?? ?}
?? ?
?? ?while(1)
?? ?{?? ?
?? ??? ?Usart6_SendData();
?? ??? ?ComUpperRxDataHandle();
?? ?}
}

7.源程序下载地址

源代码程序https://download.csdn.net/download/u011671172/31499254icon-default.png?t=L892https://download.csdn.net/download/u011671172/31499254

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-13 11:36:15  更:2021-10-13 11:37:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 4:49:12-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码