嵌入式ARM实验
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
@设置时钟 .extern clockinit bl clockinit @设置存储控制器 .extern meminit bl meminit @拷贝代码到 SDRAM 中 .extern copy ldr r0,=0x0 ldr r1,=0x30008000 ldr r2,=_bss_end bl copy @重新设置 sp 指针 ldr sp,=0x34000000 @调用 led_loop 函数 .extern led_loop ldr pc,=led_loop b. .end
Start.s 改为 .text .global _start _start: b reset b. b. b. b. b. b. b. reset: @设置 sp 指针 ldr sp,=(0x40000000+4096) @关闭看门狗 .extern disable_watchdog bl disable_watchdog
Makefile led.bin:init.o led.o led.lds arm-linux-ld -O2 -Tled.lds init.o led.o -o led.elf arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -d led.elf > led.dis init.o:init.c arm-linux-gcc -c init.c -o init.o led.o:led.s arm-linux-gcc -c led.s -o led.o clean: rm -fr led.bin led.elf *.o *~ led.dis
修改 led.s 文件名为 start.s $ cd $ mv led.s $ mv led.lds 2440_clock/ start.s clock.lds
文件名改了,链接脚本和 makefile 文件要改相应的内容: clock.lds 链接脚本修改如下: OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x40000000; .text :{ start.o(.text) *(.text) } .data :{ *(.data) } .bss :{ *(.bss) } }
(4)编译,得到 led.bin 烧写到开发板中,查看 LED 灯
2 查看 datasheet Watch dog Clock Memory controler
实验 2 调用 C 函数 汇编调用 C 函数 led.s .text .global _start _start: b reset b. b. b. b. b. b. b. reset: @设置 sp 指针 ldr sp,=(0x40000000+4096) @关闭看门狗 .extern disable_watchdog bl disable_watchdog @调用 ed_loop 函数 .extern led_loop bl led_loop b. .end
Led.lds OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x40000000; .text :{ led.o(.text) *(.text) } .data :{ *(.data) } .bss :{ *(.bss) } }
arm-linux-ld -Tled.lds delay.o led.o -o led.elf arm-linux-objcopy -O binary led.elf led.bin delay.o:delay.s arm-linux-gcc -c delay.s -o delay.o led.o:led.s arm-linux-gcc -c led.s -o led.o
实验 4 UART 串口实验
实验原理: 1 串行通信的传输式 串行通信时微电脑之间一种常见的近距离通信手段,因使用方便,编程简单 而广泛使用,几乎所有的微控制器,PC 都提供串行通信接口。
开始前,线路处于空闲状态,送出连续“1”。传送开始时首先发一个“0” 作为起始位, 然后出现在通信在线的时字符的二进制编码数据。 每个字符的数据位长可以约定为:5 位、6 位、7 位或8 位,一般采用A SC II 编码,后面是奇偶校验位,根据约定,用奇偶校验位将所传的字符中为“1”的 位数凑成奇数个或偶数个。也可以约定不要奇偶校验,这样就取消奇偶校验位。 最后时表示停止位的“1”信号,这个停止位可以约定连续1 位、1.5 位或2 位 的时间宽度。至此一个字符传送完毕,线路又进入空闲,持续为“1”。经过一 段随机的时间后,下一个字符开始传送。 2 传输速率 每一个数据位的宽度定于发送波特率的倒数。微机异步串行通信中,常用的 波特率为110、150、300、600、1200、2400、4800、9600、57600、115200 等。 3 电气特性 要完成基本的通信功能,实际上只需要R X D 、TX D 和G N D 即可,但由于R S -232-C 标准所定义的高、低电平信号于S3C 2440A 系统的LV TTL 电路定义的 高、低电平信号完全不同,LV TTL 的标准逻辑“1”对应2-3. 3V ,标准逻辑“0”
UART: 115200 IIC: 100k , 400k IIS:几十 k Timer: ADC: 2.5MHZ
UPLLCON 倍频
UCLK (USB BUS )
时钟产生框图
1.内核时钟倍频 MPLL = FCLK
B 总线时钟倍频
3.FCLK 分频 HCLK 和 PCLK
在实验 2 的基础上进行修改; 拷贝 2440_led 目录到 2440_clock $ cp 2440_led 2440_clock -a
Makefile 修改如下: clock.bin:init.o start.o clock.lds arm-linux-ld -O2 -Tclock.lds init.o start.o -o clock.elf arm-linux-objcopy -O binary clock.elf clock.bin arm-linux-objdump -d clock.elf > clock.dis init.o:init.c arm-linux-gcc -c init.c -o init.o start.o:start.s arm-linux-gcc -c start.s -o start.o clean: rm -fr clock.bin clock.elf *.o *~ clock.dis
在 init.c 文件中添加一个时钟初始化函数 #define rLOCKTIME (*(volatile unsigned *)0x4c000000) #define rMPLLCON (*(volatile unsigned *)0x4c000004) #define rCLKDIVN (*(volatile unsigned *)0x4c000014) void clockinit(void) { rLOCKTIME=0xFFFFFF; rCLKDIVN=(0x2<<1)|(1); //FCLK:HCKL:PCLK=1:4:8 rMPLLCON=(0x7f<<12)|(0x2<<4)|0x1; //FCLK 405M return; }
for(i=0;i<d;i++); return ; } void led_loop(void) { GPBCON=GPBCON&~(0xff<<10)|(0x55<<10); while(1) { delay(3000); GPBDAT&=~(0xf<<5); delay(3000); GPBDAT|=(0xf<<5); } }
在 start.s 中调用这个函数 @设置时钟 .extern clockinit bl clockinit 烧写察看效果
实验 3 SDRAM 实验 实验原理:
2440 物理内存布局图 ;
添加存储控制器的初始化函数 在 init.c 文件中添加一个函数如下: void meminit(void) { volatile unsigned long *p=(volatile unsigned long*)0x48000000; p[0]= 0x22111110; p[1]= 0x00000700; p[2]= 0x00000700; p[3]= 0x00000700; p[4]= 0x00000700; p[5]= 0x00000700; p[6]= 0x00000700; p[7]= 0x00018005; p[8]= 0x00018005; p[9]= 0x008e0459; p[10]= 0x000000B2; p[11]= 0x00000030; p[12]= 0x00000030; return; } BANK6-7 设置好之后,可以使用 SDRAM ( 0x30000000 0x34000000),可以 将代码从 flash 拷贝到内存中; 在 init.c 中添加一个代码拷贝函数; /* 将 psource 指向的数据拷贝到 pdest 中,拷贝的大小是 plimit-pdest */ void copy(unsigned char *psource, unsigned char *pdest, unsigned char *plimit) { while(pdest<plimit) { *pdest++ = *psource++; } }
实验 3 时钟设置 实验原理:
HCLK 高速总线时钟 (AHB bus) 12MHZ 晶振 MPLLCON 倍频 FCLK 内核时钟 (ARM920T) 405MHZ CLKDIVN 分频 中断控制器 存储器控制器 LCD 控制器 Nand flash DMA 控制器
PCLK 低速总线时钟 (APB bus)
链接脚本的运行时地址改为: OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x30008000; .text :{ start.o(.text) *(.text) } .data :{ *(.data) } _bss_start = .; .bss :{ *(.bss) } _bss_end = .; }
实验 1
GNU 下的 ARM 汇编程序设计
实验步骤: (1)编写汇编程序文件 Led.s
.text .global _start _start: b b. b. b. b. b. b. b. reset: @close dog ldr r0,=0x53000000 mov r1,#0 str r1,[r0] @ldr sp,=(0x40000000+4096) .extern _delay ldr r0,=0x2fff bl _delay ldr r0,=0x56000010 ldr r1,=0x15400 str r1,[r0] loop: ldr r0,=0x56000014 ldr r1,=0x0 str r1,[r0] ldr r0,=0x2ffff bl _delay reset
ldr r0,=0x56000014 ldr r1,=0x1ff str r1,[r0] ldr r0,=0x2ffff bl _delay b loop b. .end
delay.s .global _delay .text _delay: sub r0,r0,#1 cmp r0,#0x0 bne _delay mov pc,lr .end (2) 编写连接脚本 OUTPUT_FORMAT(elf32-littlearm) OUTPUT_ARCH(arm) ENTRY(_start) SECTIONS { . = 0x00000000; .text :{ led.o(.text) *(.text) } .data :{ *(.data) } .bss :{ *(.bss) } } (3)编写 Makefile led.bin:delay.o led.o led.lds
Init.c #define GPBCON (*(volatile unsigned long *)0x56000010) #define GPBDAT (*(volatile unsigned long *)0x56000014) #define rWTCON (*(volatile unsigned *)0x53000000) void disable_watchdog(void) { rWTCON = 0x0; return ; } void delay(unsigned long d) { int i;