1:主要內容
在嵌入式開發中,一般使用組合語言做一些晶元初始化工作,當對程式效率要求很高時,也有時會使用組合語言,但組合語言相對較難閱讀和理解。因此,我們希望我們以後的實驗在初始化完晶元相關功能後使用c語言進行程式設計,方便大家閱讀及理解。這一篇的內容主要是講解使用c語言來控制led燈閃爍。
2:相關要點
1,在通用pc機上寫程式都有乙個叫做main的函式,是程式的總入口。在嵌入式開發時,怎麼從組合語言跳轉到c語言?在跳轉之前需要設定哪些東西?
2:,在arm體系中,彙編和c語言之間相互呼叫時引數如何傳遞?
針對問題2:參見資料 atpcs.pdf
3:實驗原始碼
initsystem.s
@ 檔名 :initsystem.s
@ 功 能:初始化系統並copy**
@ 作者 :張連聘
.text
.global _start
@宣告常量
.equ data_dst,0x40000000 @目的位址
.equ data_src,0x80000000 @源位址
@引入外部標號
.extern main
.extern start_copy_addr
_start:
ldr pc, resetaddr
resetaddr: .word resetinit
resetinit:
ldr r0,=data_dst @ro 指向目的位址
ldr r1,=start_copy_addr @r1 指向源位址
mov r10,#128 @複製的個數為128*8*4=4k
copyloop: ldmia r1!,@從r1指定的記憶體位址處裝載資料到r2--r9中
stmia r0!,@把r2--r9的資料複製到r0指定的記憶體中
subs r10,r10,#1
bne copyloop
ldr sp,=0x40000000+1024*64 @設定堆疊指標,lpc2220內部有64kram,設定sp指標指向最高位址
ldr pc,=main @呼叫c語言的main函式
haltloop:
b haltloop
.end
main.c
* 檔名 :main.c
* 功 能:利用p2.28控制led燈閃爍
* 作者 :張連聘
//定義一些控制暫存器位址
#define io2dir (*(volatile unsigned long *)0xe0028028) //io2輸入、輸出配置暫存器
#define io2set (*(volatile unsigned long *)0xe0028024) //io2輸出1控制暫存器
#define io2clr (*(volatile unsigned long *)0xe002802c) //io2輸出0控制暫存器
#define ledcon (1<<28)
void delay(int ms);
void main(void)
io2dir = ledcon; //配置p2.28為輸出口
while (1)
io2set = ledcon; //點亮led燈
delay(6666);
io2clr = ledcon; //熄滅led燈
delay(6666);
* 名 稱:delay
* 功 能:軟體延時
* 入口引數:ms
* 出口引數:無
void delay(int ms)
int i,j;
for(i=0;i<10;i++)
for(j=0;j
led_control.lds
* led_control 的鏈結指令碼。
memory
rom (rx) : origin = 0x80000000, length = 2m
ram (!rx) : origin = 0x40000000, length = 2m
entry(_start)
sections
. = 0x80000000 ;
.init :
initsystem.o(.text)
start_copy_addr = . ;
} >rom
. = 0x40000000 ;
.main :
at (addr(.init)+sizeof(.init))
main.o(.text)
} >ram
makefile
control_led.bin:main.c initsystem.s
arm-linux-gcc -g -c -o main.o main.c
arm-linux-gcc -g -c -o initsystem.o initsystem.s
arm-linux-ld -tled_control.lds -nostdlib -g main.o initsystem.o -o control_led_elf
arm-linux-objcopy -o binary -s control_led_elf control_led.bin
clean:
rm -f control_led.bin control_led_elf *.o
4:原始碼重點分析
我們在main.c裡定義了乙個main函式,那我們在彙編**裡怎麼引用吶?
.extern main 宣告在另乙個檔案中定義了main函式。然後ldr pc,=main 跳轉到main函式。這裡說明一下,之所以不能使用bl指令跳轉,是因為啟動**執行的位址在0x80000000 ,而啟動**將main函式**copy到0x40000000。bl的跳轉範圍沒有這麼大。還有,這個main函式完全可以更改為其他函式,只是乙個普通的函式名稱。
ldr sp,=0x40000000+1024*64 使用這條指令,是設定sp堆疊指標的位置。這裡講堆疊指標設定在了lpc2220這款晶元的內部ram的最頂端。預設的arm處理器是遞減堆疊。
5:總結
由上面的實驗可見,pc機程式設計時的main函式只是乙個普通的函式名稱,只不過他們底層設定好了,呼叫main函式,所以我們一般說普通pc機程式總入口是main函式。其實,在main函式之前已經做了很多任務作。
只用 操作實現 , , 操作
減法 a b a b 乘法 a b相當於將a累加abs b 次 除法 相當於將abs a 減去 abs b 的次數 求lhs的反面值rhs,即求rhs使得lhs rhs 0 int negate int lhs return ret int abs int lhs 返回i的絕對值 lhs rhs l...
PYB操作 ADC操作
1.配置pyb內部adc 2.配置pyb內部dac 這裡由於nano沒有dac這裡就不貼出 操作了 1.putty 2.pyb nano adc 模擬訊號轉換為數字量 是嵌入式中最常用的功能之一,在micropython 同樣也提供了相應的函式,可以直接讀取 adc 轉換的結果。在pyboard中,...
Habse API操作(刪除操作)
根據rowkey刪除整行的所有列族 所有行 所有版本 public static void deleterow string tablename,string rowkey throws ioexception 刪除某個row的指定列 public static void deletecol str...