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

📄 comm.c

📁 LPC2129实现从SPI通讯和两个串口定时器中断
💻 C
📖 第 1 页 / 共 3 页
字号:

#define COMM_GLOBALES 1

#include "comm.h"
#include "InitDev.h"
#include "uart0.h"
#include "uart1.h"
#include "driver.h"
#include "I2cInt.h"
//******************有关UART通讯协议,使用前有关设置*******************************
//#define M128_EN1 PORTD |= (1<<7)			//少了多路串口使能
//#define M128_DIS1 PORTD &= (~(1<<7))
//*******************其它宏定义******************************************/

/*定义数据缓冲区结构体*/
	
//*******初始化发送与接收缓冲区,并构缓冲区环型链表
/****************************************************************************
* 名称: buf_init()	
* 功能:初始化发送与接收缓冲区
* 入口参数:无
* 出口参数:无
****************************************************************************/
void buf_init(void)				//数据缓冲区		
{
	unsigned char i;
	for ( i=0; i<UART_TOL; i++ )
	{
		TXD_BUF[i].command = 0;
		TXD_BUF[i].length = 0; 
		TXD_BUF[i].sum = 0;
		TXD_BUF[i].state = SET_NEW;		
	}
	
	for ( i=0; i<UART_TOL; i++ )
	{
		RXD_BUF[i].command = 0;
		RXD_BUF[i].length = 0;
		RXD_BUF[i].sum = 0;
		RXD_BUF[i].state = 0; 
	}
	
}
	  
/****************************************************************************
* 名称:UART0_Ini()
* 功能:初始化串口0。设置其工作模式及波特率。
* 入口参数:baud          	波特率
			datab;         	字长度,5/6/7/8
			stopb;         	停止位,1/2
			parity;    		奇偶校验位,0为无校验,1奇数校验,2为偶数校验
*          
* 出口参数:返回值为1时表示初化成功,为0表除参数出错
****************************************************************************/
 uint8  UART0_Ini(uint32 baud,	uint8 datab,	uint8 stopb,	uint8 parity )
{  
	uint8  bak;
 
/*	参数过滤 	   	*/
	if( (0==baud)||(baud>115200) ) return(0);
	if( (datab<5)||(datab>8) ) return(0);
	if( (0==stopb)||(stopb>2) ) return(0);
	if( parity>4 ) return(0);
							
	/* 设置串口波特率 	 */
	U0LCR = 0x80;                        // DLAB位置1
	bak = (uint8)((Fpclk>>4)/baud);	
	U0DLM = bak>>8;
	U0DLL = bak&0xff;
											   
	/* 设置串口模式  */
	bak = datab-5;                   // 设置字长度
	if(2==stopb) bak |= 0x04;        // 判断是否为2位停止位  

	if(0!= parity) {parity = parity-1; bak |= 0x08;}
	bak |= parity<<4;              	// 设置奇偶校验

	U0LCR = bak & 0x7f;

	PINSEL0 |= ((1<<0) | (1<<2) );	//设置I/O连接到UART0(RXD0,TXD0) 
	
                     // 使能FIFO,并设置触发点为1字节
	 U0FCR = 0x07;                     // 使能FIFO,并设置触发点为1字节
     U0IER = 0x03;                  // 允许RBR中断与THR中断,即接收中断	 
/*	*/

	return(1);	
}	
/****************************************************************************
* 名称:InitComm()
* 功能:初始化缓冲区和串口0。
* 入口参数:无
*          
* 出口参数:无
****************************************************************************/
void InitComm ( void )
{

	/*初始化数据缓冲区*/
	buf_init();		
	
	/*	UART0_Ini(19200, 8,1,0);  // 初始化串口模式,8位数据位,1位停止位,无奇偶校验*/	
    UART0_Init(19200);    
	  	
}
         
/****************************************************************************
* 名称:send_UDR ( );
* 功能:发送单字节数据到相应的串口号
* 入口参数: uart_num        	发送串口号
*          	 wait_UDR          	等待发送的数据
* 出口参数:无
****************************************************************************/

void send_UDR ( uint8 uart_num,	uint8 wait_UDR )					//发送数据
{
	switch(uart_num)
	{
		case 0:
				U0THR = wait_UDR;
				break;
				
		case 1:
				U1THR = wait_UDR;
				break;
				
		default:
				break;
				
	}
}


//*************发送中断函数,其可以自动把数据缓冲区的数通过UART发送出去
//每次有一个数据缓冲区有新的数据报来发送时,只需调用函数 uart0_tx_isr();一次就可以
//之后,系统将自动发送所有数据报的数据
//数据发送完后,TXD_BUF[0].state的第0位会置1
/****************************************************************************
* 名称:uart_tx_isr()
* 功能:发送中断函数处理函数,自动把数据通过UART发送出去
* 入口参数:uart_num		发送中断所处理的串口号     
* 出口参数:无
****************************************************************************/  
void uart_tx_isr(uint8 uart_num)
{
 /* */
 	static uint8 dataLen[UART_TOL];				//协商数据长度
	static uint8 data_index[UART_TOL];
	static uint8 com_index[UART_TOL]; 			//起动标志位
	
	static struct DATA_BUF *txd_pk[UART_TOL];	//调用数据缓冲区0
	
	static unsigned char StartFlag = FALSE;
	
	unsigned char WAIT_UDR;									//定义等待发送变量

	unsigned char  i =0 ;

	if( StartFlag != TRUE )
	{
		for(i=0; i<UART_TOL; i++)
		{
			dataLen[i] = 0;
			data_index[i] = 0;
			com_index[i] = 0;
			
			txd_pk[i] = &TXD_BUF[i]; 
		}
		
			StartFlag = TRUE;
	}	
		 

	if( com_index[uart_num] <= 4) 			
	{
		IO0SET=0x00400000;

		switch ( com_index[uart_num] )
		{
			case 0 : 
				WAIT_UDR = UART_START0;		//暂存启动一个数据报发送,第一个字头,0x55
				break;
				
			case 1 :
				WAIT_UDR = UART_START1;		//暂存启动一个数据报发送,第二个字头,0xAA
				break;
				
			case 2 :
				WAIT_UDR = txd_pk[uart_num]->IP_addr;	//暂存通讯设备的IP地址	
				break;
				
			case 3 :
				WAIT_UDR = 0x00;			//先清空标志位,主机发送数据永远是对的
				//WAIT_UDR |= (txd_pk[uart_num]->state & GET_ERROR);	//写帧状态接收正确否
				
				WAIT_UDR |= (txd_pk[uart_num]->length & GET_LEN);		//设置发送帧的数据长度0~0x3f	
				dataLen[uart_num] = txd_pk[uart_num]->length;			//暂存数据长度
				break;
			case 4 :
				WAIT_UDR = txd_pk[uart_num]->command;			//暂存发送命令
				break;
		}
		 
		com_index[uart_num]++;						//命令索引加一
		
		send_UDR ( uart_num, WAIT_UDR );						//发送数据
		 
	}
	else if ( data_index[uart_num] < dataLen[uart_num] && data_index[uart_num] < DATA_BUF_NUM)		//发送帧的数据
	{
		WAIT_UDR = txd_pk[uart_num]->data[data_index[uart_num]];		//暂存UART发送数据
		
		data_index[uart_num]++;								//数据索引加一
		
		send_UDR ( uart_num, WAIT_UDR );						//发送数据
	
	}
	else if (data_index[uart_num] <= dataLen[uart_num]  )				//发送校验和
	{
		WAIT_UDR = txd_pk[uart_num]->sum;	
		data_index[uart_num]++;
		
		send_UDR ( uart_num ,WAIT_UDR );						//发送数据
		
	}
	else 						
	{
		data_index[uart_num] = 0;								//数据与命令索引复位
		com_index[uart_num] = 0;
		txd_pk[uart_num]->state = txd_pk[uart_num]->state |= SET_NEW;	//又有一个新的缓冲区,数据发送完毕	
	   IO0CLR=0x00400000;	
	}
 	

}
	

//接收中断函数,其可以自动把接收到的数据报存放在数据缓冲区
//******如果成功接收到一个帧,并把RXD_BUF->state的第0位置1,
/****************************************************************************
* 名称:uart_rx_isr()
* 功能:接收中断函数处理函数,把接收到的数据存贮在缓冲区
* 入口参数:uart_num		发送中断所处理的串口号
			uart_UDR	相应串口号接收的数据     
* 出口参数:无
****************************************************************************/	 
void uart_rx_isr(uint8 uart_num,uint8 uart_UDR)
{
 //uart has received a character in UDR
 //uart has received a character in UDR
/*测试段程序*/	
 	  
	/*接受上位机指令并从串口1发出*/	 
	static uint8 start_flag[UART_TOL] ;			//起动标志位
	static uint8 dataLen[UART_TOL];						//协商数据长度
	static uint8 data_index[UART_TOL];					//数据索引定义 
	static uint8 com_index[UART_TOL]; 					//命令索引定义
	
	static struct DATA_BUF *rxd_pk[UART_TOL];			//缓冲区指针定义
	
	static uint8 temp_char1[UART_TOL];					//临时暂存定义
	static uint8 temp_char0[UART_TOL];

	static uint8 StartFlag = FALSE; 
	
	uint8 i;

	//数据初始化
	if(StartFlag != TRUE)				
	{
		for(i=0; i<UART_TOL; i++)
		{
			start_flag[i] = 0;
			dataLen[i] = 0;
			data_index[i] = 0;
			com_index[i] = 0;
			
			rxd_pk[i] = &RXD_BUF[i];
			
			temp_char1[i] = 0;
			temp_char0[i] = 0; 
		}

		StartFlag = TRUE;
	}
	
	temp_char1[uart_num] = uart_UDR;					//UART接收数据暂存	
	
	if(start_flag[uart_num] == RXD_WAIT)				//等待起动
	{
		if( temp_char1[uart_num]  == UART_START1 )	 	//抗一定的干拢,判断是不是帧启动的第二字节,0XAA
		{
		 	if(temp_char0[uart_num]  == UART_START0)	//判断是不是帧启动的第一字节,0X55
			{
				start_flag[uart_num] = !RXD_WAIT;		//表示一个数据包传送开始
				
				data_index[uart_num] = 0;				//数据索引复位
				com_index[uart_num] = 0;				//命令索引复位
			}
		}
		else
			temp_char0[uart_num] = temp_char1[uart_num];//暂存此数据 
	}
	else if( com_index[uart_num] <3)					//开始接收命令数据
	{	 
		
		switch(com_index[uart_num])					
		{
			case 0 :	//第0个数据,读取IP地址、LEN、STATE
				if (IP_ADDR != temp_char1[uart_num])	//判断IP地址是否符合,
					start_flag[uart_num] = RXD_WAIT; 	//如果不符合,从新进入等待自己的数据帧
					
				break;			
			case 1 :
				rxd_pk[uart_num]->length = temp_char1[uart_num] & GET_LEN;		//提取数据帧长度,范围0~63

				dataLen[uart_num] = rxd_pk[uart_num]->length;				//因为数据索引初始就是3
					
				rxd_pk[uart_num]->state &= ~GET_ERROR;	//先清空标志位
				rxd_pk[uart_num]->state |= (temp_char1[uart_num] & GET_ERROR);	//提取整个帧状态
				
				break;	 
			case 2 :
				rxd_pk[uart_num]->command = temp_char1[uart_num]; 				//第2个数据,读取命令字
					
				break;
		}
		 
		com_index[uart_num]++;							//命令索引加一

	}
		//开始接收帧的数据
	else if ( data_index[uart_num] < dataLen[uart_num] && data_index[uart_num] < DATA_BUF_NUM)	
	{	
		rxd_pk[uart_num]->data[data_index[uart_num]]				//存储数据
		= temp_char1[uart_num];	
		data_index[uart_num] ++;
/**/		
								//数据索引加一
	}
	else 	
	{
		rxd_pk[uart_num]->sum = temp_char1[uart_num];	//读取校验和
		
		com_index[uart_num] = 0;						//命令索引与数据索引复位
		data_index[uart_num] = 0;
		
		start_flag[uart_num] = RXD_WAIT;				//重启,等待下一新帧
		rxd_pk[uart_num]->state |= SET_NEW;				//有一个新帧到达,等待执行
	   	
	}
/* 	  if( ((RXD_BUF[0].state)&SET_NEW)==0x01)
	{	
		perform_command (&RXD_BUF[0]); 
	}
*/	 
}

/****************************************************************************
* 名称:set_sum ()
* 功能:设置帧的校验和
* 入口参数:set_pk	需要设置校验和的缓冲区   
* 出口参数:无
****************************************************************************/

void set_sum (struct DATA_BUF *set_pk)					//设置校验和
{
	unsigned char num_sum;				
	unsigned char i;
	
	num_sum =  UART_START0 +UART_START1;				//帧头相加
	num_sum += set_pk->IP_addr;							//加上接收IP地址
	num_sum += set_pk->length&GET_LEN 
	+ (set_pk->state&GET_ERROR);						//数据长度与标志位数据
	num_sum += set_pk->command;							//加上命令
	
	for(i=0; i<set_pk->length; i++)						//加上数据
		num_sum += set_pk->data[i];
	
	set_pk->sum = num_sum; 								//设置校验和
}

/****************************************************************************
* 名称:check_sum  ()
* 功能:检查校验和正确否
* 入口参数:check_pk		检查校验和正确否的缓冲区   
* 出口参数:返回值为1时表示校验和正确,为0表示校验和错误
****************************************************************************/
unsigned char  check_sum (struct DATA_BUF *check_pk)	//检查校验和
{
	unsigned char num_sum;
	unsigned char i;
	
	num_sum =  UART_START0 +UART_START1;				//帧头相加
	num_sum +=  check_pk->IP_addr;						//加上接收IP地址
	num_sum += check_pk->length&GET_LEN 
	+ (check_pk->state&GET_ERROR);						//数据长度与标志位数据
	num_sum += check_pk->command;						//加上命令
	
	for(i=0; i<check_pk->length; i++)					//加上数据
		num_sum += check_pk->data[i];
	
	if ( check_pk->sum == num_sum )						//检查对错
		return TRUE;
	else 
		return FALSE;
}

/****************************************************************************
* 名称:send_same_back_uart() 
* 功能:用于正确帧的原样返回发送
* 入口参数:uart_num		要返回的串口号
			rxd_pk	    需要同样返馈的数据缓冲区    
* 出口参数:无
****************************************************************************/
void send_same_back_uart(uint8 uart_num,struct DATA_BUF *rxd_pk)
{
 	struct DATA_BUF *send_pk = &TXD_BUF[uart_num];		//初始化定义
	
	while(!(send_pk->state & SET_NEW));					//等待上一个数据帧发送完毕
	 
	send_pk->IP_addr = 0x01;							//设置发送从机的IP地址
	send_pk->command = rxd_pk->command;					//设置反回发送命令,
	send_pk->length = 0;								//设置帧长为0
		
	send_pk->state &= ~GET_ERROR;						//设置错误标志位,无
	
	set_sum (send_pk);									//设置校验和
	uart_tx_isr(uart_num);								//开始发送数据
}

/****************************************************************************
* 名称:send_error_back_uart() 
* 功能:用于错误帧的返馈发送
* 入口参数:uart_num		要反馈数据的串口号
			rxd_pk	    需要同样返馈的数据缓冲区    
* 出口参数:无
****************************************************************************/
void send_error_back_uart(uint8 uart_num,struct DATA_BUF *rxd_pk)
{
 	struct DATA_BUF *send_pk = &TXD_BUF[uart_num];		//初始化定义
	
	while(!(send_pk->state & SET_NEW));					//等待上一个数据帧发送完毕
	 
	send_pk->IP_addr = 0x01;							//设置发送从机的IP地址
	send_pk->command = rxd_pk->command;					//设置反回发送命令,
	send_pk->length = 0;								//设置帧长为0
		
	send_pk->state |= GET_ERROR;						//设置错误标志位,有
	
	set_sum (send_pk);									//设置校验和
	
	uart_tx_isr(uart_num);								//开始发送数据
}

/****************************************************************************
* 名称:IRQ_UART0()
* 功能:串口UART0接收中断。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void   __irq IRQ_UART0(void)					//与总线通讯串口控制
{  	

  	uint8 TempU0RBR;
	uint8 TempU0LSR;
	uint8 TempU0IIR;

	TempU0LSR = U0LSR;
	TempU0IIR = U0IIR;

  	  
	 if( (1<<0) == (TempU0LSR&(1<<0)) )				//判断是否是接收中断
	{	
	 	TempU0RBR = U0RBR;
	 	if(transMode==0)
		{
 		 	uart_rx_isr(0,TempU0RBR);
		}
		else
		{
			if(TempU0RBR==0)
			{
				transMode=0;
			   	VICVectAddr = 0x00000000;  
				return;
			}
			Transparent(TempU0RBR);
		}
	
	 	//进行协议解协
	}
  	else if( (1<<5) == (TempU0LSR&(1<<5)) )	 	//判断是否是发送中断
	{
		uart_tx_isr(0);	  
	}	
		
	VICVectAddr = 0x00000000;              		// 中断处理结束
} 

/****************************************************************************
* 名称:IRQ_UART1()
* 功能:串口UART1接收中断。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq IRQ_UART1()
{ 

⌨️ 快捷键说明

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