久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1895|回復: 0
打印 上一主題 下一主題
收起左側

單片機智能小車源程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:112047 發表于 2016-4-3 16:17 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式

   /*預處理命令*/
#include<reg52.h>    //包含單片機寄存器的頭文件
#include<intrins.h> //包含_nop_()函數定義的頭文件
#define uchar unsigned char
#define uint  unsigned int
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
sbit IRIN=P3^2;         //紅外接收器數據線
sbit LCD_RS = P0^7;            
sbit LCD_RW = P0^6;
sbit LCD_EN = P0^5;
uchar begin[]={"My car!"};
uchar cdis1[]={"jiansu!"};
uchar cdis2[]={"qianjin!"};
uchar cdis3[]={"jiasu!"};
uchar cdis4[]={"zuozhuang!"};
uchar cdis5[]={"STOP!"};
uchar cdis6[]={"youzhuan!"};
uchar cdis8[]={"daoche!"};
sbit M1   = P1^0;
sbit M2   = P1^1;
sbit M3   = P1^2;
sbit M4   = P1^3;
sbit EN12 = P1^4;
sbit EN34 = P1^5;
uchar IRCOM[7];
uchar m,n;
uchar t=2;
uchar g;
uchar code digit[]={"0123456789"};
uint v;
uchar count;
bit flag;
void delayxms(uchar t);
void delay(unsigned char x) ;
void delay1(int ms);
void motor();
void lcd_display();
/*
檢查LCD忙狀態
lcd_busy1時,忙,等待。lcd-busy0,閑,可寫指令與數據
*/
bit lcd_busy()
{                          
        bit result;
        LCD_RS = 0;
        LCD_RW = 1;
        LCD_EN = 1;
        delayNOP();
        result = (bit)(P0&0x80);
        LCD_EN = 0;
        return(result);
}
/*
寫指令數據到LCD
RS=LRW=LE=高脈沖,D0-D7=指令碼
*/
void lcd_wcmd(uchar cmd)
{                          
   while(lcd_busy());
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_EN = 0;
    _nop_();
    _nop_();
    P2 = cmd;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;  
}
/*
寫顯示數據到LCD
RS=HRW=LE=高脈沖,D0-D7=數據
*/
void lcd_wdat(uchar dat)
{                          
   while(lcd_busy());
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_EN = 0;
    P2 = dat;
    delayNOP();
    LCD_EN = 1;
    delayNOP();
    LCD_EN = 0;
}
/*
LCD初始化設定
*/
void lcd_init()
{
    delay1(15);                  
    lcd_wcmd(0x38);      //16*2顯示,5*7點陣,8位數據
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x38);         
    delay1(5);
    lcd_wcmd(0x0c);      //顯示開,關光標
    delay1(5);
    lcd_wcmd(0x06);      //移動光標
    delay1(5);
    lcd_wcmd(0x01);      //清除LCD的顯示內容
    delay1(5);
}
/*
設定顯示位置
*/
void lcd_pos(uchar pos)
{                          
        lcd_wcmd(pos | 0x80);  //數據指針=80+地址變量
}
/*x顯示速度提示符*/
void  display_sym(void)
{
lcd_pos(0x00);
lcd_wdat('v');
lcd_wdat('=');
}
/*顯示速度數值*/
void display_vel(uint x)
{
uchar i,j,k,l;
i=x/1000;             //取千位
j=(x%1000)/100;         //取百位
k=(x%100)/10;         //取十位
l=x%10;                         //取個位
lcd_pos(0x02);
lcd_wdat(digit);
lcd_wdat(digit[j]);
lcd_wdat(digit[k]);
lcd_wdat(digit[l]);
}
/*顯示速度單位*/
void display_unit(void)
{
lcd_pos(0x06);
lcd_wdat('r');
lcd_wdat('/');
lcd_wdat('m');
lcd_wdat('i');
lcd_wdat('n');
}
/*
主函數
*/
/*******************************************************************/
void main()
{
        uint a;
   
        IRIN=1;                    //I/O口初始化       
        IE=0x83;                 //允許總中斷中斷,使能 INT0 外部中斷
        TCON=TCON|0x01;               //觸發方式為脈沖負邊沿觸發
        lcd_init();
        TMOD=0x51;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)/256;
    TR0=1;
    count=0;
    display_sym();
    display_vel(0);
    display_unit();
        lcd_pos(0x40);
        g=0;
        while(begin[g]!='\0')
        {
           lcd_wdat(begin[g]);
           g++;
         }
    while(1)
    {
      TR1=1;
      TH1=0;
      TL1=0;
      flag=0;
          display_sym();
          display_unit();
      while(flag==0);
      v=(TH1*256+TL1)*60/20;
      display_vel(v);
          motor();
          }
}
/**********************************************************/
void IR_IN() interrupt 0 using 0
{
        unsigned char j,k,N=0;
        unsigned char q=0;
        EX0 = 0;   
        delay(15);
        if (IRIN==1)
        {
                EX0 =1;
                return;
        }
                   //確認IR信號出現
        while (!IRIN)            //IR變為高電平,跳過9ms的前導低電平信號。
                delay(1);
       
        for (j=0;j<4;j++)         //收集四組數據
        {
                for (k=0;k<8;k++)        //每組數據有8
                {
                        while (IRIN)            //IR 變為低電平,跳過4.5ms的前導高電平信號。
                        {delay(1);}
                        while (!IRIN)          //IR 變為高電平
                                delay(1);
                        while (IRIN)           //計算IR高電平時長
                        {
                                delay(1);
                                N++;           
                                if (N>=30)
                                {
                                        EX0=1;
                                        return;
                                }                  //0.14ms計數過長自動離開。
                        }                        //高電平計數完畢               
                        IRCOM[j]=IRCOM[j] >> 1;     //數據最高位補“0
                        if(N>=8)
                        {
                                IRCOM[j] = IRCOM[j] | 0x80;                  //數據最高位補“1
                        }  
                        N=0;
                }
        }
       
        if(IRCOM[2]!=~IRCOM[3])
        {
                EX0=1;
                return;
        }
       
        IRCOM[5]=IRCOM[2] & 0x0F;     //取鍵碼的低四位
        IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位變為低四位
       
        if(IRCOM[5]>9)
        {
                IRCOM[5]=IRCOM[5]+0x37;
        }
        else
        IRCOM[5]=IRCOM[5]+0x30;
       
        if(IRCOM[6]>9)
        {
                IRCOM[6]=IRCOM[6]+0x37;
        }
        else
        IRCOM[6]=IRCOM[6]+0x30;
        q= (((IRCOM[6]&0x0f)<<4) + (IRCOM[5]&0x0f));
   
        switch(q)    //判斷按鍵鍵碼值
        {
                case 0x16:m=0;break; //串口發送0
                case 0x03:m=1;t++;if(t>=5)t=4;break;  //串口發送01
                case 0x18:m=2;n=2;break;              //串口發送02
                case 0x55:m=3;t--;if(t<=0)t=0;break;  //串口發送03
                case 0x08:m=4;n=4;break;              //串口發送04
                case 0x13:m=5;n=5;break;              //串口發送05
                case 0x51:m=6;n=6;break;              //串口發送06
                case 0x42:m=7;break;                  //串口發送07
                case 0x52:m=8;n=8;break;              //串口發送08
                case 0x41:m=9;break;                  //串口發送09
       
                default :break;
        }
     lcd_display();
         EX0 = 1;
          
}
/***************延時函數*****************************/
void delay(unsigned char x)    //x*0.14MS
{
        unsigned char i;
        while(x--)
        {
                for (i = 0; i<13; i++) {}
        }
}
void lcd_display()
{   
   
    g=0;
       
        switch(        m)
        {          
          case 1:  lcd_init();
                    lcd_pos(0x40);
                while(cdis1[g]!='\0')        //減速
                       {  
                                   lcd_wdat(cdis1[g]);
                          g++;
                }break;
        case 2:         lcd_init();
                    lcd_pos(0x40);                             //前進
                while(cdis2[g]!='\0')
                    {
                                  lcd_wdat(cdis2[g]);
                         g++;
                     }break;
     case 3:   lcd_init();
                    lcd_pos(0x40);                                  //加速
                while(cdis3[g]!='\0')
                    {   
                                    lcd_wdat(cdis3[g]);
                        g++;
                      }break;
        case 4:           lcd_init();
                    lcd_pos(0x40);                    //左轉
                while(cdis4[g]!='\0')
                   {   
                               lcd_wdat(cdis4[g]);
                       g++;
                      }break;
        case 5:           lcd_init();
                    lcd_pos(0x40);                          //停車
                while(cdis5[g]!='\0')
                          {
                                    lcd_wdat(cdis5[g]);
                                            g++;
                            }break;
        case 6:           lcd_init();
                    lcd_pos(0x40);                         //右轉
                           while(cdis6[g]!='\0')
                                {   
                                     lcd_wdat(cdis6[g]);
                                            g++;
                                } break;
        case 8:           lcd_init();
                    lcd_pos(0x40);                 //倒車
                        while(cdis8[g]!='\0')
                                {     
                                      lcd_wdat(cdis8[g]);
                                            g++;
                                }break;
        default :break;
   
}}
void motor()
{
     EN12=1;
         EN34=1;
    switch(        n)
        {   case 2:             //前進
                  M1=1;
                                   M2=0;
                              M3=1;
                               M4=0;
                   /* delayxms(5-t);
                              M1=0;
                                M3=0;
                   elayxms(t);           */
                  break;   
                 case 4:                              //左轉
                     M1=0;
                           M2=0;
                                  M3=1;
                                  M4=0;
                     /*delayxms(5-t);
                      M1=0;
                  M3=0;
                 layxms(t+1);          */
                   break;                         
                 case 6:                                          //右轉
                            M1=1;
                      M2=0;
                              M3=0;
                              M4=0;
                     /*delayxms(5-t);
                         M1=0;
                      M3=0;
                      layxms(t+1);                  */
                 break;          
                 case 8:                                //后退
                     M1=0;
                      M2=1;
                      M3=0;
                      M4=1;
                      /*delayxms(5-t);
                      M2=0;
                      M4=0;
                      layxms(t);          */
                   break;       
                 case 5:
                      EN12=0;
                       EN34=0;
                   break;
                default :break;
                 }
}
/*******************************************************
函數功能:定時器T0的中斷服務函數
********************************************************/
void Time0(void ) interrupt 1 using 1 //定時器T0的中斷編號為1,使用第1組工作寄存器
  {
    count++;          //T0每中斷1次,count1
         if(count==20)     //若累計滿20次,即計滿1秒鐘
          {
       flag=1;        //計滿1秒鐘標志位置1
                 count=0;       //0,重新統計中斷次數
          }
    TH0=(65536-46083)/256;   //定時器T08位重新賦初值
         TL0=(65536-46083)%256;   //定時器T08位重新賦初值
       
  }  
void delay1(int ms)
{
        unsigned char y;
        while(ms--)
        {
                for(y = 0; y<250; y++)
                {
                        _nop_();
                        _nop_();
                        _nop_();
                        _nop_();
                }
        }
}
//************************************************************
void delayxms(uchar t)
{
uint i;
uchar j;
for(j=t;j>0;j--)
    for(i=80;i>0;i--);  //延時124*8+10=1002us
}

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久人人国产 | 在线天堂免费中文字幕视频 | 天天综合91 | 黄在线免费观看 | 国产一区二区三区在线 | 国产激情一区二区三区 | 久久国产综合 | 一区二区电影网 | 亚洲精品无人区 | 日韩 国产 在线 | 成人免费在线视频 | 欧美黑人体内she精在线观看 | 免费看黄视频网站 | 亚洲免费一区 | 在线中文字幕视频 | 国产精品视频观看 | 国产成人网 | 国产成人在线播放 | 成年无码av片在线 | 中文字幕精品一区二区三区精品 | 欧美精品一区二区三区在线 | 国产一区二区三区视频 | 国内精品久久久久久久影视简单 | 亚洲日本一区二区 | 一区二区亚洲 | 欧美 日韩 国产 成人 在线 91 | 一区二区视频 | 伊人在线| 黄视频网站在线 | 色综网 | 综合久久国产 | 日韩一区在线视频 | 一区二区三区视频在线观看 | 久久青青| 亚洲国产精品成人综合久久久 | 国产亚洲一区二区三区 | 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 久久88| 日韩中文字幕第一页 | 羞羞视频网站免费观看 | 色橹橹欧美在线观看视频高清 |