最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

第8章-函數(shù)進(jìn)階與按鍵(上:跟堂作業(yè))

2023-08-26 09:41 作者:feifeiluan2  | 我要投稿

這節(jié)太難了,2個(gè)多小時(shí)分成

由于代碼量大,把跟堂作業(yè)也搬過(guò)來(lái)了

課上例子,單鍵中斷消抖讀取

#include <reg52.h>

typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

sbit KEY1 = P2 ^ 4;
sbit KEY2 = P2 ^ 5;
sbit KEY3 = P2 ^ 6;
sbit KEY4 = P2 ^ 7;

// 數(shù)碼管code
uchar code LedChar[] =
{
?? ?0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
?? ?0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

bit KeySta=1;//中斷讀取按鍵后放到這兒

void main(void)
{
?? ?uchar cnt = 0;
?? ?bit backup = 1;
?? ?bit keybuf = 1;

?? ?ENLED = 0;
?? ?ADDR3 = 1;
?? ?ADDR2 = 0;
?? ?ADDR1 = 0;
?? ?ADDR0 = 0;

?? ?TMOD=0x01;
?? ?TH0=0xF8;
?? ?TL0=0xCD;
?? ?ET0=EA=TR0=1;

?? ?P2 = 0xF7;
?? ?P0 = LedChar[cnt];

?? ?while (1)
?? ?{
?? ??? ?if(KeySta != backup)
?? ??? ?{
?? ??? ??? ?if(backup==0)
?? ??? ??? ?{
?? ??? ??? ??? ?//松開(kāi)
?? ??? ??? ??? ?cnt++;
?? ??? ??? ??? ?if(cnt>=10)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?cnt=0;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?P0=LedChar[cnt];
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?//按下
?? ??? ??? ?}
?? ??? ??? ?backup=KeySta;//保存方便,下次比對(duì)
?? ??? ?}
?? ?}
}

void Timer0_ISR(void)interrupt 1
{
?? ?static uchar keybuf=0xFF;

?? ?TH0=0xF8;
?? ?TL0=0xCD;

?? ?keybuf=(keybuf<<1)|KEY4;//讀取按鍵狀態(tài),累計(jì)到這個(gè)類(lèi)似FIFO變量里面

?? ?if(keybuf==0)
?? ?{
?? ??? ?//按下
?? ??? ?KeySta=0;
?? ?}
?? ?else if(keybuf==0xFF)
?? ?{
?? ??? ?//松開(kāi)
?? ??? ?KeySta=1;
?? ?}
?? ?else
?? ?{
?? ??? ?//抖動(dòng)
?? ?}

}

課上例子,矩陣按鍵中斷消抖讀取
#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int? u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int? i16;
typedef signed long i32;

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

//4個(gè)列,要讀取
sbit KEYIN1=P2^4;
sbit KEYIN2=P2^5;
sbit KEYIN3=P2^6;
sbit KEYIN4=P2^7;

//4個(gè)行,要拉低
sbit KEYOUT1=P2^3;
sbit KEYOUT2=P2^2;
sbit KEYOUT3=P2^1;
sbit KEYOUT4=P2^0;

//保存中斷消抖后,讀取按鍵狀態(tài)
u8 KeySta[4][4]=
{
?? ?{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
};

// 數(shù)碼管code
u8 code LedChar[] =
{
?? ?0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
?? ?0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};

void main(void)
{
?? ?//保存上一次按鍵的狀態(tài)
?? ?u8 backup[4][4]=
?? ?{
?? ??? ?{1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
?? ?};

?? ?u8 i,j,cnt;

?? ?ENLED = 0;
?? ?ADDR3 = 1;
?? ?ADDR2 = 0;
?? ?ADDR1 = 0;
?? ?ADDR0 = 0;

?? ?TMOD=0x01;
?? ?TH0=0xF8;
?? ?TL0=0xCD;
?? ?ET0=EA=TR0=1;

?? ?P0 = LedChar[cnt];

?? ?while (1)
?? ?{
?? ??? ?//掃描上一次狀態(tài)和現(xiàn)在狀態(tài),有區(qū)別嗎
?? ??? ?for(i=0; i<4; i++) //out
?? ??? ?{
?? ??? ??? ?for(j=0; j<4; j++) //in
?? ??? ??? ?{
?? ??? ??? ??? ?if(backup[i][j]!=KeySta[i][j])
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?if(backup[i][j]==0)
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?//松開(kāi)
?? ??? ??? ??? ??? ??? ?P0=LedChar[i*4+j];
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?else
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?//按下
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?backup[i][j]=KeySta[i][j];
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
}

void Timer0_ISR(void)interrupt 1
{
?? ?static u8 keyout=0;//控制4個(gè)線拉低的
?? ?u8 i=0;
?? ?
?? ?//保存按鍵每一次讀取的值
?? ?static u8 keybuf[4][4]={
?? ??? ?{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}
?? ?};

?? ?TH0=0xF8;
?? ?TL0=0xCD;

?? ?//讀keyout拉低行的,4個(gè)列按鍵狀態(tài)
?? ?keybuf[keyout][0]=(keybuf[keyout][0]<<1)|KEYIN1;//讀第1列按鍵
?? ?keybuf[keyout][1]=(keybuf[keyout][1]<<1)|KEYIN2;//讀第2列按鍵
?? ?keybuf[keyout][2]=(keybuf[keyout][2]<<1)|KEYIN3;//讀第3列按鍵
?? ?keybuf[keyout][3]=(keybuf[keyout][3]<<1)|KEYIN4;//讀第4列按鍵

?? ?//判斷剛讀取的4個(gè)按鍵,是否穩(wěn)定
?? ?for(i=0; i<4; i++)
?? ?{
?? ??? ?if((keybuf[keyout][i] & 0x0F) == 0x00)//穩(wěn)定為0
?? ??? ?{
?? ??? ??? ?KeySta[keyout][i]=0;
?? ??? ?}
?? ??? ?else if((keybuf[keyout][i] & 0x0F) == 0x0F)//穩(wěn)定為1
?? ??? ?{
?? ??? ??? ?KeySta[keyout][i]=1;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?//抖動(dòng)
?? ??? ?}
?? ?}

?? ?//切換下一行拉低,方便下次讀取
?? ?keyout++;
?? ?keyout&=0x03;
?? ?switch(keyout)
?? ?{
?? ?case 0:
?? ??? ?KEYOUT4=1;
?? ??? ?KEYOUT1=0;
?? ??? ?break;
?? ?case 1:
?? ??? ?KEYOUT1=1;
?? ??? ?KEYOUT2=0;
?? ??? ?break;
?? ?case 2:
?? ??? ?KEYOUT2=1;
?? ??? ?KEYOUT3=0;
?? ??? ?break;
?? ?case 3:
?? ??? ?KEYOUT3=1;
?? ??? ?KEYOUT4=0;
?? ??? ?break;
?? ?}

}
//分析,太費(fèi)內(nèi)存了把,使用了16*3約50個(gè)字節(jié)的變量

課上例子,加法器,up=加;enter是等于;
#include <reg52.h>

typedef unsigned char u8;
typedef unsigned int? u16;
typedef unsigned long u32;
typedef signed char i8;
typedef signed int? i16;
typedef signed long i32;

sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;

// 4個(gè)列,要讀取
sbit KEYIN1 = P2 ^ 4;
sbit KEYIN2 = P2 ^ 5;
sbit KEYIN3 = P2 ^ 6;
sbit KEYIN4 = P2 ^ 7;

// 4個(gè)行,要拉低
sbit KEYOUT1 = P2 ^ 3;
sbit KEYOUT2 = P2 ^ 2;
sbit KEYOUT3 = P2 ^ 1;
sbit KEYOUT4 = P2 ^ 0;

// 保存中斷消抖后,讀取按鍵狀態(tài)
u8 KeySta[4][4] =
??? {
?? ?{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};

// 數(shù)碼管code
u8 code LedChar[16] =
??? {
?? ?0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
?? ?0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};

// 數(shù)碼管緩沖區(qū)
u8 LedBuff[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

u8 code KeyCodeMap[4][4] = {
??? {0x31, 0x32, 0x33, 0x26}, // 數(shù)字1,2,3,UP
??? {0x34, 0x35, 0x36, 0x25}, // 數(shù)字4,5,6,LEFT
??? {0x37, 0x38, 0x39, 0x28}, // 數(shù)字7,8,9,DOWN
??? {0x30, 0x1B, 0x0D, 0x27}, // 數(shù)字0,ESC,ENTER,RIGHT

};
void KeyDriver();
void main(void)
{
?? ?TMOD = 0x01;
?? ?TH0 = 0xFC;
?? ?TL0 = 0x66;
?? ?ET0 = EA = TR0 = 1;

?? ?ENLED = 0;
?? ?ADDR3 = 1;

?? ?LedBuff[0] = LedChar[0];

?? ?while (1)
?? ?{
?? ??? ?KeyDriver();
?? ?}
}

void ShowNumber(u32 num)
{
?? ?u8 buf[6];
?? ?u8 i,j;

?? ?for (i = 0; i < 6; i++)
?? ?{
?? ??? ?buf[i] = num % 10;
?? ??? ?num /= 10;
?? ?}

?? ?for (i = 5; i >= 1; i--)
?? ?{
?? ??? ?if (buf[i] == 0)
?? ??? ?{
?? ??? ??? ?LedBuff[i] = 0xFF; // 不顯示
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?break;
?? ??? ?}
?? ?}
?? ?for (j=0; j<=i;j++)
?? ?{
?? ??? ?LedBuff[j] = LedChar[buf[j]];
?? ?}
}
void KeyAction(u8 keycode)
{
?? ?static u32 result = 0;
?? ?static u32 addend = 0;

?? ?if ((keycode >= 0x30) && (keycode <= 0x39))
?? ?{
?? ??? ?// num
?? ??? ?addend = (addend * 10) + (keycode - 0x30);
?? ??? ?ShowNumber(addend);
?? ?}
?? ?else if (keycode == 0x26) // up,+
?? ?{
?? ??? ?result += addend;
?? ??? ?addend = 0;
?? ??? ?ShowNumber(result);
?? ?}
?? ?else if (keycode == 0x0D) // enter =
?? ?{
?? ??? ?result += addend;
?? ??? ?addend = 0;
?? ??? ?ShowNumber(result);
?? ?}
?? ?else if (keycode == 0x1B) // esc clear
?? ?{
?? ??? ?addend = 0;
?? ??? ?result = 0;
?? ??? ?ShowNumber(0);
?? ?}
}
void KeyDriver(void)
{
?? ?// 保存上一次按鍵的狀態(tài)
?? ?static u8 backup[4][4] = {{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};

?? ?u8 i, j;
?? ?// 掃描上一次狀態(tài)和現(xiàn)在狀態(tài),有區(qū)別嗎
?? ?for (i = 0; i < 4; i++) // out
?? ?{
?? ??? ?for (j = 0; j < 4; j++) // in
?? ??? ?{
?? ??? ??? ?if (backup[i][j] != KeySta[i][j])
?? ??? ??? ?{
?? ??? ??? ??? ?if (backup[i][j] == 0)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?KeyAction(KeyCodeMap[i][j]);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?// 按下
?? ??? ??? ??? ?}
?? ??? ??? ??? ?backup[i][j] = KeySta[i][j];
?? ??? ??? ?}
?? ??? ?}
?? ?}
}

void KeyScan(void)
{

?? ?static u8 keyout = 0; // 控制4個(gè)線拉低的
?? ?u8 i = 0;
?? ?// 保存按鍵每一次讀取的值
?? ?static u8 keybuf[4][4] = {{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}};

?? ?// 讀keyout拉低行的,4個(gè)列按鍵狀態(tài)
?? ?keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEYIN1; // 讀第1列按鍵
?? ?keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEYIN2; // 讀第2列按鍵
?? ?keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEYIN3; // 讀第3列按鍵
?? ?keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEYIN4; // 讀第4列按鍵

?? ?// 判斷剛讀取的4個(gè)按鍵,是否穩(wěn)定
?? ?for (i = 0; i < 4; i++)
?? ?{
?? ??? ?if ((keybuf[keyout][i] & 0x0F) == 0x00) // 穩(wěn)定為0
?? ??? ?{
?? ??? ??? ?KeySta[keyout][i] = 0;
?? ??? ?}
?? ??? ?else if ((keybuf[keyout][i] & 0x0F) == 0x0F) // 穩(wěn)定為1
?? ??? ?{
?? ??? ??? ?KeySta[keyout][i] = 1;
?? ??? ?}
?? ??? ?else
?? ??? ?{
?? ??? ??? ?// 抖動(dòng)
?? ??? ?}
?? ?}

?? ?// 切換下一行拉低,方便下次讀取
?? ?keyout++;
?? ?keyout &= 0x03;
?? ?switch (keyout)
?? ?{
?? ?case 0:
?? ??? ?KEYOUT4 = 1;
?? ??? ?KEYOUT1 = 0;
?? ??? ?break;
?? ?case 1:
?? ??? ?KEYOUT1 = 1;
?? ??? ?KEYOUT2 = 0;
?? ??? ?break;
?? ?case 2:
?? ??? ?KEYOUT2 = 1;
?? ??? ?KEYOUT3 = 0;
?? ??? ?break;
?? ?case 3:
?? ??? ?KEYOUT3 = 1;
?? ??? ?KEYOUT4 = 0;
?? ??? ?break;
?? ?}
}

void LedScan(void)
{
?? ?static u8 i = 0;

?? ?P0 = 0xFF; // 消影
?? ?switch (i)
?? ?{
?? ?case 0:
?? ??? ?ADDR2 = 0;
?? ??? ?ADDR1 = 0;
?? ??? ?ADDR0 = 0;
?? ??? ?i++;
?? ??? ?P0 = LedBuff[0];
?? ??? ?break;
?? ?case 1:
?? ??? ?ADDR2 = 0;
?? ??? ?ADDR1 = 0;
?? ??? ?ADDR0 = 1;
?? ??? ?i++;
?? ??? ?P0 = LedBuff[1];
?? ??? ?break;
?? ?case 2:
?? ??? ?ADDR2 = 0;
?? ??? ?ADDR1 = 1;
?? ??? ?ADDR0 = 0;
?? ??? ?i++;
?? ??? ?P0 = LedBuff[2];
?? ??? ?break;
?? ?case 3:
?? ??? ?ADDR2 = 0;
?? ??? ?ADDR1 = 1;
?? ??? ?ADDR0 = 1;
?? ??? ?i++;
?? ??? ?P0 = LedBuff[3];
?? ??? ?break;
?? ?case 4:
?? ??? ?ADDR2 = 1;
?? ??? ?ADDR1 = 0;
?? ??? ?ADDR0 = 0;
?? ??? ?i++;
?? ??? ?P0 = LedBuff[4];
?? ??? ?break;
?? ?case 5:
?? ??? ?ADDR2 = 1;
?? ??? ?ADDR1 = 0;
?? ??? ?ADDR0 = 1;
?? ??? ?P0 = LedBuff[5];
?? ??? ?i = 0;
?? ??? ?break;
?? ?}
}

void Timer0_ISR(void) interrupt 1
{
?? ?TH0 = 0xFC;
?? ?TL0 = 0x66;
?? ?LedScan();
?? ?KeyScan();
}

//課后作業(yè)在下一篇



第8章-函數(shù)進(jìn)階與按鍵(上:跟堂作業(yè))的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
竹北市| 叙永县| 永定县| 吕梁市| 河津市| 龙海市| 固阳县| 宁化县| 彭州市| 永仁县| 迁安市| 湛江市| 韶山市| 卢湾区| 沂水县| 和平县| 墨脱县| 眉山市| 海兴县| 石渠县| 绥宁县| 周至县| 娱乐| 莲花县| 遂昌县| 贵阳市| 福鼎市| 神池县| 宝应县| 紫阳县| 东源县| 阿勒泰市| 义乌市| 台东市| 浠水县| 安乡县| 武穴市| 和顺县| 邹城市| 江源县| 喀喇沁旗|