⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.c

📁 采用循环队列的方式接收串口数据,由其在接收协议数据的时候可有效的防止丢包现象.
💻 C
字号:

#define _UART_C_
#include "include.h"

#define BAUD 	9600
#define CRYSTAL	11059200

#define BAUD_SETTING	(unsigned int)((unsigned long)CRYSTAL/(16*(unsigned long)BAUD)-1)
#define BAUD_H	(unsigned char)(BAUD_SETTING>>8)
#define BAUD_L	(unsigned char)(BAUD_SETTING)

/*******************************************************************************
** 函数名称: void uartInit(void)
** 输   入: num 0-串口0
**               1-串口1
** 输   出: 无
** 全局变量: 无
** 功能描述: 串口初始化
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
void uartInit(uint8 uartNum)
{
	if(1==uartNum)
	{
		 UCSR1B = 0x00; //disable while setting baud rate
	 	 UCSR1A = 0x00;
	 	 UCSR1C = 0x06;
	 	 UBRR1L = BAUD_L; //set baud rate lo
	 	 UBRR1H = BAUD_H; //set baud rate hi
	 	 UCSR1B = 0x98;	  // 接收、发送使能,接收中断使能
	 	 //共有3个中断源, 接受, 发送, 寄存器空, 对应此寄存器的高3位
	}	
	else
	{
		UCSR0B = 0x00; //disable while setting baud rate
	 	UCSR0A = 0x00;
		UCSR0C = 0x06;	//set frame format, 8 bits, 2stop]
		UBRR0H = BAUD_H;
		UBRR0L = BAUD_L;
		UCSR0B = 0x98;	//0x18为允许接收和发关,0x98时全能接收中断,允许接收.
	}	
}

/*******************************************************************************
** 函数名称: void putChar(void)
** 输   入: num 0-串口0
**               1-串口1
**           dat 要发送的数据.
** 输   出: 1 发送完成
**           0 发送失败
** 全局变量: 无
** 功能描述: 发送一个字节
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
uint8 putChar(uint8 num, uint8 dat)
{
	if(1 == num)
	{
	 	while ( !( UCSR1A & (1<<UDRE1)) );
		UDR1 = dat;
	}
	else if(0 == num)
	{
	 	while ( !( UCSR0A & (1<<UDRE0)) );
		UDR0 = dat;
	}
	else
	{
		return 0;
	}
	return 1;
}

/*******************************************************************************
** 函数名称: uint8 putStr(uint8 num, uint8 *str, uint8 len)
** 输   入: num  0-串口0
**                1-串口1
**           *str 要发送的数据首指.
**           len  要发送的字节数
** 输   出: 1 发送完成
**           0 发送失败
** 全局变量: 无
** 功能描述: 发送一个字符串
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
uint8 putStr(uint8 num, uint8 *str, uint8 len)
{
	uint8 i = 0;
	while((*str != NULL) && (len > 0))
	{
		if(0 ==  putChar(num, *str) )
		{
			return i;
		}
		i++;
		str++;
		len--;
	}
	return i;	
}

/*******************************************************************************
** 函数名称: void putCharHex(void)
** 输   入: num  0-串口0
**                1-串口1
**           dat  要发送的数据
** 输   出: 1 发送完成
**           0 发送失败
** 全局变量: 无
** 功能描述: 发送一个字节的hex码,分成两个字节发。
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
uint8 const hex_[] = {"0123456789ABCDEF"}; 
uint8 putCharHex(uint8 num, uint8 dat)
{
    uint8 ch;
	uint8 flag;
	ch = (dat >> 4) & 0x0F;
	flag = putChar(num, hex_[ch]);
	if (0 == flag)
	{ 
		return 0;
	}
	ch = dat & 0x0F;
	flag = putChar(num, hex_[ch]);
	if (0 == flag)
	{ 
		return 0;
	}
	return 1;
}

/*******************************************************************************
** 函数名称: void putStrHex(void)
** 输   入: num  0-串口0
**                1-串口1
**           *str 要发送的数据首指.
**           len  要发送的字节数
** 输   出: 1 发送完成
**           0 发送失败
** 全局变量: 无
** 功能描述: 发送一个字符串的HEX
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
uint8  putStrHex(uint8 num, uint8 *str, uint8 len)
{
	uint8 i = 0;
	while((*str != NULL) && (len > 0))
	{
		if (0 == putCharHex(num, *str))
		{
			return i;
		}
		str++;
		i++;
		len--;
	}
	return i;
}
/*******************************************************************************
** 函数名称: void uart0_rx_isr(void)
** 输   入: 
** 输   出: 
** 全局变量: 
** 功能描述: UART0 接受完成中断,将数据送入缓冲区
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
#pragma	interrupt_handler	uart0_rx_isr:19    //iv_USART0_RXC
void uart0_rx_isr(void)
{
 	unsigned char   temp; 
	ENTER_CRITICAL();//uart has received a character in UDR                      
	temp = UDR0;
	
	if(Uart0RxBufLen > Uart0RxBufCnt)
    {
        Uart0RxBuf[Uart0RxBufCnt++] = temp;
        Uart0RxBufCnt %= Uart0RxBufLen;
        Uart0Null=0;
    }
	
 	EXIT_CRITICAL();
}

/*******************************************************************************
** 函数名称: void uart1_rx_isr(void)
** 输   入: 
** 输   出: 
** 全局变量: 
** 功能描述: UART1 接受完成中断,将数据送入缓冲区
** 作   者: 侍任伟 
** 日   期: 2008年4月1日
**------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
**------------------------------------------------------------------------------
*******************************************************************************/
#pragma interrupt_handler uart1_rx_isr:31
void uart1_rx_isr(void)
{
 	unsigned char   temp; 
	ENTER_CRITICAL();//uart has received a character in UDR                      
	temp = UDR1;

	if(Uart1RxBufLen > Uart1RxBufCnt)
    {
        Uart1RxBuf[Uart1RxBufCnt++] = temp;
        Uart1RxBufCnt %= Uart1RxBufLen;
        Uart1Null=0;
    }
 	EXIT_CRITICAL();
}

//发送寄存器空中断
#pragma interrupt_handler uart1_udre_isr:32
void uart1_udre_isr(void)
{
 	ENTER_CRITICAL();//character transferred to shift register so UDR is now empty
 	EXIT_CRITICAL();
}

//发送完成中断
#pragma interrupt_handler uart1_tx_isr:33
void uart1_tx_isr(void)
{
 	ENTER_CRITICAL();;//character has been transmitted
 	EXIT_CRITICAL();
}


/*******************************************************************************************************
** 函数名称: int8 uartgetc(uint8 uartNum)
** 功能描述: 从串口缓冲区读取一个数据
** 输   入: uartNum - 端口号
** 输   出: dat 如果没有读出返回-1,否则返回当前读取到的数据
** 全局变量: 无
** 调用模块: 
** 作   者: 侍任伟
** 日   期: 2008年04月11日
**------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
** 描    述:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int32 UartGetChar(uint8 uartNum)
{
	int32 dat = -1;
	if(0 == uartNum)
	{
		if(1 == Uart0Null)
		{
			return dat;
		}
		else
		{
			dat = Uart0RxBuf[Uart0RdCnt];
			Uart0RdCnt++;
			Uart0RdCnt %= Uart0RxBufLen;
			if(Uart0RdCnt == Uart0RxBufCnt)
			{
				Uart0Null = 1;
			}
			return dat;
		}
	}
	if(1 == uartNum)
	{
		if(1 == Uart1Null)
		{
			return dat;
		}
		else
		{
			dat = Uart1RxBuf[Uart1RdCnt];
			Uart1RdCnt++;
			Uart1RdCnt %= Uart1RxBufLen;
			if(Uart1RdCnt == Uart1RxBufCnt)
			{
				Uart1Null = 1;
			}
			return dat;
		}
	}
	return dat;
}

/*******************************************************************************************************
** 函数名称: int8 uartgetc(uint8 uartNum)
** 功能描述: 从串口缓冲区读取一串数据,(RS485协议数据)
** 输   入: uartNum - 端口号
** 输   出: dat 如果没有读出返回-1,否则返回当前读取到的数据
** 全局变量: 无
** 调用模块: 
** 作   者: 侍任伟
** 日   期: 2008年04月11日
**------------------------------------------------------------------------------------------------------
** 修 改 人:
** 日   期:
** 描    述:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int8 uartgetc(uint8 uartNum)
{
	int32 c;
	int8 lpcnt = 1;
	int8 RecStep = 0;
	uint16 RecCnt = 0;

	if(1 == uartNum)
	{
		while(lpcnt)
		{
		lp2:c = UartGetChar(1);
			if(-1 == c)
			{
				delayNms(2);
				if(lpcnt++ > 10)
				{
					return -1;
				}
				else
				{
					goto lp2;
				}
			}
			else
			{
				lpcnt=1;
				switch(RecStep)
				{
					case 0:
						if(0x7E == c)
						{
							Usart1Buf[RecCnt++] = c;
							RecStep = 1;
						}
						else
						{
							RecCnt = 0;
							RecStep = 0;
						}
					break;
					case 1:
						Usart1Buf[RecCnt++] = c;
						if(0x7F == c)
						{
							if((RecCnt-9) == (uint16)Usart1Buf[5])
							{
								return RecCnt;
							}
						}
					break;
					default:
					break;
				}				
			}
		}
		return -1;
	}
	else if(0 == uartNum)
	{
		while(lpcnt)
		{
		lp1:c = UartGetChar(0);
			if(-1 == c)
			{
				delayNms(2);
				if(lpcnt++ > 10)
				{
					return -1;
				}
				else
				{
					goto lp1;
				}
			}
			else
			{
				lpcnt=1;
				switch(RecStep)
				{
					case 0:
						if(0x7E == c)
						{
							Usart0Buf[RecCnt++] = c;
							RecStep = 1;
						}
						else
						{
							RecCnt = 0;
							RecStep = 0;
						}
					break;
					case 1:
						Usart0Buf[RecCnt++] = c;
						if(0x7F == c)
						{
							if((RecCnt-9) == (uint16)Usart0Buf[5])
							{
								return RecCnt;
							}
						}
					break;
					default:
					break;
				}
			}
		}
		return -1;
	}
	return -1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -