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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

我的這個單片機程序為什么按鍵按下后沒有作用?

[復制鏈接]
跳轉到指定樓層
樓主
ID:521078 發表于 2019-10-19 20:33 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
25黑幣
Keil4編寫環境:A/D數模轉換和按鍵應用操作顯示到Lcd1602上,子程序Lcd1602.c,keyboard.c,I2C.c程序略,跪求主程序
程序要求實現:按上鍵查詢設定的電壓值上下限
                      按下鍵查詢當前的電壓值(當前電壓值是滑動變阻器所配置的電壓值)
                      數據采集器件用的是PCF8591測AIN0的值
為什么我的主函數這樣寫,在51液晶上按上下鍵沒有任何顯示,跪求主函數,開發板是金三角開發板
是Lcd如何通過按鍵進行翻頁操作,這個程序應該怎么寫,跪求來個大神,寫下這個程序;

#include <reg52.h>
sbit BUZZ = P1^6;  
bit flag300ms = 1;
bit enBuzz = 0;
unsigned char T0RH = 0;
unsigned char T0RL = 0;
unsigned int CountDown = 0;
void ConfigTimer0(unsigned int ms);
unsigned char GetADCValue(unsigned char chn);
void ValueToString(unsigned char *str, unsigned char val);
extern void I2CStart();
extern void I2CStop();
extern void KeyScan();
extern void KeyDriver();
extern unsigned char I2CReadACK();
extern unsigned char I2CReadNAK();
extern bit I2CWrite(unsigned char dat);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void main()
{
    EA = 1;
   ConfigTimer0(10);  
   InitLcd1602();
   LcdShowStr (0, 0, "moli");
while(1)
{
     KeyDriver();
}
}
unsigned char GetADCValue (unsigned char chn)
{
      unsigned char val;
     I2CStart();
    if (!I2CWrite (0x48<<1))
    {
        I2CStop();
        return 0;
    }
I2CWrite (0x40 | chn);
I2CStart();
I2CWrite ((0x48<<1) | 0x01);
I2CReadACK();
val = I2CReadNAK();
I2CStop();
return val;
}
void ValueToString(unsigned char *str, unsigned char val)
{
     
  val = (val * 25) / 55;
  str[0] = (val/10) + '0';  
  str[1] = '.';   //С????
  str[2] = (val%10) + '0';  
  str[3] = 'V';  
  str[4] = '\0';
}
void KeyTaAction()
{
    unsigned char val;
    unsigned char str[10];
    InitLcd1602();
    LcdShowStr (0, 0, "TABANXINHAO");  
     while (1)
    {
         if (flag300ms)
     {
         flag300ms = 0;
           
        val = GetADCValue(0);
        ValueToString(str, val);
        LcdShowStr(0, 1, str);
      if (val >= 200)
      {
         enBuzz = 1;
        if (enBuzz)
           BUZZ = ~BUZZ;
      }
      else
          BUZZ = 1;
   }
  }
}
void KeyAction (unsigned char keycode)
{
   if(keycode == 0x26)
    {
      KeyTaAction();
    }
  else if (keycode == 0x28)
   {
     LcdShowStr (0, 0, "MAX");
     LcdShowStr (0, 1, 2^5);   
     LcdShowStr (6, 0, "MIN");
     LcdShowStr (6, 1, 0^0);
   }
}
void ConfigTimer0(unsigned int ms)
{
    unsigned long tmp;  
tmp = 11059200 / 12;
tmp = (tmp * ms) / 1000;
tmp = 65536 - tmp;
tmp = tmp + 12;
T0RH = (unsigned char)(tmp >> 8);
T0RL = (unsigned char)tmp;
TMOD &= 0xF0;
TMOD |= 0x01;
TH0 = T0RH;
TL0 = T0RL;
ET0 = 1;
TR0 = 1;
}
void InterruptTimer0() interrupt 1
{
    static unsigned char tmr300ms = 0;
TH0 = T0RH;
TL0 = T0RL;
tmr300ms++;
if (tmr300ms >= 30)  
{
     tmr300ms = 0;
  flag300ms = 1;
}
}
LCD程序
#include <reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;
sbit LCD1602_RW = P1^1;
sbit LCD1602_E = P1^5;

void LcdWaitReady()
{
  unsigned char sta;
  LCD1602_DB = 0xFF;
  LCD1602_RS = 0;
  LCD1602_RW = 1;
  do{
      LCD1602_E = 1;
   sta = LCD1602_DB;
   LCD1602_E = 0;
  }while (sta & 0x80);
}

void LcdWriteCmd (unsigned char cmd)
{
   LcdWaitReady();
   LCD1602_RS = 0;
   LCD1602_RW = 0;
   LCD1602_DB = cmd;
   LCD1602_E = 1;
   LCD1602_E = 0;
}
void LcdWriteDat(unsigned char dat)
{
  LcdWaitReady();
  LCD1602_RS = 1;
  LCD1602_RW = 0;
  LCD1602_DB = dat;
  LCD1602_E = 1;
  LCD1602_E = 0;
}

void LcdSetCursor(unsigned char x, unsigned char y)
{
  unsigned char addr;
  if (y == 0)
     addr = 0x00 + x;
  else
     addr = 0x40 + x;
   LcdWriteCmd(addr | 0x80);
}

void LcdShowStr (unsigned char x, unsigned char y,
                 unsigned char *str)
{
  LcdSetCursor(x, y);  
  while (*str != '\0')   
  {
    LcdWriteDat (*str++);
  }
}

void LcdAreaClear(unsigned char x,unsigned char y, unsigned char len)
{

  LcdSetCursor(x, y);
  while (len--)
  {
    LcdWriteDat(' ');
  }
}

void LcdFullClear()
{
  LcdWriteCmd(0x01);
}
void InitLcd1602()
{
  LcdWriteCmd(0x38);
  LcdWriteCmd(0x0C);  
  LcdWriteCmd(0x06);  
  LcdWriteCmd(0x01);  
}
keyboard程序
#include <reg52.h>
sbit KEY_IN_1 = P2^4;
sbit KEY_IN_2 = P2^5;
sbit KEY_IN_3 = P2^6;
sbit KEY_IN_4 = P2^7;
sbit KEY_OUT_1 = P2^3;
sbit KEY_OUT_2 = P2^2;
sbit KEY_OUT_3 = P2^1;
sbit KEY_OUT_4 = P2^0;
unsigned char code KeyCodeMap[4][4] = {
    { '1',  '2',  '3', 0x26 },
    { '4',  '5',  '6', 0x25 },
    { '7',  '8',  '9', 0x28 },
    { '0', 0x1B, 0x0D, 0x27 }   
};
unsigned char pdata KeySta[4][4] = {
  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
};
extern void KeyAction(unsigned char keycode);

void KeyDriver()
{
    unsigned char i, j;
static unsigned char pdata backup[4][4] = {
  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1},  {1, 1, 1, 1}
};
for (i=0; i<4; i++)
{
    for (j=0; j<4; j++)
    {
    if (backup[ i][j] != KeySta[ i][j])
    {
        if (backup[ i][j] != 0)  
     {
        KeyAction(KeyCodeMap[ i][j]);
     }
     backup[ i][j] = KeySta[ i][j];
    }
    }
}
}
void KeyScan()
{
    unsigned char i;
static unsigned char keyout = 0;
static unsigned char keybuf[4][4] = {
    {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},
       {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}
};
keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
for (i=0; i<4; i++)
{
     if ((keybuf[keyout][ i] & 0x0F) == 0x00)
  {
     KeySta[keyout][ i] = 0;
  }
  else if ((keybuf[keyout][ i] & 0x0F) == 0x0F)
  {
     KeySta[keyout][ i] = 1;
  }
}
keyout++;
keyout &= 0x03;
switch(keyout)  
{
     case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
  case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
  case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
  case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
  default: break;
}
}
I2C程序
#include <reg52.h>
#include <intrins.h>
#define I2CDelay() {_nop_();_nop_();_nop_();_nop_();}
sbit I2C_SCL = P3^7;
sbit I2C_SDA = P3^6;/

void I2CStart()
{
    I2C_SDA = 1;
I2C_SCL = 1;
I2CDelay();
I2C_SDA = 0;
I2CDelay();
I2C_SCL = 0;  
}
void I2CStop()
{
    I2C_SCL = 0;
I2C_SDA = 0;
I2CDelay();
I2C_SCL = 1;  
I2CDelay();
I2C_SDA = 1;  
I2CDelay();
}
bit I2CWrite (unsigned char dat)
{
    bit ack;
unsigned char mask;
for (mask=0x80; mask!=0; mask>>=1)
{
    if ((mask&dat) == 0)
       I2C_SDA = 0;
    else
       I2C_SDA = 1;
  I2CDelay();
  I2C_SCL = 1;
  I2CDelay();
  I2C_SCL = 0;
}
I2C_SDA = 1;
I2CDelay();
I2C_SCL = 1;
ack = I2C_SDA;
I2CDelay();
I2C_SCL = 0;  
return (~ack);
            
}
unsigned char I2CReadNAK()
{
    unsigned char mask;
unsigned char dat;
I2C_SDA = 1;
for (mask=0x80; mask!=0; mask>>=1)
{
     I2CDelay();
  I2C_SCL = 1;
  if(I2C_SDA == 0)
      dat &= ~mask;
     else
      dat |= mask;   
  I2CDelay();
  I2C_SCL = 0;     
}
I2C_SDA = 1;   
I2CDelay();
I2C_SCL = 1;   
I2CDelay();
I2C_SCL = 0;   
return dat;
}
unsigned char I2CReadACK()
{
     unsigned char mask;
  unsigned char dat;
  I2C_SDA = 1;
  for (mask=0x80; mask!=0; mask>>=1)  
     {
      I2CDelay();
   I2C_SCL = 1;
   if (I2C_SDA == 0)
       dat &= ~mask;  
   else
       dat |= mask;   
   I2CDelay();
   I2C_SCL = 0;   
   }
   I2C_SDA = 0;
   I2CDelay();
   I2C_SCL = 1;  
   I2CDelay();
   I2C_SCL = 0;
   return dat;
  
}

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

使用道具 舉報

沙發
ID:616759 發表于 2019-10-20 13:17 | 只看該作者
你的KeyScan()函數在主程序中都沒有出現,這個函數的意思是按鍵掃描,一般是用來檢測按鍵是否被按下的,同時一般的按鍵掃描是放在一個大概1s的for循環中的,當然,寫在while循環里就不用這個1s的for循環了。
回復

使用道具 舉報

板凳
ID:521078 發表于 2019-10-20 14:25 | 只看該作者
bai_yun_123 發表于 2019-10-20 13:17
你的KeyScan()函數在主程序中都沒有出現,這個函數的意思是按鍵掃描,一般是用來檢測按鍵是否被按下的, ...

嗯嗯,謝謝大哥的解答,我也發現了沒寫按鍵掃描了,我把按鍵掃描加上,現在lcd可以進行翻頁操作,電壓值都可以查詢,但按上鍵我查當前值的時候,每次進去都進入了KeyTaAction()這個函數的while死循環,但再摁下鍵查詢最大最小值就沒有任何反應,我想過把while改成do while 還是實現不了這個電壓值每300ms要檢測,所以,我想問下這個問題怎么解答,謝謝,萬分感謝
回復

使用道具 舉報

地板
ID:616759 發表于 2019-10-20 17:30 | 只看該作者
不是while和do while的問題,這兩個循環只是執行條件的先后問題,我看了keytaaction的函數,while(1)是個死循環,只要進去了,沒有break,continue這種跳出循環的語句,那么就出不來,即死循環。把while括號里的條件改成你需要的條件, 比如:
while (flag300ms)
     {
         flag300ms = 0;
           
        val = GetADCValue(0);
        ValueToString(str, val);
        LcdShowStr(0, 1, str);
      if (val >= 200)
      {
         enBuzz = 1;
        if (enBuzz)
           BUZZ = ~BUZZ;
      }
      else
          BUZZ = 1;
  }
當然,條件不一定對,因為后面有個flag300ms置零,所以這個循環只執行一次,至于執行多少次就得看你的條件了,還有,你的程序很多不對齊,也沒有注釋,看起來很麻煩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 在线一区视频 | 日本精品一区二区三区四区 | 免费日本视频 | 精品国产乱码久久久久久丨区2区 | 日本高清视频在线播放 | 欧美综合国产精品久久丁香 | 在线观看精品视频网站 | 成人在线视频一区二区三区 | 精品成人| 久久的色 | 久久伦理电影 | 国产精品污www一区二区三区 | 欧美成人一区二区三区 | 一区二区三区视频在线观看 | 久操伊人| a级片在线观看 | 在线观看国产网站 | 亚洲国产精品成人久久久 | 中文精品一区二区 | 欧美福利一区 | 亚洲国产aⅴ精品一区二区 免费观看av | 最新日韩在线视频 | 亚洲精品3 | av网站在线看 | 成在线人视频免费视频 | 日韩一区中文字幕 | 午夜精品影院 | 欧美不卡一区二区三区 | 天天综合天天 | 午夜影视免费片在线观看 | 国产成人免费视频网站视频社区 | 美女在线一区二区 | 日本成人综合 | 日本成人区 | 色免费看| 中文字幕日韩欧美一区二区三区 | 特黄特色大片免费视频观看 | 国产成人短视频在线观看 | 亚洲一区二区三区桃乃木香奈 | 日韩精品一区二区三区中文在线 | 日韩精品免费视频 |