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中文参考手册;