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

標題: 為什么在單片機LCD1602上會出現70 程序哪里錯出錯了? [打印本頁]

作者: 深層次    時間: 2023-12-20 18:34
標題: 為什么在單片機LCD1602上會出現70 程序哪里錯出錯了?
為什么在LCD1602上會出現70,為什么 按鍵k3、k4調速,將速度等級在LCD1602顯示?我這程序哪里錯出錯了?
#include <reg52.h>      //包含52頭文件
#define uint unsigned int //宏定義uint代替unsigned int
#define uchar unsigned char //宏定義uchar代替unsigned char
#define out P2
sbit lcdrs=P0^5;//液晶的RS端接P2.4口
sbit lcdrw=P0^6;//液晶的RW端接P2.5
sbit lcden=P0^7;// 液晶的EN使能端接P2.6口
sbit KEY1=P3^1;     //按鍵聲明 //正轉
sbit KEY2=P3^4;     //按鍵聲明 //反轉
sbit LED=P0^4;
unsigned long beats=0;//轉動總拍數
unsigned long angle=0; //需要轉動的角度
uchar code forturn[]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//正轉拍
uchar code revtutn[]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};//反轉拍
uchar flag=0;//按鍵標志位
uchar flagmotor=0;//正反轉標記
uchar temp;//臨時變量
uchar index;//拍數索引
uchar motorturn=0;//電機轉動圈數
void T0_init();//定時器
void T1_init();
void EX_init();//外部中斷來控制加速減速
void forone();//正轉
void reone();//反轉
void stop(); //停止
void grade();//占空比等級
void delayms (uint xms);
void keyscan();
void write_str(uchar *str);
void write_data(uchar dat);
void check_busy(void);
void lcd_init();
void write_cmd(char cmd);
void xianshi();
void uart_init();
void lap();
uchar keyflag;  
uchar count=0,Hi=0,x,dat;
uchar num[6];

void  main()                            //主函數
{         motorturn=1;
        angle=motorturn*360;
        beats=(angle*4096)/360;        
        T0_init();
        EX_init();
        T1_init();
        lcd_init();
        uart_init();
        write_cmd(0x80);
        write_str("speed:");
    while(1)
    {  keyscan();
    switch(keyflag)
          {   case 1:{TR0=1;flagmotor=1;LED=0;}break;
             case 2:{TR0=1;flagmotor=2;LED=1;}break;
             default:stop();break;
          }
          lap();
               
    }
}
/*************定時器T1初始化函數**************/
void T1_init()
{
    TMOD=TMOD|0x20;    //設置T1為方式2
    TH1=256-200;          //置T1高8位,備用初值
    TL1=256-200;          //置T1低8位,初值        
    TR1=1;                              //啟動T1
    ET1=1;                //開T1中斷
    EA=1;                      //開總中斷
}
/**********T0中斷服務程序*********/
void T1_int() interrupt 3  //10ms進入中斷
{
    TH1=(65536-100)/256;//置T0高8位初值
    TL1=(65536-100)%256;//置T0低8位初值
    count++;        //累計進入中斷次數,進入1次為10ms
  if(count>=200)   //count累計200次為1s
{  

     count=0;     //1s后count清0,重新累計下一次1s  
}
if(count<Hi)flagmotor=1;
else flagmotor=0;        
}
/********外部中斷0和外部中斷1的中斷服務函數*********/
void EX_init()
{
        IT0=1;            //外中斷0下降沿觸發
        EX0=1;            //允許外中斷0中斷
        PX0=1;            //優先級設置,可選
        IT1=1;            //外中斷1下降沿觸發
        EX1=1;            //允許外中斷1中斷
        PX1=1;            //優先級設置,可選
        EA=1;            //總中斷允許
}

/********外部中斷0中斷服務函數*********/
void EX_INT0()  interrupt 0
{     uchar x=0;
    TR0=1;
    x++;
   if(x==5)x=4;
   xianshi();
   grade();
           
}
/********外部中斷1中斷服務函數*********/
void EX_INT1()  interrupt 2
{    uchar x=4;
    TR0=1;
          x--;
        if(x<=0)x=0;
        grade();
         xianshi();        
}
void stop()
{  P1=P1&0xf0;
}
void keyscan()        //按鍵檢測函數  基礎代碼
{
    KEY1=1;           // 輸入先寫"1"
    if (KEY1==0)
    {
        delayms(10);    //延時去抖
        if(KEY1==0)   //按鍵按下
        {
           keyflag=1; //設標志位
        }
        while(!KEY1); //松手檢測
    }

          KEY1=2;           // 輸入先寫"1"
    if (KEY2==0)
    {
        delayms(10);    //延時去抖
        if(KEY2==0)   //按鍵按下
        {
          keyflag=2; //設標志位
       }
        while(!KEY2); //松手檢測
    }

         
}

void forone()
{ beats--;
  temp=P1;
  temp=temp&0xf0;
  temp=temp|forturn[index];
  P1=temp;
  index++;
  if(index==0x08)index=0;
  if(beats==0)
  {          P1=P1&0XF0;
          TR0=0;
         flag=0;
         index=0;
         flagmotor=0;
         angle=motorturn*360;
         beats=(angle*4096)/360;
  }
}

void delayms (uint xms)     //毫秒函數定義
{
    uint i,j;
    for(i=0;i<xms;i++)
       for(j=0;j<120;j++);  
}
void T0_init()
{
    TMOD=TMOD|0x01;                      //設置T0為方式1
    TH0=(65536-5000)/256;//置T0高8位初值
    TL0=(65536-5000)%256;//置T0低8位初值        
    TR0=0;                              //啟動T0
    ET0=1;                //開T0中斷
    EA=1;                      //開總中斷
}
void T0_int() interrupt 1  //10ms進入中斷
{
    TH0=(65536-5000)/256;//置T0高8位初值
    TL0=(65536-5000)%256;//置T0低8位初值        
   if(flagmotor==1)
      forone();
  if(flagmotor==2)
      stop();
}
void grade()
{ switch(x)
{case 1:Hi=20;break;
  case 2:Hi=60;break;
  case 3:Hi=100;break;
  case 4:Hi=140;break;
}
}

/**********************檢查忙標志函數************************/
void check_busy(void)
{
    uchar dt;
        out=0xff;
        do
        {
           lcden=0;
           lcdrs=0;
           lcdrw=1;
           lcden=1;
           dt=out;
        }while(dt&0x80);
        lcden=0;
}
/**************************1602顯示****************************/
void write_cmd(char cmd)  //寫指令函數
{
        check_busy();
        lcden=0;//再把EN拉低
        lcdrs=0;
        lcdrw=0;//先將RW拉低
        out=cmd;
        lcden=1;
        lcden=0;
}
void write_data(uchar dat) //寫數據函數
{
        check_busy();
        lcden=0;//再把EN拉低
        lcdrs=1;
        lcdrw=0;//先將RW拉低
        out=dat;
        lcden=1;
        lcden=0;        
}
void write_str(uchar *str)//寫字符串函數
{
        while(*str!='\0')
        {
                write_data(*str++);
                delayms(5);
        }
}
/***************************初始化******************************/
void lcd_init()//初始化1602
{
        write_cmd(0x38);//顯示模式設置
        write_cmd(0x0c);//顯示開關,光標沒有閃爍
        write_cmd(0x06);//顯示光標移動設置
        write_cmd(0x01);//清除屏幕
        delayms(1);
}
void xianshi()
{   write_cmd(0x80+0x06);
    num[5]=Hi/10;
    num[5]=Hi%10;
    write_data(0x37+num[5]);
    write_data(num[5]+0x30);      
}
/****************串口方式1初始化*************/
void uart_init()
{
           SCON=0x50;                       //串口方式1,TI和RI清零,允許接收;
        PCON=0x80;                             //波特率加倍 SMOD=1
        TMOD=TMOD|0x20;                //T1定時方式2
           TH1=0xf3;
        TL1=0xf3;                         //4800b/s 晶振12MHz
           TR1=1;                           //啟動T1
        ES=1;
        EA=1;
}

/*************中斷接收一個字節數據函數*********/
void uart_receive() interrupt 4
{         
         if(RI==1)
{
RI = 0;                 //清TI標志位
dat=SBUF;         //接收數據存入變量dat
      }
}
void lap()
{   switch(dat)
{   case 0x01:{TR0=1;flagmotor=1;LED=0;}break;
    case 0x02:{TR0=1;flagmotor=2;LED=1;}break;
    case 0x03:{ TR0=1;x++;if(x==5)x=4;grade();xianshi();}break;
    case 0x04:{ TR0=1;x--;if(x==0)x=0;grade();xianshi();}break;

}
}


作者: lkc8210    時間: 2023-12-20 22:53
錯在這里




作者: 深層次    時間: 2023-12-21 09:58
lkc8210 發表于 2023-12-20 22:53
錯在這里

我不理解這里怎么錯了,真是抱歉啊,我這菜鳥啥也不懂
作者: lkc8210    時間: 2023-12-21 10:18
深層次 發表于 2023-12-21 09:58
我不理解這里怎么錯了,真是抱歉啊,我這菜鳥啥也不懂

num[5]=HI/10;
這句是取數值十位,沒問題

num[5]=HI%10;
這句是取數值個位,為什么要把取得的值放到存放十位的數組里?

write_data(0x37+num[5]);
為啥要加0x37?

write_data(num[5]+0x30);
這里加0x30是對的,為了把數值轉換為ASCII,并在LCD1602上顯示
但好想用錯了數組
作者: zhuls    時間: 2023-12-21 10:44
深層次 發表于 2023-12-21 09:58
我不理解這里怎么錯了,真是抱歉啊,我這菜鳥啥也不懂

void xianshi()
{   write_cmd(0x80+0x06);
    num[5]=Hi/10;  // 這2行賦值到同一個變量了?
    num[5]=Hi%10;//

    write_data(0x37+num[5]); //1602接收顯示數據的是ASCii碼,“0”的是0x30,“7”是0x37,當num[5]=0時,顯示出來就是7了,改成0x30試試
    write_data(num[5]+0x30);      
}




歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 成人免费一区二区三区牛牛 | www.亚洲 | 九九热最新地址 | 久久在线看 | 成年视频在线观看 | 国产欧美在线观看 | 狠狠ri| 欧美 日韩 综合 | 国产成人综合av | 欧美综合一区二区三区 | 亚洲 中文 欧美 日韩 在线观看 | 天天操夜夜拍 | 一区二区三区四区不卡视频 | 毛片99 | 国产免费又黄又爽又刺激蜜月al | 黄免费观看视频 | 涩涩视频网站在线观看 | 黄色免费网址大全 | 成人在线观看亚洲 | 精品国产一区二区三区久久久久久 | 国内精品久久久久久久 | 精品久久国产 | 欧美激情在线精品一区二区三区 | 91精品中文字幕一区二区三区 | 狠狠做深爱婷婷综合一区 | 国产精品视频一区二区三区四区国 | 精品日本久久久久久久久久 | 在线观看av网站永久 | 国产日韩欧美一区二区 | 色婷婷一区二区三区四区 | 精品不卡 | 在线中文字幕av | 不卡在线视频 | 91精品久久久 | 日韩成人影院 | 色婷婷一区 | 日本久久www成人免 成人久久久久 | www.一区二区三区 | 一区二区三区四区五区在线视频 | 成人久久18免费网站图片 | 成人精品一区二区三区四区 |