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

📄 plc_demo.c

📁 该原代码应用在cpu(st89le516AD+)上,控制GPRS模块sim100,通过检测系统状态(通电状态,运行状态,AD采样值),通过GPRS模块的短信功能,实现无线报警.
💻 C
📖 第 1 页 / 共 5 页
字号:
		*LCD_addr = str[Display_count];
		DelayCount = 0;
		while( DelayCount < 10 );		
	}
	
}

void Display_LCD2(unsigned char *str)
{
	unsigned char Display_count;
	
	LCD_addr = LCD_IR;			//Locate to line 2( 0x40 )
	LCD_data = 0xC0;			//0xC0 = 11000000b
	*LCD_addr= LCD_data;
	DelayCount = 0;
	while( DelayCount < 10 );
	
	//display at line 2( address range is from 0x40 to 0x67 )
	for( Display_count = 0; Display_count < 20; Display_count ++ )
	{		
		LCD_addr = LCD_DR;
		*LCD_addr = str[Display_count];
		DelayCount = 0;
		while( DelayCount < 10 );		
	}
	
}
/*------------------------------------------------
SendByteToPC
通过串口发送一个字节到PC
如果发送成功返回 1; 失败返回 0
------------------------------------------------*/
unsigned char SendByteToPC( unsigned char ch )
{
//	if( TI == 1 )
//	{
		TXPC_data = ch;
//		TI = 0;
		SBUF = TXPC_data;
		return 1;
//	}
//	return 0;
}


/*------------------------------------------------
ReceiveByteFromPC
通过串口从PC接收一个字节
------------------------------------------------*/
unsigned char ReceiveByteFromPC()
{
//	if( RI == 1 )
//	{
//		RI = 0;
		RXPC_data = SBUF;
		/* RX from PC one char */
		/* add receive one char code here */
		
		PCRxBuffer[PCReceiveCount] = RXPC_data;
		PCReceiveCount ++;
		
		if( RXPC_data == 0x0a)
			PCWaitFlag = 1;
//	}
	return RXPC_data;
}


/*------------------------------------------------
SendByteToModule
通过串口发送一个字节到模块
如果发送成功返回 1; 失败返回 0
------------------------------------------------*/
unsigned char SendByteToModule( unsigned char ch )
{
	Reg_16c550_Tx	=	LSR_16c550;
	TXReg_data	=	*Reg_16c550_Tx;		//check status of LSR.5
	TXReg_data	&=	0x20;
	if( TXReg_data != 0 )				//transmit one byte
	{
		TXReg_data = ch;
		Reg_16c550_Tx	=	THR_16c550;
		*Reg_16c550_Tx	=	TXReg_data;
		return 1;
	}
	return 0;
}


/*------------------------------------------------
ReceiveByteFromModule
通过串口从模块接收一个字节
------------------------------------------------*/
unsigned char ReceiveByteFromModule()
{

	Reg_16c550	=	LSR_16c550;
	RXReg_data	=	*Reg_16c550;		//check status of LSR.0
	RXReg_data	&=	0x01;
	if( RXReg_data != 0 )				//receive one byte
	{	
		Reg_16c550	=	RHR_16c550;
		RXReg_data	=	*Reg_16c550;

		if( ReceiveSMSFlag == 1 )
			SBUF	= RXReg_data;		//for test

//		for test

		if( Sms_edit_mode == 1 && RXReg_data == '>' )
			ModuleWaitFlag = 0;
		ModuleRxBuffer[ModuleReceiveCount] = RXReg_data;

		ModuleReceiveCount ++;
	}

	return RXReg_data;
}

/*------------------------------------------------
			timer 0 interrupt router
------------------------------------------------*/
void timer0_int( void )  interrupt 1
{	
	TH0	=	Timer0H;
	TL0	=	Timer0L;

//	ReceiveByteFromModule();
//	ReceiveByteFromPC();
	DelayCount ++;
	if( NetFoxConnectOpenFlag == 1 )
		PCConnectCount ++;
	else
		PCConnectCount = 0;	
	ModuleSendDelayCount ++;
	if( PWR_det == 0 && NetFoxPowerOpenFlag == 1 )
		PowerOffDelayCount ++;
	else
	{
		PowerOffDelayCount = 0;
		if( PowerSmsHasSent == 1 )
		{
			PowerSmsHasSent = 0;
			LCDRefreshFlag = 1;
			RePowerOffFlag = 1;
		}
	}
	
	LedFlashCount ++;	
	switch( LedFlashFlag )
	{
		case 1:
			if( LedFlashCount > 500 )
			{
				Beep = ~Beep;
				led1 = ~led1;
				LedFlashCount = 0;
			}
			break;
		case 2:
			if( LedFlashCount > 1000 )
			{
				Beep = ~Beep;
				led1 = ~led1;
				LedFlashCount = 0;
			}
			break;
		case 3:
			if( LedFlashCount > 2000 )
			{
				Beep = ~Beep;
				led1 = ~led1;
				LedFlashCount = 0;
			}
			break;
		default:
			led1 = 0;
			break;			
	}	
} 

/*------------------------------------------------
	external interrupt 1 router
	to receive the data from 16c550
------------------------------------------------*/
void external_int1( void )  interrupt 2
{
	ReceiveByteFromModule();
}

/*------------------------------------------------
	uart interrupt 4 router
------------------------------------------------*/
void uart_int( void )  interrupt 4
{
	if( TI == 1 )
	{
		TI = 0;
		if( PCTxBuffer[PCTxCount] != 0 )
		{
			if( SendByteToPC(PCTxBuffer[PCTxCount]) )
			{
				if(PCTxBuffer[PCTxCount] == 0x0a)
				{
					PCTxCount = 0;
					PCTxBuffer[0] = 0;
				}
				else
				{
					PCTxCount ++;	
				}
			}
		}	
//		SendStringToPC();
	}
	
	if( RI == 1 )
	{
		led1 = 1;

		RI = 0;
		ReceiveByteFromPC();

		led1 = 0;
	}
}

/*******************************************************************
   				初始化 CPU 函数
函数原型: void  Init_CPU();
功能:     初始化 CPU 的各项工作参数并开启定时器中断
********************************************************************/
void Init_CPU()
{
	TMOD	= 0x21;
	SCON	= 0x50;				//enable receive
	PCON 	= 0x80;				//double baud rate
	TH1		= 0xFD;
	TL1		= 0xFD;
	EA		= 0;
	TH0		= Timer0H;
	TL0		= Timer0L;
	TR0		= 1;				//start timer0		
	TR1		= 1;				//start serial
	IT1		= 1;				//edge interrupt

	TI  		= 0;
	RI		= 0;
			
	ET0		= 1;				//enable Timer0 interrupt
	ES		= 1;				//enabel serial interrupt
	EX1		= 1;				//enable external interrupt 1
	EA		= 1;				//enable all interrupt

	led1	= 0;
//	led2	= 0;
}

/*******************************************************************
                     初始化16c550函数               
函数原型: void  Init_16c550();
功能:     初始化16c550的各项参数
********************************************************************/
void Init_16c550()
{	
	Reg_16c550	=	IER_16c550;
	*Reg_16c550	=	0x00;		//disable all interrupts
	
	Reg_16c550	=	FCR_16c550;
	*Reg_16c550	=	0x0F;		//Rcv trigger level : 1
						//DMA mode enable
						//Reset the Tx and Rx FIFO
						//enable FIFO
	Reg_16c550	=	LCR_16c550;
	*Reg_16c550	=	0x80;		//LCR.7 = 1, enable the divisor latch

	Reg_16c550	=	DLM_16c550;
	*Reg_16c550	=	DLM_19200;
	Reg_16c550	=	DLL_16c550;
	*Reg_16c550	=	DLL_19200;		//set Baudrate to 19200bps

	Reg_16c550	=	LCR_16c550;
	*Reg_16c550	=	0x03;		//Word length : 8
								//Stop bit : 1
								//No parity
								//No tx Break condition
								//LCR.7 = 0, disable divisor latch

	Reg_16c550	=	MCR_16c550;
	*Reg_16c550	=	0x0B;		//disable loopback mode
								//bit3=1:OP2 set to 0
								//bit1=1:RTS=0
								//bit0=1:DTR=0
	Reg_16c550	=	IER_16c550;
	*Reg_16c550	=	0x01;		//enable receive interrupt and trigger level is 1 byte
//    *Reg_16c550	=	0x03;
}

/*******************************************************************
                     初始化SRAM函数               
函数原型: void  Init_SRAM();
功能:     初始化SRAM的Title
********************************************************************/
void Init_SRAM()
{
//	unsigned char Display_count;
		
	SRAM_addr = SRAM_BASEADDR;
//	for( Display_count = 0; Display_count < 20; Display_count ++ )
//	{
//		SRAM_data  = LCD_Title[ Display_count ];				
//		*SRAM_addr = SRAM_data;
//		
//		SRAM_addr ++;
//	}		
}

/*******************************************************************
                     起动总线函数               
函数原型: void  Start_I2c();  
功能:     启动I2C总线,即发送I2C起始条件...
  
********************************************************************/
void Start_I2c()
{
		  SDA=1;   /*发送起始条件的数据信号*/
		  _Nop();
		  SCL=1;
		  _Nop();    /*起始条件建立时间大于4.7us,延时*/
		  _Nop();
		  _Nop();
		  _Nop();
		  _Nop();    
		  SDA=0;   /*发送起始信号*/
		  _Nop();    /* 起始条件锁定时间大于4μs*/
		  _Nop();
		  _Nop();
		  _Nop();
		  _Nop();       
		  SCL=0;   /*钳住I2C总线,准备发送或接收数据 */
		  _Nop();
		  _Nop();
}

/*******************************************************************
                      结束总线函数               
函数原型: void  Stop_I2c();  
功能:     结束I2C总线,即发送I2C结束条件...
  
********************************************************************/
void Stop_I2c()
{
		  SDA=0;  /*发送结束条件的数据信号*/
		  _Nop();   /*发送结束条件的时钟信号*/
		  SCL=1;  /*结束条件建立时间大于4μs*/
		  _Nop();
		  _Nop();
		  _Nop();
		  _Nop();
		  _Nop();
		  SDA=1;  /*发送I2C总线结束信号*/
		  _Nop();
		  _Nop();
		  _Nop();
		  _Nop();
}

/*******************************************************************
                 字节数据传送函数               
函数原型: void  SendByte(uchar c);
功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
     此状态位进行操作.(不应答或非应答都使ack=0 假)     
     发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
********************************************************************/
void  SendByte(uchar c)
{
		 uchar BitCnt;
		 
		 for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
		    {
		     if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位*/
		       else  SDA=0;                
		     _Nop();
		     SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
		      _Nop(); 
		      _Nop();               /*保证时钟高电平周期大于4μs*/
		      _Nop();
		      _Nop();
		      _Nop();         
		     SCL=0; 
		    }
		    
		    _Nop();
		    _Nop();
		    SDA=1;               /*8位发送完后释放数据线,准备接收应答位*/
		    _Nop();
		    _Nop();   
		    SCL=1;
		    _Nop();
		    _Nop();
		    _Nop();
		    if(SDA==1)ack=0;     
		       else ack=1;        /*判断是否接收到应答信号*/
		    SCL=0;
		    _Nop();
		    _Nop();
}

/*******************************************************************
                 字节数据传送函数               
函数原型: uchar  RcvByte();
功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
     发完后请用应答函数。  
********************************************************************/	
uchar  RcvByte()
{
		  uchar retc;
		  uchar BitCnt;
		  
		  retc=0; 
		  SDA=1;             /*置数据线为输入方式*/
		  for(BitCnt=0;BitCnt<8;BitCnt++)
		      {
		        _Nop();           
		        SCL=0;       /*置时钟线为低,准备接收数据位*/
		        _Nop();
		        _Nop();         /*时钟低电平周期大于4.7μs*/
		        _Nop();
		        _Nop();
		        _Nop();
		        SCL=1;       /*置时钟线为高使数据线上数据有效*/
		        _Nop();
		        _Nop();
		        retc=retc<<1;
		        if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
		        _Nop();
		        _Nop(); 
		      }
		  SCL=0;    
		  _Nop();
		  _Nop();
		  return(retc);
}

/********************************************************************
                     应答子函数
原型:  void Ack_I2c(bit a);
 
功能:主控器进行应答信号,(可以是应答或非应答信号)
********************************************************************/
void Ack_I2c(bit a)
{
		  if(a==0)SDA=0;     /*在此发出应答或非应答信号 */
		        else SDA=1;
		  _Nop();
		  _Nop();
		  _Nop();      
		  SCL=1;
		    _Nop();
		    _Nop();              /*时钟低电平周期大于4μs*/
		    _Nop();
		    _Nop();
		    _Nop();  
		 SCL=0;                /*清时钟线,钳住I2C总线以便继续接收*/
		    _Nop();
		    _Nop();    
}


/*******************************************************************
                    向器件发送单字节数据函数               
函数原型: bit  ISendChar(uchar sla,uchar suba,uchar suba1,ucahr s);  
功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
          地址sla,子地址suba,发送内容是s的内容。
           如果返回1表示操作成功,否则操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
bit ISendChar(uchar sla,uchar suba,uchar suba1,uchar s)
{		
		Start_I2c();               /*启动总线*/
		SendByte(sla);            /*发送器件地址*/
		 if(ack==0)return(0);

//		SendByte(suba);            /*发送器件子地址*/
//		 if(ack==0)return(0);

		SendByte(suba1);            /*发送器件子地址1*/
		 if(ack==0)return(0);
		
		SendByte(s);               /*发送数据*/
		   if(ack==0)return(0);
		
		Stop_I2c();                 /*结束总线*/ 
		return(1);
}

/*******************************************************************
                    向器件读取单字节数据函数               
函数原型: uchar  ISendChar(uchar sla,uchar suba,uchar xsuba1,uchar s)
功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
          地址sla,子地址suba。
          如果返回0xFF表示操作有误。
注意:    使用前必须已结束总线。
********************************************************************/
uchar IRcvChar(uchar sla,uchar suba,uchar suba1,uchar s)
{		
		Start_I2c();               /*启动总线*/
		SendByte(sla);            /*发送器件地址*/
		 if(ack==0)	return(0xFF);

//		SendByte(suba);            /*发送器件子地址*/
//		 if(ack==0)	return(0xFF);

⌨️ 快捷键说明

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