测试要求:间隔100ms连续收发256字节数据五分钟不丢包
#include "u485.h"
#include "to_init.h"
#include <string.h>
uint8_t u485_test1_data;//测试程序数据标识
#define DATA_LENGTH 256
static uint8_t rxData1[DATA_LENGTH], rxData2[DATA_LENGTH];
static uint16_t rxIndex1 = 0, rxIndex2 = 0, DataRxLen1 = 0, DataTxLen1 =0, DataRxLen2 = 0, DataTxLen2 =0;
static uint8_t txData1[DATA_LENGTH], txData2[DATA_LENGTH];
static uint16_t txIndex1 = 0, txIndex2 = 0;
static uint8_t dataReceived1 = 0,dataReceived2 = 0;
void RS485_1_init(void)
{
rcu_periph_clock_enable(RCU_GPIOE);
rcu_periph_clock_enable(RCU_UART6);
gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_8);
gpio_af_set(GPIOE, GPIO_AF_8, GPIO_PIN_7);
gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_8);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
gpio_mode_set(GPIOE, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_7);
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_7);
usart_deinit(UART6);
usart_baudrate_set(UART6,115200U);
usart_word_length_set(UART6, USART_WL_8BIT);
usart_stop_bit_set(UART6, USART_STB_1BIT);
usart_parity_config(UART6, USART_PM_NONE);
usart_receive_config(UART6, USART_RECEIVE_ENABLE);
usart_transmit_config(UART6, USART_TRANSMIT_ENABLE);
usart_interrupt_enable(UART6,USART_INT_RBNEIE); //使能“读数据缓冲区非空中断和过载错误中断”
usart_interrupt_enable(UART6, USART_INT_IDLEIE); // 使能“IDLE线检测中断”
nvic_irq_enable(UART6_IRQn,1,2);
usart_enable(UART6);
gpio_init(RD_485_1,out,up,RD_485_1_P,PP,H50M);
gpio_out_off(RD_485_1,RD_485_1_P);
}
/**********************************************************************************
* Function Name : RS485_1_send
* Description : 串口发送函数,每次发送一个字节,如需发送协议,可嵌套调用此函数
* Input : ch:发送的字节
* Output : None
* Return : None
**********************************************************************************/
void RS485_1_send(int ch)
{
gpio_out_on(RD_485_1,RD_485_1_P);
delay_nms(1);
usart_data_transmit(UART6, ch);
delay_nms(1);
while(RESET == usart_flag_get(UART6, USART_FLAG_TBE));
gpio_out_off(RD_485_1,RD_485_1_P);
}
/**********************************************************************************
* Function Name : RS485_1_read
* Description : 串口读取函数中断
* Input : ch:发送的字节
* Output : None
* Return : None
**********************************************************************************/
void UART6_IRQHandler(void)
{
//接收中断
if (usart_flag_get(UART6, USART_FLAG_RBNE) != RESET)
{
//如果满足以下条件,说明缓存区还有空间去存储数据
if(rxIndex1 < DATA_LENGTH)
{
rxData1[rxIndex1++] = usart_data_receive(UART6);
}
usart_flag_clear(UART6,USART_FLAG_RBNE);
}
// 如果满足以下条件,说明检测到“IDLE线检测中断标志”被置位
if(RESET != usart_flag_get(UART6, USART_FLAG_IDLEF))
{
// volatile uint32_t temp = USART_STAT0(UART6);
// (void)temp;
usart_data_receive(UART6); /* 清除接收完成标志位 */
// 如果满足以下条件,说明已经接收到了一帧数据
if(rxIndex1 > 0)
{
usart_receive_config(UART6, USART_RECEIVE_DISABLE);// 关闭串口接收功能,准备处理数据
DataRxLen1 = rxIndex1;
rxIndex1 = 0;
}
usart_flag_clear(UART6,USART_FLAG_IDLEF);
}
// 如果满足以下条件,说明检测到“发送缓冲区空中断标志”被置位
if(usart_flag_get(UART6, USART_FLAG_TBE) != RESET)
{
if(DataTxLen1 > 0)
{
// 如果满足以下条件,说明缓存中还有数据没发送完
if(txIndex1 < DATA_LENGTH)
{
usart_data_transmit(UART6, txData1[txIndex1++]);
}
else// 反之,说明缓存中的数据都已经发送完毕
{
DataTxLen1 = 0;
txIndex1 = 0;
usart_interrupt_disable(UART6,USART_INT_TBEIE);//关中断
gpio_out_off(RD_485_1,RD_485_1_P);
}
}
else// 反之,说明缓存中没有数据需要发送
{
usart_interrupt_disable(UART6,USART_INT_TBEIE);//关中断
}
usart_flag_clear(UART6,USART_FLAG_TBE);
}
}
/**********************************************************************************
* Function Name : RS485_2_init
* Description : RS485初始化函数
* Input : None
* Output : None
* Return : None
**********************************************************************************/
void RS485_2_init(void)
{
rcu_periph_clock_enable( RCU_GPIOD);
rcu_periph_clock_enable(RCU_USART2);
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_8);
gpio_af_set(GPIOD, GPIO_AF_7, GPIO_PIN_9);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_8);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_8);
gpio_mode_set(GPIOD, GPIO_MODE_AF, GPIO_PUPD_PULLUP,GPIO_PIN_9);
gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_9);
usart_deinit(USART2);
usart_baudrate_set(USART2,115200U);
usart_word_length_set(USART2, USART_WL_8BIT);
usart_stop_bit_set(USART2, USART_STB_1BIT);
usart_parity_config(USART2, USART_PM_NONE);
usart_receive_config(USART2, USART_RECEIVE_ENABLE);
usart_transmit_config(USART2, USART_TRANSMIT_ENABLE);
usart_interrupt_enable(USART2,USART_INT_RBNEIE);//使能“读数据缓冲区非空中断和过载错误中断”
usart_interrupt_enable(USART2, USART_INT_IDLEIE); // 使能“IDLE线检测中断”
nvic_irq_enable(USART2_IRQn,1,3);
usart_enable(USART2);
gpio_init(RD_485_2,out,up,RD_485_2_P,PP,H50M);
gpio_out_off(RD_485_2,RD_485_2_P);
}
/**********************************************************************************
* Function Name : RS485_2_send
* Description : 串口发送函数,每次发送一个字节,如需发送协议,可嵌套调用此函数
* Input : ch:发送的字节
* Output : None
* Return : None
**********************************************************************************/
void RS485_2_send(int ch)
{
gpio_out_on(RD_485_2,RD_485_2_P);
delay_nms(1);
usart_data_transmit(USART2, ch);
delay_nms(1);
while(RESET == usart_flag_get(USART2, USART_FLAG_TBE));
gpio_out_off(RD_485_2,RD_485_2_P);
}
/**********************************************************************************
* Function Name : RS485_2_read
* Description : 串口读取函数中断
* Input : ch:发送的字节
* Output : None
* Return : None
**********************************************************************************/
void USART2_IRQHandler(void)
{
{
//接收中断
if (usart_flag_get(USART2, USART_FLAG_RBNE) != RESET)
{
//如果满足以下条件,说明缓存区还有空间去存储数据
if(rxIndex2 < DATA_LENGTH)
{
rxData2[rxIndex2++] = usart_data_receive(USART2);
}
usart_flag_clear(USART2,USART_FLAG_RBNE);
}
// 如果满足以下条件,说明检测到“IDLE线检测中断标志”被置位
if(RESET != usart_flag_get(USART2, USART_FLAG_IDLEF))
{
// volatile uint32_t temp = USART_STAT0(USART2);
// (void)temp;
usart_data_receive(USART2); /* 清除接收完成标志位 */
// 如果满足以下条件,说明已经接收到了一帧数据
if(rxIndex2 > 0)
{
usart_receive_config(USART2, USART_RECEIVE_DISABLE);// 关闭串口接收功能,准备处理数据
DataRxLen2 = rxIndex2;
rxIndex2 = 0;
}
usart_flag_clear(USART2,USART_FLAG_IDLEF);
}
// 如果满足以下条件,说明检测到“发送缓冲区空中断标志”被置位
if(usart_flag_get(USART2, USART_FLAG_TBE) != RESET)
{
if(DataTxLen2 > 0)
{
// 如果满足以下条件,说明缓存中还有数据没发送完
if(txIndex2 < DATA_LENGTH)
{
usart_data_transmit(USART2, txData2[txIndex2++]);
}
else// 反之,说明缓存中的数据都已经发送完毕
{
DataTxLen2 = 0;
txIndex2 = 0;
usart_interrupt_disable(USART2,USART_INT_TBEIE);//关中断
gpio_out_off(RD_485_2,RD_485_2_P);
}
}
else// 反之,说明缓存中没有数据需要发送
{
usart_interrupt_disable(USART2,USART_INT_TBEIE);//关中断
}
usart_flag_clear(USART2,USART_FLAG_TBE);
}
}
}
void rs485datacopy(void)
{
// 如果满足以下条件,说明串口接收到了一帧数据
if(DataRxLen1 > 0)
{
// 如果满足以下条件,说明串口并没有在发送数据
if(!(DataTxLen1 > 0))
{
memcpy(txData1, rxData1, DataRxLen1);// 将接收到的数据从 RX 缓存保存到 TX 缓存
DataTxLen1 = DataRxLen1;
DataRxLen1 = 0;
gpio_out_on(RD_485_1,RD_485_1_P);
usart_interrupt_enable(UART6,USART_INT_TBEIE);//启用RS485-1发送中断
// 处理完数据,重新开启串口接收功能以及相关中断
usart_receive_config (UART6, USART_RECEIVE_ENABLE);
usart_interrupt_enable(UART6, USART_INT_RBNEIE);
usart_interrupt_enable(UART6, USART_INT_IDLEIE);
}
}
// 如果满足以下条件,说明串口接收到了一帧数据
if(DataRxLen2 > 0)
{
// 如果满足以下条件,说明串口并没有在发送数据
if(!(DataTxLen2 > 0))
{
memcpy(txData2, rxData2, DataRxLen2);// 将接收到的数据从 RX 缓存保存到 TX 缓存
DataTxLen2 = DataRxLen2;
DataRxLen2 = 0;
gpio_out_on(RD_485_2,RD_485_2_P);
usart_interrupt_enable(USART2,USART_INT_TBEIE);//启用RS485-2发送中断
// 处理完数据,重新开启串口接收功能以及相关中断
usart_receive_config (USART2, USART_RECEIVE_ENABLE);
usart_interrupt_enable(USART2, USART_INT_RBNEIE);
usart_interrupt_enable(USART2, USART_INT_IDLEIE);
}
}
}