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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機秒表程序問題,無論k2在何時按都會清零

[復制鏈接]
跳轉到指定樓層
樓主
ID:562692 發表于 2019-6-18 11:37 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
做了一個秒表,硬件是pz的開發板。效果是開機后,按下k1后開始計時,在四位共陰管上顯示xx.yy。其中xx是分,yy是秒。
k1是啟動/暫停鍵,k2是歸零鍵,目的是短按k1實現定時器啟動與關閉,在暫停模式下再按k2才可歸零。
按鍵掃描程序如下圖,問題是無論k2在何時按都會清零
void keyscan()
{        u8 keymod=0;
        if(k1==0)
        {
                delay(1000);
                if(k1==0)
                {
                        TR0=!TR0;
                        keymod=!keymod;               
                }
                while(!k1);
        }
        if(keymod==0)
        {
                if(k2==0)
                {
                        delay(1000);
                        if(k2==0)
                        {
                                sec=0,min=0,hour=0;               
                        }
                        while(!k2);
                }
        }
}
對此不是很理解,單片機才學了二十天左右,要是有愚蠢錯誤別打。 clock.zip (20 KB, 下載次數: 12)




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

使用道具 舉報

沙發
ID:552614 發表于 2019-6-18 15:36 | 只看該作者
你的keymod初始化就已經等于零了啊,直接進入if(keymod==o)里面的語句了
回復

使用道具 舉報

板凳
ID:332444 發表于 2019-6-18 16:41 | 只看該作者
那就應該判斷暫停模式狀態后才使K2有效,邏輯問題
回復

使用道具 舉報

地板
ID:565305 發表于 2019-6-18 17:50 | 只看該作者
你這個函數是被別的函數調用吧, keymod 是一個局部變量,進一次函數就會初始化一次
void keyscan()
{        u8 keymod=0;

解決方法,要么這個變量設定為全局變量,要么透過入口參數傳入
=======================
另外不得不說一下,這種到處寫 while(!xxxxx) 真心要不得,阻塞主程序流程不說,還不方便做并行操作

=======================
//  請確保 main 函數的 while 循環和 delay_1ms 均存在并且不會超時。并且帶下文三個全局變量
int  keymod=0;
int  k1_count=0, k2_count=0;
void main()
{
    while(1)   
    {
        scan_key();
        other_event_func();
        delay_1ms(); ....
     }
}

void scan_key()
{
    // 判斷:兩個按鍵必須有連續 10ms 處于按住(去抖)狀態才能當做“有效按下”
    // 由于只需要判斷按下瞬間,所以下文 100 的常量只是讓其不溢出且大于 10ms 即可
    if(k1==0){ if(k1_count<100) k1_count++; } else k1_count=0;
    if(k2==0){ if(k2_count<100) k2_count++; } else k2_count=0;

    // 有按住的時序計數器了,那么計數器等于 10 的瞬間就是“按下瞬間”,而不是“按住瞬間”
    if(k1_count==10)
    {
        TR0=!TR0; keymod=!keymode;  // 進入狀態切換
    }
    // k2 按下瞬間,只要 keymod==0 (暫停態),就做歸零
    if(k2_count==10 && keymod==0)
    {
        sec=0;min=0;hour=0;  
    }
}


回復

使用道具 舉報

5#
ID:562692 發表于 2019-6-18 20:54 | 只看該作者
egypt 發表于 2019-6-18 17:50
你這個函數是被別的函數調用吧, keymod 是一個局部變量,進一次函數就會初始化一次
void keyscan()
{    ...

謝謝指點,發現只要把keymod設置成全局變量,然后用
if((k2==0)&&(keymod==0))
替換那兩句就可以了
回復

使用道具 舉報

6#
ID:562692 發表于 2019-6-18 21:03 | 只看該作者
egypt 發表于 2019-6-18 17:50
你這個函數是被別的函數調用吧, keymod 是一個局部變量,進一次函數就會初始化一次
void keyscan()
{    ...

我是按照教程上學的while(!xxxx),學習教程是買開發板送的,原來不好啊。不知道您有什么好的教程推薦?
回復

使用道具 舉報

7#
ID:517466 發表于 2019-6-18 23:22 | 只看該作者
你的程序中有錯誤。定時器TR沒有設成1,導致定時器不工作,沒法計時。程序修改如下:
/*采用普中科技ES-V2.0開發板作為實驗硬件*/
#include<reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;

sbit LSA=P2^0;
sbit LSB=P2^1;
sbit LSC=P2^2;
sbit LSD=P2^3;
sbit k1=P3^1;  
sbit k2=P3^0;

u8 sec,min,hour;

u8 code  shuzu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
                                  0x7f,0x6f,0x77};        //共陽數碼管碼表,code表示保存到flash空間,節省rom       
u8 code table[]={   // 共陰數碼管,筆段=0時,筆段點亮。0-0xC0
    0xc0,0xf9,0xa4,0xb0,0x99,
        0x92,0x82,0xf8,0x80,0x90,0xff, 0xbf};
void delay(u16 i)
{
        while(i--);       
}
void Timer0Init()
{
        TMOD|=0X01;//選擇為定時器0模式,工作方式1,僅用TR0打開啟動。
        TH0=0X3c;        //給定時器賦初值,定時50ms
        TL0=0Xb0;       
        ET0=1;//打開定時器0中斷允許
        EA=1;//打開總中斷
        TR0=1;//關閉定時器                       
}
void keyscan()
{        u8 keymod=0;
        if(k1==0)
        {
                delay(1000);
                if(k1==0)
                {
                        TR0=!TR0;
                        keymod=!keymod;               
                }
                while(!k1);
        }
        if(keymod==0)
        {
                if(k2==0)
                {
                        delay(1000);
                        if(k2==0)
                        {
                                sec=0,min=0,hour=0;               
                        }
                        while(!k2);
                }
        }
}

void DigDisplay(u8 min,u8 sec)
{
        u8 i;
        for(i=0;i<4;i++)
        {
                switch(i)         //位選,選擇點亮的數碼管,
                {
                  // 共陰用
                        case(0):
                                LSA=0;LSB=1;LSC=1;LSD=1;P0=shuzu[min/10]; break;//顯示第0位
                        case(1):
                                LSA=1;LSB=0;LSC=1;LSD=1;P0=shuzu[min%10];break;//顯示第1位
                        case(2):
                                LSA=1;LSB=1;LSC=0;LSD=1;P0=shuzu[sec/10];break;//顯示第2位
                        case(3):
                                LSA=1;LSB=1;LSC=1;LSD=0;P0=shuzu[sec%10]; break;//顯示第3位                               
                }
    delay(100); //間隔一段時間掃描       
                // 共陰用
                P0=0x00;//消隱筆段
        }
}
void main()
{       
        Timer0Init();
        while(1)
        {       
                P1=sec;
                DigDisplay(min,sec);
                keyscan();
                       
        }               
}


void Timer0() interrupt 1
{
        static u16 i;
        TH0=0X3c;        //給定時器賦初值,定時50ms
        TL0=0Xb0;
        i++;
        if(i==20)
        {
                i=0;
                sec++;
                if(sec==60)
                {
                        sec=0;
                        min++;
                        if(min==60)
                        {
                                min=0;
                                hour++;
                                if(hour==99)
                                {
                                        hour=0;

                                }
                        }
                }       
        }       
}               
回復

使用道具 舉報

8#
ID:517466 發表于 2019-6-18 23:25 | 只看該作者
附上proteus的仿真文件

test.zip

15.92 KB, 下載次數: 10

回復

使用道具 舉報

9#
ID:207421 發表于 2019-6-19 01:08 | 只看該作者
其實把 u8 keymod=0; 變為全局變量,改為 u8 keymod=1; 就好了。
當按K1, TR0 =1; keymod=0;
此時 K2有效
回復

使用道具 舉報

10#
ID:565305 發表于 2019-6-19 08:46 | 只看該作者
帶多個鎖死 while 的程序,真正測試的時候,會發現有按鍵不響應的 BUG

你試著按住 k1 后不松手,再按 k2 ,試個兩三次就知道了

或者按住 k2 不松手,再按 k1 看看功能正常不
回復

使用道具 舉報

11#
ID:566603 發表于 2019-6-19 11:36 | 只看該作者
將下面的if(keymod==0)改為if(keymod!=0)試試,keymod應該是在key1按下后取反,表示key1已經按下,那么下面的判斷就不能是keymod==0,因為keymod的初始化情況就是0,當然按下key2會清零.-----建議僅供參考
回復

使用道具 舉報

12#
ID:160500 發表于 2019-6-19 16:39 | 只看該作者
建議你先畫一個流程圖,理清其中的邏輯關系,根據流程圖再編程實現所需要的功能
回復

使用道具 舉報

13#
ID:564631 發表于 2019-6-19 17:49 | 只看該作者
void keyscan()
{        u8 keymod=0;
        if(k1==0)
        {
                delay(1000);
                if(k1==0)
                {
                        TR0=!TR0;
                        keymod=!keymod;               
                }
                while(!k1);
        }
        if(keymod==1)
        {
                if(k2==0)
                {
                        delay(1000);
                        if(k2==0)
                        {
                                sec=0,min=0,hour=0;               
                        }
                        while(!k2);
                }
        }
}
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 午夜视频在线视频 | 成人免费大片黄在线播放 | 国产亚洲精品一区二区三区 | 黄色大片视频 | 精品久久久久久亚洲精品 | 成人久久 | 精品视频在线免费观看 | 成人国产一区二区三区精品麻豆 | 久久久久久久一区 | 在线免费国产 | 亚洲日韩中文字幕一区 | 久久久国产精品 | 久久高清 | 欧美成人精品在线观看 | 久久精品国产一区二区电影 | 国产精品免费av | 国产美女永久免费无遮挡 | 精品国产一区久久 | 成人精品鲁一区一区二区 | 精品一二区 | av色噜噜 | 人人人人干 | 日本在线观看网址 | 春色av| 91久久精品一区二区二区 | 日韩欧美亚洲一区 | 人人人艹 | 亚洲第一在线 | 久久久这里只有17精品 | 91精品国产99 | av网站在线播放 | 久久午夜精品 | 欧美三级免费观看 | 日韩av在线播| 欧美激情精品久久久久久变态 | 操人网站 | 精品蜜桃一区二区三区 | 91精品国产欧美一区二区成人 | 久久黄色精品视频 | 国产精品一码二码三码在线 | 天天夜干 |