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

📄 main.c.bak

📁 单片机LCD驱动
💻 BAK
字号:
#include <c8051f310.h>
#include <intrins.h>
#include "Lcd.h"

sbit Lcd_EN=P2^2;
sbit Lcd_RW=P2^1;
sbit Lcd_RS=P2^0;
sbit Busy=P1^7;

sbit Led1=P2^7;
sbit Led2=P2^6;
sbit Led3=P2^5;

sbit Key1=P0^1;
sbit Key2=P0^0;

sbit Key3=P3^1;
sbit Key4=P3^2;
sbit Key5=P3^3;

unsigned char Key_Value=0;
unsigned char Need_to_Send=0;

unsigned char Present_State=0;
unsigned int Time_Out_Count=0;
unsigned int Recv_Out_Times=0;
unsigned int Recv_Time_Out=0;
unsigned int Work_Time_Out=0;

unsigned char Buf_Temp;
unsigned char Uart_Coun=0;
unsigned char Uart_Flag=0;
unsigned char delay_num=0;
//unsigned char x,y;
unsigned char serial_rx_buff[8];
unsigned char serial_tx_buff[8];
unsigned char LED_Count;
unsigned char Uart_Enable=0;
unsigned char Key_Enable=1;

//unsigned char KEY[2][3]={1,2,3,4,5,6};

void INIT_SYS_CLK(void)
{

	OSCXCN = 0x67;     //启动外部振荡器用 24 MHz 晶体 设置外部振荡器控制寄存器			
	while (!(OSCXCN & 0x80)); // 等待晶体稳定	
	CLKSEL = 0x01;     //设置CLKSL0为1,选择外部振荡  设置时钟选择寄存器
	OSCICN = 0x08;     //选择外部振荡器作为系统时钟源 //使能丢失时钟检测器 	          
} 

void WDT_Init(void)
{
  PCA0MD&= ~0x40;            //禁止WDT
  PCA0MD= 0x00;     
}

//void SendChar(unsigned char chr)
//{
//  SBUF0=chr;		   		            /*将接收到数据送出*/
//  while(!TI0);
//  TI0 = 0;
//}

void SendString (unsigned char *str, unsigned char strlen)
{
  unsigned char m = 0;
	do
	{
	   SBUF0 = *(str + m); 
	   while(!TI0);
	   TI0 = 0; 	   
	   m ++;
	}
	while (m < strlen);
}

void Timer0_Init (void)
{
 	CKCON|=0x04;
 	TMOD|=0x1;    	                  //16Bit
 	TR0 = 0;                          // 停止定时器0
 	TH0 = (-SYSCLK/1000) >> 8;    	  // 定时器1ms溢出
 	TL0 = -SYSCLK/1000;
 	TR0 = 1;   	                      // 启动定时器
 	IE|= 0x2; 						   					//定时器0中断允许
}
	
void Timer0_ISR (void) interrupt 1  //1ms
{
	  TH0 = (-SYSCLK/1000) >> 8;  
   	TL0 = -SYSCLK/1000;
	  delay_num++;
	  Time_Out_Count++;
	  Recv_Time_Out++;
	  if (Recv_Time_Out>=1000)
	  {
	  	Recv_Time_Out=0;
	  	Recv_Out_Times++;
	  }
	  TF0=0;
}

void UATR0_ISR(void)  interrupt 4
{
	if(RI0)
  	{					    
		RI0 = 0;
		//Led2=~Led2;
		Buf_Temp =SBUF0;
		if (Uart_Coun<8)
		{
		   serial_rx_buff[Uart_Coun]=Buf_Temp;
		   Uart_Coun++;
		}
		if (Uart_Coun >=8)
		{
		   Uart_Flag=1;
		   Uart_Coun=0;
		   Led2=~Led2;
		}		
	}
}

void RS232_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
   if (SYSCLK/BAUD_RATE/2/256 < 1) 
   {
      TH1 = -(SYSCLK/BAUD_RATE/2);
      CKCON &= ~0x0B;                  // T1M = 1; SCA1:0 = xx
      CKCON |=  0x08;
   } 
   else if (SYSCLK/BAUD_RATE/2/256 < 4) 
   {
      TH1 = -(SYSCLK/BAUD_RATE/2/4);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 01                  
      CKCON |=  0x09;
   } 
   else if (SYSCLK/BAUD_RATE/2/256 < 12) 
   {
      TH1 = -(SYSCLK/BAUD_RATE/2/12);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 00
   } 
   else 
   {
      TH1 = -(SYSCLK/BAUD_RATE/2/48);
      CKCON &= ~0x0B;                  // T1M = 0; SCA1:0 = 10
      CKCON |=  0x02;
   }

   TL1 = TH1;                          // init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;                       
   TR1 = 1;                            // START Timer1
   ES0 = 1;
   TI0 = 0;
   RI0 = 0;     
}

void INIT_PORT (void)
{
	XBR1 = 0x40 ;   //XBARE位置1,交叉开关使能。
  XBR0 = 0x09 ;   //SYSCLK位置1:/SYSCLK连到端口引脚。URT0E置1,1:UART TX0, RX0连到端口引脚P0.4和P0.5。          

	P0MDIN = 0xf3 ; //端口0输入寄存器配置,p0.2,p0.3接外部晶振,数字输入置1
	P0SKIP = 0x0c;  //端口0跳过寄存器配置,p0.2,p0.3接外部晶振

	P1MDIN = 0xff;
	P1MDOUT = 0xff;

	P0MDOUT |= 0x10;
  P2MDOUT = 0xff ;//设置为推挽输出
}

void DetectBusy(void)
{
	P1MDOUT = 0x00;
	Lcd_EN = 0;
	Lcd_RS = 0 ;
	Lcd_RW = 1 ;
	_nop_();
	Lcd_EN = 1;
	_nop_();
	_nop_();
	_nop_();
	_nop_();
	_nop_();
  while(Busy==1) ;  //Busy为P1.7	
	delay_num=0;
	while(delay_num<2)      //2ms
	{;}
  Lcd_EN = 0;
	P1MDOUT = 0xff;
}

void LcdWriteCmd(unsigned char value)
{	
	Lcd_RS = 0 ; //写命令为0,写数据为1
	Lcd_RW = 0 ; //写为0,读为1
	P1 = value ;
	Lcd_EN = 1;  //EN高脉冲
	_nop_();
	Lcd_EN = 0;
}

void LcdWriteData(unsigned char value)
{	
	Lcd_RS = 1 ; //写命令为0,写数据为1
	Lcd_RW = 0 ; //写为0,读为1
	P1 = value ;
	Lcd_EN = 1;  //EN高脉冲
	_nop_();
	Lcd_EN = 0;
}

void LcdInit(void)
{
	delay_num=0;
	while(delay_num<15)      //15ms
	{;}

	/* 写指令0x38连续3次, 不检测忙信号*/
	LcdWriteCmd( 0x38 );   //1
		delay_num=0;
		while(delay_num<5)    //5ms
		{;}
	LcdWriteCmd( 0x38 );   //2	
		delay_num=0;
		while(delay_num<5)    //5ms
		{;}
	LcdWriteCmd( 0x38 );   //3

	/* 以后的读写操作均要判断忙信号 */
	DetectBusy();
	LcdWriteCmd( 0x38 );

	/* 先设置关屏 */
	DetectBusy();
	LcdWriteCmd( 0x08 );

	/* 清屏 */
	DetectBusy();
	LcdWriteCmd( 0x01 );

	/* 设置光标显示模式 */
	DetectBusy();
	LcdWriteCmd( 0x06 );

	/* 开屏并显示光标 */
	DetectBusy();
	LcdWriteCmd( 0x0F );
}

void LocateXY(char x , char y)
{
	unsigned char temp;
	temp = x & 0x0f;
	y &= 0x01;
	if ( y ) temp |= 0x40;
	temp |= 0x80;
	DetectBusy();
	LcdWriteCmd(temp);
	
}

void PutChar(char x , char y , char value)
{
	LocateXY(x,y);
	delay_num=0;
	while(delay_num<5)
	{;}
	DetectBusy();
	LcdWriteData(value);
}

void PutStr(char x , char y , char* str)
{
	unsigned char i,len=0;
	// 计算字符串长度
	while (str[len] >31)
	len++;			
	//显示字符串
	for (i=0;i<len;i++) 
	{   
    	PutChar(x++,y,str[i]);
		if ( x == 16 )
		{
			x = 0; y = 1;
		}
	}
}

void SelectedKeyShow(unsigned char keynum, unsigned char showid)
{
	switch(keynum)
	{
		case 1:
			if (showid==0)
			{
				PutStr(0,0,"Boil Water Order");
				PutStr(0,1," Wait For Reply ");
			}
			else if(showid==1)
			{
				PutStr(0,0,"Boiling Water...");
				PutStr(0,1,"Wait For Working");
			}
			else if(showid==2)
			{
				PutStr(0,0,"Boil Water is OK");
				PutStr(0,1," Wait For Press ");
			}
			break;
		case 2:
			if (showid==0)
			{
				PutStr(0,0,"Now Coffee Order");
				PutStr(0,1," Wait For Reply ");
			}
			else if(showid==1)
			{
				PutStr(0,0,"Making Coffee...");
				PutStr(0,1,"Wait For Working");
			}
			else if(showid==2)
			{
				PutStr(0,0,"Now Coffee is OK");
				PutStr(0,1," Wait For Press ");
			}
			break;
		case 3:
			if (showid==0)
			{
				PutStr(0,0,"Make Clean Order");
				PutStr(0,1," Wait For Reply ");
			}
			else if(showid==1)
			{
				PutStr(0,0,"Making Clean....");
				PutStr(0,1,"Wait For Working");
			}
			else if(showid==2)
			{
				PutStr(0,0,"Make Clean is OK");
				PutStr(0,1," Wait For Press ");
			}
			break;
		case 4:
			if (showid==0)
			{
				PutStr(0,0,"Make Dirty Order");
				PutStr(0,1," Wait For Reply ");
			}
			else if(showid==1)
			{
				PutStr(0,0,"Making Dirty....");
				PutStr(0,1,"Wait For Working");
			}
			else if(showid==2)
			{
				PutStr(0,0,"Make Dirty is OK");
				PutStr(0,1," Wait For Press ");
			}
			break;
		case 5:
			if (showid==0)
			{
				PutStr(0,0,"Make Steam Order");
				PutStr(0,1," Wait For Reply ");
			}
			else if(showid==1)
			{
				PutStr(0,0,"Making Steam....");
				PutStr(0,1,"Wait For Working");
			}
			else if(showid==2)
			{
				PutStr(0,0,"Make Steam is OK");
				PutStr(0,1," Wait For Press ");
			}
			break;
		case 6:
			if (showid==0)
			{
				PutStr(0,0,"Make Reset Order");
				PutStr(0,1," Wait For Reply ");
			}
			else if(showid==1)
			{
				PutStr(0,0,"Making Reset....");
				PutStr(0,1,"Wait For Working");
			}
			else if(showid==2)
			{
				PutStr(0,0,"Make Reset is OK");
				PutStr(0,1," Wait For Press ");
			}
			break;
		default:
			break;
	}
}


unsigned char Key_Scan(void)
{
	P3MDOUT|=0x0e;
	P0MDOUT|=0x03;
	Key1=1;
	Key2=1;
	Key3=1;
	Key4=1;
	Key5=1;

	Key1=0;          
  Key2=0;

		P3MDOUT&=0xf1;
    P0MDOUT&=0xfc;
    if (!(Key3&Key4&Key5))    //全部扫描
    { 	   
		delay_num=0;           //防抖
		while(delay_num<100)
		{;}
	 
		if(!(Key3&Key4&Key5)) 	//再次全部扫描
		{   			
		
			P3MDOUT|=0x0e;
			P0MDOUT|=0x03;
			Key1=1;      //第一行
			Key2=0;
			Key3=1;
			Key4=1;
			Key5=1;	
			P3MDOUT&=0xf1; 
			P0MDOUT&=0xfc;
			if(!(Key3&Key4&Key5)) 
			{
				//SendChar('1');
				if(Key3==0)   return 0x01;  
				if(Key4==0)   return 0x02; 	
				if(Key5==0)   return 0x03; 
		    }

			P3MDOUT|=0x0e;
			P0MDOUT|=0x03;
			Key1=0; 
			Key2=1;      //第一行
			Key3=1;
			Key4=1;
			Key5=1; 
			P3MDOUT&=0xf1; 
			P0MDOUT&=0xfc;
			if(!(Key3&Key4&Key5)) 
			{
				//SendChar('2');
				if(Key3==0)   return 0x04;  
				if(Key4==0)   return 0x05; 	
				if(Key5==0)   return 0x06; 
		    }
		}
		else  //只是抖动
		{
			return 0;	
		}
	 }
	 else  //没有按下任何键
	 {
	 	return 0;
	 }
}
void main(void)
{	
//****************************************	
	INIT_PORT();
	WDT_Init();	
	INIT_SYS_CLK();
	EA=1;
	Timer0_Init();
	RS232_Init();
	LcdInit();
//****************************************
	PutStr(0,0,"Welcome to YLong");
	PutStr(0,1," Idle,Press KEY ");
	
	for(LED_Count=0;LED_Count<3;LED_Count++)
	{
		Time_Out_Count=0;
		while(Time_Out_Count<500)    //5ms
		{;}
		Led1=~Led1;
		Led2=~Led2;
		Led3=~Led3;
	}	

	while(1)
	{
		//增加键盘扫描程序,键值放在Key_Value
		Key_Value=Key_Scan();
		if (Key_Enable)
		{
			if (Key_Value)
			{
				Led1=~Led1;
				Present_State=Key_Value;
				Key_Value=0;
				switch(Present_State)
				{
					case 1:
						serial_tx_buff[0]=FRAME_WATER;
						Need_to_Send=1;
						Work_Time_Out=WATER_WORKONG_TIME;
					  break;
					case 2:
						serial_tx_buff[0]=FRAME_NOW_COFF;
						Need_to_Send=1;
						Work_Time_Out=NOW_WORKONG_COFF_TIME;
						break;
					case 3:
						serial_tx_buff[0]=FRAME_CLEAN;
						Need_to_Send=1;
						Work_Time_Out=CLEAN_WORKONG_TIME;
						break;
					case 4:
						serial_tx_buff[0]=FRAME_DIRTY;
						Need_to_Send=1;
						Work_Time_Out=DIRTY_WORKONG_TIME;
						break;
					case 5:
						serial_tx_buff[0]=FRAME_STEAM;
						Need_to_Send=1;
						Work_Time_Out=STEAM_WORKONG_TIME;
						break;
					case 6:
						serial_tx_buff[0]=FRAME_RESET;
						Need_to_Send=1;
						Work_Time_Out=RESET_WORKONG_TIME;
						break;
					default:
						Need_to_Send=0;
						Work_Time_Out=0;
						break; 
				}
				if (Need_to_Send)
				{
					Led3=~Led3;
					Need_to_Send=0;
					SendString(serial_tx_buff,8);
					//Led3=0;				
					//PutStr(0,0,"Order Have Send!");
					//PutStr(2,1,"Please  Wait");
					SelectedKeyShow(Present_State,0);				
					Time_Out_Count=0;
					Uart_Flag=0;
					Uart_Coun=0;
					while(Time_Out_Count<COFFE_TIME_OUT)
					{
						if (Uart_Flag)
						break;
					}
					if (Uart_Flag)
					{
						Uart_Flag=0;
						Uart_Coun=0;
						//Led2=~Led2;
						if (serial_rx_buff[0]==COFFE_BUSY_STATUS)
						{
							//PutStr(0,0,"Start to Working");
						  //PutStr(2,1,"Please  Wait");
						  Uart_Enable=1;
						  Key_Enable=0;
						  Recv_Out_Times=0;
						  Recv_Time_Out=0;
						  SelectedKeyShow(Present_State,1);
						}
						else if(serial_rx_buff[0]==COFFE_ERROR_STATUS)
						{
							PutStr(0,0,"Have Some Error!");
						  PutStr(0,1,"Please Reselect!");
						}
						else
						{
							PutStr(0,0,"Unknown Status 0");
						  PutStr(0,1,"Please Reselect!");
						}
						//serial_rx_buff[0]=0x00;
					}
					else
					{
						PutStr(0,0,"Coffee Center is Busy or Timeout");
						Time_Out_Count=0;
						while(Time_Out_Count<1000)
						{;}
						PutStr(0,0,"Welcome to YLong");
						PutStr(0,1," Idle,Press KEY ");
					}
				}
				else
				{
					PutStr(0,0," Key Not Exist! ");
					PutStr(0,1," Wait For Press ");//按键错误
				}
			}
		}
		
		if (Uart_Enable)
		{
			if (Recv_Out_Times < Work_Time_Out)
			{
				if (Uart_Flag)
				{
					Uart_Enable=0;
					Key_Enable=1;
					Uart_Flag=0;
					Uart_Coun=0;
					if (serial_rx_buff[0]==COFFE_IDLE_STATUS)
					{
						//PutStr(0,0,"Working Has Done");
					  //PutStr(0,1,"Please Reselect!");
					  SelectedKeyShow(Present_State,2);
					}
					else if(serial_rx_buff[0]==COFFE_ERROR_STATUS)
					{
						PutStr(0,0,"Have Some Error!");
					  PutStr(0,1,"Please Reselect!");
					}
					else
					{
						PutStr(0,0,"Unknown Status 1");
					  PutStr(0,1,"Please Reselect!");
					}
					//serial_rx_buff[0]=0x00;			
				}
			}
			else
			{
				Uart_Enable=0;
				Key_Enable=1;
				PutStr(0,0,"Working Time Out");
				PutStr(0,1,"Please Reselect!");
			}
		}
	}
   _nop_();
}

⌨️ 快捷键说明

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