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

📄 12.c

📁 08浙江省大学生电子设计竞赛 C题,智能公交系统 获二等奖
💻 C
字号:
/**********************************************
  显示和键盘都已经正常,键盘采用的是中断方式
  
  2008.7.2
  
**************************************/
#include <P89V51.h>
#include <absacc.h>
#include <intrins.h>
#include <stdlib.h>
#include <stdio.h> 
#define   uchar unsigned char 
//SYSTEM ADDRESS ALLOCATION	******************
#define KEYCOLUM XBYTE[0xEFFF]
#define KEYROW XBYTE[0xDFFF]
#define ALARM XBYTE[0xCFFF]
#define HC245C1 XBYTE[0xBFFF]
#define HC245C2 XBYTE[0xAFFF]
#define HC573C1 XBYTE[0x9FFF]
#define HC573C2 XBYTE[0x8FFF]
#define HC573C3 XBYTE[0x7FFF]
#define ADCS XBYTE[0x6FFF]
#define DACS XBYTE[0x5FFF]
#define DACLOAD XBYTE[0x4FFF]
//***************************************	

//static unsigned char keyin=0;


/*-------------LCD1602 definitions and functions--------------*/
#define nops() {_nop_();_nop_();_nop_();}
typedef bit BOOL;

#define FALSE (bit)0
#define TRUE  (bit)1
 
sbit lcd_cs = P2^0;            //控制位
sbit lcd_rw = P2^1; 
sbit lcd_rs = P2^2;
#define DataPort      P0 
#define DataDirPort   P0  
#define StatePort     P0   
      
#define Busy 0x80 // 忙判别位  
uchar keystate,keyin=0;
char n=0,i,flag=0,c_2;
unsigned int a, ADs,ch;
char ADval[10];
//**************时间变量**********************
unsigned int tick=0,second=0,second_1=0,minute=0,b_out,c_0,c_1,mid,mid2,ch,ch_0=0,ch_no=0;

//*****************控制变量*********************
unsigned int step=0,t_1=0,t_2,t_3,t_no=0,co_2;

float co_1;

void delay(long t)
{
    while(t)
     t--;
} 

code unsigned char* WrtieLcdErr =  "Display char outof range."; 

// ------ Private function prototypes --------------------------
static BOOL WaitTillNotBusy();
static BOOL LocateXY(unsigned char posx, unsigned char posy); 
static BOOL LcdWData(unsigned char dataW);
static BOOL LcdWCMD(unsigned char CMD);
BOOL LCDInit() ;
BOOL DisplayOneChar(unsigned char x ,unsigned char y ,unsigned char Wdata) ;
BOOL DisplayString(unsigned char posx, unsigned char posy,  unsigned char*  str);
unsigned char keyscan(void);
unsigned char Gatkey(char keystate);

BOOL WaitTillNotBusy()
{ 
    unsigned int delay = 0xffff;  
 
        DataDirPort = 0xff; 
                            
        lcd_cs = 1;
        lcd_rs = 0;
        lcd_rw = 1;
        while( (StatePort & Busy) && delay)
            delay--;
        lcd_cs = 0;  
        if (!delay)  
            return FALSE ; 
    
    return TRUE; 
}      

BOOL LocateXY( unsigned char posx,unsigned char posy)
{
    posy &= 0x01;
    if (posy == 1)
        posx |= 0x40;
    posx |= 0x80;
   
    return LcdWCMD(posx);   
}


BOOL LcdWCMD(unsigned char CMD) 
{        
        unsigned char i=1;
                            
        if (!WaitTillNotBusy()) // 检测忙信号? 
        return FALSE;    
                                
        DataPort = CMD;
        lcd_rs = 0;
        lcd_rw = 0;
        lcd_cs = 1;
        while(i++);
        lcd_cs = 0;  
    
       return TRUE;
}


BOOL LcdWData( unsigned char dataW )
{    
     
        unsigned char i = 1;
         
        if (!WaitTillNotBusy()) // 检测忙信号? 
            return FALSE; 
      
        
        DataPort = dataW;
        lcd_rs = 1;
        lcd_rw = 0;
        lcd_cs = 1;
        while(i++);
        lcd_cs = 0;   

       return TRUE;
} 

// LCD输出用函数
//LCDInit--LCD初始化
//DisplayOneChar(x,y,char) --在指定x,y显示一个字符
//DisplayString(x,y,str)--在指定位置x,y开始显示一个字符串

BOOL LCDInit() 
{
  
    // 显示模式设置,光标移动设置,显示开及光标设置,显示清屏 
    return (LcdWCMD( 0x38) && LcdWCMD( 0x06) && LcdWCMD( 0x0c) && LcdWCMD( 0x01));       

}

BOOL DisplayOneChar(unsigned char x ,unsigned char y ,unsigned char Wdata) 
{
   
    if( (x >= 0 && x < 16) && (y >= 0 && y < 2) )
        return (LocateXY( x, y ) && LcdWData( Wdata )) ;// 定位显示地址,写字符 
    else
        return ( LCDInit() && DisplayString(0, 0, WrtieLcdErr));    //显示越界消息    
}

BOOL DisplayString(unsigned char posx, unsigned char posy,  unsigned char*  str)
{    
    while ( (*str) != '\0' )
    {
        if (!DisplayOneChar(posx, posy, (*str)))
            return FALSE;
        str++;
        posx++;
        if( posx == 16 )
        {
            posx = 0;
            posy++;

        }
    }
    
    return TRUE;              
}
/*--------------End of LCD1602 macros and functions------------------*/

/*-------------- ----SPI protocols-----------------------------------	*/

void SpiInit(void)
{
   SPCR = 0x51;
   SPSR = 0x00;
}

void SpiClose(void)  {SPCR = 0x00;}

/*----------------End of SPI protocols---------------------------*/

//-----------ADC MCP3208 functions--------------------
// ReadAD(chx)读AD,chx为通道号
//chx=0x00----0x07对应AD0---AD7通道
unsigned int ReadAD(unsigned char chx)
{

    unsigned int lsb,msb;
	char sbuf;
    lsb=0;msb=0;
  	
	ADCS = 0x00;	
	sbuf = 0x06 | (chx>>2);
	SPDAT = sbuf;
    while(!(SPSR&0x80) );
	SPSR = 0x00;
    sbuf = SPDAT;
	
	sbuf = (chx&0x03)<<6;
	SPDAT = sbuf;
    while(!(SPSR&0x80) );
	SPSR = 0x00;
    sbuf = SPDAT;
	msb = sbuf&0x0F;
	
	sbuf = 0x00;
	SPDAT = sbuf;
    while(!(SPSR&0x80) );
	SPSR = 0x00;
    lsb = SPDAT;
	
	XBYTE[0xFFFF] = 0x00;
	
    return msb*256+lsb;

}  
//------------End ADC MCP3208 functions-----------------        

//-----------------DAC MCP4922 functions----------------------
void DACout( unsigned char DACH, unsigned int DAValue)
{
    unsigned char msb,lsb,temp;  

   XBYTE[0xFFFF] = 0;

   DAValue&=0x0FFF;
 
   temp = (DAValue/256)&0x0F;

  DACS = 0x00; 
   
  if(DACH==1)
    {
    msb =0x70|temp;
    lsb = (unsigned char)(DAValue & 0xFF) ; 
    }
  else if(DACH==2)
   {
    msb =0xF0|temp;			  
    lsb = (unsigned char)(DAValue & 0xFF) ; 
    }
  else
    { }
   
 
   SPDAT = msb;
   while(!(SPSR&0x80) );
   SPSR = 0x00;

   SPDAT = lsb;
   while(!(SPSR&0x80) );
   SPSR = 0x00;
  
   XBYTE[0xFFFF] = 0;
   DACLOAD = 0x00;
   nops();
   XBYTE[0xFFFF] = 0;
 
}



//**********************按键中断响应**********************

void Int1_keyscan(  )  interrupt 0	 
{   
    unsigned char ucSKey;
    unsigned int  uiI;
	EA=0;
    for (uiI=0;uiI<100;uiI++);                //延时,去掉抖动 
    if(INT1==1) 
	goto end01;                     
    for (uiI=0;uiI<100;uiI++);                //延时,去掉抖动 
    if(INT1==1) 
	goto end01;                                     //关闭外部中断
    //LcdWCMD( 0x01) ;  //显示清屏
    keyscan();   //获取按键状态
    Gatkey(keystate);                        
    DisplayOneChar(0,1,keyin);   //显示按键对应的字符


	//delay(500);  	
	while(P3_2==0){;}
	delay(100);
	while(P3_2==0){;}
	end01:;
	EA=1;  // 开启中断
	KEYROW=0x00;
}

//*****************获取按键状态函数******************
unsigned char keyscan(void)      
{
   uchar recode,sccode;
   KEYROW=0xE0;       //将行都设置为低电平
   recode=KEYCOLUM;   //获取列的状态
    if((recode&0x0F)!=0x0F)  //判断是否有键按下和延时去抖动
     {
       delay(6000);        
     if((recode&0x0F)!=0x0F)
       {
        sccode=0xFE;          //设置行扫描的初始值
        while((sccode&0x20)!=0)     //判断并逐行扫描
         {   
             KEYROW=sccode;
             recode=KEYCOLUM;
             if((recode&0x0F)!=0x0F)
              {
                 recode=(recode&0x0F)|0xF0;  //记录列号
                 sccode=~sccode;               //记录行号
		         sccode=sccode<<4;       //把行号方到高四位
		         keystate=(sccode)+(~recode);  //记录行列状态,高四位为行号,低四位为列号
				 return keystate;             
		         break; 
               }
              else
               sccode=(sccode<<1)|0x01;        //行扫描后没找到按键状态则转到下一行
         }
       } 
    }
  return(0); 
} 
//**********************按键对应的显示字符**********************************
unsigned char Gatkey(char keystate)
{

 switch (keystate)
 {
   case 0x11: keyin='a';
              break;
   case 0x12: keyin='b';
              break;
   case 0x14: keyin='c';
              break;
   case 0x18: keyin='d';
              break;
   case 0x21: keyin='e';
              break;
   case 0x22: keyin='f';
              break;
   case 0x24: keyin='g';
              break;
   case 0x28: keyin='h';
              break;
   case 0x41: keyin='i';
              break;
   case 0x42: keyin='j';
              break;
   case 0x44: keyin='k';
              break;
   case 0x48: keyin='l';
              break;
   case 0x81: keyin='m';
              break;
   case 0x82: keyin='n';
              break;
   case 0x84: keyin='0';
              break;
   case 0x88: keyin='p';
              break;
   case 0x01: keyin='q';
              break;
   case 0x02: keyin='r';
              break;
   case 0x04: keyin='s';
              break;
   case 0x08: keyin='t';
              break;
   default: keyin='N' ;
   }
   return keyin;

}

void Setpwm(char channel,  unsigned char pwmval)
{
   switch (channel )
   {
	case 0:
	  CCAP0L = pwmval;	   //PWMVAL值确定占空比,0X00-0XFF;反比例:
	  CCAP0H = pwmval;CCAPM0 = 0x4A;
	  break;
	case 1:
	  CCAP1L = pwmval;
	  CCAP1H = pwmval;CCAPM1 = 0x4A;
  	  break;
	default:
	  CCAP0L = pwmval;
	  CCAP0H = pwmval;CCAPM0 = 0x4A	;

   }
    

}

//**********************子程序附加*******************
//***********************************
   void stop(void)
   {
   HC573C1=0x00;         //停止
   }

   void go_left(void)
   {
    HC573C1=0x01;		 //左转
   }

   void go_right(void)
   {
    HC573C1=0x04;		 //右转
   }

   
  void go(void)
   {
   HC573C1=0x05;		 //前进
   }


	  //*************处理*****************

void deal_go(void)
{ 
mid=HC245C1%4;		  //寻迹读入

if(mid==2)go_left();
if(mid==1)go_right();
if(mid==3)go();
if(mid==0)
{
t_no++;
stop();
if((t_no==3)||(t_no==4))
{
while(mid==0)
{
go();
mid=HC245C1%4;
}
}
else 
{
go();
delay(100);
while(mid==0)
{
go();
mid=HC245C1%4;
}
for(i=0;i<16;i++)
{ 
mid=HC245C1%4;
if(mid==2)go_left();
if(mid==1)go_right();
if(mid==3)go();
if(mid==0)go();
delay(100);
}
stop();
delay(60000); 
HC573C2=0x00;
}

}

}
/*
void deal_go2(void)

{ 
if((P2_0==0)||(P2_1==0))
{

t_no++;
flag=1;
t_1=second_1;
}

}
*/
//******************时间显示**************************
void LCD_TIME(void)
{
  DisplayString(11,0,"m   s ");
  sprintf(ADval,"%d",second);
  DisplayString(13,0,ADval);
  sprintf(ADval,"%d",minute);
  DisplayString(10,0,ADval);
}
void LCD_cesu(void)
{
 a=TH1*256+TL1;
 sprintf(ADval,"%d",a);
 if(a<10000)ADval[4]=' ';
 if(a<1000)ADval[3]=' ';
 if(a<100)ADval[2]=' ';
 if(a<10)ADval[1]=' ';
 DisplayString(10,1,ADval);
}
//********************************平衡************************

void T0INT( )  interrupt 1
{ 
  EA=0;
  TH0 = 0x3C;
  TL0 = 0xAF;
  tick ++;
  if(tick>=19)
    { 
      tick =0;
      second++ ; 
	  second_1++;
	  if(second>=60)
        {
         second=0;
         minute++;
        }

     }
	  P1=0xff;
      Setpwm(0,co_2);
	 EA=1;

} 
 







//******************************主程序***************************
void main()
{
   
   //int b,c;
   SpiInit();
   LCDInit();
   DisplayString(5,1,"No= ");
   HC573C1 = 0x0f;
   HC573C2 = 0x0F;
   KEYROW = 0x00;
   P1 = 0x01;
				 //0x51--T0计时,T1计数
   TMOD = 0x51;	 //	最高位置1测INTX脚高低电平长短,C/T位(第7位)置1选择计数模式 //*T1* GATE||C/T||M1||M0|*T0*|GATE||C/T||M1||M0||
   TL0 = 0xAF;
   TH0 = 0x3C;
   TL1 = 0X00;
   TH1 = 0X00;
   ET0 = 1;
   ET1 = 1;
   TR0 = 1;
   TR1 = 1; 
   EA  = 1;
   EX0 = 1;

   CMOD = 0x02;  
   CCAPM0 = 0x4A; 
   CCAPM1 = 0x4A;
   CL =0;
   CCAP0H = 16;
   CCON = 0x40;   
   
 	//  ADs = ReadAD(0x01);
	//  sprintf(ADval,"%d",ADs);
	// DisplayString(0,0,ADval);
	// DACout(1,ADs);
	//  DACout(2,ADs);
    // KEYROW=0xE0;
    //HC573C1 ^= 0x01;
    // delay(10000);             //这里加了延时会出现按键不正常



//HC573C1=0x01;		 //左转
//HC573C1=0x04;		 //右转
//HC573C1=0x05;		 //前进
//HC573C1=0x00;	 //停止 
P1=0xff;
HC573C2 = 0xff;
while(keyin!='a'){;}
while(1)
{
deal_go();

LcdWCMD( 0x01) ;  //显示清屏

a = TH1*256+TL1;

sprintf(ADval,"%d",a);

DisplayString(8,0,ADval);

sprintf(ADval,"%d",t_no);

DisplayString(0,1,ADval);

}

}

⌨️ 快捷键说明

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