串口空闲中断加DMA数据搬运

ops/2024/10/18 2:28:29/

1 usart.c 

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>//void Serial_Init(void)
//{
//    //使能GPIOA 以及串口1的时钟
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE); 
//    
//    
//    GPIO_InitTypeDef GPIO_InitStructure;;
//    //初始化对应IO
//	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
//	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
//	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//	GPIO_Init(GPIOA,&GPIO_InitStructure);
//	
//	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
//	GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;
//	GPIO_Init(GPIOA,&GPIO_InitStructure);
//    
//    
//    USART_InitTypeDef USART_InitStructure;
//    	//配置USART参数
//	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(USART1,&USART_InitStructure);
//    
//    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//    
//    NVIC_InitTypeDef NVIC_InitStructure;
//	//配制中断源
//	NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;	
//	//配制抢占优先级
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
//	//配制子优先级
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
//	//使能中断
//	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
//  //初始化配置NVIC
//	NVIC_Init(&NVIC_InitStructure);
//    
//    //使能串口接收中断
//	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
//    //使能串口1
//	USART_Cmd(USART1,ENABLE);	
//    
//}void Uart_Config(void)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//使能GPIOA 以及串口1的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE); //初始化对应IOGPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置USART参数USART_DeInit(USART1);USART_InitStructure.USART_BaudRate=115200;USART_InitStructure.USART_WordLength=USART_WordLength_8b; //字节宽度8USART_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);//配置中断控制器//配置中断控制器组选择NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//配制中断源NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;	//配制抢占优先级NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//配制子优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//使能中断NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//初始化配置NVICNVIC_Init(&NVIC_InitStructure);//使能串口接收中断修改为串口总线空闲中断
//	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);//使能串口1USART_Cmd(USART1,ENABLE);	}void Serial_SendByte(uint8_t Byte)
{USART_SendData(USART1, Byte);		//将字节数据写入数据寄存器,写入后USART自动生成时序波形while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);	//等待发送完成/*下次写入数据寄存器会自动清除发送完成标志位,故此循环后,无需清除标志位*/
}/*** 函    数:使用printf需要重定向的底层函数* 参    数:保持原始格式即可,无需变动* 返 回 值:保持原始格式即可,无需变动*/
int fputc(int ch, FILE *f)
{Serial_SendByte(ch);			//将printf的底层重定向到自己的发送字节函数return ch;
}//void DMA_SendConfig(DMA_Channel_TypeDef* DMAy_Channelx,u32 cpar,u32 cmar,u16 buf)
//{
//	
//	DMA_InitTypeDef DMA_InitStructure;
//	NVIC_InitTypeDef NVIC_InitStructure;
//    //使能DMA时钟
//	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
//	//配置DMA参数
//	
//	//配置内存地址
//	DMA_InitStructure.DMA_MemoryBaseAddr=cmar;
//	//配置外设地址
//	DMA_InitStructure.DMA_PeripheralBaseAddr=cpar; 
//	//配置数据传输方向 外设作为数据传输目的地(外设作为数据源)
//	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;
//	//配置数据传输大小
//	DMA_InitStructure.DMA_BufferSize=buf;
//	//禁止外设地址递增
//	DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
//	//允许内存地址是否递增
//	DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
//	//配置外设数据单位 8位字节传输
//	DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
//	//配置内存数据单位
//	DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
//	//配置DMA模式 单次传输(循环传输)
//	DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;
//	//配置DMA优先级
//	DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;
//	//配置是否使能从内存到内存传输
//	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;
//	//配置DMA通道初始化
//	DMA_Init(DMAy_Channelx,&DMA_InitStructure);
//	DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
//	
//		//配置串口接收中断源
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//	NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel4_IRQn;
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2;
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//	NVIC_Init(&NVIC_InitStructure);
//	
//	//使能DMADMA_Cmd(DMAy_Channelx,ENABLE);
//}//void USART1_IRQHandler(void)                               
//{   
//	
//	u8 temp=0;
//	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
//	{temp=USART_ReceiveData(USART1);USART_SendData(USART1,temp);
//        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
//	}
//    u8 temp1=0;
//	if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)
//	{
//		temp1=USART_ReceiveData(USART1);
//		USART_SendData(USART1,temp1);
//	}
//}void DMA_SendConfig(DMA_Channel_TypeDef* DMAy_Channelx,u32 cpar,u32 cmar,u16 buf)
{DMA_InitTypeDef DMA_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//使能DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//配置DMA参数//配置内存地址DMA_InitStructure.DMA_MemoryBaseAddr=cmar;//配置外设地址DMA_InitStructure.DMA_PeripheralBaseAddr=cpar; //配置数据传输方向 外设作为数据传输目的地(外设作为数据源)DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralDST;//配置数据传输大小DMA_InitStructure.DMA_BufferSize=buf;//禁止外设地址递增DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//允许内存地址是否递增DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//配置外设数据单位 8位字节传输DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//配置内存数据单位DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//配置DMA模式 单次传输(循环传输)DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//配置DMA优先级DMA_InitStructure.DMA_Priority=DMA_Priority_Medium;//配置是否使能从内存到内存传输DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//配置DMA通道初始化DMA_Init(DMAy_Channelx,&DMA_InitStructure);DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);//配置串口接收中断源NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel=DMA1_Channel4_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//使能DMA
//	DMA_Cmd(DMAy_Channelx,ENABLE);
}void DMA_ReceiveConfig(DMA_Channel_TypeDef* DMAy_Channelx,u32 cpar,u32 cmar,u16 buf)
{DMA_InitTypeDef DMA_InitStructure;//使能DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//配置DMA参数//配置内存地址DMA_InitStructure.DMA_MemoryBaseAddr=cmar;//配置外设地址DMA_InitStructure.DMA_PeripheralBaseAddr=cpar; //配置数据传输方向 外设作为数据源DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC;//配置数据传输大小DMA_InitStructure.DMA_BufferSize=buf;//禁止外设地址递增DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//允许内存地址是否递增DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//配置外设数据单位 8位字节传输DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//配置内存数据单位DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//配置DMA模式 单次传输(循环传输)DMA_InitStructure.DMA_Mode=DMA_Mode_Normal;//配置DMA优先级DMA_InitStructure.DMA_Priority=DMA_Priority_High;//配置是否使能从内存到内存传输DMA_InitStructure.DMA_M2M=DMA_M2M_Disable;//配置DMA通道初始化DMA_Init(DMAy_Channelx,&DMA_InitStructure);//使能DMADMA_Cmd(DMAy_Channelx,ENABLE);}u16 Data_LEN=100; //数据长度
u8 SendBuf[100];  
u8 ReceBuf[100];uint8_t Data_Receive_Usart; void USART1_IRQHandler(void)                               
{   uint32_t temp = 0;uint16_t i = 0;if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET){//USART_ClearFlag(USART3,USART_IT_IDLE);//temp = USART1->SR;  //串口状态寄存器temp = USART1->DR; // 串口数据寄存器 (取消后会有数据丢位现象 原因待查)DMA_Cmd(DMA1_Channel5,DISABLE); //禁用DMA接收通道temp = Data_LEN - DMA_GetCurrDataCounter(DMA1_Channel5); //获取DMA1通道5剩余数据for (i = 0;i < temp;i++){Data_Receive_Usart = ReceBuf[i]; //变量接收DMA通道5的数据	SendBuf[i]=Data_Receive_Usart;	 //将接收到的数据传到SendBuf中DMA1_Channel4->CNDTR = (uint16_t)temp; //设置需要传输的数据量DMA_Cmd(DMA1_Channel4, ENABLE);   		}//设置传输数据长度DMA_SetCurrDataCounter(DMA1_Channel5,Data_LEN);  //设置当前DMA1通道5中的数据量//打开DMADMA_Cmd(DMA1_Channel5,ENABLE);} 
} 	void DMA1_Channel4_IRQHandler(void)
{if(DMA_GetITStatus(DMA1_FLAG_TC4)==SET)  //传输完成中断{DMA_ClearFlag(DMA1_FLAG_GL4);    //清楚通道4全局标志位    DMA_Cmd(DMA1_Channel4, DISABLE); //关闭数据输出通道}
}void Test_fun(void)
{DMA_ReceiveConfig(DMA1_Channel5,(u32)&USART1->DR,(u32)ReceBuf,100);USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);DMA_SendConfig(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuf,100);USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);}

2 usart.h

#ifndef __SERIAL_H
#define __SERIAL_H#include <stdio.h>void Serial_Printf(char *format, ...);
void Uart_Config(void);void Test_fun(void);void DMA_SendConfig(DMA_Channel_TypeDef* DMAy_Channelx,u32 cpar,u32 cmar,u16 buf);
void DMA_ReceiveConfig(DMA_Channel_TypeDef* DMAy_Channelx,u32 cpar,u32 cmar,u16 buf);#endif

3 main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"uint8_t RxData;			//定义用于接收串口数据的变量int main(void)
{/*串口初始化*/
//	Serial_Init();		//串口初始化Uart_Config();//通过串口1发送单个数据 
//    USART_SendData(USART1,0xA0);  	
//检查指定的串口标志位是否设置Test_fun();while (1){}
}


http://www.ppmy.cn/ops/126360.html

相关文章

C++ IO多路复用 poll模型

原文链接&#xff1a;C IO多路复用 poll模型 预备知识 poll模型前置需要了解的可以参考: IO控制:fcntl库:IO控制库 多线程:C Linux多线程同步通信-信号量 socket:C Linux多进程Socket通信 select模型:C IO多路复用 select模型 poll模型 特性 原理 poll是对select的改…

C#从零开始学习(Head First C#)

想要开发游戏&#xff0c;C#是unity用的编程语言,所以想系统的巩固和学习一下&#xff0c;在此记录自己的学习笔记&#xff0c;来和大家共同学习&#xff0c;同时也希望能够帮助一些想入门的同学&#xff0c;因此我会使用Head First C#这本书籍,从最开始的章节记录。给自己定个…

【环境搭建】远程服务器搭建ElasticSearch

参考&#xff1a; 非常详细的阿里云服务器安装ElasticSearch过程..._阿里云服务器使用elasticsearch-CSDN博客 服务器平台&#xff1a;AutoDL 注意&#xff1a; 1、切换为非root用户&#xff0c;su 新用户名&#xff0c;否则ES无法启动 2、安装过程中没有出现设置账号密码…

使用shell实现高精度时间日志记录与时间跳变检测

文章目录 0. 概述1. 使用说明1.1. 参数说明1.2. 运行脚本 2. 脚本详细解析2.1. 参数初始化2.2. 参数解析与验证2.3 主循环条件2.4 时间跳变检测与处理2.5. 日志轮转机制2.6. 睡眠时间计算 0. 概述 之前写过单线程版本的高精度时间日志记录小程序&#xff1a;C编程&#xff1a;…

前端布局,y轴超出滚动、x轴超出展示方案

想要实现布局效果&#xff0c;红区高度固定可滑动可收起。红区引用绿区组件。 一般会想到如下方案&#xff0c;红区样式&#xff1a; width&#xff1a;200px; height: 100%; overflow-y: auto; overflow-x: visible; 但是效果并不好&#xff0c;绿区直接隐藏了 最终采用布局方…

数字后端零基础入门系列 | Innovus零基础LAB学习Day1

一 Floorplan 数字IC后端设计如何从零基础快速入门&#xff1f;(内附数字IC后端学习视频&#xff09; Lab5-1这个lab学习目标很明确——启动Innovus工具并完成设计的导入。 在进入lab之前&#xff0c;我们需要进入我们的FPR工作目录。 其中ic062为个人服务器账户。比如你端…

C++初阶学习第七弹——string的模拟实现

C初阶学习第六弹------标准库中的string类_c语言返回string-CSDN博客 通过上篇我们已经学习到了string类的基本使用&#xff0c;这里我们就试着模拟实现一些&#xff0c;我们主要实现一些常用到的函数。 目录 一、string类的构造 二、string类的拷贝构造 三、string类的析构函…

JDBC增删改查操作的基本步骤

JDBC&#xff08;Java Database Connectivity&#xff09;是一种用于执行数据库操作的Java API。以下是使用JDBC进行增删改查&#xff08;CRUD&#xff09;操作的基本步骤和代码示例。 步骤&#xff1a; 加载数据库驱动&#xff1a;确保JDBC驱动程序类被加载。建立数据库连接…