【筆記】重學單片機(51)

為學習嵌入式做準備,重新拿起51單片機學習。此貼為學習筆記,僅記錄易忘點,實用理論基礎,并不是0基礎。
資料參考:清翔零基礎教你學51單片機

51單片機學習筆記

  • 1. C語言中的易忘點
    • 1.1 數據類型
    • 1.2 位運算符
    • 1.3 常用控制語句
    • 1.4 C51程序的基本結構
  • 2.電子電路基礎
    • 2.1 電平
    • 2.2 I/O(引腳)
      • 2.2.1 P3口的第二用途
    • 2.3 電子元器件
      • 2.3.1 電阻:
      • 2.3.2 電容:
      • 2.3.3 蜂鳴器
        • 2.3.3.1 判斷有源蜂鳴器和無源蜂鳴器
        • 2.3.3.2 驅動蜂鳴器
      • 2.3.4 常見符號
  • 3.單片機 基礎知識點
    • 3.1 單片機最小系統
    • 3.2 基本時序
  • 4. 51單片機基礎例程(I/O外設)
    • 4.1 點亮LED燈
      • 4.1.1編程知識點
        • 4.1.1.1 位定義
      • 4.1.2 編程
    • 4.2 LED閃爍
      • 4.2.1 編程知識點
        • 4.2.1.1 變量作用域
        • 4.2.1.2 軟件延時
      • 4.2.2 編程
    • 4.3 流水燈
      • 4.3.1 編程知識點
        • 4.3.1.1宏定義
        • 4.3.1.2 函數的定義
          • 4.3.1.3 延時函數
        • 4.3.1.4 循環移位函數
          • 4.3.1.4.1 循環移位函數與左移和右移運算符的區別
      • 4.3.2 編程
    • 4.4 數碼管靜、動態顯示
      • 4.4.1 單個數碼管--==靜態==顯示原理
      • 4.4.2 74HC573鎖存器工作原理
      • 4.4.3 多個數碼管--==動態==顯示原理
      • 4.4.4 編程知識點
        • 4.4.4.1 數組的定義與引用
      • 4.4.5 編程
        • 4.4.5.1 共陰極數碼管,靜態顯示(只亮一個數碼管)
        • 4.4.5.2 共陰極數碼管,動態顯示
    • 4.5 非編碼鍵盤
      • 4.5.1 獨立鍵盤
      • 4.5.2 矩陣鍵盤
        • 1.硬件接線
        • 2.掃描
      • 4.5.3 編程知識點
        • 4.5.3.1程序去抖
        • 4.5.3.2 開關語句
      • 4.5.4 編程
        • 4.5.4.1 獨立鍵盤
        • 4.5.4.2 矩陣鍵盤

1. C語言中的易忘點

1.1 數據類型

在這里插入圖片描述

1.2 位運算符

~  按位取反
<< 左移
>> 右移
& 按位與
^ 按位異或
| 按位或

異或:相同取0,不同取1.
在這里插入圖片描述

1.3 常用控制語句

條件 if
循環while 、 for
開關switch

1.4 C51程序的基本結構

#include <reg52.h> 		//包含51單片機頭文件void main()		//主函數
{}

C語言設置的程序中只允許有一個main函數。程序總是從main函數開始運行的,main函數是void型(無返回值)。

2.電子電路基礎

2.1 電平

數字電路中只有兩種電平:高電平和低電平。
高電平:5V
低電平:0V

TTL電平規定高電平輸出電壓>2.4V,低電平輸出電壓<0.4V	

計算機串口使用的是RS232電平
高電平:-12V
低電平:+12V
Tips:單片機與計算機串口通信時需要使用電平轉換芯片,把RS232電平轉為TTL電平后單片機才能識別。

2.2 I/O(引腳)

在這里插入圖片描述
例程中
P0接LED,P2^3接蜂鳴器。

2.2.1 P3口的第二用途

在這里插入圖片描述

2.3 電子元器件

2.3.1 電阻:

常用的貼片電阻封裝:0402、0603、0805、1206、1210
貼片電阻讀數參考:貼片電阻上的字符是如何表示電阻的?

103,那么10是有效數字,3表示10的3次方,所以103表示的阻值就是10x10^{3}
1502,150是有效數字,2表示10的2次方,所以,1502表示的阻值就是150*10^{2}
5R6=5.6Ω、R16=0.16Ω
01C就是10k

2.3.2 電容:

電容的作用:儲能,濾波,通交流隔直流,旁路,耦合,補償,充放電等

1F(法拉)	 = 1000000μF(微法)
1μF(微法)= 1000nF(納法)
1nF(納法) = 1000pF(皮法)

2.3.3 蜂鳴器

2.3.3.1 判斷有源蜂鳴器和無源蜂鳴器

可以用萬用表電阻檔Rxl檔測試:用黑表筆接蜂鳴器 "+"引腳,紅表筆在另一引腳上來回碰觸,如果觸發出咔、咔聲的且電阻只有8Ω(或16Ω)的是無源蜂鳴器;如果能發出持續聲音的,且電阻在幾百歐以上的,是有源蜂鳴器。

2.3.3.2 驅動蜂鳴器

由于蜂鳴器的工作電流一般比較大,以致于單片機的I/O 口是無法直接驅動的,所以要利用放大電路來驅動,一般使用三極管來放大電流就可以了。
(除此之外還有一些其他驅動方式:PWM 輸出口直接驅、I/O 口定時翻轉電平驅動蜂鳴器方式)
在這里插入圖片描述

2.3.4 常見符號

在這里插入圖片描述

3.單片機 基礎知識點

3.1 單片機最小系統

電源 (給整個系統提供能量)
單片機芯片 (運行程序/處理數據)
晶振電路 (給單片機工作提供節拍)
復位電路 (單片機上電時需要復位使程序從頭開始運行)
在這里插入圖片描述

3.2 基本時序

振蕩周期: 也稱時鐘周期, 是指為單片機提供時鐘脈沖信號的振蕩源的周期。

機器周期: 一個機器周期包含 12 個時鐘周期。 在一個機器周期內, CPU可以完成一個獨立的操作。

例如計算外部晶振頻率為11.0592Mhz的單片機一個機器周期所需的時間:
1/11.0592 * 12 ≈ 1.085μS
說明:“1/(11.0592*1000000)”乘以106把Mhz轉為hz再乘以“12”是12個時鐘周期等于一個機器周期最終值為秒,把這個單位為秒的值乘以106所得值約等于1.085微秒。

4. 51單片機基礎例程(I/O外設)

例程中LED位共陽極!
點亮開發板上LED燈只需要控制P1口輸出低電平即可
(編程時給P1口賦值“0”)
在這里插入圖片描述

4.1 點亮LED燈

普通發光二極管工作壓降為:1.6v ~ 2.1 V。
工作電流為:1~20mA
注意:二極管需要上拉電阻。
否則電流=(5V-2.1V)/0Ω,電流無限大
有電阻后,電流=(5V-2.1V)/1kΩ,約等于3mA.
在這里插入圖片描述

4.1.1編程知識點

4.1.1.1 位定義

關鍵字:sbit
功能:位定義
一般格式: sbit 標識符 = 地址值;

例如:sbit LED1 = P1^0;
注意:地址值中P1的“P”必須為大寫的P

4.1.2 編程

#include <reg52.h> //引用51頭文件sbit LED1 = P1^0; //位定義void main()	//主函數
{LED1 = 0;//點亮P1.0上的LED		
}

4.2 LED閃爍

4.2.1 編程知識點

4.2.1.1 變量作用域
全局變量:在函數體外定義的變量通常為全局變量,作用范圍:從定義開始的整個程序局部變量:在函數體內定義的變量通常為局部變量,作用范圍:函數體內
4.2.1.2 軟件延時

軟件延時例如:

unsigned int i;
i=65535;
while(i);

4.2.2 編程

實現:P1口上所有LED閃爍

#include <reg52.h>//包含51頭文件unsigned int i;//0~65535void main()//main函數自身會循環
{while(1)//大循環{P1 = 0;	//點亮P1口8個LEDi = 65535;while(i--);//軟件延時P1 = 0xff;//1111 1111 熄滅P1口8個LEDi = 65535;while(i--);//軟件延時	}	
}   

按位取反 閃爍寫法:

#include <reg52.h>unsigned int i;//0~65535void main()//main函數自身會循環
{P1 = 0xff;//熄滅8位LEDwhile(1) //大循環{P1 = ~P1;	//使用按位取反運算符使LED閃爍i = 65535;while(i--);//軟件延時}	
}   

4.3 流水燈

4.3.1 編程知識點

4.3.1.1宏定義

理解成 用define/ typedef 取小名

#define uchar unsigned char
注意宏定義后面不能加分號,它是預處理指令不是語句。

其中用“uchar”直接替換了unsigned char
此時我們可以用uchar去定義變量類型如:uchar i;等價于unsigned char i;

【C語言】typedef與define的區別

typedef,我們可以為基本類型(如int、float)或自定義的結構體、聯合體等定義新的名稱。define,定義常量、函數替換宏、條件編譯等,它的作用范圍更為廣泛。所有滿足條件的宏定義在預處理階段都會被替換為指定的文本。
4.3.1.2 函數的定義

自定義函數一般格式為:

函數類型 函數名 (形式參數表)
{局部變量定義函數體語句
}
4.3.1.3 延時函數

自定義函數:延時函數delay(毫秒級)

void delay(unsigned int z)
{unsigned int x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--);
}

給形參z賦值,如延時100毫秒:delay(100);

4.3.1.4 循環移位函數
標準庫函數: intrins.h

內部函數:

字符型循環左移:_crol_
字符型循環右移:_cror_
#include <intrins.h>
void test_crol (void) {unsigned char a;unsigned char b;a = 0xFE;      //1111 1110b = _crol_(a,1); // b now is 0xFD  二進制為1111 1101
}
4.3.1.4.1 循環移位函數與左移和右移運算符的區別

循環左移是把最高位移到最低位上,
左移運算符是把最高位移除最低位補0

4.3.2 編程

實現:流水燈一直左循環

#include <reg52.h>	 //包含51頭文件
#include <intrins.h> //包含移位標準庫函數頭文件#define uint unsigned int
#define uchar unsigned charuchar temp;//LED燈相關變量
/*====================================
函數	: delay(uint z)
參數	:z 延時毫秒設定,取值范圍0-65535
返回值	:無
描述	:12T/Fosc11.0592M毫秒級延時
====================================*/
void delay(uint z)
{uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); 		
} void main()//main函數自身會循環
{temp = 0xfe;P1 = temp; //1111 1110  初值LED1亮delay(100);//毫秒級延時 100毫秒while(1){temp = _crol_(temp, 1);//循環左移P1 = temp;//移位完成后賦值給P1 每個一個燈點亮delay(100);//毫秒級延時 100毫秒}	
}  

4.4 數碼管靜、動態顯示

4.4.1 單個數碼管–靜態顯示原理

有共陽、共陰極,例程使用共陰!即b圖左邊。
在這里插入圖片描述
共陰極數碼碼表:

0x3F,  //"0"
0x06,  //"1"
0x5B,  //"2"
0x4F,  //"3"
0x66,  //"4"
0x6D,  //"5"
0x7D,  //"6"
0x07,  //"7"
0x7F,  //"8"
0x6F,  //"9"
0x77,  //"A"
0x7C,  //"B"
0x39,  //"C"
0x5E,  //"D"
0x79,  //"E"
0x71,  //"F"
0x76,  //"H"
0x38,  //"L"
0x40,  //"-"
0x00,  //熄滅

4.4.2 74HC573鎖存器工作原理

鎖存器作用:可以把數據輸入端與輸出端進行隔離或連接
左邊D為輸入,右邊Q為輸出
在這里插入圖片描述
在這里插入圖片描述
輸出口Q要想輸出高低電平OE腳必須接GND。
LE腳為時,輸出端Q隨輸入端D的數據而變化。
LE腳為時,輸出端Q數據保持不變,輸入端D數據變化不會改變Q的數據。
在這里插入圖片描述

4.4.3 多個數碼管–動態顯示原理

段選和位選

位選:選擇哪一個數碼管亮
段選:該數碼管怎么亮(數碼管里的二極管怎么亮)

工作流:
打開位選鎖存器->指定某個數碼管->關閉位選鎖存器,
打開段選鎖存器->指定亮什么數字->關閉段選鎖存器,
因為掃描周期短,所以肉眼可以看到多數碼管同時亮 不同的數字。

4.4.4 編程知識點

4.4.4.1 數組的定義與引用

數組是一組有序數據的集合,數組中每一個數據都是同一數據類型。數組中的元素可以用數組名和下標來唯一確定。

數組的一般格式定義如下:

數據類型 數組名[常量表達式] = {元素表};

例如:

unsigned char tabel[3] ={0x3F, 0x06, 0x5B, };
P0 = tabel[0]; //P0此時的值為0x3F

4.4.5 編程

4.4.5.1 共陰極數碼管,靜態顯示(只亮一個數碼管)
#include <reg52.h>
#include <intrins.h>#define uint unsigned int
#define uchar unsigned charsbit DU = P2^6;//數碼管段選
sbit WE = P2^7;//數碼管位選////毫秒級延時函數定義
//void delay(uint z)
//{
//	uint x,y;
//	for(x = z; x > 0; x--)
//		for(y = 114; y > 0 ; y--); 		
//} void main()//main函數自身會循環
{WE = 1;//打開位選鎖存器P0 = 0XFE; //1111 1110 選通第一位數碼管WE = 0;//鎖存位選數據DU = 1;//打開段選鎖存器P0 = 0X06;//0000 0110 顯示“1”DU = 0;//鎖存段選數據while(1){}	
}  
4.4.5.2 共陰極數碼管,動態顯示
#include <reg52.h>//包含51頭文件
#include <intrins.h>//包含移位標準庫函數頭文件#define uint unsigned int
#define uchar unsigned charsbit DU = P2^6;//數碼管段選
sbit WE = P2^7;//數碼管段選//共陰數碼管段選表0-9
uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};/*====================================
函數	: delay(uint z)
參數	:z 延時毫秒設定,取值范圍0-65535
返回值	:無
描述	:12T/Fosc11.0592M毫秒級延時
====================================*/
void delay(uint z)
{uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); 		
} /*====================================
函數	:display(uchar i)
參數	:i 顯示數值,取值范圍0-255
返回值	:無
描述	:三位共陰數碼管動態顯示
====================================*/
void display(uchar i)
{uchar bai, shi, ge;bai = i / 100; //236 / 100  = 2shi = i % 100 / 10;	//236 % 100 / 10 = 3ge  = i % 10;//236 % 10 =6//第一位數碼管  		P0 = 0XFF;//清除斷碼WE = 1;//打開位選鎖存器P0 = 0XFE; //1111 1110WE = 0;//鎖存位選數據DU = 1;//打開段選鎖存器P0 = tabel[bai];//DU = 0;//鎖存段選數據delay(5);//第二位數碼管P0 = 0XFF;//清除斷碼WE = 1;//打開位選鎖存器P0 = 0XFD; //1111 1101WE = 0;//鎖存位選數據DU = 1;//打開段選鎖存器P0 = tabel[shi];//DU = 0;//鎖存段選數據delay(5);//第三位數碼管P0 = 0XFF;//清除斷碼WE = 1;//打開位選鎖存器P0 = 0XFB; //1111 1011WE = 0;//鎖存位選數據DU = 1;//打開段選鎖存器P0 = tabel[ge];//DU = 0;//鎖存段選數據delay(5);
}void main()//main函數自身會循環
{	while(1){display(236); //數碼管顯示函數}	
}  

4.5 非編碼鍵盤

4.5.1 獨立鍵盤

每個按鍵占用一個IO口,當按鍵數量較多時,IO口利用效率不高,
但程序簡單,適用于所需按鍵較少的場合。

在這里插入圖片描述
在這里插入圖片描述
按鍵一端與IO口連接,另外一端接地。I/O進行檢測,
按鍵按下會被檢測到電平,未按下被檢測為電平。

4.5.2 矩陣鍵盤

電路連接復雜,但提高了IO口利用率,軟件編程較復雜。
適用于使用大量按鍵的場合。

在這里插入圖片描述
上圖為4行和4列,一共16個按鍵組成。

確定矩陣鍵盤上哪一個按鍵被按下可以采用列掃描和行掃描。
列掃描時先把接在列上面的所有IO口拉高,接在行上的所有IO置低。
當其中有一列內任何一個按鍵按下那么整條列線都會被拉低。
1.硬件接線
P3口的高4位(P3.4~P3.7)作為列線(輸出)
P3口的低4位(P3.0~P3.3)作為行線(輸入)
uchar cord_l,cord_h;//聲明列線和行線的值的儲存變量P3 = 0xf0;//1111 0000
2.掃描

掃描分為兩步:列掃描和行掃描,通過檢測電平變化確定按鍵位置。
step1–列判斷:行線(P3.0 ~ P3.7)為0,列線(P3.4 ~ P3.7)為1,即P3=0xf0。
當四列中,某一列被按下,列線的對應的值就會改變。

  cord_l = P3 & 0xf0;// 只儲存列線值 (f0的0作用:無論行線是多少,都不保存,寫0)			
例:2行2列的S11按下,讀到L=0xd0(圖中從下P37往上P30,1101 0000)

step2–行判斷:在列判斷后,保留讀到的列線值,行線值寫1。即用讀到的列線值 或 0x0f。

例:0xd0|0x0f (1101 0000|00001111)得到1101 1111,
2行2列的S11按下,導致P31的1變為0,即變為1101 1101 (0xdd)
0xdd&0x0f=0x0d,此為行線值
  P3 = cord_l | 0x0f;cord_h = P3 & 0x0f;// 只儲存行線值(0f的0作用:無論列線是多少,都不保存,寫0)

在這里插入圖片描述
step3:
列線值+行線值

return (cord_l + cord_h);//返回鍵值碼

4.5.3 編程知識點

4.5.3.1程序去抖

在這里插入圖片描述

if(key_s3 == 0)//判斷S3是否被按下{delay(20);//按鍵消抖if(key_s3 == 0){...while(!key_s3);//松手檢測}	}
4.5.3.2 開關語句
switch (表達式)
{case 常量表達式1: 語句1breakcase 常量表達式2: 語句2break}

4.5.4 編程

4.5.4.1 獨立鍵盤

實現:按下開發板左下角S2按鍵數碼管值+1,最大到9按下S3按下,值減一,最小減到0

#include <reg52.h>
#include <intrins.h>#define uint unsigned int
#define uchar unsigned charsbit DU = P2^6;//數碼管段選
sbit WE = P2^7;//數碼管位選
sbit key_s2 = P3^0;//獨立按鍵S2
sbit key_s3 = P3^1;//獨立按鍵S3
uchar num;//數碼管顯示的值//共陰數碼管段選表0-9
uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,};//毫秒級延時函數定義
void delay(uint z)
{uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); 		
} void main()//main函數自身會循環
{	num = 0; WE = 1;//打開位選鎖存器P0 = 0XFE; //1111 1110WE = 0;//鎖存位選數據while(1){if(key_s2 == 0)//判斷S2是否被按下{delay(20);//按鍵消抖if(key_s2 == 0){if(num != 9)//如果值不等于9則+1,功能把值限定為小于9num++;while(!key_s2);//松手檢測}	}if(key_s3 == 0)//判斷S3是否被按下{delay(20);//按鍵消抖if(key_s3 == 0){if(num > 0)	//如果大于0則執行減一num--;while(!key_s3);//松手檢測}	}//松手之后刷新顯示DU = 1;//打開段選鎖存器P0 = tabel[num];//DU = 0;//鎖存段選數據}	
}  
4.5.4.2 矩陣鍵盤

實現:矩陣鍵盤

#include <reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit we = P2^7;
sbit du = P2^6;
uchar code leddata[]={ 0x3F,  //"0"0x06,  //"1"0x5B,  //"2"0x4F,  //"3"0x66,  //"4"0x6D,  //"5"0x7D,  //"6"0x07,  //"7"0x7F,  //"8"0x6F,  //"9"0x77,  //"A"0x7C,  //"B"0x39,  //"C"0x5E,  //"D"0x79,  //"E"0x71,  //"F"0x76,  //"H"0x38,  //"L"0x37,  //"n"0x3E,  //"u"0x73,  //"P"0x5C,  //"o"0x40,  //"-"0x00,  //熄滅0x00  //自定義};
void delay(uint z)
{uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--);
}uchar KeyScan()	//帶返回值的子函數
{uchar cord_l,cord_h;//聲明列線和行線的值的儲存變量P3 = 0xf0;//1111 0000if( (P3 & 0xf0) != 0xf0)//判斷是否有按鍵按下{delay(5);//軟件消抖if( (P3 & 0xf0) != 0xf0)//判斷是否有按鍵按下{cord_l = P3 & 0xf0;// 儲存列線值P3 = cord_l | 0x0f;cord_h = P3 & 0x0f;// 儲存行線值while( (P3 & 0x0f) != 0x0f );//松手檢測return (cord_l + cord_h);//返回鍵值碼}	}}void KeyPro()
{switch( KeyScan() ){//第一行鍵值碼case 0xee: P0 = leddata[0];		break;case 0xde: P0 = leddata[1];		break;case 0xbe: P0 = leddata[2];		break;case 0x7e: P0 = leddata[3];		break;//第二行鍵值碼case 0xed: P0 = leddata[4];		break;case 0xdd: P0 = leddata[5];		break;case 0xbd: P0 = leddata[6];		break;case 0x7d: P0 = leddata[7];		break;//第三行鍵值碼case 0xeb: P0 = leddata[8];		break;case 0xdb: P0 = leddata[9];		break;case 0xbb: P0 = leddata[10];	break;case 0x7b: P0 = leddata[11];	break;//第四行鍵值碼case 0xe7: P0 = leddata[12];	break;case 0xd7: P0 = leddata[13];	break;case 0xb7: P0 = leddata[14];	break;case 0x77: P0 = leddata[15];	break;}	
}void main()
{we = 1;//打開位選P0 = 0;//八位數碼管全顯示we = 0;//鎖存位選du = 1;//打開段選端P0 = leddata[22];while(1){KeyPro();//提取鍵值碼并且送不同數值給數碼管顯示}
}

實現:按下矩陣鍵盤和獨立鍵盤任意鍵,數碼管顯示相應數值初始顯示“-”橫

#include <reg52.h>//包含51頭文件
#include <intrins.h>//包含移位標準庫函數頭文件#define uint unsigned int
#define uchar unsigned charsbit DU = P2^6;//數碼管段選
sbit WE = P2^7;//數碼管段選
uchar num;//數碼管顯示的值
uchar KeyValue = 20;//按鍵值 顯示-//共陰數碼管段選表
uchar  code tabel[]= {
//0		1	 2     3     4     5     6     7     8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9     A     B	   C	 D	   E	 F		H	 L	 
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x76, 0x38,
//n	   u	  -	  熄滅
0x37, 0x3E, 0x40, 0x00 };/*====================================
函數	: delay(uint z)
參數	:z 延時毫秒設定,取值范圍0-65535
返回值	:無
描述	:12T/Fosc11.0592M毫秒級延時
====================================*/
void delay(uint z)
{uint x,y;for(x = z; x > 0; x--)for(y = 114; y > 0 ; y--); 		
} 
/*====================================
函數	:KeyScan()
參數	:無
返回值	:無
描述	:4*4矩陣鍵盤與獨立鍵盤掃描
按鍵按下KeyValue全局變量值發生相應變化
====================================*/
void KeyScan()
{//4*4矩陣鍵盤掃描P3 = 0XF0;//列掃描if(P3 != 0XF0)//判斷按鍵是否被按下{delay(10);//軟件消抖10msif(P3 != 0XF0)//判斷按鍵是否被按下{switch(P3) //判斷那一列被按下{case 0xe0:	KeyValue = 0;	break;//第一列被按下case 0xd0:	KeyValue = 1;	break;//第二列被按下case 0xb0:	KeyValue = 2;	break;//第三列被按下case 0x70:	KeyValue = 3;	break;//第四列被按下 }P3 = 0X0F;//行掃描switch(P3) //判斷那一行被按下{case 0x0e:	KeyValue = KeyValue;	break;//第一行被按下case 0x0d:	KeyValue = KeyValue + 4;	break;//第二行被按下case 0x0b:	KeyValue = KeyValue + 8;	break;//第三行被按下case 0x07:	KeyValue = KeyValue + 12;	break;//第四行被按下 }while(P3 != 0X0F);//松手檢測	}}P3 = 0XFF;//獨立按鍵掃描if(P3 != 0XFF){delay(10);//軟件消抖10msif(P3 != 0XFF){switch(P3) //判斷那一行被按下{case 0xfe:	KeyValue = 16;	break;//S2被按下case 0xfd:	KeyValue = 17;	break;//S3被按下case 0xfb:	KeyValue = 18;	break;//S4被按下case 0xf7:	KeyValue = 19;	break;//S5被按下 }while(P3 != 0XFF);//松手檢測			}	}}void main()//main函數自身會循環
{WE = 1;//打開位選鎖存器P0 = 0XFE; //1111 1110WE = 0;//鎖存位選數據DU = 1;//打開段選鎖存器while(1){KeyScan();//20個按鍵鍵盤掃描P0 = tabel[KeyValue];//顯示按鍵值}	
}  

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/91502.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/91502.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/91502.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++現代Redis客戶端庫redis-plus-plus詳解

&#x1f680; C現代Redis客戶端庫redis-plus-plus詳解&#xff1a;告別繁瑣的hiredis&#xff0c;擁抱現代C的Redis操作 &#x1f4c5; 更新時間&#xff1a;2025年07月28日 &#x1f3f7;? 標簽&#xff1a;C | Redis | redis-plus-plus | 現代C | 后端開發 文章目錄&#x…

Redis存儲原理與數據模型(上)

一、Redis數據模型 1.1、查看Redis數據定義&#xff1a; typedef struct redisDb {kvstore *keys; /* The keyspace for this DB 指向鍵值存儲的指針&#xff0c;用于快速訪問和修改數據庫中的鍵值對*/kvstore *expires; /* Timeout of keys with a t…

視頻生成模型蒸餾的方法

1.fastvideo https://github.com/hao-ai-lab/FastVideohttps://github.com/hao-ai-lab/FastVideo Distillation support Recipes for video DiT, based on PCM. Support distilling/finetuning/inferencing state-of-the-art open video DiTs: 1. Mochi 2. Hunyuan. 2.l

【mysql】—— mysql中的timestamp 和 datetime(6) 有什么區別,為什么有的地方不建議使用timestamp

在 MySQL 中,TIMESTAMP 和 DATETIME(6) 都是用于存儲日期和時間的數據類型,但它們在存儲范圍、時區處理、存儲方式等方面有顯著區別。 1. 核心區別對比 特性 TIMESTAMP DATETIME(6) 存儲范圍 1970-01-01 00:00:01 UTC ~ 2038-01-19 03:14:07 UTC(受限于 32 位時間戳) 1000…

前端下載文件相關

1、下載 ‘Content-Type‘: ‘application/octet-stream‘ 的文件 當后端返回的響應頭中 Content-Type 為 application/octet-stream 時&#xff0c;表示這是一個二進制流文件&#xff0c;瀏覽器無法直接展示&#xff0c;需要前端處理后下載到本地。 通過請求獲取二進制數據…

代碼隨想錄算法訓練營第五十六天|動態規劃part6

108.冗余連接 題目鏈接&#xff1a;108. 冗余的邊 文章講解&#xff1a;代碼隨想錄 思路&#xff1a; 題意隱含 只有一個冗余邊 #include <iostream> #include <vector> using namespace std; int n1001; vector<int>father(n,0);void init(){for(int i0;…

智能體通信協議

智能體通信協議A2AACPANPAgoraagents.jsonLMOSAITPA2A A2A官方文檔&#xff1a;https://www.a2aprotocol.net/docs/introduction 開源代碼和詳細規范&#xff1a;https://github.com/google/A2A ACP ACP官方文檔&#xff1a;https://acp.agentunion.cn ANP ANP官方文檔&am…

QT交叉編譯環境配置

QT交叉編譯環境配置1 配置交叉編譯工具鏈1.1 解壓 放到/opt中1.2 使用環境變量1.2.1 設置成永久的環境變量1.2.2 臨時環境變量1.3 安裝編譯需要的軟件2 編譯tslib庫&#xff08;如果不需要觸摸屏直接跳過&#xff09;3. 編譯qt3.1 編譯源碼3.2 設置QCreator4 說明4.1 關于編譯器…

【Android】【Java】一款簡單的文本/圖像加解密APP

寫在前面 之前寫過一篇博客,名為《【Java編程】【計算機視覺】一種簡單的圖片加/解密算法》,介紹了用Java在電腦上對圖片進行簡單的加密和解密操作,見鏈接: 文章鏈接 但是,文中所描述的算法在實際操作當中,存在嚴重的噪音(圖像失真)的問題(且原因不明),本次經筆者研…

技術筆記 | Ubuntu 系統 OTA 升級全流程詳解

前言&#xff1a;在嵌入式系統設備管理中&#xff0c;OTA&#xff08;Over-The-Air&#xff09;升級是實現設備遠程維護、功能迭代的核心能力。本文基于 Ubuntu 系統環境&#xff0c;詳細拆解 updateEngine 工具的 OTA 升級方案&#xff0c;從配置開啟、命令使用到實戰案例與問…

重復請求問題

重復請求問題 使用Promise和AbortController來實現思路是&#xff1a;通過在會話緩存中存儲和比較請求信息&#xff0c;來防止用戶在短時間內重復提交相同的請求。 具體思路如下&#xff1a; 存儲請求信息&#xff1a;每次請求時&#xff0c;將請求的相關信息&#xff08;如URL…

CentOS7 Docker安裝RocketMQ完整教程

目錄 前言 環境準備 系統要求 檢查Docker狀態 創建網絡和目錄 創建Docker網絡 創建數據目錄 安裝NameServer 啟動NameServer容器 參數說明 驗證NameServer啟動 安裝Broker 創建Broker配置文件 啟動Broker容器 參數說明 驗證Broker啟動 安裝管理控制臺 啟動控制…

main函數,常量指針與指針常量,野指針等,void與void的區別

指針&#xff08;續&#xff09; main函數原型 定義 main函數有多種定義格式&#xff0c;main函數也是函數&#xff0c;函數相關的結論對main函數也有效。 main函數的完整寫法&#xff1a;int main(int argc, char *argv[]){..}int main(int argc, char **argv){..}擴展寫法&am…

Mac m系列芯片安裝node14版本使用nvm + Rosetta 2

由于蘋果 M 系列芯片&#xff08;包括 M4&#xff09;使用的是 ARM 架構&#xff0c;而 Node.js 14 是在英特爾 x86 架構時代發布的&#xff0c;因此在 M 系列 Mac 上安裝 Node.js 14 可能會遇到兼容性問題 解決方法&#xff1a;使用 nvm Rosetta 2右鍵點擊「終端」→「顯示簡…

前端基礎之《Vue(26)—Vue3兩種語法范式》

一、選項式1、HTML寫法<!-- 跟 Vue 說 Hello World&#xff01; --><script type"module"> import { createApp } from vuecreateApp({data() {return {message: Hello World!}} }).mount(#app) </script><div id"app"><h1>…

題目:BUUCTF之rip(pwn)

網址 BUUCTF在線評測https://buuoj.cn/challenges#rip打開&#xff0c;如圖所示 提示&#xff1a;先別啟動靶機&#xff0c;靶機可以最后在啟動&#xff0c;先分析下載的附件pwn1。 點擊下載&#xff0c;下載完成之后&#xff0c;該文件后綴類型改為exe&#xff08;就是將pwn…

el-button長按觸發事件(含未響應的解決方案)

參考代碼實現按鈕長按觸發邏輯 <template><el-button mousedown"handleMouseDown" mouseup"handleMouseUp">長按我</el-button> </template>data(){return{isPressed: false,timer: null,}},methods:{handleMouseDown() {this.isP…

List和 ObservableCollection 的區別

1. 變更通知機制?? ??ObservableCollection<T>?? 實現了INotifyCollectionChanged和INotifyPropertyChanged接口&#xff0c;當集合元素被添加、刪除、替換或重置時&#xff0c;會自動觸發CollectionChanged事件&#xff0c;通知綁定的UI控件更新&#xff08;如WPF…

支付寶沙箱(白屏,用戶訂單參數錯誤等)

情況&#xff1a;Laravel項目的line 對接 支付寶沙箱測試 手機網站支付 1&#xff1a;沙箱地址&#xff0c;小到我找不到&#xff1a;沙箱應用 - 開放平臺 2&#xff1a;雖然提供了系統密鑰&#xff0c;但是只是測API鏈接的&#xff0c;要沙箱測試轉賬什么的&#xff0c;得用…

【NLP輿情分析】基于python微博輿情分析可視化系統(flask+pandas+echarts) 視頻教程 - 微博評論IP地圖可視化分析實現

大家好&#xff0c;我是java1234_小鋒老師&#xff0c;最近寫了一套【NLP輿情分析】基于python微博輿情分析可視化系統(flaskpandasecharts)視頻教程&#xff0c;持續更新中&#xff0c;計劃月底更新完&#xff0c;感謝支持。今天講解微博評論IP地圖可視化分析實現 視頻在線地…