【1】點燈(匯編點燈/C語言點燈)
1、分析電路圖
led燈:RGBLED1
紅燈:GPIOA28
綠燈:GPIOE13
藍燈:GPIOB12
2、分析芯片手冊
紅燈:GPIOA28
1.設置GPIOALFN1為GPIO功能function0 地址:0xC001A024 GPIOALFN1_28[25:24] = 0b00
2.設置GPIOAOUTENB為輸出模式 地址:0xC001A004 GPIOAOUTENB[28] = 0b1
3.設置GPIOAOUT輸出高低電平 地址:0xC001A020 GPIOAOUT[28]=0b0 GPIOAOUT[28]=0b1
綠燈:GPIOE13
1.設置GPIOALFN0為GPIO功能function0 0xC001E020 GPIOALFN1_13[27:26] = 0b00
2.設置GPIOAOUTENB為輸出模式 GPIOAOUTENB[13] = 0b1
3.設置GPIOAOUT輸出高低電平 GPIOAOUT[13]=0b0 GPIOAOUT[13]=0b1
藍燈:GPIOB12
1.設置GPIOALFN0為GPIO功能function0 0xC001B020 GPIOALFN1_12[25:24] = 0b10
2.設置GPIOAOUTENB為輸出模式 GPIOAOUTENB[12] = 0b1
3.設置GPIOAOUT輸出高低電平 GPIOAOUT[12]=0b0 GPIOAOUT[12]=0b1
3、編寫代碼
封裝寄存器方法:
1.*(unsigned int *)0xC001A024 =
*(unsigned int *)0xC001A024 & (~(0x3 << 24));
2.#define GPIOALTFN1 (*(volatile unsigned int*)0xC001A024)
GPIOALTFN1 = GPIOALTFN1 & (~(0x3 << 24));
3.#define GPIOALTFN1 ((volatile unsigned int*)0xC001A024)
*GPIOALTFN1 = *GPIOALTFN1 & (~(0x3 << 24));
4.封裝結構體
typedef struct{
volatile unsigned int OUT;
volatile unsigned int OUTENB;
volatile unsigned int DETMODE0;
volatile unsigned int DETMODE1;
volatile unsigned int INTENB;
volatile unsigned int DET;
volatile unsigned int PAD;
volatile unsigned int RSVD;
volatile unsigned int ALTFN0;
volatile unsigned int ALTFN1;
}gpio_t;
#define GPIOA (*(volatile gpio_t *)0xC001A000)
【2】PWM驅動蜂鳴器實驗
Pluse Width Modulation(PWM)脈沖寬度調制定時器
1、周期與頻率概念
1.周期:完成一個方波的時間
2.頻率:1S產生方波的個數
3.周期和頻率之間的關系:F = 1 / T
4.占空比:高電平占整個周期的百分比
2、有源蜂鳴器和無源蜂鳴器區別
1.有源蜂鳴器:有源蜂鳴器內部有一個震盪源,當給蜂鳴器供電,震盪源會按照一定的頻率震盪,產生高低電平的變化。
2.有源蜂鳴器的驅動給高電平,蜂鳴器響;
給低電平,蜂鳴器不響;
3.無源蜂鳴器:無源蜂鳴器的內部沒有震盪源,需要人為的按照一定的頻率給蜂鳴器提供高低電平的變化,蜂鳴器可以發聲;
4.開發板的蜂鳴器是有源蜂鳴器;
3、PWM應用
它是利用調制的數字輸出來對模擬電路進行控制的一種非常有效的技術,廣泛的測量,通信,功率控制與變換等許多領域,脈沖寬度調制是一種對模擬信號通過改進的計數器的使用,方波的替代被調制變成對一個具體模擬信號的可以進行編碼。
常見應用有:電機控制,DAC輸出等
4、分析電路圖
蜂鳴器:BUZ1
SOC芯片:GPIOC14---->PWM2
5、分析芯片手冊
Register | Description |
---|---|
TCFG0 | Clock-Prescalar 時鍾預分頻器 |
TCFG1 | Clock Multiplexers 時鍾多路復用器 |
TCON | Timer control register 定時器控制寄存器 |
TCNTB2 | Timer 2 count buffer register 定時器2計數緩沖寄存器 |
TCMPB2 | Timer 2 compare buffer register 定時器2 比較緩沖寄存器 |
TCNTO2 | Timer 2 count observation register 定時器2觀測寄存器 |
1.設置GPIOC14引腳位PWM功能(function2功能)GPIOcALTFN0
0xC001C020[29:28] = 0b10
2.設置PWM定時器的1級分頻值 TCFG0
3.設置PWM定時器的2級分頻值 TCFG1
4.設置定時器控制寄存器 TCON
5.設置定時器緩沖寄存器2 TCNTB2
6.設置定時器比較緩沖寄存器2 TCMPB2
6、編寫代碼
1.頭文件包含
2.src/pwm.c 蜂鳴器代碼編寫
void hal_pwm_init( )
{
1.設置GPIOC14引腳位PWM功能
2.設置PWM2的一級分頻值 TCFG0[15:8]
3.設置PWM2的二級分頻值 TCFG1[11:8]
4.設置計數緩沖寄存器初始值 TCCNTB2[31:0]
5.設置比較緩沖寄存器初始值 TCMPB2[31:0]
6.打開手動更新位 TCON[13]
7.打開自動更新位 TCON[15]
8.關閉手動更新位 TCON[13]
9.打開翻轉位 TCON[14]
10.開啟PWM2定時器的功能 TCON[12]
}
主函數main.c進行調用函數
【3】UART通用的異步串行全雙工總線
總線是計算機各種功能部件之間傳送信息的公共通信干線,它是由導線組成的傳輸線束,按照計算機所傳輸的信息種類,計算機的總線可以划分為數據總線、地址總線和控制總線,分別用來傳輸數據、數據地址和控制信號,總線是一種內部結構,它是CPU、內存、輸入、輸出設備傳遞信息的公用通道,主機的各個部件通過總線相連接,外部設備通過相應的接口電路再與總線相連接,從而形成了計算機硬件系統,在計算機系統中,各個部件之間傳送信息的公共通路叫總線,微型計算機是以總線結構來連接各個功能部件的
1、總線的種類
1.串行總線:一個時鍾周期主機發送一位數據,同時從機接受一位數據
2.優點:節約引腳資源 去電:傳輸速率慢
常見的串行總線:UART IIC SPI CAN
1.並行總線:一個時鍾周期主機可以並行的發送多位數據,同時從機可以並行的接收多位的數據
2.優點:傳輸速率高 缺點:浪費引腳資源
場合:LCD屏,內存,硬盤
2、按照數據的傳輸方向
單工總線
雙工總線
3、按照時鍾划分
同步總線
異步總線:主機和從機采用各自獨立的時鍾源,要求各自的時鍾源要保持相同的時鍾頻率
4、UART串行總線的硬件連接
5、UART串口的通信協議
串口在空閑時,數據線處於高電平的狀態
發送端將數據線從高拉倒低,就是一個起始位
起始信號:開始發送數據的信號
數據位:要發送或者接收的數據,先發低位再發高位
校驗位:奇偶校驗,保證數據位加校驗位1的個數和為奇數或者偶數
停止位:一幀數據發送結束,用於校准時鍾
1.在一幀數據內部,每一位數據的傳輸都需要一個時鍾周期
2.每幀數據之間的時間間隔是任意的,及空閑時間任意
3.串口采用異步時鍾,各自采用各自獨立的時鍾源
4.時鍾就會存在一定的誤差,在數據的發送過程中,誤差會累加,因此發送完一幀數據之后需要校准時鍾
6、分析硬件電路圖
1.sp3232芯片的作用:電平轉換芯片
具有跟sp3232芯片具有相同功能的芯片有:SP232 MAX232 MAX3232
2.s5p6818采用的是TTL電平
3.3V -->表示高電平
0v -->表示低電平
3.串口采用的是RS232電平
+3 ~ -12 --> 表示高電平
+3 ~ +12 --> 表示低電平
7、分析芯片手冊
【5】arm異常處理過程
1、arm處理器的工作模式
為了提高arm處理器的工作效率,為arm處理器設計了多種工作模式,在不同的工作模式下,處理不同的時間,及執行不同的程序,完成特定的功能
2、五種異常模式,七種異常源
異常模式 | 異常源 | |
---|---|---|
FIQ模式 | 快速中斷模式 | 外部中斷事件觸發 |
IRQ模式 | 普通中斷模式 | 外部中斷事件觸發 |
SVC模式 | 管理(特權)模式 | Reset或軟中斷指令 |
Abort模式 | 中止模式 | 指令或數據異常 |
Undef模式 | 未定義模式 | 指令沒有定義/無法解析的指令 |
3、異常源
異常源是引發程序進入異常模式下,執行異常處理代碼一類的事件
異常模式 | 異常源 |
---|---|
FIQ模式 | FIQ |
IRQ模式 | IRQ |
SVC模式 | Reset/軟中斷 |
Abort模式 | data abort / pretfch abort |
Undef模式 | undef指令 |
data Abort:數據中止異常 --> 取數據失敗
Pretfch Abort:指令中止異常 --> 取指令失敗
Undef指令:未定義指令異常 --> 翻譯指令不成功
1>五種異常模式對應七種異常源
2>異常源具有優先級,復位的優先級最高,FIQ優先級高於IRQ
4、異常處理過程
保存現場:4大步3小步 CPU自動完成
1.保存CRSR到spsr_<mode>
2.修改cpsr
1>切換到ARM狀態
2>禁止中斷位,根據需要
3>修改模式位,切換到對應的異常模式
3.保存返回地址到lr_<mode>
4.修改PC值,執行對應的異常向量表位置
恢復現場:(需要手動完成)
1.恢復spsr_<mode>到cpsr中
2.恢復lr_<mode>到PC中
1.當異常發生之后,cpu自動完成保護現場的過程,自動修改PC值指向異常處理程序,而異常處理程序的入口地址可能不固定
2.所以設計芯片時,設計了一個異常向量表,異常發生后,先讓PC指向異常向量表的位置,在通過異常向量表跳轉到異常處理程序中
5、異常向量表
1.異常向量表就是內存代碼段中一塊連續的空間,這塊空間的大小是32字節,被平均分成8份,每份占4個字節;
2.這個異常向量表中就存放7種異常源,還有一個是保留的
3.7種異常源在異常向量表中的位置是固定的,異常向量表的首地址
也是固定的;
4.既可以通過根據異常向量表的首地址做地址的偏移,就可以找到對應的異常源;
【6】按鍵中斷實驗
1、分析電路圖
2、分析芯片手冊
設置GPIO控制器流程
①通過GPIOxALTFN0/1寄存器設置為按鍵功能
②通過GPIOxOUTENB寄存器設置為輸入功能
③通過GPIOxDETENB寄存器使能事件檢測使能寄存器
④通過GPIOxDETMODE0/1寄存器設置事件檢測模式
⑤通過GPIOxINTENB寄存器使能中斷使能寄存器
⑥通過GPIOxDET寄存器設置事件檢測寄存器
寄存器 | 寄存器描述 |
---|---|
GPIOxOUTENB | GPIO輸出使能寄存器 |
GPIOxDETMODE0 | GPIO事件檢測模式寄存器0 |
GPIOxDETMODE1 | GPIO事件檢測模式寄存器1 |
GPIOxINTENB | GPIO中斷使能寄存器 |
GPIOxDET | GPIO事件檢測寄存器 |
GPIOxPAD | GPIO引腳狀態寄存器 |
GPIOxALTFN0 | GPIO復用功能選擇寄存器0 |
GPIOxALTFN1 | GPIO復用功能選擇寄存器1 |
GPIOxDETMODEEX | GPIO事件檢測模式擴展寄存器 |
GPIOxDETENB | GPIO 檢測使能寄存器 |
1.16個軟件產生的中斷 --> 簡稱SGIS
2.6個外部私有外設中斷 --> 簡稱PPIS
3.1個內部私有外設中斷 --> 簡稱PPIS
4.128個共享外設中斷 --> 簡稱SPIS
GIC本身支持16個SGIS,16個PPIS,128個SPIS
s5p6818芯片只使用7個PPIS
GIC寄存器分為:分配器層(GICD)和CPU接口層(GICC)
【1】分配器層配置流程(GICD)
1、設置ISENABLERn寄存器:使能中斷使能寄存器
2、設置IPRIORITYRn寄存器:中斷優先級寄存器
3、設置ITARGETSRn寄存器:中斷處理器目標寄存器
4、設置GICD_CTRL寄存器:設置分配器控制寄存器GICD層全局使能
5、GICD_ICPENDER寄存器:清除中斷掛起標志位寄存器
【2】CPU接口層(GICC)
1、設置GICC_PMR寄存器:中斷優先級屏蔽寄存器
2、設置GICC_CTRL寄存器:CPU接口控制寄存器
3、從GICC_IAR寄存器中獲取終端號
4、GICC_EOIR中斷結束寄存器
寄存器 | 寄存器描述 |
---|---|
GICD_CTRL | 分配器控制寄存器 |
GICD_ISENABLERn | 設置中斷使能寄存器 |
GICD_ICPENDERn | 清除中斷掛起標志寄存器 |
GICD_IPRIORITYRn | 中斷優先級寄存器 |
GICD_ITARGETSRn | 中斷處理器目標寄存器 |
GICC_CTRL | CPU接口控制寄存器 |
GICC_PMR | 中斷優先級屏蔽寄存器 |
GICC_IAR | 中斷應答寄存器 |
GICC_EOIR | 中斷結束寄存器 |
GICD_CTRL:GICD層全局中斷使能寄存器
GICD_ISENABLERn:GICD中設置中斷使能寄存器
GICD_ICPENDERn:清除GICD層的中斷掛起標志位
GICD_IPRIORITYRn:GICD層設置中斷優先級
GICD_ITARGETSRn:GICD層中斷目標分配寄存器
GICC_CTRL:GICC層中斷全局使能寄存器
GICC_PMR:GICC層中斷優先級屏蔽寄存器
GICC_IAR:GICC層中斷應答寄存器,可以讀到中斷號
GICC_EOIR:GICC層中斷結束寄存器,清除中斷號
GIC作用:
1.所有的中斷信號都是通過GIC轉發中斷信號到CPU中
2.GIC管理中斷信號轉發給哪個CPU核進行處理
3.中斷信號具有優先級,當同時來多個中斷信號時,GIC先轉發高優先級的中斷給CPU核處理,低優先級的在GIC中排隊
4.高端ARM處理器不允許出現中斷的嵌套,即高優先級的中斷不可以打斷低優先級的中斷信號
5.GIC給每個中斷信號都分配了一個唯一的中斷號,通過中斷號就可以區分中斷的類型
GICD_ISENABLERn:GICD中設置中斷使能寄存器
GICD_ISENABLERn每一位管理一個中斷號,而GIC最多支持160個中斷(16個SGIS,16個PPIS,128個SPIS),而一個GICD_ISENABLERn寄存器最多管理32個中斷號,因此需要5個這樣的寄存器共同管理160個中斷源
GPIOB8引腳對應的中斷號是86號,對應着寄存器的哪一位
86/32=2....22 第二個寄存器22位
GICD_IPRIORITYRn:GICD層設置中斷優先級
GICD_ISENABLERn每8位管理一個中斷號,而GIC最多支持160個中斷(16個SGIS,16個PPIS,128個SPIS),而一個GICD_IPRIORITYRn寄存器最多管理4個中斷號,因此需要40個這樣的寄存器共同管理160個中斷源
GPIOB8引腳對應的中斷號是86號,對應着寄存器的哪8位
86/4=21....2 第21個寄存器[23:16]位
GICD_ITARGETSRn:GICD層中斷目標分配寄存器
GICD_ITARGETSRn每8位管理一個中斷號,而GIC最多支持160個中斷(16個SGIS,16個PPIS,128個SPIS),而一個GICD_ITARGETSRn寄存器最多管理4個中斷號,因此需要40個這樣的寄存器共同管理160個中斷源
GPIOB8引腳對應的中斷號是86號,對應着寄存器的哪8位
86/4=21....2 第21個寄存器[23:16]位
GICD_ICPENDERn:清除GICD層的中斷掛起標志位
GICD_ICPENDERn每一位管理一個中斷號,而GIC最多支持160個中斷(16個SGIS,16個PPIS,128個SPIS),而一個GICD_ICPENDERn寄存器最多管理32個中斷號,因此需要5個這樣的寄存器共同管理160個中斷源
GPIOB8引腳對應的中斷號是86號,對應着寄存器的哪一位
86/32=2....22 第二個寄存器22位
3、代碼編寫流程
1>GPIO按鍵初始化
1.設置GPIO引腳為GPIO功能
2.設置GPIO引腳為輸入模式
3.設置GPIO引腳的檢測使能
4.設置GPIO引腳的事件檢測模式
5.設置GPIO引腳的中斷使能
6.清除GPIO層中斷掛起標志位
2>GIC寄存器中GICD初始化
1.設置GICD層中斷使能寄存器
2.設置中斷的優先級寄存器
3.設置GICD層目標分配寄存器,中斷信號給CPU0處理
4.設置GICD層全局使能寄存器
3>GIC寄存器中GICC初始化
1.設置GICC層中斷屏蔽寄存器
2.設置GICC層全局中斷使能寄存器
4>中斷函數do_irq.c
1.通過GICC_IAR寄存器,獲取中斷號
2.通過GPIODET寄存器對應位的值,可以判斷那個gpio引腳觸發的中斷
3.清除GICD層的中斷掛起標志位
4.清除中斷號
【7】ADC實驗
1、ADC概念
ADC:Analog Digital Covererter->模數轉換器->將模擬量轉換為數字量
DAC:Digital Analog Converter->數模轉換器->將數字量轉換為模擬量
2、模擬型傳感器
模擬型傳感器:輸出的信號是一個模擬信號
3、數字型傳感器
數字型傳感器:輸出量是一個數字量
4、模擬量和數字量關聯
假設測量的模擬電壓值為0~1.8v,轉換對應的12位的數字量
數字量 | 模擬量 |
---|---|
0000 0000 0000 | 0V |
........................... | .......................... |
1111 11111 11111 | 1.8v |
原理:將模擬量平均分成很多的小份,讓數字量乘以一份的值,就是實際的測量的模擬量的值
5、分析硬件電路圖
6、分析芯片手冊
1>ADC框圖
APSV:分頻器
APEN:分頻器使能
ADEN:AD使能
ATBY:電源
CLKIN:時鍾輸入
ADCDAT:ADC轉換結果數字量
2>ADC時序圖
AIN[15:0]:模擬輸入通道
CLK:時鍾 (時鍾<6MHZ)
SEL[3:0]:通道選擇
PD:電源
SOC:開啟轉換信號
EOC:轉換結束信號
DO[11:0]:輸出的數字量
3>ADCCON寄存器設置
1.讀取轉換結果的延時周期的個數
2.ADC供電之后,延時幾個周期之后開啟ADC轉換
3.ADC通道的選擇
4.打開ADC電源
5.ADEN使能
讀0:轉換結束
讀1:正在進行轉換
寫0:沒有影響
寫1:開啟ADC轉換
4>ADCDAT寄存器設置
轉換結果存放在這個寄存器
5>PRESCALERCON寄存器設置
1.APEN:設置分頻器使能
2.APSV:分頻器值
7、編寫代碼流程
1>adc初始化函數
1.設置ADCDAT讀取轉換結果的延時時間
2.社會ADC開啟電源之后,時鍾周期的延時個數
3.設置ADC的通道選擇 選擇0通道
4.開啟ADC的電源
5.設置ADC的分頻值
6.設置ADC的分頻使能為
2>讀取轉換結果的值
1.開啟ADC轉換
2.等待ADC轉換結果,如果ADC轉換沒有結束,等待ADC轉換結束,如果轉換結束,讀取轉換結果
3.從ADCDAT中讀取轉換結果
4.將獲取的數字量通過公式轉換為模擬量
【8】IIC總線串行半雙工
1、IIC串行總線概述
1.IIC總線是PHLIPS公司在八十年代出推出的一種串行的半雙工總線,主要用於連接整體電路;
2.IIC總線為兩線制,只有兩根雙向信號號,一根是數據線(SDA),另外一根是時鍾線(SCL);
2、IIC總線硬件連接
1.IIC是具備多主多從,系統所需的包括總線裁決功能的高性能串行的總線
2.能夠主動發起通信的叫做主機,被動接受的屬於從機
3.每個接到IIC總線上的器件都有唯一的地址,主機與其他器件進行數據傳送時,總線上發送數據的器件為發送器,總線上接受數據的器件則為接收器
3、IIC總線的時序
1>起始信號時序
SCL線上為高電平期間,SDA線由高電平向低電平變化表示起始信號
2>數據信號時序
1.時鍾在低電平期間,發送器向數據線上寫入數據
2.時鍾在高電平期間,接收器從數據線上讀取數據
3>應答和非應答信號時序
1.接收器接收到8位的數據之后,需要給發送器返回一個應答信號或者非應答信號
2.在第九個時鍾周期,低電平期間,接收器向數據線上寫入數據
3.在第九個時鍾周期,高電平期間,發送器從數據線上讀取數據
4.如果讀到的是高電平就是非應答信號,如果讀到的是低電平就是應答信號
4>停止信號時序
1.SCL線上為高電平期間,SDA線由低電平到高電平變化表示停止信號
2.起始信號和終止信號都是由主機發出,起始信號產生后,總線上就處於占用的狀態,終止信號產生后,總線上就處於空閑態
5>IIC的尋址
1.IIC總線傳送的數據信號是廣義的,包括地址信號,又包括真正的數據信號
2.主機在起始信號后,必須傳送一個從機的地址(7位),第8位是數據的傳送方向為(R/T),用0表示主機發送數據(T),用1表示接受數據(R)
3.總線上的每個從機將這7位從機地址與字節的地址進行比較,如果相同,則恩威自己被主機尋址,根據R/T位將自己定為發送器或接收器(本課程mma8451q所用的地址是0x1c)
4、IIC總線通信協議
1>主機給從機發送(寫)一個字節數據
2>主機給從機發送連續的多個字節數據
3>主機從從機接受一個字節數據
4>主機從從機接受多個字節數據
5、模擬IIC時序代碼
1>MMA8451q從機地址
GPIOD6:SCL
GPIOD7:SDA
#define SLAVE_ADDR 0x1C
2>設置GPIOD7位輸入或者輸出
#define SET_SDA_OUT hal_gpio_mode(GPIOD,GPIO_PIN_7,OUT_MODE)
#define SET_SDA_IN hal_gpio_mode(GPIOD,GPIO_PIN_7,IN_MODE)
3>設置GPIOD7輸出高低電平
#define SDA_OUT_H hal_gpio_write(GPIOD,GPIO_PIN_7,HIGH_LEVEL)
#define SDA_OUT_L hal_gpio_write(GPIOD,GPIO_PIN_7,LOW_LEVEL)
4>設置GPIOD6輸出高低電平
#define SCL_OUT_H hal_gpio_write(GPIOD,GPIO_PIN_6,HIGH_LEVEL)
#define SCL_OUT_L hal_gpio_write(GPIOD,GPIO_PIN_6,LOW_LEVEL)
5>讀取SDA線上的數據
#define READ_SDA_DATA hal_gpio_read(GPIOD,GPIO_PIN_7)
6>延時函數
void delay_us(void);
7>IIC的初始化
void iic_init(void);
8>模擬開始信號時序的函數
void iic_start(void);
9>模擬停止信號時序的函數
void iic_stop(void);
10>主機給從機發送一幀數據的函數
char iic_send_char(char dat);
11>從機給主機發送一幀的數據
char iic_recv_char(char ack);
12>主機向mma8451q中寫入一個字節的數據
void mma8451_write_byte(unsigned char reg_addr,
char dat);
13>主機從mma8451q中讀取一個字節的數據
char mma8451_read_byte(unsigned char reg_addr);
14>mma8451q初始化函數
void mma8451_init(void);