雅特力单片机用串口USART_INT_TDE中断(发送缓冲区空闲时中断)比用USART_INT_TRAC(发送全部完成时中断)的 发送效率要高:
请自行验证代码的正确性,不对此负责!!
void UART0_SendData(volatile Uint8 *buf, Uint8 len)
{
union
{
Uint8 crc[2];
Uint16 crc16;
} my_crc;
UART0_PointerSend = buf;
UART0_SendCount = len + 2;
my_crc.crc16 = Uart_GenerateCRC(buf, len);
UART0_SendBuffer[len] = my_crc.crc[0];
UART0_SendBuffer[len + 1] = my_crc.crc[1];
//UART0_Enable(B_FALSE, B_TRUE);
UART0_Enable(B_FALSE, B_TRUE);
}
#define RS485_DIR_PORT GPIOF
#define RS485_DIR_PIN GPIO_Pins_7
#define UART0_SEND_ENABLE() GPIO_SetBits(RS485_DIR_PORT, RS485_DIR_PIN)
#define UART0_RECEIVE_ENABLE() GPIO_ResetBits(RS485_DIR_PORT, RS485_DIR_PIN)
void UART0_Enable( Uint8 xRxEnable, Uint8 xTxEnable)
{
if( xRxEnable )
{
UART0_RECEIVE_ENABLE();
USART_INTConfig(USART1, USART_INT_RDNE, ENABLE);
USART_INTConfig(USART1, USART_INT_TDE, DISABLE);
}
if( xTxEnable )
{
UART0_SEND_ENABLE();
USART_INTConfig(USART1, USART_INT_RDNE, DISABLE);
USART_INTConfig(USART1, USART_INT_TDE, ENABLE);
}
}
u32 V2_1_left_times_for_writeOut=0;
u8 started_writeOut=0;
void TMR4_for_when_UART0_Enable_falt(void)//20us 一次
{
if(V2_1_left_times_for_writeOut>0){
V2_1_left_times_for_writeOut--;
}
if(UART0_SendCount==0&&V2_1_left_times_for_writeOut==0){
if(started_writeOut==1){
UART0_Enable(B_TRUE, B_FALSE);//这个用于保证不发生:如果丢了一次UART0_Enable(B_TRUE, B_FALSE),则再也不能进入接收模式,导致通讯卡死
started_writeOut=0;
}
}
}
//20us中断一次的定时器中断:
void TMR4_GLOBAL_IRQHandler(){ //100khz RCLK
if (TMR_GetINTStatus(TMR4, TMR_INT_Overflow) != RESET)
{
TMR_ClearITPendingBit(TMR4, TMR_INT_Overflow);
TMR4_for_when_UART0_Enable_falt();
}
}
void USART1_IRQHandler(void)
{
volatile Uint8 dummy = 0;
volatile Uint8 temp = 0;
if(USART_GetITStatus(USART1, USART_INT_ERR) != RESET)
{
USART_ClearITPendingBit(USART1, USART_INT_ERR);
}
if(USART_GetITStatus(USART1, USART_INT_ORERR) != RESET)
{
USART_ClearITPendingBit(USART1, USART_INT_ORERR);
}
if(USART_GetITStatus(USART1, USART_INT_NERR) != RESET)
{
USART_ClearITPendingBit(USART1, USART_INT_NERR);
}
if(USART_GetITStatus(USART1, USART_INT_FERR) != RESET)
{
USART_ClearITPendingBit(USART1, USART_INT_FERR);
}
if(USART_GetITStatus(USART1, USART_INT_TDE) != RESET)
{
USART_ClearITPendingBit(USART1, USART_INT_TDE);
if(0 != UART0_SendCount)
{
UART0_SendOneByte((Uint8)(*UART0_PointerSend));
UART0_SendCount--;
UART0_PointerSend++;
started_writeOut=1;
V2_1_left_times_for_writeOut=400;//200的话2400波特率下不行,400在2400波特率下可以(在2400波特率下传输1个字节的时间大约 4.17毫秒,所以超时时间必须大于4.2ms),200*20us=4ms,考虑 UART0_Enable(B_TRUE, B_FALSE); 丢了一次后,TMR4_GLOBAL_IRQHandler里强制设置UART0_Enable(B_TRUE, B_FALSE)还能来得及,比如6ms内回码时可以
}
else
{
USART_INTConfig(USART1, USART_INT_TDE, DISABLE);
USART_INTConfig(USART1, USART_INT_TRAC, ENABLE);
}
}
else
if(USART_GetITStatus(USART1, USART_INT_TRAC) != RESET)
{
USART_ClearITPendingBit(USART1, USART_INT_TRAC);
USART_INTConfig(USART1, USART_INT_TRAC, DISABLE);
UART0_Enable(B_TRUE, B_FALSE); //如果丢了一次UART0_Enable(B_TRUE, B_FALSE),则再也不能进入接收模式,导致通讯卡死
started_writeOut=0;
}
if(USART_GetITStatus(USART1, USART_INT_RDNE) != RESET ) //接收中断使能
{
Flag.ModbusFrameStart = B_TRUE;
Flag.ModbusFrameOver = B_FALSE;
Flag.UartDelay35ms = 0;
USART_ClearITPendingBit(USART1, USART_INT_RDNE);
if(UART0_ReceiveCount < 39)
{
UART0_ReceiveBuffer[UART0_ReceiveCount] = (USART_ReceiveData(USART1));
UART0_ReceiveCount++;
}
else
{
temp = (USART_ReceiveData(USART1));
}
}
}