//-------------------------------------------------------------------
// Uart1.c
// 串口通讯控制:用于内阻仪的通讯
//-------------------------------------------------------------------
#include "System_Define.h"
#include "DataProcess.h"
#include "crc8.h"
#include "uart1.h"
Commu_Rec_Fmt CommBuff1; // 接收缓冲 结构体变量
uint08 UartTxBuff[UART_MAX_PACKET]; // 发送缓冲
uint08 UartRxBuff[UART_MAX_PACKET]; // 发送缓冲
__IO uint08 Flag_Uart_Send = 0; // 允许发送
//---------------------------------------------------------
// 初始化UART的接口和时钟
void Init_Uart1_IO(void)
{
GPIO_InitTypeDef PortDef;
//-----------------------------------------------------
// UART
// TX
PortDef.GPIO_Pin = USART1_TX_GPIO_PIN;
PortDef.GPIO_Speed = USART1_TX_GPIO_SPEED;
PortDef.GPIO_Mode = USART1_TX_GPIO_MODE;
GPIO_Init(USART1_TX_GPIO_PORT,&PortDef);
// RX
PortDef.GPIO_Pin = USART1_RX_GPIO_PIN;
PortDef.GPIO_Speed = USART1_RX_GPIO_SPEED;
PortDef.GPIO_Mode = USART1_RX_GPIO_MODE;
GPIO_Init(USART1_RX_GPIO_PORT,&PortDef);
//-----------------------------------------------------
}
//------------------------------------------------------
// DMA发送中断设置
void Init_Uart_DMA(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
//------------------------------------------------------------------
// DMA UART TX中断
//------------------------------------------------------------------
// 中断设置
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//------------------------------------------------------------------
// DMA UART TX
//------------------------------------------------------------------
// DMA1通道4配置
DMA_DeInit(DMA1_Channel4);
// 外设地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);
// 内存地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UartTxBuff;
// dma传输方向单向
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
// 设置DMA在传输时缓冲区的长度
DMA_InitStructure.DMA_BufferSize = UART_MAX_PACKET;
// 设置DMA的外设递增模式,一个外设
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 设置DMA的内存递增模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外设数据字长
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
// 内存数据字长
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;
// 设置DMA的传输模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
// 设置DMA的优先级别
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
// 设置DMA的2个memory中的变量互相访问
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel4,&DMA_InitStructure);
// 中断允许
DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);
//------------------------------------------------------------------
// DMA UART RX
//------------------------------------------------------------------
// DMA1通道5配置
DMA_DeInit(DMA1_Channel5);
// 外设地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DR);
// 内存地址
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)UartRxBuff;
// dma传输方向单向
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
// 设置DMA在传输时缓冲区的长度
DMA_InitStructure.DMA_BufferSize = UART_MAX_PACKET;
// 设置DMA的外设递增模式,一个外设
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 设置DMA的内存递增模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外设数据字长
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_VeryHigh;
// 设置DMA的2个memory中的变量互相访问
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5,&DMA_InitStructure);
//使能通道5
DMA_Cmd(DMA1_Channel5,ENABLE);
}
// 初始化Uart
void Init_Uart1(uint32 Baud)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// IO口设置
Init_Uart1_IO();
// DMA处理
Init_Uart_DMA();
//------------------------------------------------------
// 时钟控制
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
// 清除参数
USART_DeInit(USART1);
// 参数设定
USART_InitStructure.USART_BaudRate = Baud;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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);
// 时钟设定
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_1Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
USART_ClockInit(USART1,&USART_ClockInitStructure);
// 串口中断
//USART_ITConfig(USART1,USART_IT_TC,DISABLE); //
//USART_ITConfig(USART1,USART_IT_RXNE,DISABLE); // 禁止接收中断
USART_ITConfig(USART1,USART_IT_IDLE,ENABLE); //
// Enable the USART1 global Interrupt
NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );//中断优先级分组,先占优先级4位,从占优先级0为
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// DMA操作
USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);// 使能UART1的DMA方式
USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE);
// Enable the USART1
USART_Cmd(USART1, ENABLE);
// 初始值
CommBuff1.Enb = 0;
CommBuff1.Len = 0;
}
// 串口1DMA方式发送中断
void DMA1_Channel4_IRQHandler(void)
{
//清除标志位
DMA_ClearFlag(DMA1_FLAG_TC4);
//关闭DMA
DMA_Cmd(DMA1_Channel4,DISABLE);
// 等待发送完成
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){}
//允许再次发送
Flag_Uart_Send = 0;
}
// 串口发送一个包
void Uart1_Send_Packet(uint08 *buff,uint08 length)
{
uint08 i;
// 等待发送完成
while(Flag_Uart_Send){}
if(length<=UART_MAX_PACKET)
{
// 补充数据
UartTxBuff[0] = 0x4C;
UartTxBuff[1] = 0xE2;
UartTxBuff[2] = length+1;
// 数据
for(i=0;i<length;i++)
{
UartTxBuff[i+3] = buff[i];
}
// 校验
UartTxBuff[length+3] = CRC8(UartTxBuff+3,length);
// 发送
Flag_Uart_Send = 1;
DMA_SetCurrDataCounter(DMA1_Channel4,length+4);
DMA_Cmd(DMA1_Channel4,ENABLE);
}
else
{
// 发送出错信息--数据溢出
SendErrInfo(_ERR_OVR);
}
}
// 串口数据接收:中断处理
void USART1_IRQHandler(void)
{
uint32_t temp = 0;
uint16_t i = 0;
// 空闲中断
if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
{
// 清USART_IT_IDLE标志
temp = USART1->SR;
temp = USART1->DR;
DMA_Cmd(DMA1_Channel5,DISABLE);
// 数据量
temp = UART_MAX_PACKET - DMA_GetCurrDataCounter(DMA1_Channel5);
// 格式判断
if((UartRxBuff[0] == 0x70)&&(UartRxBuff[1] == 0x48))
{
// 长度比较
if(UartRxBuff[2] == temp-3)
{
// 长度
CommBuff1.Len = UartRxBuff[2];
// 数据转移
for (i = 0;i < CommBuff1.Len; i++)
{
CommBuff1.Buf[i] = UartRxBuff[i+3];
}
CommBuff1.Enb = 1;
}
}
//设置传输数据长度
DMA_SetCurrDataCounter(DMA1_Channel5,UART_MAX_PACKET);
//打开DMA
DMA_Cmd(DMA1_Channel5,ENABLE);
}
}