本帖最后由 AlphaESS 于 2019-11-7 10:23 编辑
1. 最近uart这里运行1天左右就通讯丢失了
2. 经查证是uart就不进入中断了,485总线上我的数据一直在发,也有回应
3. 但是为什么有数据不能进入中断,而且是运行1天左右才能出现这个现象,之前都是正常的,百思不得其解?
4. 下面是我uart部分的代码,求大神给个解决方向
/*********************************************************************************
* Includes
*********************************************************************************/
#include "includes.h"
#include "usart3.h"
#include "delay.h"
#include "timer.h"
/*********************************************************************************
* Globales
*********************************************************************************/
struct FifoQueue usart3_rx_Queue;
OS_EVENT *USART3_MUTEX;
OS_EVENT *USART3_SEM;
UART_HandleTypeDef USART3_Handler; //USART3句柄(用于USART3)
/*********************************************************************************
* Functions
*********************************************************************************/
/*********************************************************************************************
* @Name :void USART3_QueueInit(struct FifoQueue *Queue)
* @Parameter :
* @Return :NULL
* @Brief :
*********************************************************************************************/
void USART3_QueueInit(struct FifoQueue *Queue)
{
Queue->front = Queue->rear = 0; //????????????
Queue->count = 0; //?????0
memset(Queue->dat,0,QueueSize);
}
/*********************************************************************************************
* @Name :uint8 USART3_QueueIn(struct FifoQueue *Queue,uint8 sdat)
* @Parameter :
* @Return :NULL
* @Brief :0 ueueFull 2 ueueOperateOk
*********************************************************************************************/
uint8 USART3_QueueIn(struct FifoQueue *Queue,uint8 sdat) //??????
{
if( (Queue->rear + 1) % QueueSize == Queue->front )
{ // full
return QueueFull;
}
else
{ // in
Queue->dat[Queue->rear] = sdat;
Queue->rear = (Queue->rear + 1) % QueueSize;
Queue->count = Queue->count + 1;
return QueueOperateOk;
}
}
/*********************************************************************************************
* @Name :uint8 USART3_QueueOut(struct FifoQueue *Queue,uint8 *sdat)
* @Parameter :
* @Return :NULL
* @Brief : 1 ueueEmpty 2 ueueOperateOk
*********************************************************************************************/
uint8 USART3_QueueOut(struct FifoQueue *Queue,uint8 *sdat)
{
if(Queue->front == Queue->rear)
{ // empty
return QueueEmpty;
}
else
{ // out
*sdat = Queue->dat[Queue->front];
Queue->front = (Queue->front + 1) % QueueSize;
if(Queue->count > 0)
{
Queue->count = Queue->count - 1;
}
else
{
Queue->count = 0;
}
return QueueOperateOk;
}
}
/*********************************************************************************************
* @Name :uint8 Is_usart3_rev_data()
* @Parameter :
* @Return :NULL
* @Brief : 1 :收到数据 0 :没有收到数据
*********************************************************************************************/
uint8 Is_rev_usart3_data()
{
uint8 res;
if(usart3_rx_Queue.front != usart3_rx_Queue.rear)
{
res = 1;
}
else
{
res = 0;
}
return res;
}
/*********************************************************************************************
* @Name :void uart3_init(u32 bound)
* @Parameter ://初始化IO 串口3 //bound:波特率
* @Return :NULL
* @Brief :
*********************************************************************************************/
void uart3_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_GPIOH_CLK_ENABLE(); //开启GPIOH时钟
__HAL_RCC_USART3_CLK_ENABLE(); //使能USART3时钟
GPIO_Initure.Pin=GPIO_PIN_10; //PH10
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOH,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_10|GPIO_PIN_11; //PB10,11
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
GPIO_Initure.Alternate=GPIO_AF7_USART3; //复用为USART3
HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化 PB10,11
//USART 初始化设置
USART3_Handler.Instance=USART3; //USART3
USART3_Handler.Init.BaudRate=bound; //波特率
USART3_Handler.Init.WordLength=UART_WORDLENGTH_8B; //字长为8位数据格式
USART3_Handler.Init.StopBits=UART_STOPBITS_1; //一个停止位
USART3_Handler.Init.Parity=UART_PARITY_NONE; //无奇偶校验位
USART3_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE; //无硬件流控
USART3_Handler.Init.Mode=UART_MODE_TX_RX; //收发模式
HAL_UART_Init(&USART3_Handler); //HAL_UART_Init()会使能USART3
__HAL_UART_DISABLE_IT(&USART3_Handler,UART_IT_TC);
__HAL_UART_ENABLE_IT(&USART3_Handler,UART_IT_RXNE);//开启接收中断
HAL_NVIC_EnableIRQ(USART3_IRQn); //使能USART3中断
HAL_NVIC_SetPriority(USART3_IRQn,PREEMPT_PRIOR_LEV_03,SUB_PRIOR_LEV_03); //抢占优先级3,子优先级3
USART3_TX_Set(0); //设置为接收模式
USART3_QueueInit(&usart3_rx_Queue);
#if (RS485_COM_TIME_DELAY == TIMEX_DELAY_USART_SEM)
TIM13_Init( get_timer_t35_base_50us(bound) );
#endif
}
/*********************************************************************************************
* @Name :void USART3_IRQHandler(void)
* @Parameter :
* @Return :NULL
* @Brief :
*********************************************************************************************/
void USART3_IRQHandler(void)
{
u8 ret = 0;
u8 res;
u8 temp = 0 ;
#if SYSTEM_SUPPORT_OS //使用OS
OSIntEnter();
#endif
if(__HAL_UART_GET_FLAG(&USART3_Handler,UART_FLAG_RXNE) != RESET) //接收中断
{
ret = HAL_UART_Receive(&USART3_Handler,&res,1,1000);
if( USART3_QueueIn(&usart3_rx_Queue,res) == QueueFull) //接收到数据 头指针 == 尾指针
{
USART3_QueueOut(&usart3_rx_Queue,&temp); //取出一个数据 尾指针后移一个字节
USART3_QueueIn(&usart3_rx_Queue,res); //填充一个数据 头指针后移一个字节
}
__HAL_UART_CLEAR_FLAG(&USART3_Handler,UART_FLAG_RXNE);
if( __HAL_UART_GET_FLAG(&USART3_Handler,UART_FLAG_ORE)!=RESET )
{
__HAL_UART_CLEAR_OREFLAG(&USART3_Handler);
}
#if (RS485_COM_TIME_DELAY == TIMEX_DELAY_USART_SEM)
mb_port_timer13_enable();
#endif
}
else if( __HAL_UART_GET_FLAG(&USART3_Handler,UART_FLAG_ORE)!=RESET )
{
__HAL_UART_CLEAR_OREFLAG(&USART3_Handler);
}
#if SYSTEM_SUPPORT_OS //使用OS
OSIntExit();
#endif
}
/*********************************************************************************************
* @Name :void USART3_TX_Set(u8 en)
* @Parameter ://en:0,接收;1,发送.
* @Return :NULL
* @Brief ://USART3模式控制.
*********************************************************************************************/
void USART3_TX_Set(u8 en)
{
if(Get_Version_Hard_EMS() == VER_HARD_V104)
{
RS485_RE3 = en;
}
else if(Get_Version_Hard_EMS() == VER_HARD_V105)
{
RS485_RE3 = !en;
}
else
{
RS485_RE3 = !en;
}
}
/*********************************************************************************************
* @Name :u8 USART3_Send_Data(u8 *buf,u16 len,u16 timeout)
* @Parameter :
* @Return :1:发送成功
* @Brief ://USART3发送len个字节.//buf:发送区首地址 //len:发送的字节数
*********************************************************************************************/
u8 USART3_Send_Data(u8 *buf,u16 len,u16 timeout)
{
INT8U err;
u8 res = 0;
INT8U l_u8_err = 0;
#if SYSTEM_SUPPORT_OS //使用OS
OSMutexPend(USART3_MUTEX,timeout,&err);
#endif
if(err == OS_ERR_NONE)
{
USART3_TX_Set(1); //设置为发送模式
res = HAL_UART_Transmit(&USART3_Handler,buf,len,timeout);//串口3发送数据
if(res == HAL_OK)
{
res= 1;
}
USART3_TX_Set(0); //设置为接收模式
}
#if SYSTEM_SUPPORT_OS //使用OS
OSMutexPost(USART3_MUTEX);
#if (RS485_COM_TIME_DELAY == TIMEX_DELAY_USART_SEM)
OSSemPend(USART3_SEM, OS_PEND_SEM_TIMEOUT, &l_u8_err);
#endif
#endif
return res;
}
/*********************************************************************************************
* @Name :u16 USART3_Receive_Data(u8 *buf,u16 len,u16 timeout)
* @Parameter :
* @Return :实际接收到的长度
* @Brief ://从队列 中 取len 数据 ,直到取完为止
*********************************************************************************************/
u16 USART3_Receive_Data(u8 *buf,u16 len,u16 timeout)
{
INT8U err;
u16 i=0;
#if SYSTEM_SUPPORT_OS //使用OS
OSMutexPend(USART3_MUTEX, timeout, &err);
#endif
if(err == OS_ERR_NONE)
{
for(i = 0;i < len;i++ )
{
if( USART3_QueueOut(&usart3_rx_Queue,&buf) == QueueEmpty )
{
#if SYSTEM_SUPPORT_OS //使用OS
OSMutexPost(USART3_MUTEX);
#endif
return (i);
}
}
#if SYSTEM_SUPPORT_OS //使用OS
OSMutexPost(USART3_MUTEX);
#endif
return len;
}
#if SYSTEM_SUPPORT_OS //使用OS
OSMutexPost(USART3_MUTEX);
#endif
return 0;
}
/*********************************************************************************************
* @Name :void USART3_test()
* @Parameter :
* @Return :
* @Brief :
*********************************************************************************************/
void USART3_test()
{
u8 test_buf[10] = {0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55};
u8 rev_buf[64];
// USART3_Send_Data(test_buf,10,USART_TX_TIMEOUT);
while(Is_rev_usart3_data() != 0)
{
USART3_Receive_Data(rev_buf,1,USART_RX_TIMEOUT);
USART3_Send_Data(rev_buf,1,USART_TX_TIMEOUT);
}
} |
|