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

📄 line_call.c

📁 此程序为一排队机呼叫器,主要功能是:用键盘控制液晶显示实现485通讯,具体协议可参考《排队机通讯协议050609.doc》.编译环境为ICC-AVR6.3,采用了ATmega8芯片,晶振速率为6.00
💻 C
📖 第 1 页 / 共 2 页
字号:

  Key=KeySet[Key];
  
  
 if(Key==KeyPre)
   { 
     KeyPre=Key;
	 if(Key)KeyCount++;
	 Key=0;

	 }
 else 
    {
	 KeyPre=Key;
	 KeyCount=0;
	} 
}


void Beep(UChar temp)
{
   DDRC |=0x10;
   PORTC   |=0x10;
   lcdwriteCommandData(1,0,0x09);    //开蜂鸣器
   delay(temp);   
   lcdwriteCommandData(1,0,0x08);    //关蜂鸣器
   PORTC   &=0xEF;	      
 }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<keyboard

//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>LCD
void InitLCD(void)
{
   unsigned int j;
    char i=0;
	//延迟时间200毫秒
	for(i=0;i<10;i++)
   	   for(j=0;j<6000;j++);
  // 
  //液晶复位                         
    DDRD  |= 0xf0;                  //PD4-PD7输出
    PORTD |= 0xf0;                  //高电平 

    lcdwriteCommandData(1,0,0x29);    //定义模块
    lcdwriteCommandData(1,0,0x18);    //内部震荡

    lcdwriteCommandData(1,0,0x01);    //开振荡器
    lcdwriteCommandData(1,0,0x03);    //开液晶显示
	lcdwriteCommandData(1,0,0x40);    //置液晶蜂鸣器4K赫兹
    

	dsp_data(SelfAddr-9,0);
	dsp_status(gStatus);  //  'A' 显示当前呼叫器地址,等待登录
	delay(100);
	         
}


/*显示数据,其中data为显示的数据,dot为小数点个数  */
void dsp_data(long int x, UChar dot)
{
 
  UChar i;
  UChar  bit_sgn=0;
  unsigned long y;
  UChar ymod10;
 
  if (x<0)
    { x= -x; bit_sgn=1;}
  y=x;
     
  for (i=0; i<6; i++ )//有效位数不大于6,其余2位用于显示状态
   {
   ymod10=y%10;
   
   if(i==dot)
    lcdwriteCommandData(0,i*2,lcdtable[ymod10*2] | 0x01 );    //小数点
   else    
	lcdwriteCommandData(0,i*2,lcdtable[ymod10*2]);
	
    lcdwriteCommandData(0,i*2+1,lcdtable[ymod10*2+1]);
   
    y=y/10;
    if(y==0 && i>1)
    { 	  
       break;
    }
   }
   while(i<6)
   {
       i++;
      if(bit_sgn)
	      {
		   lcdwriteCommandData(0,i*2,0x00);
		   lcdwriteCommandData(0,i*2+1,0x04);
		   break;
		   } 
      else 
	       {
		    lcdwriteCommandData(0,i*2,0x00);
			lcdwriteCommandData(0,i*2+1,0x00);
		   }
	  }//  清除前面的零
} 

//显示数据,其中x为排队人数
void dsp_Wait_SerNum(unsigned int W, unsigned int S )
{
 
  UChar i;
  unsigned int y;
  UChar ymod10;
   
   //现处理排队人数
  y=W;     
  for (i=0; i<2; i++ )//有效位数不大于2,其余2位用于显示状态
   {
    ymod10=y%10;
    lcdwriteCommandData(0,i*2+10,lcdtable[ymod10*2]);//从右数第6个数码
	lcdwriteCommandData(0,i*2+1+10,lcdtable[ymod10*2+1]);   
    y=y/10;
    if(y==0 && i>1)
    { 	 break;
    }
   }
   while(i<2)
   {
       i++;
       lcdwriteCommandData(0,i*2+10,0x00);
	   lcdwriteCommandData(0,i*2+1+10,0x00);		
	  }//  清除前面的零
	  
	//现处理呼叫编号
	
	 y=S;     
  for (i=0; i<4; i++ )//有效位数不大于4
   {
    ymod10=y%10;
    lcdwriteCommandData(0,i*2,lcdtable[ymod10*2]);//从右数第6个数码
	lcdwriteCommandData(0,i*2+1,lcdtable[ymod10*2+1]);   
    y=y/10;
    if(y==0 && i>1)
    { 	 break;
    }
   }
   while(i<4)
   {
       i++;
       lcdwriteCommandData(0,i*2,0x00);
	   lcdwriteCommandData(0,i*2+1,0x00);		
    }//  清除前面的零  
}

//显示状态
void dsp_status( UChar status)
{    
    lcdwriteCommandData(0,14,lcdtable[status*2] | 0x01 );    //小数点
  	lcdwriteCommandData(0,15,lcdtable[status*2+1]);
} 

void lcdwriteCommandData(UChar CommData,UChar RamAdd,UChar lcddata)
{
  UChar i,lcdbitdata; 
  DDRD  |= 0xF0;  //输出                 
  delay_1us();
  PORTD &=0xEF;   //片选 
  delay_1us();
  if(CommData)    //命令  
  { 
     PORTD |= 0x80;  delay_1us();
	   PORTD &= 0xBF;delay_1us();	 
	     PORTD |= 0x40;delay_1us();                 //写命令100
	 PORTD &= 0x7F; delay_1us();
	    PORTD &= 0xBF;delay_1us();
		 PORTD |= 0x40;delay_1us();
	 PORTD &= 0x7F; delay_1us(); 
	   PORTD &= 0xBF; delay_1us();	
	     PORTD |= 0x40;delay_1us();   
   
     for(i=0;i<8;i++)  //C7 c6 ... c1, c0
    {  
	  if( lcddata  & 0x80) {
	   PORTD |= 0x80; delay_1us();
	    PORTD &= 0xBF;	delay_1us(); 
		PORTD |= 0x40;	delay_1us();
		}
	  else     {
	   PORTD &= 0x7F; delay_1us(); 
	    PORTD &= 0xBF;	delay_1us(); 
		 PORTD |= 0x40;delay_1us();}
      lcddata=lcddata<<1;	   
    }
    
     PORTD &= 0x7F; delay_1us();
	   PORTD &= 0xBF;	delay_1us(); 
	     PORTD |= 0x40;delay_1us(); // 0
  }
  else            //写数据
  {
  
      PORTD |= 0x80; delay_1us(); 
	    PORTD &= 0xBF;	delay_1us();
		  PORTD |= 0x40;  delay_1us();               //写数据101
	  PORTD &= 0x7F;  delay_1us();
	    PORTD &= 0xBF;	delay_1us();
		   PORTD |= 0x40;delay_1us();
	   PORTD |= 0x80; delay_1us(); 
	     PORTD &= 0xBF;	 delay_1us();
		   PORTD |= 0x40;delay_1us();   
  
     //ram 地址 
      PORTD &= 0x7F; delay_1us();
	    PORTD &= 0xBF;	 delay_1us();
		  PORTD |= 0x40; delay_1us();// 0
    
	 for(i=0;i<5;i++)  //A4,。。。,A0
     {  
	  if( RamAdd  & 0x10) { 
	     PORTD |= 0x80; delay_1us();
		  PORTD &= 0xBF;	delay_1us();
		   PORTD |= 0x40;delay_1us();
		   }
	  else        { PORTD &= 0x7F; delay_1us(); 
	           PORTD &= 0xBF;	delay_1us(); 
			     PORTD |= 0x40;delay_1us();}
      RamAdd=RamAdd<<1;	   
     }
    
      //ram 数据 
    
	 for(i=0;i<4;i++)  //A4,。。。,A0
     {  
	  if( lcddata  & 0x01) { 
	         PORTD |= 0x80; delay_1us(); 
			   PORTD &= 0xBF;delay_1us();
			    	 PORTD |= 0x40;delay_1us();}
	  else                 {
	        PORTD &= 0x7F; delay_1us(); 
			  PORTD &= 0xBF;delay_1us();
			    PORTD |= 0x40;delay_1us();}
      lcddata=lcddata>>1;	   
     }  
  }
  
  PORTD |= 0x80;  //数据线拉高
  delay_1us();
  PORTD |=0x10;   //片选高
  delay_1us();  
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<LCD


//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>COMM
//通讯测试:
//  对于本程序原始地址和主机地址,按照协议,主机应该返回如下代码
//  用户编号 U: @@811A6666665@
//  密码:     P: @@811B6666666@
//  正常数据:F: @@BcC0901237@
//                   F: @@BcC0901248@ 
//采用中断来处理,否则过于消耗资源
#pragma interrupt_handler Usart_Rx_isr:12
void Usart_Rx_isr(void)   //串行通讯接收中断服务程序
{   
         static UChar pRe=0,Check=0;
		 int a,b;
        
	   	  RxBuf[pRe]  = UDR;
          
//		  UDR=RxBuf[pRe]+1;
		  
		
		  if(RxBuf[pRe] == '@')  //消息帧开始
          {
		    Check=0;
		    pRe=0;		   
			RxBuf[pRe]='@';
		  }
		  if(pRe==11)		 
		  {
		 //   dsp_data(((Check%10)+'0'),0);//debug
		  }
		  
		  if(((Check%10)+'0') == RxBuf[pRe] && pRe>10)//消息帧结尾字节,校验和成功
		  {

		    if(RxBuf[1]!=(SelfAddr/10+'0')  ||  RxBuf[2]!=(SelfAddr%10+'0'))   //不是本机的消息
		    
		    //if(RxBuf[1]!=SelfAddr  ||  RxBuf[2]!=MasterAddr)   //不是本机的消息
		     {
			    Check=0;
		        pRe=0;
				return;			   
			 }
		    CommReceiveFlag=1;//接收到有效的数据
		    switch(RxBuf[4])   //消息类型 
			{
			   case 'A':        //用户工号返回码
			           if(RxBuf[5]=='6' && RxBuf[6]=='6' ) //成功
					   { 
                          gStatus=21;					    
					   }
			           break;
			   case 'B':        //用户密码返回码
			           if(RxBuf[5]=='6' && RxBuf[6]=='6' ) //成功
					   { 
					      gStatus=15;					    
					   }
			           break;
               case 'C':        //用户操作返回码
			        //   NumKeyIn=(RxBuf[4]-'0')*100000+ (RxBuf[5]-'0')*10000
					//         +(RxBuf[6]-'0')*1000+ (RxBuf[7]-'0')*100
                    //                   +(RxBuf[8]-'0')*10+ (RxBuf[9]-'0');
					// 由于编译器的问题,改写如下
				   
				   NumKeyIn=(RxBuf[5]-'0');
   				   NumKeyIn=NumKeyIn*10+(RxBuf[6]-'0');
   				   NumKeyIn=NumKeyIn*10+(RxBuf[7]-'0');
   				   NumKeyIn=NumKeyIn*10+(RxBuf[8]-'0');
				   NumKeyIn=NumKeyIn*10+(RxBuf[9]-'0');
				   NumKeyIn=NumKeyIn*10+(RxBuf[10]-'0');
			           break;
			}
		  }
          Check+=RxBuf[pRe];
		  pRe++;
		  if(pRe>=RXBUFLENGTH)pRe=0;      	  
}

#pragma interrupt_handler Usart_Tx_isr:14
void Usart_Tx_isr(void)   //串行通讯发送缓冲区空中断服务程序
{

   static UChar pTx=0; 
   if(TxBuf[pTx])  //0表示无数据
   {
       UDR=TxBuf[pTx];                         //发送一个字节
	   TxBuf[pTx]=0;//清空 
	   pTx++;	  	   
   }
   else pTx=0;
  
}

//发送消息到主机
void send_message(UChar TargetAddr,UChar MsgType,UChar * MsgBuf)
{
	
     UChar check=0;
     
     TxBuf[0]='@';									check+=TxBuf[0];
     TxBuf[1]=TargetAddr+'0';  			    check+=TxBuf[1];				  
     TxBuf[2]=SelfAddr/10+'0';              check+=TxBuf[2];
     TxBuf[3]=SelfAddr%10+'0';            check+=TxBuf[3];
	 
     TxBuf[4]=MsgType;                        check+=TxBuf[4];
	 
     TxBuf[5]=MsgBuf[0];                      check+=TxBuf[5];
	 TxBuf[6]=MsgBuf[1];                      check+=TxBuf[6];
	 TxBuf[7]=MsgBuf[2];                      check+=TxBuf[7];
	 TxBuf[8]=MsgBuf[3];                      check+=TxBuf[8];
	 TxBuf[9]=MsgBuf[4];                      check+=TxBuf[9];
	 TxBuf[10]=MsgBuf[5];                    check+=TxBuf[10];
	 	 
	 TxBuf[11]=check%10+'0';	
	 TxBuf[12]='@';
	 TxBuf[13]=0; 	 
	 
     putchar(0x0a);//回车换行
     putchar(0x0d);
//	 UDR='@'; //首先发送一个起始字节,并引发发送中断  
}

/*  		字符输出函数 		 */
void putchar(UChar c)
	{	 
     while (!(UCSRA&(1<<UDRE)));  //等待发送结束
	 UDR=c;                                          //发送一个字节
	}
/*  		字符输入函数 		 */	
UChar getchar(void)
  	{
	 while(!(UCSRA& (1<<RXC)));
     return UDR;
	}		
/*			字符串输出函数	   	 */	
int puts(char *s)
	{
	while (*s)
		{
		putchar(*s);
		s++;
		}	
    putchar(0x0a);//回车换行
	putchar(0x0d);
	return 1;
	}
/*	 	   不含回车换行的字符串输出函数 	 */	
void putstr(char *s)
	{
	while (*s)
		{
		putchar(*s);
		s++; 
		}	
	}	
/*			UART初始化				*/	
//UART0 initialisation
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
//9600
 UCSRB = 0x00; //disable while setting baud rate
 UCSRA = 0x00;
 UCSRC = 0x86;
// UBRRL = 0x26; //set baud rate lo   9600
 UBRRL = 0x13; //set baud rate lo   19200
 UBRRH = 0x00; //set baud rate hi
 UCSRB = 0xD8;
}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<COMM

⌨️ 快捷键说明

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