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

📄 main.c

📁 一个实现一个串口扩展四个串口的实现程序
💻 C
📖 第 1 页 / 共 2 页
字号:

//UART 1 TO 4 MODULE
//MCU : P89LPC930
//INTERFACE: VK3224
//MODIFIED TIME: 2007-8-13
/********************************************************************/  


#include <stdio.h>
#include <intrins.h>
#include <string.h>
#include "def.h"
#include "Vk32.h"




#define 	PARITY_NONE		0		// 无校验
#define 	PARITY_EVEN		1		// 奇校验
#define 	PARITY_ODD			2		// 偶校验
#define 	PARITY_CUSTOMER	3		// 用户

#define	FRAME_LEN_10		0
#define  	FRAME_LEN_11		1

//#define 	1_STOP_BIT			0
//#define 	2_STOP_BIT			1

#define 	IR_STAND			0
#define 	IR_COMPATIBLE		1

#define 	FrameHead1   		32
#define 	FrameHead2   		32
#define 	COM_SUM			4	// 子串口数量
#define	LEN_COM			12	// 子串口接受数据缓冲区长度
#define   SEND_BUFF_LEN		(COM_SUM*(LEN_COM+3)*2)
#define 	RECEIVE_BUFFER_LENGTH	(LEN_COM*4)
#define 	PORT_FLAG_MASK(i)   (1<<i)

typedef struct
{
	uchar port;
//	uchar len;
	uchar ucTop;
	uchar ucTail;
	uchar flag;
	uchar aucData[RECEIVE_BUFFER_LENGTH];
}T_SendData;
/********************************************************************/  



//sbit SPI_CLK=P2^5;
//sbit SPI_MOSI=P2^2;
//sbit SPI_MISO=P2^3;
sbit RST_VK	=P1^4;
sbit GM_IRQ	=P1^3;

sbit MCOM	=P2^4;		//MASTER COM BAUDRATE SELECT
sbit C1BAUD1	=P2^0;	//SLAVE COM1 BAUDRATE SELECT
sbit C1BAUD0	=P2^1;
sbit C2BAUD1	=P0^0;	//SLAVE COM2 BAUDRATE SELECT
sbit C2BAUD0	=P1^7;
sbit C3BAUD1	=P2^7;	//SLAVE COM3 BAUDRATE SELECT
sbit C3BAUD0	=P2^6;
sbit C4BAUD1	=P0^1;	//SLAVE COM4 BAUDRATE SELECT
sbit C4BAUD0	=P0^2;

sbit C1CHK	=P1^6;
sbit C2CHK	=P3^1;
sbit C3CHK	=P3^0;
sbit C4CHK	=P0^3;
sbit C1CHK_EXIT =P0^4;
sbit C2CHK_EXIT =P0^5;
sbit C3CHK_EXIT =P0^6;
sbit C4CHK_EXIT =P0^7;

/********************************************************************/  
#if CPU_DO_AS_RX
bdata uchar FlagTemp1=0x80;
sbit Flag_First	=FlagTemp1^7;	//rev FrameHead1
sbit Flag_Second=FlagTemp1^6;	//rev FrameHead2
sbit Flag_Third	=FlagTemp1^5;	//rev Com number
sbit Flag_Data	=FlagTemp1^4;
sbit RevSComFlag=FlagTemp1^0;	//slave Com have data enter into Rx FIFO

idata T_SendData g_tMRevBuff[COM_SUM];
uchar ComNo,len;

#endif

#if CPU_DO_AS_TX
idata uchar	SRevBuff[COM_SUM][LEN_COM];				// zi串口received 数据缓存
idata uchar	MSendBuff[SEND_BUFF_LEN];					//单片机串口发送缓存
static 	uchar s_ucMSendBuffTop = 0;
static 	uchar s_ucMSendBuffTail	= 0;

//uchar 		fgComXNeedHandle[COM_SUM];		//子串口有任务neeed  handle 标志
//uchar 		fgComXReceivedData[COM_SUM];		//某个子串口缓冲区有数据需要发送。
//uchar		fgComXCanSendData[COM_SUM];		//某个子串口fifo有空间可以写入数据。
uchar		fgComXReceiveDataTimeOut[COM_SUM];	//某个子串口等待接满len_len数据的时间超时
uchar 		RevDataCount[COM_SUM];				// 子串口接受数据计数器。
uint 			ComXOverTimeCount[COM_SUM];		// 子串口超时计数器
uchar 		fgStartComxSoftTimer[COM_SUM];		// 子串口软件定时器允许标志

#endif

idata 	uchar SoftCountNum[COM_SUM];				//cdy,软件定时技术,和波特率相关
/********************************************************************/  
void Delay(unsigned int);

void McuInit();		//initialize mcu config
void Timer0(void);	//200us timer

void SerialReceiveInterrupt(void);	//UART interrupt receive data
void SerialSendInterrupt(void);		// UART SEND INTERRUPT
void TestSent(uint);

void Vk3224Init();	//initialize VK3224


uchar HandleComXTask(uchar port);		// handle comxtask base IRQ interrupt
uchar PutDataToMComBuff(uchar port,uchar * pdsr, uchar length);	// put comx data to master com.

/********************************************************************/  
void main(void)
{
	
	uchar port_no,ucVKRevCount;
	uchar ucVKSendCount;
	Delay(2000);
	
	//data initial
#if CPU_DO_AS_RX
	Flag_First = 1;		// initial =1 for first master receive.
	memset((uchar *)&g_tMRevBuff[0],0,sizeof(T_SendData)*COM_SUM);
#endif

#if CPU_DO_AS_TX
	for(port_no =0;port_no < COM_SUM; port_no++)
	{
		fgComXReceiveDataTimeOut[port_no] =0;
		RevDataCount[port_no] = 0;
		fgStartComxSoftTimer[port_no] = FALSE;
	}
	s_ucMSendBuffTail =\
	s_ucMSendBuffTop = 0;
#endif	
	
	
	McuInit();
	Vk3224Init();
	
	while(1)
	{
				
/*****************     from VK to CPU Com      ********************* */		
		//是否子串口received any data;then put to buffer.
#if CPU_DO_AS_TX
		for(port_no = 0; port_no < COM_SUM; port_no++)
		{
			ucVKRevCount = GetComXRevDataLength(port_no);					
		
			if(ucVKRevCount >LEN_COM)
			{
				ucVKRevCount = LEN_COM;
			}

			if(ucVKRevCount)
			{
				while( (ucVKRevCount--)
					&& (RevDataCount[port_no] <LEN_COM))
				{						
					SRevBuff[port_no][RevDataCount[port_no]] = ReadDataFromFIFO(port_no);
					RevDataCount[port_no]++;					
					
				}
					
			}	

		


		//如果从串口收到四个数据或者定时器到,把收到的数据加桢头放入spi 的发送buffer里
//		for(port_no = 0; port_no < COM_SUM; port_no++)
//		{
			if((RevDataCount[port_no] == LEN_COM )||fgComXReceiveDataTimeOut[port_no])		// 接受缓冲满或者定时器到,
			{
				ET0=0;
				PutDataToMComBuff(port_no,&SRevBuff[port_no][0],RevDataCount[port_no]);
				RevDataCount[port_no] = 0;
				
				ComXOverTimeCount[port_no] = 0;
				fgComXReceiveDataTimeOut[port_no] = FALSE;
				ET0=1;
				fgStartComxSoftTimer[port_no] = TRUE;
				
			}
		}

		
		//启动串口发送中断,把住串口发送buff里的数据发送出去。

		if(s_ucMSendBuffTail != s_ucMSendBuffTop)
		{
			SBUF = MSendBuff[s_ucMSendBuffTail++];
			s_ucMSendBuffTail %= SEND_BUFF_LEN;
		}
#endif	

/*****************     from VK to CPU Com    End  ********************* */	


/*****************     from CPU Com to  VK      ********************* */	

#if CPU_DO_AS_RX
	{

		// if comx send data fifo is convinence,then send data to the buffer.
		for(port_no =0; port_no< COM_SUM; port_no++)
		{
			// comx need send data?
			if(g_tMRevBuff[port_no].ucTail != g_tMRevBuff[port_no].ucTop)
			{
				//how much can be send?
				ucVKSendCount = GetComXTFIFOLength(port_no);
				// 
				while((ucVKSendCount--)
					&&(g_tMRevBuff[port_no].ucTail != g_tMRevBuff[port_no].ucTop))
				{
					WriteDataToFIFO(port_no, g_tMRevBuff[port_no].aucData[g_tMRevBuff[port_no].ucTail++]);
					g_tMRevBuff[port_no].ucTail %= RECEIVE_BUFFER_LENGTH;
				}
			}
		}
	}
#endif	
/*****************     from CPU Com to  VK End     ********************* */			
//如果一定时间内某种中断没有产生系统复位。

	}//end while
}
/***********************************************************
 Function:	Delay
 Describe:	Time delay
 Input:		int  formated time
 Output:	       void
***********************************************************/
void Delay(unsigned int nTime)
{
	while(--nTime) {;}
}  
/********************************************************************/  

void McuInit(void)
{
	DIVM = 0;		//CPU_clk =Fosc
	
	TMOD |= 0x01;		//定时器0用作定时功能;
	TAMOD = 0x00;		//16bit timer
	TH0 = 0xfc;		//每个PCLK,计数器加1;PCLK=cclk/2;  CCLK=7.373
	TL0 = 0xe0;		// 200us
	TCON |=0x10;		//start timer0
//	ET0 = 1;			//enable timer 0 interrupt 
	
	P1M1 &=0xfc;		//把TXD	RXD设置成准双向;
	P1M2 &=0xfc;
	// uart
	SSTAT=0x20;			// clear master uart	,and use RI and TX in defferent interrupt.		
	SCON = 0x50;		//串口方式1,(1,8,1),接收允许;双缓冲禁止,中断禁止,采用查询方式发送和接收
						//if need interrupt , scon = 0x53
	BRGCON=0x00; 		//关波特率发生器
	if(MCOM)
	{
		BRGR1=0x02; 	//设置串口波特率:Fosc / ((BRGR1,BRGR0)+16)
       	BRGR0=0xf0;     // baud rate = 9600bps @ 7.373MHz 
    }
    else
    {
		BRGR1=0x01; 	//设置串口波特率:Fosc / ((BRGR1,BRGR0)+16)
       	BRGR0=0x70;     // baud rate = 19200bps=0x0170 //4800=0x05f0//38400bps==0x00b0
	}        	
	BRGCON=0x03;		//打开串口波特率发生器,使用独立的波特率发生器
#if SPI_INT_ENABLE 
	//SPI //wan,poll mode
	SPCTL  = 0;
	SPCTL = 	0xd0;	//SSIG|SPEN|MSTR;			
	SPSTAT = 0xC0;		//清楚STAT中的标注
//	ESPI = 1;
#endif	

#if WDT_ENABLE
	// WDT	
	ACC = WDCON; 		//读取WDT控制寄存器
	ACC = ACC|0x04; 	//置位ACC.2准备启动WDT
	WDL = 0xff; 		//设置8位倒计时器初值
	WDCON = ACC; 		//启动WDT
	WFEED1 = 0xA5; 		//清零第一部分
	WFEED2 = 0x5A; 		//清零第二部分
#endif	

#if INT_ENABLE
	IT0=0;			//LOW LEVEL 
	EX0=1;			//enable
#endif

	ES = 1;			//enable Rx interrupt
	EA = 1;			//all interrupt enable

//00=准双向;01=推挽;11=开漏;10=高阻输入

	P0M1=0x00;		
	P0M2=0x00;		//准双向口
	P1M1=0x04;
	P1M2=0x04;
	P2M1=0x08;
	P2M2=0x00;
	P3M1=0x00;
	P3M2=0x00;

	SPI_CS=1;
}

//********************************************************************/  
#if CPU_DO_AS_TX
void Timer0(void) interrupt 1	//Timer0 interrupt routine		
{
	
//	EA=0;
	uchar i;
	uint temp;
	TH0 = 0xfc;		//200us,如果机器周期=1/6us
	TL0 = 0xe0;

	WFEED1 = 0xA5; 		//执行清零第一部分
	WFEED2 = 0x5A; 		//执行清零第二部分
//	EA=1;

	for(i =0; i < COM_SUM;i++)
	{
		if(fgStartComxSoftTimer[i])
		{
			temp = SoftCountNum[i]*250;
			if(++ComXOverTimeCount[i] >= temp)
			{
				fgComXReceiveDataTimeOut[i] =TRUE;
				ComXOverTimeCount[i] = 0;
			}
		}
		else
		{
			ComXOverTimeCount[i] = 0;
		}	
	}
		
}
#endif

#if 0
/********************************************************************/  
void TestSent(uint c)			//for test
{
	uchar t1;

⌨️ 快捷键说明

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