找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 3106|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

看不懂單片機(jī)的移位程序

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:403906 發(fā)表于 2018-9-29 15:45 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
#include <reg51.h>
#include <intrins.h>

unsigned char scan_key();
void proc_key(unsigned char key_v);
void delayms(unsigned char ms);

sbit        K1 = P3^0;
sbit        K2 = P3^1;
unsigned char scan_key()
{
        unsigned char key_s;
        key_s = 0x00; //key_s=0x00;賦值
        key_s |= K2;     //key_s=key_s|k2
    key_s<<=1;      //key_s =key_s << 1;
        key_s |= K1;   //相當(dāng)于key_s=key_s|k1
        return key_s;//  返回key_s的值
}
main()
{
        
        unsigned char key_s,key_v;
        key_v = 0x03;//既然key_v = 0x03為啥if(key_s != key_v) 沒有按鍵的時(shí)候?yàn)榧伲?br />         P1 = 0xfe;
        while(1)
        {
                key_s = scan_key();//scan_key()是另一個(gè)返回函數(shù)
                if(key_s != key_v) //以下的都是不懂請(qǐng)教各位老師
                {
                        delayms(10);
                        key_s = scan_key();//key_s 不等于 key_v時(shí)
                        if(key_s != key_v)
                        {        
                                key_v = key_s;//二者相等時(shí)        if(key_s != key_v)         為假,key_v位0x03
                                proc_key(key_v);                                       
                        }
                }
        }        
}



void proc_key(unsigned char key_v)
{
        if((key_v & 0x01) == 0)
        {
                P1 = _cror_(P1,1);
        }
        else if((key_v & 0x02) == 0)
        {
                P1 = _crol_(P1, 1);
        }
}

void delayms(unsigned char ms)        
// 延時(shí)子程序
{                                                
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i < 120; i++);
        }
}
本人自學(xué)請(qǐng)各位老師指教

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

使用道具 舉報(bào)

沙發(fā)
ID:277374 發(fā)表于 2018-9-29 19:56 | 只看該作者
key_v是上一次循環(huán)采集到的按鍵值,紅色第一行是判斷新掃描的鍵值與 key_v(上次值)不同,則進(jìn)入if語句內(nèi),延時(shí)是為了去除按鍵按下時(shí)的抖動(dòng),之后再次讀取鍵值(讀取的目的是判斷按鍵仍舊在按下狀態(tài),防止本次進(jìn)入是因?yàn)楦蓴_),同樣再次判斷鍵值;把本次獲得的鍵值賦值給上次的鍵值,最后一句就是對(duì)該按鍵的處理函數(shù)了,具體功能你分析proc_key函數(shù)可得到

評(píng)分

參與人數(shù) 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

板凳
ID:404160 發(fā)表于 2018-9-29 19:59 | 只看該作者
紅色一段程序,是延時(shí)后,再次讀鍵,如果兩次讀的鍵值一致,去處理按下的鍵。否側(cè),是鍵在抖動(dòng)。
回復(fù)

使用道具 舉報(bào)

地板
ID:404160 發(fā)表于 2018-9-29 20:01 | 只看該作者
紅色的程序,是防鍵抖動(dòng)程序。經(jīng)延時(shí)后,再讀一次鍵值,如果一致,去處理鍵。否則的鍵的抖動(dòng)。
回復(fù)

使用道具 舉報(bào)

5#
ID:261288 發(fā)表于 2018-9-29 21:06 | 只看該作者
這段程序是判斷按鍵(K2;K1)是否被按下,key_s的值寫為二進(jìn)制為0000 00K2K1,只要不等于0x03,代表有鍵被按下,接著延時(shí)消抖再判斷一次,如為“真”,則key_s(當(dāng)前值)賦值給key_v,再運(yùn)行proc_key(key_v)。但 if((key_v & 0x01) == 0)和 else if((key_v & 0x02) == 0)有問題?是否應(yīng)==1,這樣才可解碼啊
回復(fù)

使用道具 舉報(bào)

6#
ID:261288 發(fā)表于 2018-9-29 22:51 | 只看該作者
上面有錯(cuò),漏打一句,if((key_v & 0x01) == 0)和 else if((key_v & 0x02) == 0)有問題?是否應(yīng)==1和==10。
回復(fù)

使用道具 舉報(bào)

7#
ID:405642 發(fā)表于 2019-3-24 22:05 來自觸屏版 | 只看該作者
老師們,請(qǐng)問<<=和<<有什么區(qū)別啊?
回復(fù)

使用道具 舉報(bào)

8#
ID:213173 發(fā)表于 2019-3-25 08:55 | 只看該作者
這個(gè)程序如果是用于訓(xùn)練邏輯思維還算能行。如果用于編程就純屬故弄玄虛,畫蛇添足。
如此簡單的事情為什么要搞得這么復(fù)雜?給你逐條注釋了,應(yīng)該能夠理解了。
#include <reg51.h>
#include <intrins.h>

unsigned char scan_key();
void proc_key(unsigned char key_v);
void delayms(unsigned char ms);
sbit        K1 = P3^0;
sbit        K2 = P3^1;
unsigned char scan_key()//此函數(shù)是為了把兩個(gè)bit型數(shù)據(jù)組合成無符號(hào)字符型數(shù)據(jù)。K1、K2默認(rèn)為1
{                                        //組合后成0000 0011,單獨(dú)按鍵后只會(huì)發(fā)生2種變化:0000 0010 和 0000 0001
        unsigned char key_s;
        key_s = 0x00; //key_s=0x00;賦初值
        key_s |= K2;  //把K2理解為0000 0001 加 0000 0000,key_s=0000 0001
        key_s<<=1;      //key_s 左移1,key_s=0000 0010
        key_s |= K1;   //把K1理解為0000 0001 加 0000 0010,key_s=0000 0011
        return key_s;        //無鍵按下返回key_s的鍵值0x03,有鍵按下鍵返回的鍵值0x01或0x02
}
void main()
{       
        unsigned char key_s,key_v;
        key_v = 0x03;
        P1 = 0xfe;
        while(1)
        {
                key_s = scan_key();//讀取鍵值
                if(key_s != key_v) //判斷條件成立即為真,執(zhí)行以下語句
                {
                        delayms(10);
                        key_s = scan_key();//延時(shí)后再讀取鍵值
                        if(key_s != key_v)//判斷條件成立即為真,執(zhí)行以下語句
                        {        
                                key_v = key_s;//將有效鍵值賦值于key_v
                                proc_key(key_v);//將key_v作為參數(shù)傳輸給proc_key函數(shù)
                        }
                }
        }        
}

void proc_key(unsigned char key_v)
{
        if((key_v & 0x01) == 0)
        {
                P1 = _cror_(P1,1);//循環(huán)右移
        }
        else if((key_v & 0x02) == 0)
        {
                P1 = _crol_(P1,1);//循環(huán)左移
        }
}

void delayms(unsigned char ms)        
// 延時(shí)子程序
{                                                
        unsigned char i;
        while(ms--)
        {
                for(i = 0; i < 120; i++);
        }
}
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表