#include "rs485.h"
#include "delay.h"
#include "usart.h"
uint8_t RS485_RX_BUF[256];
uint8_t RS485_RX_CNT = 0;
uint8_t RS485_RX_Flag = 0 ;
/**
* @brief 485初始化
* @param 波特率
* @retval
*/
void RS485Init(uint32_t bount)
{
uart2_init(bount);
RS485DmaInit();
}
/**
* @brief 串口2初始化
* @param 波特率
* @retval
*/
static void uart2_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_st;
USART_InitTypeDef USART_st;
//GPIO,USART1时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB,ENABLE);
//使能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_7);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_7);
//TX/RX
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,ENABLE);//复位串口2
RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2,DISABLE);//停止复位
//USART
USART_st.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART_st.USART_BaudRate = bound;
USART_st.USART_WordLength = USART_WordLength_8b;
USART_st.USART_Parity = USART_Parity_No;//奇偶校验位
USART_st.USART_StopBits = USART_StopBits_1;
USART_st.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_Init(USART2,&USART_st);
//NVIC
NVIC_st.NVIC_IRQChannel = USART2_IRQn;
NVIC_st.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_st.NVIC_IRQChannelSubPriority = 3;
NVIC_st.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_st);
#if Rs485IdleStatus
USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//开启串口空闲中断
USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
#else
USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//接收中断
#endif
USART_Cmd(USART2,ENABLE);
RS485_Rx;
}
/**
* @brief 串口2DMA初始化
* @param 波特率
* @retval
*/
static void RS485DmaInit(void)
{
DMA_InitTypeDef DMA_InitSt;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //DMA时钟
DMA_DeInit(DMA1_Channel6);
/*DMA初始化*/
DMA_InitSt.DMA_Mode = DMA_Mode_Normal;//普通模式
DMA_InitSt.DMA_BufferSize = 256;//256最大
DMA_InitSt.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->RDR);
DMA_InitSt.DMA_MemoryBaseAddr = (uint32_t)&RS485_RX_BUF;
DMA_InitSt.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设地址8位
DMA_InitSt.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器地址8位
DMA_InitSt.DMA_DIR = DMA_DIR_PeripheralSRC;//外设到存储器,存储器是目的地址
DMA_InitSt.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不增加
DMA_InitSt.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器地址增加
DMA_InitSt.DMA_Priority = DMA_Priority_High;//中等优先级
DMA_InitSt.DMA_M2M = DMA_M2M_Disable;//存储器到存储器关闭
DMA_Init(DMA1_Channel6,&DMA_InitSt);
DMA_Cmd(DMA1_Channel6,ENABLE);
}
//串口2接收中断服务函数
void USART2_IRQHandler(void)
{
uint8_t res;
#if Rs485IdleStatus
if (USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
{
USART2->ICR=1<<4; //stm32f334中的usart空闲中断需要把ICR寄存器中的IDLECF位置1清除空闲中断
// res=USART2->ISR;
// res=USART2->RDR; //清除USART_IT_IDLE标志位
DMA_Cmd(DMA1_Channel6,DISABLE);
res = 256 - DMA_GetCurrDataCounter(DMA1_Channel6); //得到接收的数据个数
DMA1_Channel6->CNDTR=256; //设置DMA下一次接收的字节数
DMA_Cmd(DMA1_Channel6,ENABLE);
RS485_RX_CNT = res;
USART_SendData(USART1,res);
}
#else
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
res = USART_ReceiveData(USART2); //读取接收到的数据
USART_SendData(USART1,res);
}
#endif
}
评论0