//发送DMA配置
DMA_Cmd(DMA_USART1_TX_CHANNEL, DISABLE); // 关DMA通道
DMA_DeInit(DMA_USART1_TX_CHANNEL); // 恢复缺省值
DMA_Initstructure.DMA_PeripheralBaseAddr =(unsigned int)(&USART1->DR); // 设置串口接收数据寄存器
DMA_Initstructure.DMA_MemoryBaseAddr = (unsigned int)Usart1_Info.TxDMABuf; // 设置发送缓冲区首地址
DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralDST; // 设置外设为目的地址,内存缓冲区 ->外设寄存器
DMA_Initstructure.DMA_BufferSize = USART1_BUFLENGTH; // 需要最大可能接收到的字节数
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_Mode_Circular; 单次传输模式DMA_Mode_Normal;
DMA_Initstructure.DMA_Priority = DMA_Priority_High; // 优先级设置,设置为高
DMA_Initstructure.DMA_M2M = DMA_M2M_Disable;
//启动发送DMA
DMA_Init(DMA_USART1_TX_CHANNEL,&DMA_Initstructure); // 开启接收DMA通道,等待接收数据
// 开启发送DMA通道中断
DMA_ITConfig(DMA_USART1_TX_CHANNEL, DMA_IT_TC, ENABLE); //DMA_IT_TC传输完成中断(transfer complete)
DMA_ITConfig(DMA_USART1_TX_CHANNEL, DMA_IT_TE, ENABLE); //DMA_IT_TE传输错误中断(transfer error)
DMA_ClearFlag(DMA_USART1_TX_FLAG); // 清除DMA所有标志
DMA_Cmd(DMA_USART1_TX_CHANNEL,DISABLE); //启用DMA通道
//接收DMA配置
DMA_Cmd(DMA_USART1_RX_CHANNEL,DISABLE); //关DMA通道
DMA_DeInit(DMA_USART1_RX_CHANNEL);
DMA_Initstructure.DMA_PeripheralBaseAddr =(unsigned int)(&USART1->DR); // 设置串口接收数据寄存器
DMA_Initstructure.DMA_MemoryBaseAddr = (unsigned int)Usart1_Info.RxBuf; // 设置发送缓冲区首地址
DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置外设为数据源,外设寄存器 ->内存缓冲区
DMA_Initstructure.DMA_BufferSize = USART1_BUFLENGTH; // 需要最大可能接收到的字节数
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_Circular; // 循环传输模式:DMA_Mode_Circular; 单次传输模式DMA_Mode_Normal;
DMA_Initstructure.DMA_Priority = DMA_Priority_High; // 优先级设置,设置为高
DMA_Initstructure.DMA_M2M = DMA_M2M_Disable; //关闭存储器到存储器传输模式
//开启接收DMA通道
DMA_Init(DMA_USART1_RX_CHANNEL,&DMA_Initstructure);
DMA_ITConfig(DMA_USART1_RX_CHANNEL,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA_USART1_RX_CHANNEL,DMA_IT_TE,ENABLE);
DMA_ClearFlag(DMA_USART1_RX_FLAG);
DMA_Cmd(DMA_USART1_RX_CHANNEL,ENABLE);
//开启USART1的DMA模式
USART_DMACmd(USART1,USART_DMAReq_Rx|USART_DMAReq_Tx,ENABLE);
}
/********************************************************************************
* 函 数 名 : Usart1_SendtoTXbuf *
* 功 能 说 明 : Usart1发送数据到TX缓存区 *
* 形 参 : data:待发送数据首地址 *
* length:待发送数据长度
* 返 回 值 : 无 *
*********************************************************************************/
void Usart1_SendtoTXbuf( unsigned char *data, unsigned int length )
{
unsigned int i;
if( length )
{
for( i=0;i
{
Usart1_Info.TxLength++;
Usart1_Info.TxBuf[Usart1_Info.TxTail++]= data
; //循环缓冲区装载数据
if( Usart1_Info.TxTail >= USART1_BUFLENGTH )
{
Usart1_Info.TxTail -= USART1_BUFLENGTH;
}
}
}
}
/********************************************************************************
* 函 数 名 : Usart1_SendtoTXDMAbuf *
* 功 能 说 明 : Usart1发送数据到TX缓存区 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void Usart1_SendtoTXDMAbuf( void )
{
unsigned int i;
if( Usart1_Info.TxLength && ( Usart1_Info.TxDMABusy == USART1_DMA_IDLE ) )
{
//有数据发送,往DMA缓冲区转移
for( i=0; i
{
Usart1_Info.TxDMABuf = Usart1_Info.TxBuf[Usart1_Info.TxIndex++];
Usart1_Info.TxIndex = CirclePosition( Usart1_Info.TxIndex, USART1_BUFLENGTH );
}
//启动DMA数据发送
DMA_SetCurrDataCounter(DMA_USART1_TX_CHANNEL,Usart1_Info.TxLength);
Usart1_Info.TxLength = 0x00;
Usart1_Info.TxDMABusy = USART1_DMA_BUSY;
DMA_Cmd(DMA_USART1_TX_CHANNEL, ENABLE);
}
}
/********************************************************************************
* 函 数 名 : USART1_IRQHandler *
* 功 能 说 明 : Usart1中断处理函数 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void USART1_IRQHandler(void)
{
//DMA模式
unsigned int num;
unsigned int Length;
//DMA_GetCurrDataCounter
if( USART_GetITStatus( USART1,USART_IT_IDLE ) == SET ) //整帧接收完成中断
{
DMA_Cmd(DMA_USART1_RX_CHANNEL,DISABLE); //关闭接收DMA通道
//num = USART1->SR;
num = USART1->DR; //读SR后读DR清USART_IT_IDLE标志
num = DMA_GetCurrDataCounter(DMA_USART1_RX_CHANNEL); //DMA接收数据后剩余缓存区间大小
//计算接收数据的长度
if( Usart1_Info.PreRxDMACounter >= num )
{
Length = Usart1_Info.PreRxDMACounter - num;
}
else
{
Length = USART1_BUFLENGTH - num + Usart1_Info.PreRxDMACounter;
}
Usart1_Info.RxLength += Length;
Usart1_Info.PreRxDMACounter = num;
Usart1_Info.RxIndex = CirclePosition( Usart1_Info.RxIndex + Length, USART1_BUFLENGTH );
USART_ClearITPendingBit(USART1, USART_IT_IDLE); //清除中断标志
DMA_Cmd(DMA_USART1_RX_CHANNEL,ENABLE); //重新开启DMA接收
}
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR
USART_ReceiveData(USART1); //读DR
}
}
/********************************************************************************
* 函 数 名 : DMA1_Channel2_IRQHandler *
* 功 能 说 明 : 发送DMA中断处理函数 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void DMA1_Channel4_IRQHandler(void)
{
DMA_ClearFlag(DMA1_FLAG_GL4); //清除DMA发送完成标志
DMA_Cmd(DMA_USART1_TX_CHANNEL, DISABLE); //关闭发送DMA通道
Usart1_Info.TxDMABusy = USART1_DMA_IDLE; //发送通道空闲
}
/********************************************************************************
* 函 数 名 : Usart1_Init *
* 功 能 说 明 : Usart1初始化 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void Usart1_Init(void)
{
Usart1_ParameterInit(115200,'N',8,1);
Usart1_HardwareInit();
Usart1_DMAInit();
}
UART1.h
#ifndef _BSP_UART1_H_
#define _BSP_UART1_H_
#include "stm32f10x.h"
#define USART1_BUFLENGTH 256
#define DMA_USART1_RX_CHANNEL DMA1_Channel5
#define DMA_USART1_TX_CHANNEL DMA1_Channel4
#define DMA_USART1_RX_FLAG DMA1_FLAG_GL5 //DMA1_CHANNEL5全局中断标志
#define DMA_USART1_TX_FLAG DMA1_FLAG_GL4 //DMA1_CHANNEL4全局中断标志
#define USART1_DMA_IDLE 0x00 //USART3_DMA 空闲
#define USART1_DMA_BUSY 0x01 //USART3_DMA 忙
typedef struct
{
unsigned long Baudrate; //波特率
unsigned int Parity; //奇偶校验
unsigned int DataBit; //数据位
unsigned int StopBit; //停止位
unsigned char RxBuf[USART1_BUFLENGTH]; //接收缓存区长度
unsigned int RxIndex; //
unsigned int RxHead; //
unsigned int RxLength; //接收数据长度
unsigned int PreRxDMACounter; //DMA剩余缓存区间大小
unsigned char TxBuf[USART1_BUFLENGTH]; //发送缓存区长度
unsigned char TxDMABuf[USART1_BUFLENGTH ]; //DMA缓冲区
unsigned int TxIndex; //
unsigned int TxTail; //
unsigned int TxLength; //待发送数据长度
unsigned int TxDMABusy; //DMA发送忙信号
unsigned int OverTime; //通讯延时
} Stu_USART1_INFO;
//GPIO定义
#define USART1_TX_PORT GPIOA
#define USART1_TX_PIN GPIO_Pin_9
#define USART1_RX_PORT GPIOA
#define USART1_RX_PIN GPIO_Pin_10
/********************************************************************************************
* 变 量 声 明 *
*********************************************************************************************/
extern Stu_USART1_INFO Usart1_Info;
/********************************************************************************************
* 函 数 声 明 *
*********************************************************************************************/
extern void Usart1_SendtoTXbuf( unsigned char *data, unsigned int length );
extern void Usart1_SendtoTXDMAbuf( void );
extern void Usart1_Init(void);
extern unsigned int CirclePosition( unsigned int position, unsigned int length );
#endif
//发送DMA配置
DMA_Cmd(DMA_USART1_TX_CHANNEL, DISABLE); // 关DMA通道
DMA_DeInit(DMA_USART1_TX_CHANNEL); // 恢复缺省值
DMA_Initstructure.DMA_PeripheralBaseAddr =(unsigned int)(&USART1->DR); // 设置串口接收数据寄存器
DMA_Initstructure.DMA_MemoryBaseAddr = (unsigned int)Usart1_Info.TxDMABuf; // 设置发送缓冲区首地址
DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralDST; // 设置外设为目的地址,内存缓冲区 ->外设寄存器
DMA_Initstructure.DMA_BufferSize = USART1_BUFLENGTH; // 需要最大可能接收到的字节数
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_Mode_Circular; 单次传输模式DMA_Mode_Normal;
DMA_Initstructure.DMA_Priority = DMA_Priority_High; // 优先级设置,设置为高
DMA_Initstructure.DMA_M2M = DMA_M2M_Disable;
//启动发送DMA
DMA_Init(DMA_USART1_TX_CHANNEL,&DMA_Initstructure); // 开启接收DMA通道,等待接收数据
// 开启发送DMA通道中断
DMA_ITConfig(DMA_USART1_TX_CHANNEL, DMA_IT_TC, ENABLE); //DMA_IT_TC传输完成中断(transfer complete)
DMA_ITConfig(DMA_USART1_TX_CHANNEL, DMA_IT_TE, ENABLE); //DMA_IT_TE传输错误中断(transfer error)
DMA_ClearFlag(DMA_USART1_TX_FLAG); // 清除DMA所有标志
DMA_Cmd(DMA_USART1_TX_CHANNEL,DISABLE); //启用DMA通道
//接收DMA配置
DMA_Cmd(DMA_USART1_RX_CHANNEL,DISABLE); //关DMA通道
DMA_DeInit(DMA_USART1_RX_CHANNEL);
DMA_Initstructure.DMA_PeripheralBaseAddr =(unsigned int)(&USART1->DR); // 设置串口接收数据寄存器
DMA_Initstructure.DMA_MemoryBaseAddr = (unsigned int)Usart1_Info.RxBuf; // 设置发送缓冲区首地址
DMA_Initstructure.DMA_DIR = DMA_DIR_PeripheralSRC; // 设置外设为数据源,外设寄存器 ->内存缓冲区
DMA_Initstructure.DMA_BufferSize = USART1_BUFLENGTH; // 需要最大可能接收到的字节数
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_Circular; // 循环传输模式:DMA_Mode_Circular; 单次传输模式DMA_Mode_Normal;
DMA_Initstructure.DMA_Priority = DMA_Priority_High; // 优先级设置,设置为高
DMA_Initstructure.DMA_M2M = DMA_M2M_Disable; //关闭存储器到存储器传输模式
//开启接收DMA通道
DMA_Init(DMA_USART1_RX_CHANNEL,&DMA_Initstructure);
DMA_ITConfig(DMA_USART1_RX_CHANNEL,DMA_IT_TC,ENABLE);
DMA_ITConfig(DMA_USART1_RX_CHANNEL,DMA_IT_TE,ENABLE);
DMA_ClearFlag(DMA_USART1_RX_FLAG);
DMA_Cmd(DMA_USART1_RX_CHANNEL,ENABLE);
//开启USART1的DMA模式
USART_DMACmd(USART1,USART_DMAReq_Rx|USART_DMAReq_Tx,ENABLE);
}
/********************************************************************************
* 函 数 名 : Usart1_SendtoTXbuf *
* 功 能 说 明 : Usart1发送数据到TX缓存区 *
* 形 参 : data:待发送数据首地址 *
* length:待发送数据长度
* 返 回 值 : 无 *
*********************************************************************************/
void Usart1_SendtoTXbuf( unsigned char *data, unsigned int length )
{
unsigned int i;
if( length )
{
for( i=0;i
{
Usart1_Info.TxLength++;
Usart1_Info.TxBuf[Usart1_Info.TxTail++]= data; //循环缓冲区装载数据
if( Usart1_Info.TxTail >= USART1_BUFLENGTH )
{
Usart1_Info.TxTail -= USART1_BUFLENGTH;
}
}
}
}
/********************************************************************************
* 函 数 名 : Usart1_SendtoTXDMAbuf *
* 功 能 说 明 : Usart1发送数据到TX缓存区 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void Usart1_SendtoTXDMAbuf( void )
{
unsigned int i;
if( Usart1_Info.TxLength && ( Usart1_Info.TxDMABusy == USART1_DMA_IDLE ) )
{
//有数据发送,往DMA缓冲区转移
for( i=0; i
{
Usart1_Info.TxDMABuf = Usart1_Info.TxBuf[Usart1_Info.TxIndex++];
Usart1_Info.TxIndex = CirclePosition( Usart1_Info.TxIndex, USART1_BUFLENGTH );
}
//启动DMA数据发送
DMA_SetCurrDataCounter(DMA_USART1_TX_CHANNEL,Usart1_Info.TxLength);
Usart1_Info.TxLength = 0x00;
Usart1_Info.TxDMABusy = USART1_DMA_BUSY;
DMA_Cmd(DMA_USART1_TX_CHANNEL, ENABLE);
}
}
/********************************************************************************
* 函 数 名 : USART1_IRQHandler *
* 功 能 说 明 : Usart1中断处理函数 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void USART1_IRQHandler(void)
{
//DMA模式
unsigned int num;
unsigned int Length;
//DMA_GetCurrDataCounter
if( USART_GetITStatus( USART1,USART_IT_IDLE ) == SET ) //整帧接收完成中断
{
DMA_Cmd(DMA_USART1_RX_CHANNEL,DISABLE); //关闭接收DMA通道
//num = USART1->SR;
num = USART1->DR; //读SR后读DR清USART_IT_IDLE标志
num = DMA_GetCurrDataCounter(DMA_USART1_RX_CHANNEL); //DMA接收数据后剩余缓存区间大小
//计算接收数据的长度
if( Usart1_Info.PreRxDMACounter >= num )
{
Length = Usart1_Info.PreRxDMACounter - num;
}
else
{
Length = USART1_BUFLENGTH - num + Usart1_Info.PreRxDMACounter;
}
Usart1_Info.RxLength += Length;
Usart1_Info.PreRxDMACounter = num;
Usart1_Info.RxIndex = CirclePosition( Usart1_Info.RxIndex + Length, USART1_BUFLENGTH );
USART_ClearITPendingBit(USART1, USART_IT_IDLE); //清除中断标志
DMA_Cmd(DMA_USART1_RX_CHANNEL,ENABLE); //重新开启DMA接收
}
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE)==SET)
{
USART_ClearFlag(USART1,USART_FLAG_ORE); //读SR
USART_ReceiveData(USART1); //读DR
}
}
/********************************************************************************
* 函 数 名 : DMA1_Channel2_IRQHandler *
* 功 能 说 明 : 发送DMA中断处理函数 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void DMA1_Channel4_IRQHandler(void)
{
DMA_ClearFlag(DMA1_FLAG_GL4); //清除DMA发送完成标志
DMA_Cmd(DMA_USART1_TX_CHANNEL, DISABLE); //关闭发送DMA通道
Usart1_Info.TxDMABusy = USART1_DMA_IDLE; //发送通道空闲
}
/********************************************************************************
* 函 数 名 : Usart1_Init *
* 功 能 说 明 : Usart1初始化 *
* 形 参 : 无 *
* 返 回 值 : 无 *
*********************************************************************************/
void Usart1_Init(void)
{
Usart1_ParameterInit(115200,'N',8,1);
Usart1_HardwareInit();
Usart1_DMAInit();
}
UART1.h
#ifndef _BSP_UART1_H_
#define _BSP_UART1_H_
#include "stm32f10x.h"
#define USART1_BUFLENGTH 256
#define DMA_USART1_RX_CHANNEL DMA1_Channel5
#define DMA_USART1_TX_CHANNEL DMA1_Channel4
#define DMA_USART1_RX_FLAG DMA1_FLAG_GL5 //DMA1_CHANNEL5全局中断标志
#define DMA_USART1_TX_FLAG DMA1_FLAG_GL4 //DMA1_CHANNEL4全局中断标志
#define USART1_DMA_IDLE 0x00 //USART3_DMA 空闲
#define USART1_DMA_BUSY 0x01 //USART3_DMA 忙
typedef struct
{
unsigned long Baudrate; //波特率
unsigned int Parity; //奇偶校验
unsigned int DataBit; //数据位
unsigned int StopBit; //停止位
unsigned char RxBuf[USART1_BUFLENGTH]; //接收缓存区长度
unsigned int RxIndex; //
unsigned int RxHead; //
unsigned int RxLength; //接收数据长度
unsigned int PreRxDMACounter; //DMA剩余缓存区间大小
unsigned char TxBuf[USART1_BUFLENGTH]; //发送缓存区长度
unsigned char TxDMABuf[USART1_BUFLENGTH ]; //DMA缓冲区
unsigned int TxIndex; //
unsigned int TxTail; //
unsigned int TxLength; //待发送数据长度
unsigned int TxDMABusy; //DMA发送忙信号
unsigned int OverTime; //通讯延时
} Stu_USART1_INFO;
//GPIO定义
#define USART1_TX_PORT GPIOA
#define USART1_TX_PIN GPIO_Pin_9
#define USART1_RX_PORT GPIOA
#define USART1_RX_PIN GPIO_Pin_10
/********************************************************************************************
* 变 量 声 明 *
*********************************************************************************************/
extern Stu_USART1_INFO Usart1_Info;
/********************************************************************************************
* 函 数 声 明 *
*********************************************************************************************/
extern void Usart1_SendtoTXbuf( unsigned char *data, unsigned int length );
extern void Usart1_SendtoTXDMAbuf( void );
extern void Usart1_Init(void);
extern unsigned int CirclePosition( unsigned int position, unsigned int length );
#endif
举报