亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
51單片機學習:4*4矩陣鍵盤與可對時電子鐘
[打印本頁]
作者:
51黑電子迷
時間:
2017-2-9 22:19
標題:
51單片機學習:4*4矩陣鍵盤與可對時電子鐘
今天學習了下矩陣鍵盤,
4*4, 分別代表0~F這16個數字
我們按了哪個鍵就顯示到數碼管上
看完郭老師講解原理后就自己動手寫了,郁悶的是
在keil軟件中,我在switch-case語句中 少了個冒號,竟然編譯通過!
結果當然不正確了,然后我再keil中調試代碼,那更郁悶了,P3口在掃描到第2行鍵盤時就
會復位成0xff,怎么賦值都沒用,其實是沒寫冒號啊!
調了半天都不行,最后不得不將STC89C52RC換上仿真芯片SST89E516,在線調試后才發現的錯誤,
然后參考書上的代碼才調試成功的,表示無語~~~
mark下
#include <reg52.h>
#include "MY51.H"
void showKey(uint8 num); //靜態顯示
void keyScan();
void main()
{
showKey(18); //初始顯示的是6個負號
while(1)
{ //循環檢測
keyScan();
}
}
void showKey(uint8 num)
{
P0=0xc0; //11000000 打開6個數碼管
wela=open;
wela=lock;
P0=table[num];
dula=1;
dula=0;
}
void keyScan()
{
uint8 num=0; //定義顯示的數字
uint8 temp=0; //P3口回讀信息
uint8 i=0; //定義矩陣鍵盤行號索引
for(i=0; i<4;i++) //共4行
{
P3=_crol_(0xfe,i); //掃描的行索引號,從第0行到第3行
temp=P3; //讀取P3口
temp=temp&0xf0; //提取高4位
if(temp!=0xf0) //按鍵了
{
delayms(5); //消抖
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0) //真的按鍵了
{
switch(temp)
{
case 0xe0: //1110 0000
{
num=0+4*i;
break;
}
case 0xd0: //1101 0000
{
num=1+4*i;
break;
}
case 0xb0: //1011 0000
{
num=2+4*i;
break;
}
case 0x70: //0111 0000
{
num=3+4*i;
break;
}
default:
{
num=18; //18號索引是負號
led7=0; // 按了不該按的指示燈
break;
}
}
while(1) //松開按鍵檢測
{
temp=P3; //讀取P3口
temp=temp&0xf0; //提取高4位
if(temp==0xf0) //松開按鍵了
{
delayms(5);
temp=P3;
temp=temp&0xf0;
if(temp==0xf0) //真的松開鍵盤了
{
break;
}
}
}
showKey(num); //靜態顯示按鍵
}
}
}
}
void T0_Work() //T0定時器調用的工作函數
{
}
復制代碼
#ifndef _MY51_H_
#define _MY51_H_
#include <math.h>
#include <intrins.h>
typedef int int16 ;
typedef int INT16 ;
typedef unsigned int uint16 ;
typedef unsigned int UINT16 ;
typedef unsigned short uint ;
typedef unsigned short UINT ;
typedef unsigned short word ;
typedef unsigned short WORD ;
typedef unsigned long uint32 ;
typedef unsigned long UINT32 ;
typedef unsigned long DWORD ;
typedef unsigned long dword ;
typedef signed long int32 ;
typedef signed long INT32 ;
typedef float float32 ;
typedef double double64 ;
typedef signed char int8 ;
typedef signed char INT8 ;
typedef unsigned char byte ;
typedef unsigned char BYTE ; //WINDOWS的windef.h里面是這么定義的
typedef unsigned char uchar ;
typedef unsigned char UCHAR ;
typedef unsigned char UINT8 ;
typedef unsigned char uint8 ;
typedef unsigned char BOOL ; //windows中定義BOOL為int
typedef unsigned char bool ; //bool是c++的內置類型
#define TRUE 1
#define true 1
#define FALSE 0
#define false 0
#define open 1 //open和close用于 標志打開和關閉狀態
#define OPEN 1
#define close 0
#define CLOSE 0
#define lock 0
#define start 1
#define START 1
#define stop 0
#define STOP 0
#define keyDown 0
#define keyUp 1
sbit dula =P2^6; //段選鎖存器控制 控制筆段
sbit wela =P2^7; //位選鎖存器控制 控制位置
#define led P1 //燈總線控制
sbit led0=P1^0; //8個led燈,陰極送低電平點亮
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;
sbit keyS2=P3^4; //4個獨立按鍵
sbit keyS3=P3^5;
sbit keyS4=P3^6;
sbit keyS5=P3^7;
void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot);
void delayms(uint16 ms);
void T0_Work();
void delayms(uint16 ms) //軟延時函數
{
uint16 i,j;
for(i=ms;i>0;i--)
{
for(j=113;j>0;j--)
{}
}
}
///////////////////////////////////////////////////////////////////////////
#define dark 0x11 //在段中,0x11是第17號元素,為0是低電平,數碼管不亮
#define dotDark 0xff //小數點全暗時
uint8 code table[]= { //0~F外加小數點和空輸出的數碼管編碼
0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3
0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7
0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B
0x39 , 0x5e , 0x79 , 0x71 , // C D E F
0x80 , 0x00 ,0x40 // . 空 負號 空時是第0x11號也就是第17號元素
};
/////////////////////////////////////////////////////////////////////////////
uint8 TH0Cout=0 ; //初值
uint8 TL0Cout=0 ;
uint16 T0IntCout=0; //中斷計數
uint16 T0IntCountAll=0; //(N-1)/65536+1; //總中斷次數
bool bT0Delay=false; //使用延時函數標志,初始未用
bool bT0Over=false; //中斷處理函數執行結果之一
void startT0(uint32 ms) //開啟定時器
{
float32 t=ms/1000.0; //定時時間
double64 fox =11.0592*(pow(10,6)); //晶振頻率
uint32 N=(t*fox)/12 ; //定時器總計數值
TH0Cout =(65536-N%65536)/256; //裝入計時值零頭計數初值
TL0Cout =(65536-N%65536)%256;
T0IntCountAll=(N-1)/65536+1; //總中斷次數
TMOD=TMOD | 0x01; //設置定時器0的工作方式為1
EA =open; //打開總中斷
ET0=open; //打開定時器中斷
TH0=TH0Cout; //定時器裝入初值
TL0=TL0Cout;
TR0=start; //啟動定時器
}
void delayT0(uint32 ms) //硬延時函數,自己亂寫的不好用,求指點
{
startT0(ms); //啟動定時器
bT0Delay=true; //告訴T0定時器,起用延時模式
while(bT0Over==false); //時間沒到的話繼續檢測
bT0Over=false; //時間到了,讓標志復位
}
void T0_times() interrupt 1 //T0定時器中斷函數
{
T0IntCout++;
if(T0IntCout==T0IntCountAll) //達到總中斷次數值
{
T0IntCout=0; //中斷次數清零,重新計時
bT0Over=true; //時間真的到了
if(bT0Delay) //本次中斷是用來延時的嗎
{
TR0=stop; //如果是由延時函數開啟T0的話,關閉T0
return;
}
TH0=TH0Cout; //循環定時的話要重裝初值,每次定時1秒,重裝一次
TL0=TL0Cout;
T0_Work(); //工作函數
}
}
////////////////////////////////////////////////////////////////////////////////
void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot)
{ //控制6位數碼管顯示函數,不顯示的位用參數 dark
P0=0;
dula=1;
dula=0; //段選數據清空并鎖定
//////////////////////////
P0=0xff; //送位數據前關閉所有顯示
wela=1;
P0=0xfe;
wela=0;
P0=0; //低電平輸到數碼管陽極,避免數碼管吳亮
dula=1;
P0=table[oneWela]|((0x01&dot)?0x00:0x80); //送段數據,使用小數點顯示標志
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
P0=0;
dula=1;
P0=table[twoWela]|((0x02&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
P0=0;
dula=1;
P0=table[threeWela]|((0x04&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
P0=0;
dula=1;
P0=table[fourWela]|((0x08&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xef;
wela=0;
P0=0;
dula=1;
P0=table[fiveWela]|((0x10&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
P0=0;
dula=1;
P0=table[sixWela]|((0x20&dot)?0x00:0x80);
dula=0;
delayms(2);
}
#endif
復制代碼
作者:
51黑電子迷
時間:
2017-2-9 22:21
51單片機學習筆記:可對時電子鐘
本篇是對上一篇的改進,昨天學習了第4章 中的獨立鍵盤的使用
獨立鍵盤擁有自己獨有的IO口,所以比較簡單,我上一篇寫的電子鐘程序只能燒程序對時,
不能手動按鍵對時,這肯定是最差勁的做法,所以學習了按鍵之后,就立馬動手改進我的電子鐘了
同時改進了數碼管小數點的顯示,消除了疊影
使用芯片STC89C52RC, 2個鎖存器
6個帶小數點共陰極數碼管顯示一個24時制時鐘
沒有時鐘芯片,所以掉電后時間會復位
原理圖為TX-1C開發板
==============================
最終顯示的<時.分.秒>是 16.31.37 形式
使用3個按鍵, S2 S3 S5
其中S2和S3是加減數值,S5是切換對時狀態,
#include <reg52.h>
#include "MY51.H"
void show();
int8 shi=22; //初識時間22:45:00 按S5鍵進入對時模式
int8 fen=45;
int8 miao=0;
uint8 timeFlag=0;//0計時模式,1校對時鐘,2校對分鐘,3校對秒鐘
void main()
{
startT0(1000); //開始定時器
while(1)
{
show(); //送入數碼管顯示
if(keyS5==keyDown) //按下S5鍵
{
delayms(5);//消抖處理
if(keyS5==keyDown)
{
while(1)
{
show();
if(keyS5==keyUp)//放開按鈕
{
delayms(5); //消抖處理
if(keyS5==keyUp)
{
break;
}
}
}
timeFlag=(++timeFlag)%4; //按S5鍵進行狀態切換
while(timeFlag)
{
if(timeFlag==1)
{
led=0xff;
led7=0; //進入對時鐘模式,且打開7號指示燈
}
else if(timeFlag==2)
{
led=0xff;
led5=0; //進入校對分鐘模式,且打開5號指示燈
}
else if(timeFlag==3)
{
led=0xff;
led3=0; //進入校對秒鐘模式,且打開3號指示燈
}
show(); //刷新數碼管
if(keyS2==keyDown)//S2和S3用于調整數值,加減運算
{
delayms(5);//消抖處理
if(keyS2==keyDown)
{
if(timeFlag==1)
{
shi--;
if(shi<0)
{
shi=23;
}
}
else if(timeFlag==2)
{
fen--;
if(fen<0)
{
fen=59;
}
}
else if(timeFlag==3)
{
miao--;
if(miao<0)
{
miao=59;
}
}
while(1)
{
show(); //就算S2鍵被按著,也要刷新數碼管
if(keyS2==keyUp)
{
delayms(10);
if(keyS2==keyUp)
{
break;
}
}
}
}
}
if(keyS3==keyDown)
{
delayms(5);//消抖處理
if(keyS3==keyDown)
{
if(timeFlag==1)
{
shi++;
if(shi>23)
{
shi=0;
}
}
else if(timeFlag==2)
{
fen++;
if(fen>59)
{
fen=0;
}
}
else if(timeFlag==3)
{
miao++;
if(miao>59)
{
miao=0;
}
}
while(1)
{
show();
if(keyS3==keyUp)
{
delayms(5);
if(keyS3==keyUp)
{
break;
}
}
}
}
}
if(keyS5==keyDown)
{
delayms(5);//消抖處理
if(keyS5==keyDown)
{
timeFlag=(++timeFlag)%4;//按S5鍵切換狀態
while(1)
{
show();
if(keyS5==keyUp)
{
delayms(5);
if(keyS5==keyUp)
{
break;
}
}
}
}
}
}
led=0xff; //對時結束,指示燈滅
}
}
}
}
void show() //顯示時鐘
{
uint8 oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela; //oneWela是最左邊的數碼管
sixWela =miao%10;
fiveWela=miao/10;
foreWela=fen%10;
threeWela=fen/10;
twoWela=shi%10;
oneWela=shi/10;
displaySMG(oneWela,twoWela,threeWela,foreWela,fiveWela,sixWela,0xf5); //0xf5是小數點的位置
}
void T0_Work() //T0定時器調用的工作函數
{
miao++;
if(miao>59)
{
miao=0;
fen++;
}
if(fen>59)
{
fen=0;
shi++;
}
if(shi>23)
{
shi=0;
}
}
復制代碼
#ifndef _MY51_H_
#define _MY51_H_
#include <math.h>
#include <intrins.h>
typedef int int16 ;
typedef int INT16 ;
typedef unsigned int uint16 ;
typedef unsigned int UINT16 ;
typedef unsigned short uint ;
typedef unsigned short UINT ;
typedef unsigned short word ;
typedef unsigned short WORD ;
typedef unsigned long uint32 ;
typedef unsigned long UINT32 ;
typedef unsigned long DWORD ;
typedef unsigned long dword ;
typedef signed long int32 ;
typedef signed long INT32 ;
typedef float float32 ;
typedef double double64 ;
typedef signed char int8 ;
typedef signed char INT8 ;
typedef unsigned char byte ;
typedef unsigned char BYTE ; //WINDOWS的windef.h里面是這么定義的
typedef unsigned char uchar ;
typedef unsigned char UCHAR ;
typedef unsigned char UINT8 ;
typedef unsigned char uint8 ;
typedef unsigned char BOOL ; //windows中定義BOOL為int
typedef unsigned char bool ; //bool是c++的內置類型
#define TRUE 1
#define true 1
#define FALSE 0
#define false 0
#define open 1 //open和close用于 標志打開和關閉狀態
#define OPEN 1
#define close 0
#define CLOSE 0
#define lock 0
#define start 1
#define START 1
#define stop 0
#define STOP 0
#define keyDown 0
#define keyUp 1
sbit dula =P2^6; //段選鎖存器控制 控制筆段
sbit wela =P2^7; //位選鎖存器控制 控制位置
#define led P1 //燈總線控制
sbit led0=P1^0; //8個led燈,陰極送低電平點亮
sbit led1=P1^1;
sbit led2=P1^2;
sbit led3=P1^3;
sbit led4=P1^4;
sbit led5=P1^5;
sbit led6=P1^6;
sbit led7=P1^7;
sbit keyS2=P3^4; //4個獨立按鍵
sbit keyS3=P3^5;
sbit keyS4=P3^6;
sbit keyS5=P3^7;
void displaySMG(uint8 one,uint8 two,uint8 three,uint8 four,uint8 five,uint8 six,uint8 dot);
void delayms(uint16 ms);
void T0_Work();
void delayms(uint16 ms) //軟延時函數
{
uint16 i,j;
for(i=ms;i>0;i--)
{
for(j=113;j>0;j--)
{}
}
}
///////////////////////////////////////////////////////////////////////////
#define dark 0x11 //在段中,0x11是第17號元素,為0是低電平,數碼管不亮
#define dotDark 0xff //小數點全暗時
uint8 code table[]= { //0~F外加小數點和空輸出的數碼管編碼
0x3f , 0x06 , 0x5b , 0x4f , // 0 1 2 3
0x66 , 0x6d , 0x7d , 0x07 , // 4 5 6 7
0x7f , 0x6f , 0x77 , 0x7c , // 8 9 A B
0x39 , 0x5e , 0x79 , 0x71 , // C D E F
0x80 , 0x00 // . 空 空時是第0x11號也就是第17號元素
};
/////////////////////////////////////////////////////////////////////////////
uint8 TH0Cout=0 ; //初值
uint8 TL0Cout=0 ;
uint16 T0IntCout=0; //中斷計數
uint16 T0IntCountAll=0; //(N-1)/65536+1; //總中斷次數
bool bT0Delay=false; //使用延時函數標志,初始未用
bool bT0Over=false; //中斷處理函數執行結果之一
void startT0(uint32 ms) //開啟定時器
{
float32 t=ms/1000.0; //定時時間
double64 fox =11.0592*(pow(10,6)); //晶振頻率
uint32 N=(t*fox)/12 ; //定時器總計數值
TH0Cout =(65536-N%65536)/256; //裝入計時值零頭計數初值
TL0Cout =(65536-N%65536)%256;
T0IntCountAll=(N-1)/65536+1; //總中斷次數
TMOD=TMOD | 0x01; //設置定時器0的工作方式為1
EA =open; //打開總中斷
ET0=open; //打開定時器中斷
TH0=TH0Cout; //定時器裝入初值
TL0=TL0Cout;
TR0=start; //啟動定時器
}
void delayT0(uint32 ms) //硬延時函數,自己亂寫的不好用,求指點
{
startT0(ms); //啟動定時器
bT0Delay=true; //告訴T0定時器,起用延時模式
while(bT0Over==false); //時間沒到的話繼續檢測
bT0Over=false; //時間到了,讓標志復位
}
void T0_times() interrupt 1 //T0定時器中斷函數
{
T0IntCout++;
if(T0IntCout==T0IntCountAll) //達到總中斷次數值
{
T0IntCout=0; //中斷次數清零,重新計時
bT0Over=true; //時間真的到了
if(bT0Delay) //本次中斷是用來延時的嗎
{
TR0=stop; //如果是由延時函數開啟T0的話,關閉T0
return;
}
TH0=TH0Cout; //循環定時的話要重裝初值,每次定時1秒,重裝一次
TL0=TL0Cout;
T0_Work(); //工作函數
}
}
////////////////////////////////////////////////////////////////////////////////
void displaySMG(uint8 oneWela,uint8 twoWela,uint8 threeWela,uint8 fourWela,uint8 fiveWela,uint8 sixWela,uint8 dot)
{ //控制6位數碼管顯示函數,不顯示的位用參數 dark
P0=0;
dula=1;
dula=0; //段選數據清空并鎖定
//////////////////////////
P0=0xff; //送位數據前關閉所有顯示
wela=1;
P0=0xfe;
wela=0;
P0=0; //低電平輸到數碼管陽極,避免數碼管吳亮
dula=1;
P0=table[oneWela]|((0x01&dot)?0x00:0x80); //送段數據,小數點可選顯示 dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
P0=0;
dula=1;
P0=table[twoWela]|((0x02&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
P0=0;
dula=1;
P0=table[threeWela]|((0x04&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
P0=0;
dula=1;
P0=table[fourWela]|((0x08&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xef;
wela=0;
P0=0;
dula=1;
P0=table[fiveWela]|((0x10&dot)?0x00:0x80);
dula=0;
delayms(2);
/////////////////////////
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
P0=0;
dula=1;
P0=table[sixWela]|((0x20&dot)?0x00:0x80);
dula=0;
delayms(2);
}
#endif
復制代碼
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1