#define MCU_TX GPIO_Pin_9
#define MCU_RX GPIO_Pin_10
#define USARTCOM USART1
#define Clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE)
#define USART_IRQ USART1_IRQn
#define USART_IRQHandler USART1_IRQHandler
#define USART_RX_DMA_CHANNEL DMA1_Channel5
#define BUF_SIZE 0xFF
char USART_RX_BUF[BUF_SIZE];
//USART初始化
extern void USARTInit(uint32_t BaudRate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
GPIO_InitStructure.GPIO_Pin = MCU_TX;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = MCU_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = RS485_CTL ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
Clock;
USART_DeInit(USARTCOM);//串口默认配置 波特率9600 数据位8 停止位 无,控制位 NONE
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = BaudRate;
USART_Init(USARTCOM, &USART_InitStructure);
USART_ITConfig(USARTCOM, USART_IT_RXNE, ENABLE);
USART_ITConfig(USARTCOM, USART_IT_IDLE, ENABLE);
USART_Cmd(USARTCOM, ENABLE);
NVICInit();
DMAINIT();
}
//DMA配置
void DMAINIT(void)
{
USART_DMACmd(USARTCOM,USART_DMAReq_Rx,ENABLE); //使能串口1 DMA接收
//相应的DMA配置
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
DMA_DeInit(USART_RX_DMA_CHANNEL); //将DMA的通道5寄存器重设为缺省值 串口1对应的是DMA通道5
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //DMA外设usart基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)USART_RX_BUF; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,从外设读取发送到内存
DMA_InitStructure.DMA_BufferSize = BUF_SIZE; //DMA通道的DMA缓存的大小
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通道 x拥有中优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输
DMA_Init(USART_RX_DMA_CHANNEL, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道
DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE); //正式驱动DMA传输
}
void NVICInit(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStructure.NVIC_IRQChannel = USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void MYDMA_Enable(void)
{
DMA_Cmd(USART_RX_DMA_CHANNEL, DISABLE ); //关闭USART1 TX DMA1所指示的通道
DMA_SetCurrDataCounter(USART_RX_DMA_CHANNEL,RxSize);//DMA通道的DMA缓存的大小
DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE); //打开USART1 TX DMA1所指示的通道
}
//中断处理函数
void USART_IRQHandler(void)
{
if(USART_GetITStatus(USARTCOM, USART_IT_IDLE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
USART_ReceiveData(USARTCOM);//读取数据注意:这句必须要,否则不能够清除中断标志位。
RLen =RxSize-DMA_GetCurrDataCounter(USART_RX_DMA_CHANNEL); //算出接本帧数据长度
USART_ClearITPendingBit(USARTCOM,USART_IT_IDLE); //清除中断标志
}
}
//输出数据
extern void USARTWrite(char *pSrc,uint16_t len)
{
USART_ClearFlag(USARTCOM,USART_FLAG_TXE);
USART_ClearFlag(USARTCOM,USART_FLAG_TC);
while(len-- > 0)
{
while(USART_GetFlagStatus(USARTCOM,USART_FLAG_TXE) == RESET);
USART_SendData(USARTCOM,*pSrc++);
}
while(USART_GetFlagStatus(USARTCOM,USART_FLAG_TC) == RESET);
}
//接收数据处理
extern void USARTRead(void)
{
if(RLen > 0)
{
USARTWrite(USART_RX_BUF,RLen);
RLen = 0;
MYDMA_Enable();//恢复DMA指针,等待下一次的接收
}
}