STM32之DMA及USART使用

usart.h文件:

#ifndef __USART_H
#define __USART_H

/* 引用头文件 */
#include "stm32f10x.h"

/* 接口定义 */
#define MY_USART                       USART1
#define MY_USART_BaudRate              115200
#define TIMOUT                      (uint32_t)0xFFF
#define BUFFER_SIZE                     10000

/* 函数声明 */
void USART_Config(void);
uint8_t USART_SendByte(USART_TypeDef * pUSARTx, uint8_t ch);
uint8_t USART_SendString(USART_TypeDef * pUSARTx,uint8_t* str);
uint8_t USART_Send_Num(USART_TypeDef * pUSARTx, uint32_t *array, uint16_t length);
void USART_DMA_Config(void);

#endif

usart.c文件:

#include "usart.h"

/** 函数功能:配置USART1
  * 返回值:void
  * 作者:ZY
  * 时间:2021.9.14
  */
void USART_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;

	/* 使能GPIOA USART1的时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);    
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

	/* USART TX PA9配置 复用推挽输出 */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 

	/* USART配置 */
	USART_InitStruct.USART_BaudRate = MY_USART_BaudRate; //波特率设置
	USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控制
	USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //收和发模式
	USART_InitStruct.USART_Parity = USART_Parity_No; //无奇偶校验
	USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位为1个位
	USART_InitStruct.USART_WordLength = USART_WordLength_8b; //无校验位 字长为8
	USART_Init(MY_USART,&USART_InitStruct);

	/* USAT1的中断配置*/ 
	NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
	NVIC_Init(&NVIC_InitStruct);
	
	/* 使能USART1接收中断 */
	USART_ITConfig(MY_USART,USART_IT_RXNE,ENABLE);
	
	/* 使能USART */
	USART_Cmd(MY_USART,ENABLE);
}

/** 函数功能:使用USART发送1字节数据
  * pUSARTx:使用USART号
  * ch:1字节数据
  * 返回值:0x01,发送成功 0x00,发送失败
  * 作者:ZY
  * 时间:2021.9.14
  */
uint8_t USART_SendByte(USART_TypeDef * pUSARTx, uint8_t ch)
{
	uint32_t time =0;
	
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx,ch);
	
	/* 等待发送数据寄存器为空 */
	while ((USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET) && (time != TIMOUT))
	{time++;}
	
	/* 再次判断是否发送成功 */
	if(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == SET)
		return 0x01;
	else return 0x00;
}

/** 函数功能:使用USART发送字符串
  * pUSARTx:使用USART号
  * str:字符串数据
  * 返回值:0x01,发送成功 0x00,发送失败
  * 作者:ZY
  * 时间:2021.9.14
  */
uint8_t USART_SendString(USART_TypeDef * pUSARTx,uint8_t* str)
{
	uint32_t time =0;
	
	/* 发送字符串数据 */
	do
	{
		USART_SendByte(pUSARTx,*(str++));
	}while(*str != '\0'); 
	
	/* 等待发送完成 */
	while ((USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) && (time != TIMOUT)) 
	{time++;}
	
	/* 再次判断是否发送成功 */
	if(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==SET)
		return 0x01;
	else return 0x00;
}

/** 函数功能:使用USART发送数字或数字数组
  * array:数字或数组地址
  * str:字符串数据
  * num:数组长度
  * 返回值:0x01,发送成功 0x00,发送失败
  * 作者:ZY
  * 时间:2021.9.14
  */
uint8_t USART_Send_Num(USART_TypeDef * pUSARTx, uint32_t *array, uint16_t length)
{
	uint8_t i;
	uint32_t time;
	
	for(i = 0; i<length; i++)
	{
		/* 发送数值 */
		USART_SendByte(pUSARTx,'0'+ array[i]);
	}
	
	time = 0;
	while ((USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) && (time != TIMOUT)) 
	{time++;}
	
	/* 再次判断是否发送成功 */
	if(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==SET)
		return 0x01;
	else return 0x00;
}

uint8_t usart_buffer[BUFFER_SIZE];
/** 函数功能:USART的DMA操作初始化
  * 返回值:void
  * 作者:ZY
  * 时间:2021.9.14
  */
void USART_DMA_Config(void)
{
	DMA_InitTypeDef DMA_InitStruct;
	
	/* 使能DMA1的时钟 */
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	
	/* DMA配置 */
	DMA_InitStruct.DMA_BufferSize = BUFFER_SIZE; // 传输数据大小
	DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralDST; // 传输方向 存储器到外设
	DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; // 存储器到存储器模式不使能
	DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)usart_buffer; // 内存地址
	DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; // 内存传输数据宽度
	DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; // 内存地址递增
	DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; // 传输1次
	DMA_InitStruct.DMA_PeripheralBaseAddr = USART1_BASE + 0x04; // 外设地址
	DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; // 外设传输数据宽度
	DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; // 外设地址不递增
	DMA_InitStruct.DMA_Priority = DMA_Priority_Medium; // 通道优先级为中
	DMA_Init(DMA1_Channel4,&DMA_InitStruct); 
	
	/* 使能DMA1 */
	DMA_Cmd(DMA1_Channel4,ENABLE);
}
/*****************************************END FILE**********************************************/

main.c文件:

#include "stm32f10x.h"
#include "usart.h"
#include "led.h" 
#include "delay.h"

extern uint8_t usart_buffer[BUFFER_SIZE];

int main(void)
{
	uint32_t i;
	uint32_t buff[]={1,2,3};
	
	for(i = 0; i<BUFFER_SIZE; i++)
	{
		usart_buffer[i] = 'A';
	}
	
	/* 2位抢占 2位相应 */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	delay_init();
	
	LedInt();
	
	/* USART1初始化 */
	USART_Config();
	
	/* 发送测试数据 */
	USART_SendString(MY_USART,"这是一个串口中断接收回显实验\r\n");
	USART_Send_Num(MY_USART,buff,3);
	
	USART_DMA_Config();
	
	USART_DMACmd(MY_USART, USART_DMAReq_Tx, ENABLE);
	
	while(1)
	{
		LED0 = !LED0;
		delay_ms(100);
	}
}

中断服务函数:

#include "usart.h"

uint8_t temp = 0;
void USART1_IRQHandler(void)
{
	if(USART_GetITStatus(MY_USART,USART_IT_RXNE) == SET)
	{
		temp = USART_ReceiveData(MY_USART);
		USART_SendData(MY_USART,temp);
		
		USART_ClearFlag(MY_USART,USART_FLAG_RXNE);
	}
}

注:亲测可用
参考资料:1.野火例程;2.STM32中文参考手册;

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值