電路原理圖:
如何點亮一個LED?
通過對原理圖進行分析,我們能夠發現給三極管的基極加上一個高點平時,三級管be結導通構成通路,此時二極管就點亮了。若要將LED熄滅只需取消高電平輸出。
如何使三級管基極獲得一個高電平?
控制三極管基極的其實是exynos4412的一個引腳(忽略具體是怎么連接的),因此我們要做的就是:
- 配置相關寄存器使引腳變為輸出功能(這里配置為輸出功能 0x1)
- 配置上下拉(若需要)
- 操作寄存器改變引腳電平變化
- 配置帶負載能力(若需要)
相關寄存器
配置引腳功能
獲取或設置引腳狀態
配置引腳內部上下拉
配置帶負載能力
一個簡單流水燈的實現:
#include "exynos_4412.h" /* LED點亮、熄滅以及狀態反轉操作 */ #define LED_ON(LED_x) ( *(LED_x.port) |= (1 << LED_x.pin) ) #define LED_OFF(LED_x) ( *(LED_x.port) &= (~(1 << LED_x.pin)) ) #define LED_REV(LED_x) ( *(LED_x.port) ^= (1 << LED_x.pin) ) /* 存放一個LED的端口信息以及引腳信息 */ typedef struct { unsigned int *port; /* LED端口狀態寄存器地址 */ int pin; /* 端口中的第幾pin */ }led_t; /* 定義並初始化4個LED,方便接下來操作 */ led_t LED_2 = {(unsigned int *)0x11000C44, 7}; /*GPX2DAT, bit[7]*/ led_t LED_3 = {(unsigned int *)0x11000C24, 0}; /*GPX0DAT, bit[0]*/ led_t LED_4 = {(unsigned int *)0x114001E4, 4}; /*GPF3DAT, bit[4]*/ led_t LED_5 = {(unsigned int *)0x114001E4, 5}; /*GPF3DAT, bit[5]*/ /* 簡單延時函數 */ void delay_ms(unsigned int time); int main() { /*配置引腳作為輸出*/ GPX2.CON = GPX2.CON & ~(0xf << 28) | (0x1 << 28); GPX1.CON = GPX1.CON & ~0xf | 0x1; GPF3.CON = GPF3.CON & ~(0xff << 16) | (0x11 << 16); /*實現簡單流水燈*/ while(1) { LED_ON(LED_2); LED_OFF(LED_3); LED_OFF(LED_4); LED_OFF(LED_5); delay_ms(500); LED_OFF(LED_2); LED_ON(LED_3); LED_OFF(LED_4); LED_OFF(LED_5); delay_ms(500); LED_OFF(LED_2); LED_OFF(LED_3); LED_ON(LED_4); LED_OFF(LED_5); delay_ms(500); LED_OFF(LED_2); LED_OFF(LED_3); LED_OFF(LED_4); LED_ON(LED_5); delay_ms(500); } return 0; } void delay_ms(unsigned int time) { int i, j; while(time--) { for(i = 0; i < 5; i++) for(j = 0; j < 610; j++); //do nothing } }
ARM匯編代碼實現LED閃爍
.globl _start .arm _start: LDR R0,=0x11000C20 LDR R1,[R0] BIC R1,R1,#0x0000000f ORR R1,R1,#0x00000001 STR R1,[R0] loop: LDR R0,=0x11000C24 LDR R1,[R0] ORR R1,R1,#0x01 STR R1,[R0] BL delay LDR R1,[R0] BIC R1,R1,#0x01 STR R1,[R0] BL delay B loop delay: LDR R2,=0xfffffff loop1: SUB R2,R2,#0x1 CMP R2,#0x0 BNE loop1 MOV PC,LR .end