【筆記】重學單片機(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/news/917487.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/917487.shtml
英文地址,請注明出處:http://en.pswp.cn/news/917487.shtml

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

相關文章

Arrays.asList() add方法報錯java.lang.UnsupportedOperationException

1. 問題說明 記錄一下遇到的這個bug&#xff0c;下面是段個簡化后的問題重現代碼。 public class Test {public static void main(String[] args) {List<Integer> list Arrays.asList(1, 2, 3);list.add(4);} }2. 原因分析 我們看一下Arrays.asList(…) 的源碼&#xff…

克羅均線策略思路

一個基于移動平均線的交易策略&#xff0c;主要通過比較不同周期的移動平均線來生成買賣信號。該策略交易邏輯思路和特點&#xff1a;交易邏輯思路1. 多頭交易邏輯&#xff1a;- 當當前周期的收盤價高于其4周期移動平均線&#xff0c;并且4周期移動平均線高于9周期移動平均線&a…

Go語言--語法基礎7--函數定義與調用--自定義函數

函數是基本的代碼塊&#xff0c;用于執行一個任務。Go 語言最少有 1 個 main() 函數。你可以通過函數來劃分不同功能&#xff0c;邏輯上每個函數執行的是指定的任務。函數聲明告訴了編譯器函數的名稱、返回類型和參數。函數三要素名稱 》功能參數 》接口返回值 》結果函數分類內…

Ollama模型庫模型下載慢完美解決(全平臺)

前言在我們從ollama下載模型時,會發現ollama最開始下載速度很快,能達到10-20MB/s但到了后期,速度就會越來越慢,最終降低到10-20kb/s下載一個模型大多需要1到1.5小時這是因為ollama服務器負荷過大的問題思路如果在下載中終斷下載,在用ollama run恢復下載,速度就會又提上去,但3-4…

web:js的模塊導出/導入

一般web頁面中&#xff0c;html文件通過標簽script引用js文件。但是js文件之間的引用要通過import/exprot進行導入/導出&#xff0c;同時還要在html文件中對js文件的引用使用type屬性標注。在下面的例子中&#xff0c;html頁面<!DOCTYPE html> <html lang"en&quo…

關于Web前端安全防御之安全頭配置

一、核心安全頭的作用 1. X-Content-Type-Options: nosniff 該響應頭用于阻止瀏覽器對資源的 MIME 類型進行 “嗅探”&#xff08;猜測&#xff09;&#xff0c;強制瀏覽器嚴格遵守服務器返回的 Content-Type 頭部聲明。 風險背景&#xff1a; 瀏覽器默認會對未明確聲明類型…

C++ : 反向迭代器的模擬實現

一、reverse_iterator.h#pragma once namespace txf { //外界傳什么類型的iteator&#xff0c;它就用什么iterator 初始化 , list用_list_iterator<T,T&,,T*> ,vector<T> 用T*template<class Iterator,class Ref,class Ptr>//在這個反向迭代器中涉及到…

自動化與配置管理工具 ——SaltStack

一、SaltStack 概述1.1 核心特性SaltStack 是一款開源的自動化運維工具&#xff0c;采用客戶端 - 服務器&#xff08;C/S&#xff09;架構&#xff0c;以高效、靈活和可擴展著稱。其核心特性包括&#xff1a;高性能架構&#xff1a;基于 ZeroMQ 消息隊列&#xff0c;支持大規模…

Rust → WebAssembly 的性能剖析全指南

一、用優化&#xff08;Release&#xff09;構建 ? 務必在做性能測量前使用 優化模式 構建你的 WASM。默認情況下&#xff1a; wasm-pack build → Release 優化wasm-pack build --dev 或 cargo build → Debug&#xff0c;性能大打折扣 優化編譯能開啟 LLVM 的各項優化和 LT…

第15屆藍橋杯Pthon青少組_國賽_中/高級組_2024年9月7日真題

更多內容請查看網站&#xff1a;【試卷中心 -----> 藍橋杯----> Python----> 國賽】 網站鏈接 青少年軟件編程歷年真題模擬題實時更新 第15屆藍橋杯Pthon青少組_國賽_中/高級組_2024年9月7日真題 一、單選題 第 1 題 單選題 下列運算符中&#xff0c;表示并集的…

【Django】-9- 單元測試和集成測試(上)

一、Django 項目單元 & 集成測試準備 &#x1f447;依賴安裝&#xff08;給項目裝 “測試小幫手”&#x1f37c;&#xff09;pdm add -d black isort flake8 pytest pytest-django pytest-coverage &#x1f449; 這行命令像在給項目 “采購” 測試工具&#xff1a;black …

VUE-第二季-01

目錄 1.Vue程序初體驗 1.1 下載并安裝vue.js 1.2 第一個Vue程序 1.3 Vue的data配置項 1.4 Vue的template配置項 1.5 Vue實例 和 容器 的關系是&#xff1a;一夫一妻制 2.Vue核心技術 2.0 Vue的模板語法 2.0.1 插值語法 插值語法總結&#xff1a; 2.0.2 指令語法 指…

Android 15 中禁用/啟用應用的系統級方法

在 Android 15 的開發中,有時我們需要以系統級權限來控制應用的啟用狀態。本文將介紹如何使用 PackageManager 來實現應用的禁用和啟用功能。 核心方法 在 Android 15 代碼中,可以使用以下方法來禁用或啟用應用: packageManager.setApplicationEnabledSetting(pkg,Packag…

2025網絡工程師技能圖譜(附思維導圖)

------------比較全面&#xff0c;供學習參考路線圖。-----------------------

【ROS2】rclcpp::Node 常用 API

ROS 系列學習教程(總目錄) ROS2 系列學習教程(總目錄) 目錄1. 構造函數2. 節點名稱相關3. 獲取log對象句柄4. 回調組相關5. Topic發布與訂閱6. Service服務端與客戶端1. 構造函數 public:Node(const std::string & node_name, const NodeOptions & options NodeOptio…

自動駕駛:技術、應用與未來展望——從開創到全面革新交通出行

一、引言1.1 研究背景與意義在過去的幾十年里&#xff0c;隨著科技的飛速發展&#xff0c;自動駕駛技術逐漸從科幻小說中的概念走進了現實生活。從最初簡單的輔助駕駛功能&#xff0c;到如今高度自動化的自動駕駛系統&#xff0c;這一領域的進步正深刻地改變著我們的出行方式和…

【gradle】插件那些事

文章目錄 1. 前言 2. 插件相關介紹 2.1 gradle插件的apply 2.2 引入自定義插件 2.3 常見構建任務 2.4 gradle生命周期 2.5 gradle的惰性屬性&可注入的服務 2.6 常見命令 檢查依賴樹 查看tasks 構建掃描 查看多項目構建的結構 顯示所選項目的構建腳本依賴項 指定控制臺模式來…

測試平臺如何重塑CI/CD流程中的質量協作新范式

測試平臺如何重塑CI/CD流程中的質量協作新范式 在DevOps革命席卷全球軟件行業的今天&#xff0c;測試的角色正在經歷前所未有的轉變。傳統的"測試最后"模式正在被"測試全程"的新理念所取代&#xff0c;這一轉變背后是測試平臺與CI/CD流程深度融合帶來的質量…

node.js不同環境安裝配置

node.js不同環境安裝配置 Windows環境安裝配置 一、Node.js是什么&#xff1f; ? Node.js是一個基于Chrome V8引擎的[JavaScript運行環境]。 Node.js使用了一個事件驅動、非阻塞式I/O 的模型&#xff0c;Node.js是一個讓JavaScript運行在服務端的開發平臺&#xff0c;它讓J…

深度學習-讀寫模型網絡文件

模型網絡文件是深度學習模型的存儲形式&#xff0c;保存了模型的架構、參數等信息。讀寫模型網絡文件是深度學習流程中的關鍵環節&#xff0c;方便模型的訓練、測試、部署與共享。1. 主流框架讀寫方法&#xff08;一&#xff09;TensorFlow保存模型可以使用 tf.saved_model.sav…