一.基本概念
????????1.裸機程序? BSP?
? ? ? ? ????????BSP:bord suppord pack? 板級支持包
? ? ? ? ????????就是程序編寫的內容是沒有操作系統的,直接通過代碼去控制寄存器,讓硬件按照要求去工作。
? ? ? ? ????????主要內容:51單片機? ? ?IMAX6ULL
????????2.linux驅動部分
? ? ? ? ????????在裸機BSP程序的基礎上,把對硬件管理的方法,算法,流程,挪到linux系統中,讓linux能識別,操作硬件,相當于程序建立在linux系統上。
? ? ? ? ????????主要內容:系統移植? ?驅動
? ? ? ?3.CPU、MPU、GPU、MCU
1. CPU(Central Processing Unit)中央處理器
功能: 電腦和大多數電子設備的“核心大腦”,負責執行程序指令、進行運算和控制數據流。
常見于: 電腦、手機、平板等。
特點: 通用性強,適合復雜多任務處理。
2. GPU(Graphics Processing Unit)圖形處理器
功能: 專門用于圖形、圖像、視頻的渲染和并行處理,也被廣泛用于AI計算。
常見于: 游戲顯卡、AI訓練服務器、手機、圖形工作站。
特點: 并行處理能力強,適合執行大量相同操作(如矩陣計算)。
3. MPU(Microprocessor Unit)微處理器單元
功能: 一種更小、更簡單的 CPU,常用于嵌入式系統中(如洗衣機、微波爐)。
常見于: 工業控制、小型智能設備。
特點:
沒有內置內存(RAM、ROM)或IO接口,需要外接。
更靈活但需要更多外圍電路。
4. MCU(Microcontroller Unit)微控制器單元
功能: 一體化的嵌入式系統,集成了 CPU(或MPU)、內存、I/O接口等。
常見于: 家電、汽車、智能硬件、IoT設備。
特點:
集成度高(“一顆芯片搞定一切”)
功耗低、成本低、適合簡單控制任務
簡單對比總結表:
縮寫
全稱
用途
是否集成RAM/ROM
應用舉例
CPU
Central Processing Unit
通用計算
否
PC、筆記本、服務器
GPU
Graphics Processing Unit
圖像處理、并行計算
否
顯卡、AI服務器
MPU
Microprocessor Unit
嵌入式計算(需要外設)
否
工控板、定制電子系統
MCU
Microcontroller Unit
嵌入式控制(單芯片系統)
是
空調、遙控器、智能燈泡
如果你想了解這些在某個具體應用(如AI、嵌入式、機器人)中的角色,我可以進一步解釋。
? ? ? ? 4.寄存器
????????在數字電路中,用來存放二進制數據或代碼的電路稱為寄存器。
? ? ? ? 外設寄存器有固定的地址。
? ? ? ? 5.RAM和ROM
????????
ROM(只讀存儲器)和 RAM(隨機存取存儲器)是計算機中兩種常見的內存類型,它們在功能、特性和用途方面有顯著區別。以下是詳細的概念與對比:
一、ROM(Read-Only Memory)只讀存儲器
1. 概念:
ROM 是只能讀取、不能隨意寫入的內存。
數據在斷電后仍然保留,屬于非易失性存儲器。
通常由廠家在生產時寫入數據,主要用于保存固件(Firmware),如 BIOS(基本輸入輸出系統)。
2. 特點:
數據不可更改或只能有限更改(如 EEPROM 可多次擦寫,但速度慢)。
通常存儲啟動程序、硬件初始化信息等關鍵內容。
啟動時首先讀取 ROM 中的內容來引導系統。
二、RAM(Random Access Memory)隨機存取存儲器
1. 概念:
RAM 是可讀寫的內存,數據可以隨時讀寫。
數據在斷電后會丟失,屬于易失性存儲器。
是 CPU 執行程序時的臨時工作區域,用來存儲正在運行的程序和數據。
2. 特點:
訪問速度快,是系統運行的關鍵。
包括兩類:
DRAM(動態 RAM):常用作主內存,成本低,需不斷刷新。
SRAM(靜態 RAM):速度更快,用于緩存,如 CPU 的緩存(Cache)。
三、ROM 與 RAM 的主要區別對比表
項目
ROM
RAM
全稱
Read-Only Memory
Random Access Memory
讀寫性
通常只讀
可讀可寫
易失性
非易失性(斷電不丟失)
易失性(斷電數據丟失)
用途
存儲固件、啟動程序(如 BIOS)
存儲臨時數據和程序運行信息
是否可修改
通常不可修改(或需特定方法修改)
可隨時讀寫
速度
較慢
較快
例子
BIOS、固件、游戲卡帶中的程序
操作系統加載后使用的內存、緩存等
四、簡單類比
你可以把它們比作:
ROM:像一本印刷好的說明書,只能看不能寫(或要特別工具才能改),斷電不會丟失。
RAM:像一塊寫字板,你可以隨便寫寫擦擦,但一斷電內容就沒了。
如需我進一步解釋 EEPROM、Flash ROM 或是 RAM 的擴展類型如 DDR4/DDR5 等,也可以繼續問我!
二.環境搭建
1.keil安裝
2.STC-ISP
? ? ? ? 下載使用。
三.工程??
? ? ? ? 1.LED
? ? ? ? ? ? ? ? 1.原理圖
從原理圖得知是P2寄存器,控制8個led燈,高電平關,低電平開。
? ? ? ? ? ? ? ? 2.位運算
????&= :是讓指定位置0;
? ? ? ? ? ?P2 &= ~(1 << 0):就是讓bit0位為0,打開。
?? ?|=:是讓指定位置1;? ? ? ? ???P2 |= 1 << 0?:就是讓bit0位為1,關閉。
?? ?^=:是讓指定位反轉;? ? ? ? ? ?P2 ^= 1<< 0:就是讓bit0位反轉
? ? ? ? ? ? ? ? 3.代碼
led.c
#include "led.h"
#include <reg52.h>//初始化
void init_led(void)
{P2 = 0xff;
}
//打開某個燈
void led_on(unsigned char n) //1111 0000
{P2 = ~n;
}
//打開所有燈
void led_all_on()
{P2 = 0x00;
}
//關閉某個燈
void led_off(unsigned char n)
{P2 = n;
}
//關閉所有燈
void led_all_off()
{P2 = 0xff;
}
//反轉某個燈
void led_nor(unsigned char n)
{P2 ^= n;
}
//反轉所有燈
void led_all_nor()
{P2 ^= 0xff;
}
main.c
#include <reg52.h> //register
#include "led.h"
//延時
void Delay(unsigned int xms)
{while (xms--) //每次需要10us{}
}
int main(void)
{unsigned char i = 1;int n = 0;init_led();//全部反轉
// while(1)
// {
// led_all_nor();
// Delay(0x3fff);
// }//來回跑流水燈while(1){for(n = 0;n < 7;++n){led_on(i);Delay(0x3fff);i <<= 1;if(n == 6){for(n = 0;n < 7;++n){led_on(i);Delay(0x3fff);i >>= 1; }}}}
}
led.h
#ifndef _LED_H_
#define _LED_H_extern void init_led(void);
extern void led_on(unsigned char n);
extern void led_all_on();
extern void led_off(unsigned char n);
extern void led_all_off();
extern void led_nor(unsigned char n);
extern void led_all_nor();#endif
????????2.digister
? ? ? ? ? ? ? ? 1.原理圖
????????有四個顯示,分別由P10,P11,P12,P13控制,當為高電平的時候,打開相應的數碼管。
? ? ? ? abcdefg dp由P0寄存器控制,當為1的時候,相應的位置亮起來。
? ? ? ? ? ? ? ? 2.代碼
?digister.c
#include <reg52.h>
#include "digiter.h"void bit_select(int n)
{P1 &= ~(0x00ff << 0); //全部置0P1 |= (1 << n); //bit n位置1
}void seg_select(int n)
{ //定義一個顯示0~9數字對應寄存器狀態的數組code unsigned char segs[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};P0 = segs[n];
}void display(int n)
{int t = 0;while(n != 0){int m = n % 10;P0 = 0;bit_select(t++);seg_select(m);Delay(300);n /= 10;}}
????????code是把這個數組變量放在ROM區,不是放在RAM區。
main.c
#include <reg52.h>
#include "digiter.h"
void Delay(unsigned int num)
{while(num--){}
}int main(void)
{int i = 0;while(1){//for(i = 0;i < 10;++i)//{// bit_select(0);// seg_select(i);// Delay(0xffff);//}display(i++);if(i > 9999){i = 0;}}}
digister.h
#ifndef _DIGITER_H_
#define _DIGITER_H_extern void bit_select(int n);
extern void seg_select(int n);#endif
? ? ? ? 3.key
? ? ? ? 1.? 原理圖
這是輸入,當按鍵按下去之后,拉低P1,從而通過判斷P1的狀態而做相應的處理。?
? ? ? ? 2.代碼
void init_key(void)
{P1 |= (0x0f << 4);
}int key_pressed(void)
{int ret = 0;if((P1 & (1 << 4)) == 0){ret = 1;}else if((P1 & (1 << 5)) == 0){ret = 2;}else if((P1 & (1 << 6)) == 0){ret = 3;}else if((P1 & (1 << 7)) == 0){ret = 4;}return ret;
}
????????4.中斷
? ? ? ? 1.概念
????????當中央處理機CPU正在處理某件事的時候外界發生了緊急事件請求,要求CPU暫停當前的工作,轉而去處理這個緊急事件,處理完以后,再回到原來被中斷的地方,繼續原來的工作,這樣的過程稱為中斷。
? ? ? ? 2.五個中斷源
????? ? 51單片機有五個中斷源:外部中斷0(INTO)定時器0中斷、外部中斷1(INT1)、定時器1中斷、串口(UART)中斷、定時器2中斷。對應的中斷號。
????????3.中斷流程
1.中斷源發出中斷請求
2.CPU檢查是否響應中斷及該中斷源是否被屏蔽;
3.檢測中斷優先級;
4.保護現場;
5.執行中斷服務函數;
6.恢復現場
? ? ? ? 4.中斷向量
????????中斷向量表:是一個函數指針數組,數組里面保存中斷服務函數的入口地址。51單片機的中斷向量有五種:外部中斷0/1,timer0/1,串口。
? ? ? ? 5.中斷和輪詢區別
中斷(Interrupt)和輪詢(Polling)是兩種常見的CPU與外設通信方式,它們在處理外設請求、數據傳輸等方面有明顯區別:
? 一、定義
方式
定義
輪詢(Polling)
CPU定期主動查詢外設是否需要服務,一直輪詢外設狀態。
中斷(Interrupt)
外設在需要服務時主動向CPU發出中斷請求,CPU暫停當前工作來響應外設。
? 二、工作原理
🔁 輪詢
CPU執行主程序的同時,定期檢查設備狀態。
如果設備準備好了,就處理它的請求;否則繼續主程序。
不停檢查,浪費資源。
?中斷
外設完成某個操作或需要處理時,向CPU發送中斷信號。
CPU暫停當前任務,保存現場,跳轉到中斷服務程序(ISR)處理外設請求,處理完再恢復原任務。
? 三、對比總結
項目
輪詢(Polling)
中斷(Interrupt)
主動方
CPU
外設
CPU效率
低(忙等待)
高(只在需要時才響應)
實時性
差,響應不及時
好,可快速響應事件
實現復雜度
簡單
復雜(需中斷機制、ISR等)
適用場景
少量設備、實時性要求不高的場景
設備多、實時性要求高的場景
資源占用
高,占用CPU時間
低,CPU可做其他任務
? 舉個例子
假設你在等一個包裹:
輪詢:你每5分鐘就下樓查看快遞到了沒(浪費時間、效率低)。
中斷:快遞員來了按門鈴,你再下樓取(只在必要時行動,效率高)。
如果你需要進一步了解硬件電路實現或在單片機(如STM32、8051)中如何設置中斷和輪詢,我也可以繼續說明。
????????6.代碼
? ? ? ? 1.外部中斷
int g_i;
void eint0_handler(void) interrupt 0
{++g_i;
}
void eint1_handler(void) interrupt 2
{--g_i;
}void init_einto(void)
{P3 |= (1 << 2) | (1 << 3);IE |= (1 << 7) | (1 << 0) |( 1<< 2);TCON |= (1 << 0) | (1 << 2);}
? ? ? ? ? ? ? ? 2.定時器中斷
?
#include <reg52.h>
#include "timer.h"
#include "led.h"#define HZ200 63231unsigned g_n = 0;
void timer_handler(void) interrupt 1
{
// TH0 = 64613 >> 8;
// TL0 = 64613;
// ++g_n;
// if(g_n >= 100)
// {
// led_all_nor();
// g_n = 0;
// }TH0 = HZ200 >> 8;TL0 = HZ200;P2 ^= (1 << 1);}void init_timer(void)
{TMOD &= ~(0x0f << 0);TMOD |= (1 << 0);
// TH0 = 64613 >> 8;
// TL0 = 64613;TH0 = HZ200 >> 8;TL0 = HZ200;IE |= (1 << 7) | (1 << 1);TCON |= (1 << 4);}
TH0 = HZ200 >> 8;TL0 = HZ200;P2 ^= (1 << 1);
?????????這里高將counter的值的高八位保存在TH0中,所以將counter向右移動8位,那么低八位原來的位置就變成高八位,一個TH0占8位,剛好存放高八位。
? ? ? ? 低八位直接賦值,高八位丟失,那么TL0剛好存放低八位。
???????5.定時器
? ? ? ? 工作原理:配置TMOD確認工作模式和計數來源,再向TH0/TL0寫入計數初值,工作開始后計數溢出時,觸發中斷服務函數。
? ? ? ? 1.定時器計算
????????以16位的定時器舉例,如何計算定時器
????????16位 = 2^16 - 1 = 65535,定義計數的值位unsigned short 類型,當超過65535的時候,counter0就會變成0。
? ? ? ? 晶振的頻率為12MHz,12分頻之后,cpu 的工作頻率就是1MHz。
? ? ? ? 假如要一個1ms刷新的值,那么 1MHz的情況下, 1 / 1M秒,counter0加1,也就是1us加1,要想1ms刷新,那么就需要conunter就要加1000次,也就是將counter的初始值設定為65535-1000 = 64534,這樣1000次之后coeunter變成0。實現1ms。
? ? ? ? 65535 - 0.001 /(1 / 1000000) =? 65535 - 1000 = 64535.
? ? ? ? 2.PWM
? ? ? ? 1.概念
PWM(脈寬調制,Pulse Width Modulation)是一種通過改變**脈沖信號高電平持續時間(即“脈寬”)**來控制模擬量輸出的技術。它常用于電機控制、LED調光、音頻合成等應用中。
? 一、PWM是什么?
PWM 是一種數字方式模擬連續模擬信號的方法:
高電平表示“開”,低電平表示“關”
通過控制高電平持續的比例(占空比)來調節輸出的平均電壓
雖然是開關信號,但其平均電壓對外表現為模擬值
? 二、PWM的波形特征
PWM波形是一種周期性方波,每一個周期內:
有一段時間是高電平(ON)
剩余時間是低電平(OFF)
? 三、PWM的關鍵指標
指標名稱 含義說明 頻率(Frequency) PWM信號的周期性重復速率,單位是 Hz。頻率 = 1 / 周期時間。 周期(Period) 一次完整高+低電平持續的總時間。周期 = 高電平時間 + 低電平時間。 占空比(Duty Cycle) 高電平持續時間占一個周期的百分比。占空比 = 高電平時間 / 總周期時間 × 100% 分辨率(Resolution) PWM占空比的可調精度,常用位數表示,如8位(256級)、10位(1024級)等。 幅度(Amplitude) 高電平電壓的大小,例如3.3V、5V等。通常由電源電壓決定。
? 四、PWM平均電壓計算
PWM 實際輸出的 平均電壓 可以表示為:
Vavg=占空比×V高電平V_{\text{avg}} = 占空比 \times V_{\text{高電平}}例如:5V PWM,占空比為 60% ? 平均電壓 = 5V × 0.6 = 3V
? 五、PWM應用舉例
應用場景 PWM作用 LED調光 改變LED亮度(占空比高 → 更亮) 電機調速 控制電機平均電壓,調節轉速 音頻輸出 生成模擬音頻信號 伺服控制 控制舵機角度(特定脈寬映射角度)
如果你在使用具體平臺(如STM32、Arduino、ESP32)開發PWM應用,我也可以幫你講解代碼和硬件細節。是否需要這方面的幫助?
? ? ? ? 2. 200Hz,50%占空比的PWM怎么計算
????????
? ? ? ? 200hz 就是 1 / 200 = 0.005秒刷新一次,PWM占空比是50%,也就是高低電平的時間各占一半,那么高電平的保持時間為0.0025,
? ? ? ? 65535 - 0.0025 / (1 / 1000000) =? 65535? -? 2500 = 63235.
? ? ? ? 2.代碼
編寫程序實現按下不同的按鍵使蜂鳴器產生不同的音調
6.蜂鳴器
? ? ? ? 1.原理圖
????????
? ? ? ? 2.代碼
temer.c
#include <reg52.h>
#include "timer.h"
#include "key.h"unsigned int hz = 100;void timer_handler(void) interrupt 1
{TH0 = 65535 - (11059200 / (24 * hz)) >> 8;TL0 = 65535 - (11059200 / (24 * hz));P2 ^= (1 << 1);
}void init_timer(void)
{TMOD &= ~(0x0f << 0);TMOD |= (1 << 0);TH0 = 65535 - (11059200 / (24 * hz)) >> 8;TL0 = 65535 - (11059200 / (24 * hz));IE |= (1 << 7) | (1 << 1);TCON |= (1 << 4);}
main.c
#include <reg52.h>
#include "timer.h"
#include "key.h"
#include "digiter.h"
#include "delay.h"
int main(void)
{init_timer();init_key();while(1){int key = key_pressed();if(key == 1){hz = 100;}else if(key == 2){hz = 200;}else if(key == 3){hz = 400;}else if(key == 4){hz = 600;}display(hz);}}
? ? ? ? 3.占空比
????????通過調節一次中斷后的計數器,也就是高電平變成低電平產生中斷之后,計數器時間變化,同理,低電平變成高電平之后也進行一次計數器的設置,這樣循環下去就可以。
????????7.uart
????????????????1.串口通信
?
嵌入式系統中的通信是指兩個或兩個以上的主機之間的數據互交,這里的主機可以是計算機也可以是嵌入式主機,甚至可以是芯片。主機間通信的方式一般可以分為兩類:并行通信和串行通信。并行通信是指多個比特同時通過并行線進行傳輸,這種方式的傳輸速率較高,但會占用大量的芯片資源;串行通信是指將數據拆分成一個個比特,按照先后次序在一根總線上進行發送,串行通信有著系統占用資源少,結構簡單等優點,是主機間通信的常用方式。串口通信(Serial Port)是串行通信的一種,屬于串行通信中的異步通信。我們經常聽到的RS232、RS485、RS422都是串行通信。
- 單工模式(Simplex Communication):主機間通信時如果一方固定為發送端另外一方固定為接收端,通過一根總線實現數據通信。這種通信方式就像是你只能聽別人說話,但無法回答他們一樣,只能單向傳遞信息。
- 半雙工通信(Half-Duplex Communication)是一種通信方式,其中數據傳輸可以在兩個方向之間交替進行,但不能同時進行。換句話說,通信雙方可以既發送數據又接收數據,但不能同時進行這兩種操作。比方說,就像你可以和別人交替說話和傾聽對方說話一樣。當你在說話時,對方在聽你說;當對方在說話時,你在傾聽對方。這種方式允許雙方之間在發送和接收數據之間切換,但不能同時進行。半雙工通信常用于對話式交流和一些簡單的通信場景中。
- 全雙工通信(Full-Duplex Communication)是一種通信方式,其中數據傳輸可以同時在兩個方向進行,允許通信雙方同時發送和接收數據,實現雙向通信。就像打電話一樣,你可以同時說話也可以聽對方說話,雙方可以同時進行數據傳輸,實現雙向溝通。
- 作為常用的串行通信方式,以TTL為例,串口通信在不同主機之間的數據格式為:
- 空閑時數據線為高電平;
- 發送發發送一個低電平表示起始位;
- 發送的第一個比特是最低為(最右邊);
- 校驗位分為奇校驗,偶校驗和無校驗。奇校驗是指確保數據位加上校驗位中"1",1的總數為奇數;偶校驗是指確保數據位加上校驗位中"1",1的總數為偶數;
- 為保證下一個字節發送前的起始位能夠表現出來,校驗位之后發送一個停止位1。
- 數據的傳輸速率問題:
很明顯上圖的縱坐標為電壓值,橫坐標就是時間了。無論起始位、數據為還是停止位、校驗位,每個比特在數據線上的時間決定了數據傳輸的速率。串行通信用波特率(bit per second)來描述數據傳輸的速率,記作bps。常見的波特率有1200、2400,4800,9600,115200等,表示每秒鐘傳輸的比特數。以9600為例,表明每秒能傳輸9600個比特。每個比特傳輸時所需的時間為1/9600秒=1.041*10-4秒。
- 同步通信和異步通信
串口通信時,收發雙方的波特率必須是事先約定好的,否則數據傳輸就會出現混亂。很明顯,為保證每個比特占用數據線的時間,發送方和接收方需按照各自的系統計時且雙方之間的誤差不能太大。通常不能超過(6%)。這種雙方各自“計時”的方式稱為異步。就好比在打字一樣,每次敲擊鍵盤發送一個字母,速度快慢由打字者自己控制,沒規定每敲擊一個字母之間要等多久,只要保證接收端能夠正確識別并解析即可。同步通信設備之間除了有數據線以為還有一條時鐘線(SDA和SCL)。其中SCL就是時鐘線(serial clock)。發送方負責控制時鐘線的變化,每發送一個比特,都需要將時鐘線按照規則進行改變。就好比在合唱團里,大家一起唱歌的節奏是由指揮員指揮的,每個人都按照指揮員的節奏唱歌,保證大家唱的是同一首歌且節奏一致。這種通信方式就稱為同步通信。譬如IIC、SPI等。
- 主機間通信時的電器物理問題
主機間通信無論采用并行還是串行方式,都無法避免一個物理現象:導線內阻不為零造成的電壓衰減。以之前討論的TTL電平為例,主機之間的距離會造成高電平在接收端出現衰減現象和串擾(指不同信號之間相互干擾導致信號失真)影響。
- TTL(Transistor-Transistor Logic)通常指的就是芯片引腳產生的電壓,這個電壓值跟選擇的芯片有關,在51單片機系統下是5v;在2440下是3.3v等等。5vTTL通信距離通常被限制在10~20米之間,如果需要更遠的距離,怎么解決呢?
- 為解決這個問題IEEE(Institute of Electrical and Electronics Engineers)頒布了RS232標準,其中規定了:
邏輯高電平(邏輯1):在-3V到-15V之間
邏輯低電平(邏輯0):在+3V到+15V之間
收發主機間有三根線,分別是收、發和地,因此RS232是全雙工的。
理論上RS232能夠傳輸20~30米。
- 同理RS485使用兩根信號線(A和B)來傳輸數據,通過比較A和B之間的電壓差來識別信息,電壓范圍分別為+7V到+12V和-7V到-12V。正電壓表示高電平,負電壓表示低電平。這種差分信號傳輸方式提高了抗干擾能力。RS485的傳輸距離可達1200米,適用于大范圍的數據傳輸需求。由于采用的是壓差,RS485在傳輸數據的某一時刻,兩根線都要用到,所以它是半雙工的。
1.uart:異步全雙工串行通信。
? ?usart:異步/同步全雙工
?? ?單工,半雙工,全雙工。
?? ?異步,同步
?? ?并行:通信的二者之間有倆根和倆根之上。
?? ?串行:只有一根通信線,一個bit一個bite的傳輸(usb)
TTL: