0x00 前言
6月份實驗室考覈,考覈的內容我也不知道(估計是 51,c,加點電分,或者數據結構?不知道),雖然是一些入門的東西,不過爲了萬無一失(誰也不敢說會不會出一些犄角旮旯的東西),還是從頭捋一遍。(菜雞瑟瑟發抖),先51看一下吧。我就拿
普中-51-A3的舉例了
0x01 最小系統板:
1.電源電路 2.復位電路 3.時鐘電路 4.下載電路
MCU
4個廣角,P0 P1 P2 P3 對應就行。
復位
RST 網絡標號 跟上述單片機的9腳相連,
1)當按鍵按下後,電源會經過按鍵,接入RST引腳進行復位(51單片機是進行高電頻復位)
2)不按的化,通過R與電容組成的RC充放電電路,進行復位
晶振電路
可以看出來是採用12兆晶振,兩邊c12 c13電容,接在單片機的18 19 腳。
電源電路 && 下載電路
通過下面的usb接口,接入電源,經過濾波電容進行濾波(圖中紅框處),緊接這連接D5V的開關,送到VCC,之後各部分纔有電,當沒有按下開關時,這個DIN5VS(5伏)只是和 CH340 這個芯片來識別串口,並沒有供電
P5短接板
CH340用的也是12兆晶振
下載時就利用RTS 和DTR高低電頻的變化,進行下載復位(STM就需要人爲了)
注意:CH340的位置一定要接地,不然會發燙。
0x02 LED
1.定義:LED,即發光二極管,是一種半導體固體發光器件。(寫上吧,萬一考呢)
2.LED的工作原理。 LED的符號爲: LED的工作是有方向性的,只有當正級接到LED陽極,負極接到LED的陰極的時候才能工作,如果反接LED是不能正常工作的。
3.原理圖
正入負出,所以陽極都接到了VCC(高電平)上,陰極串聯一個電阻接到了P2口,所以點亮的話把對應的P2口拉低就行。
流水:
#include <REGX51.H>
#include <intrins.h>
typedef unsigned char u8;
typedef unsigned int u16;
void delay(u16 i)
{
while(i--);//ͨ¹ýËÀÑ»·Õ¼ÓÃcpuÔËËãʱ¼äÀ´ÑÓʱ
}
void LED_WATER()
{
int i;
for (i = 0 ; i < 7; i++)
{
P2 = ~(0x01 << i);
delay(25000);
}
for (i = 0 ; i < 7; i++)
{
P2 = ~(0x80 >> i);
delay(25000);
}
}
void main()
{
P2 = ~(0x01);
delay(25000);
while(1)
{
LED_WATER();
}
}
(下面的代碼只寫關鍵部分)
0x03 蜂鳴器
有電路板的是無源蜂鳴器,沒有電路板的是有緣蜂鳴器(用黑膠封閉)
有源:在IO裏輸出一個電平就行 無源:電平 + 一定頻率脈衝
電磁式蜂鳴器由振盪器、電磁線圈、磁鐵、振動膜片及外殼等組成。 接通電源後,振盪器產生的音頻信號電流通過電磁線圈,使電磁線圈產生磁場,振動膜片在電磁線圈和磁鐵的相互作用下,週期性地振動發聲。
電磁式蜂鳴器由振盪器、電磁線圈、磁鐵、振動膜片及外殼等組成。 接通電源後,振盪器產生的音頻信號電流通過電磁線圈,使電磁線圈產生磁場,振動膜片在電磁線圈和磁鐵的相互作用下,週期性地振動發聲。
壓電式蜂鳴器主要由多諧振盪器、壓電蜂鳴片、阻抗匹配器及共鳴箱、外殼等組成。 多諧振盪器由晶體管或集成電路構成,當接通電源後(1.5~15V直流工作電壓),多諧振盪器起振,輸出1.5~2.5kHZ的音頻信號,阻抗匹配器推動壓電蜂鳴片發聲。
聲音
改變單片機引腳輸出波形的頻率,就可以調整控制蜂鳴器音調,產生各種不同音色、音調的聲音。
大小
改變輸出電平的高低電平佔空比,則可以控制蜂鳴器的聲音大小。、
原理圖
可以看到蜂鳴器BEEP接到了ULN2003D上,對應的是P2^5
ULN2003
放大電路,放大驅動電流
(下面是套話)
ULN2003 是高耐壓、大電流達林頓陳列,由七個硅NPN 達林頓管組成。 ULN2003是大電流驅動陣列,多用於單片機、智能儀表、PLC、數字量輸出卡等控制電路中。可直接驅動蜂鳴器、繼電器等負載 。
代碼
sbit bee = P2 ^ 5; //因爲是無源,所以要 脈衝+電平
void main()
{
bee = ~bee; //產生脈衝
delay(10);
}
0x04 數碼管
(因爲是複習,就不分靜態和動態了)
顯示器&&接口
LED顯示器有兩種:段顯示(7段,米字型等)和點陣顯示
LED數碼管根據LED的不同接法可分爲2類:共陰和共陽。
(A3裏沒有單個的,這是別人的圖)
共陰就是陰極接地,所以要是亮就得輸入高電平
共陽就是陽極接vcc,所以要是亮就得輸入低電平
共陽極數碼管編碼表:
unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
共陰極數碼管編碼表:
unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
原理圖:
引腳對應着 P0,看一眼P0口:
共陽,低電平有效
注意:P0口是露底開路的,如果不加上拉電阻(VCC)的話,對P0無法進行輸入輸出的控制。
使能
鎖存器:74HC245 (一般是74HC573,這個普中A3的板子有點神奇)
簡單地說鎖存器就是一個緩存器,它能保存上一次的狀態,自帶使能端口,清零端口。當使能端有效時,則左右兩端導通,否則斷開。
74HC245:
7HC573 :通常配合或非門(74HC02)使用
138譯碼器
74HC138 簡單地說138譯碼器將一個特殊的編碼翻譯成一個狀態。
代碼:(因爲普中這個板子,138譯碼器,接的是P2^2,P2^3,P2^4,有些麻煩,爲了直觀代碼如下)
sbit lsa=P2^2;
sbit lsb=P2^3;
sbit lsc=P2^4;
void wei_poc(u8 poc)
{
switch(poc)
{
case 0:
lsa=1;lsb=1;lsc=1;break;
case 1:
lsa=0;lsb=1;lsc=1;break;
case 2:
lsa=1;lsb=0;lsc=1;break;
case 3:
lsa=0;lsb=0;lsc=1;break;
case 4:
lsa=1;lsb=1;lsc=0;break;
case 5:
lsa=0;lsb=1;lsc=0;break;
case 6:
lsa=1;lsb=0;lsc=0;break;
case 7:
lsa=0;lsb=0;lsc=0;break;
}
}
在藍橋杯裏有方便的寫法。
動態數碼管
動態顯示的特點是將所有數碼管的段選線並聯在一起,由位選線控制是哪一位數碼管有效。選亮數碼管採用動態掃描顯示。所謂動態掃描顯示即輪流向各位數碼管送出字形碼和相應的位選,利用發光管的餘輝和人眼視覺暫留作用,使人的感覺好像各位數碼管同時都在顯示。動態顯示的亮度比靜態顯示要差一些,所以在選擇限流電阻時應略小於靜態顯示電路中的。
說白了就是利用視覺殘留,讓多個靜態數碼管循環亮起。
代碼
u8 code DUANXUAN[]={ //標準字庫
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
//black - H J K L N o P U t G Q r M y
0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8.
void SMC_Bit(u8 dat, u8 poc)
{
P0 = ~DUANXUAN[dat];//段
wei_poc(poc);//位
}
void SMC_Display()
{
SMC_Bit(1,0);
delay(500);
SMC_Bit(0,0);//消影
SMC_Bit(2,1);
delay(500);
SMC_Bit(0,1);//消影
SMC_Bit(3,2);
delay(500);
SMC_Bit(0,2);//消影
SMC_Bit(4,3);
delay(500);
SMC_Bit(0,3);//消影
SMC_Bit(5,4);
delay(500);
SMC_Bit(0,4);//消影
SMC_Bit(6,5);
delay(500);
SMC_Bit(0,5);//消影
SMC_Bit(7,6);
delay(500);
SMC_Bit(0,6);//消影
SMC_Bit(8,7);
delay(500);
SMC_Bit(0,7);//消影
}
(代碼要結合前文,注意一下自己的是共陰還是共陽)
0x05 獨立按鍵
按鍵的兩個引腳,一端通過電阻上拉到高電平,另一端接地。
沒有按鍵按下時,輸入引腳爲高電平。
有按鍵按下時,輸入引腳爲低電平。
掃描:通過反覆讀取按鍵輸入引腳的信號,然後識別高低電平來判斷是否有按鍵觸發。
去抖動
(別人的圖)
首次檢測到輸入引腳有低電平後,稍做延時,再次讀取該引腳,如果確實是低電平,則觸發,否則就是干擾信號。
原理圖:
代碼:
-------------------------------------
按鍵按下,L1燈亮;
按鍵鬆開,L1燈滅;
-------------------------------------
sbit K1 P3^1;
sbit L1 P2^0;
void ScanKeys_Alone()
{
if (K1 == 0)
{
delay(100);
if(K1 == 0)
{
L1 = 0; //按鍵按下,L1燈亮
while(K1 == 0); //分界線
L1 = 1; //按鍵鬆開,L1燈滅
}
}
}
要注意,按下和鬆開的位置。
0x06 矩陣按鍵
小蜜蜂老師這篇寫得很仔細:https://www.cnblogs.com/ALittleBee/p/8411771.html
下面是我摘抄的一些:
與獨立按鍵不同的是,按鍵的兩個引腳都分別連接的單片機的I/O端口,一個作爲行信號,另外一個作爲列信號。我們以4X4的矩陣鍵盤爲例,試着探討其工作方式和掃描思路。
在上面的矩陣鍵盤中,要識別出黃色按鍵的按下狀態,應該怎麼做呢?
對與矩陣鍵盤,我們只能逐行掃描,然後讀取列的狀態信號。如果R3行輸出低電平,那麼黃色按鍵如果有按下動作的話,那讀取C2列信號也應該爲低電平,而該行上其他沒有按下動作的按鍵的列信號則爲高電平。因此,我們可以得到矩陣鍵盤的基本掃描步驟:
<1> R1輸出點電平,R2、R3、R4輸出高電平,逐個讀取判斷列信號,如果都爲高電平則R1行上沒有按鍵按下。
<2> R2輸出點電平,R1、R3、R4輸出高電平,逐個讀取判斷列信號。
<3> R3輸出點電平,R1、R2、R4輸出高電平,發現C2列信號爲低電平,那麼可以判斷得R3行的C2列的按鍵有按下動作。
<4> R4輸出點電平,R1、R3、R4輸出高電平,逐個讀取判斷列信號。
如此循環往復,掃描的按鍵的狀態。
我們知道有按鍵按下動作,那麼又怎麼知道是哪一個按鍵按下呢?這時,我們最好定義一個鍵值全局變量,給矩陣行列上的每一個的按鍵編一個唯一的號碼。當掃描的某一行某一列的按鍵動作後,把對應的編號複製給鍵值變量,這樣我們判斷這個鍵值,就知道是那個按鍵有觸發動作了。
代碼:
原理圖:
sbit R1 = P1^7;
sbit R2 = P1^6;
sbit R3 = P1^5;
sbit R4 = P1^4;
sbit C1 = P1^3;
sbit C2 = P1^2;
sbit C3 = P1^1;
sbit C4 = P1^0;
void ScanKeys()
{
keyNum = 16;//黑屏
R1 = 0;
R2 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
while(C1 == 0);
keyNum = 0;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C2 == 0)
{
while(C2 == 0);
keyNum = 1;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C3 == 0)
{
while(C3 == 0);
keyNum = 2;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C4 == 0)
{
while(C4 == 0);
keyNum = 3;
ShowKeyNum(SMG_NoDot[keyNum]);
}
R2 = 0;
R1 = R3 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
while(C1 == 0);
keyNum = 4;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C2 == 0)
{
while(C2 == 0);
keyNum = 5;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C3 == 0)
{
while(C3 == 0);
keyNum = 6;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C4 == 0)
{
while(C4 == 0);
keyNum = 7;
ShowKeyNum(SMG_NoDot[keyNum]);
}
R3 = 0;
R2 = R1 = R4 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
while(C1 == 0);
keyNum = 8;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C2 == 0)
{
while(C2 == 0);
keyNum = 9;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C3 == 0)
{
while(C3 == 0);
keyNum = 10;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C4 == 0)
{
while(C4 == 0);
keyNum = 11;
ShowKeyNum(SMG_NoDot[keyNum]);
}
R4 = 0;
R2 = R3 = R1 = 1;
C1 = C2 = C3 = C4 = 1;
if(C1 == 0)
{
while(C1 == 0);
keyNum = 12;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C2 == 0)
{
while(C2 == 0);
keyNum = 13;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C3 == 0)
{
while(C3 == 0);
keyNum = 14;
ShowKeyNum(SMG_NoDot[keyNum]);
}
else if(C4 == 0)
{
while(C4 == 0);
keyNum = 15;
ShowKeyNum(SMG_NoDot[keyNum]);
}
}
按鍵掃描有很多種寫法,這是一種好理解,引腳比較靈活,但是笨笨的寫法。
下面這種,需要引腳比較規則時比較方便:
void KeyDown()
{
io_Key=0x0f; //行
if(io_Key !=0x0f) //判斷是否按下
{
delay(1000); //去抖動
if(io_Key !=0x0f)
{
io_Key =0x0f; //行
switch(io_Key)
{
case 0x07:
KeyValue=0;break;
case 0x0b:
KeyValue=1;break;
case 0x0d:
KeyValue=2;break;
case 0x0e:
KeyValue=3;break;
}
io_Key =0xf0; //列
switch(io_Key)
{
case 0x70:
KeyValue=KeyValue;break;
case 0xb0:
KeyValue=KeyValue+4;break;
case 0xd0:
KeyValue=KeyValue+8;break;
case 0xe0:
KeyValue=KeyValue+12;break;
}
while((a<50) && io_Key!=0xf0)
{
delay(1000);
a++;
}
}
}
}
0X07 中斷系統
參考文章https://bbs.21ic.com/icview-2477100-1-1.html(小蜜蜂老師賽高)
在執行cpu當前程序時,由於系統中出現了某種急需處理的情況,cpu暫停正在執行的程序,轉而去執行另外一段特殊的程序來處理出現的緊急事務,處理結束後,CPU自動返回到原來暫停的程序中去繼續執行。這種程序在執行過程中由於外界的原因而被中間打斷的情況,成爲中斷。
圖解:
引起CPU中斷的根源,稱爲中斷源。中斷源向CPU提出的中斷請求。CPU暫時中斷原來的事務A,轉去處理事件B。對事件B處理完畢後,再回到原來被中斷的地方(即斷點),稱爲中斷返回。實現上述中斷功能的部件稱爲中斷系統。
中斷服務函數:內核響應中斷後執行的相應處理程序。
中短向量:中斷服務函數的入口地址。每個中斷源都對應一個固定的入口地址。當內核響應中斷請求時,就會暫停當前的程序執行,然後跳轉到該入口地址執行代碼。
注意:有中斷請求不一定能打斷主程序。
隨着計算機技術的應用,人們發現中斷技術不僅解決了快速主機與慢速I/O設備的數據傳送問題,而且還具有如下優點: 分時操作。CPU可以分時爲多個I/O設備服務,提高了計算機的利用率;
實時響應。CPU能夠及時處理應用系統的隨機事件,系統的實時性大大增強;
可靠性高。CPU具有處理設備故障及掉電等突發性事件能力,從而使系統可靠性提高。
(以上看一眼瞭解一下,萬一考呢,下面說正事)
中斷系統
一般來說,51單片機有5箇中斷源(忽略定時/計數器2),分2個優先級,這個5箇中斷源按照自然優先級從高到低依次爲:
外部中斷0:INT0
定時/計數器0:TF0
外部中斷1:INT1
定時/計數器1:TF1
串口中斷:RI/TI
(圖一)
每個中斷源都對應着一個固定的入口地址,也就是中斷向量,它們依次是:
0 0x0003: INT0
1 0x000B: TF0
2 0x0013: INT1
3 0x001B: TF1
4 0x0023: RI/TI
也就是說,不管主程序執行到什麼地方,只要外部中斷1產生請求,內核要響應該中斷,就會到0x0013這個地址去執行代碼。如果你是在使用彙編語言進行程序開發的時候,你需要記住每個中斷源對應的地址;如果你使用的是C語言,你只需要記住中斷源的順序就可以了,也就是最左邊的中斷號。
寄存器
中斷相關的寄存器有4個,每個寄存器都是可以位尋址的,這該編程帶來了方便。 其中2個爲控制寄存器:IE寄存器與IP寄存器:
另外2個爲中斷請求標誌:TCON寄存器與SCON寄存器:
代碼
/////////////////////////////==中斷0==///////////////
void Init_INT0()//觸發方式
{
IT0 = 1;//下降沿觸發
EX0 = 1;//中斷使能打開
EA = 1;//總中斷打開
}
void ServiceINT0() interrupt 0
{
......//終端服務函數的編寫
}
///////////////////////////==中斷0_end==////////////
(Init_INT0()函數結合 圖一 去看)
0x08 定時/計數器
參考文章:https://bbs.21ic.com/icview-2477676-1-1.html
作爲定時器時,計數信號的來源選擇週期性的內部時鐘脈衝;用作計數器時,計數信號的來源選擇非週期性的外部輸入信號。
本質上都是計數器
計算:
51單片機有兩個定時/計數器T0和T1,爲16位加法計數器,由低8位TLx和高8位THx兩個寄存器組成,最大計數值爲65535個計數脈衝。
原理: 每接收到一個計數脈衝,計數器就會加1,當計數值累計至全爲1時(8位255,13位8191,16位65535),再輸入一個計數脈衝,計數器便會溢出回零,並且計數器的溢出是TCON寄存器的TF0或TF1位置1,同時向內核提出中斷請求。如果定時/計數器工作於定時模式,則表示間隔定時時間到,如果工作與計數模式,則表示計數值已滿。
假設單片機的外部晶振爲12MHz,那麼,經過12分頻後輸入計數器的計數脈衝爲1MHz,即每個脈衝的週期爲1us。因此定時器T0的16位工作模式最大的定時時間爲65535us,65.5ms。如果要定時10ms的話,計數器就不能夠從0開始計數了,必須給它一個計數初值。怎麼計算這個初值呢?
要定時10ms,則相當於計數10000個脈衝後計數器的值就到達65535了,那麼開始計數的這個地方就是計數初值。
65535 - 10000 = 55535 = 0xd8ef
把這個計算得到的初值寫入TH0和TL0寄存器即可:
TH0 = 0xd8;或者 TH0 = (65535 - 10000) / 256;
TL0 = 0xef; 或者 TL0 = (65535 - 10000) % 256;
當然明白了,上述文章中還有個例題,也是同樣的計算方法(具體見上述文章)。
寄存器
除了除了計數初值寄存器THx和TLx之外,還有TMOD寄存器和TCON寄存器
(小蜜蜂的圖)
TCON:見上段落(中斷)所寫。
代碼:
void Init_T0()//需要配置TMOD THX TLX ET0 EA TR0
{
//TMOD: GATE = 0; c/t = 0; M1,M0 = 0x01
TMOD = 0X01;
//初值5ms * 100 = 0.5s
TH0 = (65535 - 50000) / 256;//高8位
TL0 = (65535 - 50000) % 256;//低8位
//打開使能
ET0 = 1;
//總中斷
EA = 1;
TR0 = 1;
}
void ServiceT0() interrupt 1
{
//因爲沒有打開自動重裝載,所以要重新配置
TH0 = (65535 - 50000) / 256;//高8位
TL0 = (65535 - 50000) % 256;//低8位
......//編寫服務函數
}
(定時器通常與全局變量相結合來編寫)
0x09 串口通信
串口通信的概念有很多,這裏只講述博主認爲重要的(重要的意思就是感覺能考的(手動滑稽))
一些概念:
串行 && 並行:
串行通信:是將數據字節分成一位一位的形式在 一條傳輸線上逐個地傳送。
串行通信的特點:傳輸線少,長距離傳送時成本低,且可以利用電話網等現成的設備,但數據的傳送控制比並行通信複雜。
並行通信:通常是將數據字節的各位用多條數據線同時進行傳送 。
並行通信的特點:並行通信控制簡單、傳輸速度快;由於傳輸線較多,長距離傳送時成本高且接收方的各位同時接收存在困難。
通信種類:
在51中一般是串行,在此不談並行,串行通信有SPI,IIC,UART,大多數,串行通信指的就是UART.
傳輸方向:
單工是指數據傳輸僅能沿一個方向,不能實現反向傳輸。
半雙工是指數據傳輸可以沿兩個方向,但需要分時進行。
全雙工是指數據可以同時進行雙向傳輸。
通信方式:
異步通信:通信中雙方的比特率要保持一致。以字符爲單位進行數據幀傳輸,一次一幀。
同步通信:需要同一個時鐘,以數據塊傳輸。
比特率:
串口每秒傳輸的位數。
在51中有4種模式:
模式1,3,由定時器1的溢出率決定,波特率可變
通常用模式2 因爲是由定時器1的8位自動重裝載產生,當TH1溢出時,自動裝到TL1去。
波特率怎麼算的就大致看一下把(瞭解爲主)主要是圖中後兩行話
串口通信有2個緩衝寄存器SBUF,一個發送,一個接收,物理上完全獨立,字節尋址(99h).
發送:自動發完之後,TI標誌位置1。
SBUF = 0x00; //發送
接收:自動接收之後,RI標誌位置1。
變量 = SBUF; //接收到一個變量裏
SCON
(小蜜蜂的圖)
記住SCON = 0x50,類似藍橋杯的板子還需要設置AUXR,普中A3就不用了。
代碼:
// sfr AUXR=0x8e; //藍橋杯要用
//--------------------------------------
unsigned char tmpRecv;
void Init_Uart()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd;
TR1=1;
SCON = 0x50;
ES=1;
EA=1;
// AUXR &= 0x40; //藍橋杯要用
}
/*==============發送一個字節===============*/
void SendByte(unsigned char dat)
{
SBUF = dat;
while(TI == 0);
TI = 0;
}
/*=============服務函數================*/
void Sevice_Uart() interrupt 4
{
if(RI == 1)
{
RI = 0;
tmpRecv = SBUF;//接收
SendByte(tmpRecv + 1);//再發出去 (接收的值 + 1)
}
}
當然這裏也給出穿字符串的寫法:
void Send_Byte(u8 dat)
{
SBUF = dat;//發送
while(TI == 0);
TI = 0;
}
void Send_Str(u8* str)
{
while(*str != '\0')
{
Send_Byte(*str++);
}
}
0x0A 總結
因爲篇幅的原因,51單片機的外設芯片,pwm之類的放到下一章去寫,本文是博主的複習,借用了小蜜蜂和普中的一些素材。
因爲是複習,所以點了一些博主覺得會考的知識點,放了一些博主用慣了的代碼。如有不正確的地方,請路過的大佬斧正,希望可以幫助到各位看官,(下一篇是外設芯片篇)。