一、硬件
fs4412 sd卡 串口线 电源
二、根据原理图点灯
1、确定需求:
点灯(亮 or 灭)
2、查看原理图
2.1 外设原理图 devboard
查找LED2->CHG_COK(核心板)
2.2 核心板原理图 coreboard
查找CHG_COK->XEINT23/KP_ROW7/ALV_DBG19/GPX2_7
2.3 看芯片手册
GPIO控制(第六章)->查找GPX2
2.4 筛选寄存器(概述)
整体的配置或控制寄存器、功能相关的寄存器、不知道干嘛的寄存器
不需要的:
pull-up/pull-down:上拉下拉-引脚不能悬空,上拉为高电平或下拉接地为低电平 |
drive strength control register:驱动强度控制-输出电流大小 -- 影响灯的亮度,不影响亮灭,所以不需要GPF3DRV |
补充:下电模式寄存器:power down & power off,关机/睡眠,不影响灯的亮灭,所以不需要 |
需要的:
2.5 写代码
GPX2CON 0x11000c40 [31:28] 0x1 ---output 代码中,需要将[31:28]4位设置为0x1(先清零后置1) C代码:GPX2CON = (GPX2CON & (~(0xf << 28)) ) | ((0x1)<<28 ) 汇编代码: |
GPX2DAT 0x11000c44 [7] 0x0 --低电平 0x1-高电平 //输出模式(灯亮) -- 第七位置1(GPX2_7) C代码:GPX2DAT = GPX2DAT | (0x1 << 7) |
作业:流水灯
见下方代码
三、编译环境
Makefile:
1 all:
2 arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o start.o start.s
3 arm-none-linux-gnueabi-gcc -fno-builtin -nostdinc -c -o main.o main.c
4 arm-none-linux-gnueabi-ld start.o main.o -Tmap.lds -o led.elf
5 arm-none-linux-gnueabi-objcopy -O binary led.elf led.bin
6 arm-none-linux-gnueabi-objdump -D led.elf > led.dis
7 clean:
8 rm -rf *.bak *.o *.elf *.dis *.bin
map.lds:
1 /*linux下的连接脚本模板*/
2 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") /*指定输出可执行文件是elf格式,32位ARM指令,小端*/
3 OUTPUT_ARCH(arm) /*指定输出可执行文件的平台(arm平台)*/
4 ENTRY(_start) /*指定连接之后第一条指令的地址为_start*/
5 SECTIONS /*指定连接之后的代码段(.text) 数据段(.data) .bss段如何摆放*/
6 {
7 . = 0x40008000; /*指定链接的起始地址 从0x40008000地址开始摆放*/
8 . = ALIGN(4); /*指令对齐(4字节对齐)*/
9 .text : /*代码段开始*/
10 {
11 start.o(.text) /*0x40008000地址放start.o对应的start.s的第一条指令*/
12 *(.text) /* *:其他的*.o文件系统自动安排位置*/
13 }
14 . = ALIGN(4);
15 .data : /*数据段开始*/
16 { *(.data) } /*数据段也让系统自动分配*/
17 . = ALIGN(4);
18 .bss :
19 { *(.bss) }
20 }
map.lds解释:
1、 *表示所有.o文件的text
|
start.s:
1 .global delay1s
2 .text
3 .global _start
4 _start:
5 b reset @0x00
6 ldr pc,_undefined_instruction @0x04
7 ldr pc,_software_interrupt
8 ldr pc,_prefetch_abort
9 ldr pc,_data_abort
10 ldr pc,_not_used
11 ldr pc,_irq
12 ldr pc,_fiq
13
14 _undefined_instruction: .word _undefined_instruction
15 _software_interrupt: .word _software_interrupt
16 _prefetch_abort: .word _prefetch_abort
17 _data_abort: .word _data_abort
18 _not_used: .word _not_used
19 _irq: .word _irq
20 _fiq: .word _fiq
21
22
23 reset:
24 ldr r0,=0x40008000 @设置异常向量表的起始地址为0x40008000
25 mcr p15,0,r0,c12,c0,0 @ Vector Base Address Register
26
27 init_stack:
28 ldr r0,stacktop /*get stack top pointer*/
29
30 /********svc mode stack********/
31 mov sp,r0
32 sub r0,#128*4 /*512 byte for irq mode of stack*/
33 /****irq mode stack**/
34 msr cpsr,#0xd2
35 mov sp,r0
36 sub r0,#128*4 /*512 byte for irq mode of stack*/
37 /***fiq mode stack***/
38 msr cpsr,#0xd1
39 mov sp,r0
40 sub r0,#0
41 /***abort mode stack***/
42 msr cpsr,#0xd7
43 mov sp,r0
44 sub r0,#0
45 /***undefine mode stack***/
46 msr cpsr,#0xdb
47 mov sp,r0
48 sub r0,#0
49 /*** sys mode and usr mode stack ***/
50 msr cpsr,#0x10
51 mov sp,r0 /*1024 byte for user mode of stack*/
52
53 b main
54
55 delay1s:
56 ldr r4,=0x1ffffff
57 delay1s_loop:
58 sub r4,r4,#1
59 cmp r4,#0
60 bne delay1s_loop
61 mov pc,lr
62
63
64 .align 4
65
66 /**** swi_interrupt handler ****/
67
68
69 stacktop: .word stack+4*512
70
71 .data
72
73 stack:
74 .space 4*512
75 .end
main.c:
1 //led 2 3 4 5
2 //led2
3 #define GPX2CON (*(volatile unsigned int *)0x11000c40)
4 #define GPX2DAT (*(volatile unsigned int *)0x11000c44)
5 //led3
6 #define GPX1CON (*(volatile unsigned int *)0x11000c20)
7 #define GPX1DAT (*(volatile unsigned int *)0x11000c24)
8 //led4
9 #define GPF3CON (*(volatile unsigned int *)0x114001E0)
10 #define GPF3DAT (*(volatile unsigned int *)0x114001E4)
11 //led 5
12
13
14
15 void mydelay(int x) //延时
16 {
17 int i;
18 while(x --){ //1ms
19 for(i = 1000; i>0; i--);
20 }
21 }
22
23 void GPIO_init()
24 {
25 GPX2CON = (GPX2CON & (~(0xf << 28))) | ((0x1)<<28);
26 GPX1CON = (GPX1CON & (~(0xf ))) | ((0x1));
27 GPF3CON = (GPF3CON & (~(0xf << 16))) | ((0x1) << 16);
28 GPF3CON = (GPF3CON & (~(0xf << 20))) | ((0x1) << 20);
29
30 }
31
32 void led2_on() //开灯 7位置1
33 {
34 GPX2DAT = GPX2DAT | (0x1 << 7);
35 }
36 void led2_off() //关灯 7位置0
37 {
38 GPX2DAT = GPX2DAT & ~(0x1 << 7);
39 }
40 void led3_on() //开灯 0位置1
41 {
42 GPX1DAT = GPX1DAT | (0x1);
43 }
44 void led3_off() //关灯 0位置0
45 {
46 GPX1DAT = GPX1DAT & ~(0x1);
47 }
48 void led4_on() //开灯 4位置1
49 {
50 GPF3DAT = GPF3DAT | (0x1 << 4);
51 }
52 void led4_off() //关灯 4位置0
53 {
54 GPF3DAT = GPF3DAT & ~(0x1 << 4);
55 }
56 void led5_on() //开灯 5位置1
57 {
58 GPF3DAT = GPF3DAT | (0x1 << 5);
59 }
60 void led5_off() //关灯 4位置0
61 {
62 GPF3DAT = GPF3DAT & ~(0x1 << 5);
63 }
64
65 int main()
66 {
67 GPIO_init();//初始化
68 while(1) //循环
69 {
70 led2_on();
71 mydelay(500);
72 led2_off();
73 mydelay(500);
74 led3_on();
75 mydelay(500);
76 led3_off();
77 mydelay(500);
78 led4_on();
79 mydelay(500);
80 led4_off();
81 mydelay(500);
82 led5_on();
83 mydelay(500);
84 led5_off();
85 }
86 return 0;
87 }
编译:
打开超级终端 名字随便输 只需配置波特兰和硬件为115200和无
1.打开板子的开关,三秒内按回车
2.loadb 40008000 //地址见编译环境
3.发送文件 -- 打开windows下的.bin二进制文件
4.go 40008000文章来源:https://www.toymoban.com/news/detail-805652.html
四、其他注意事项
1、人通过代码操作内存,CPU通过取指译码执行来访问内存 2、另一块内存中通过地址映射并访问设备控制器中的寄存器(寄存器是物理设备,里面是一些写死的规则),CPU通过该内存来访问设备控制器中的寄存器 3、板子=CPU+设备控制器 4、设备控制器通过IO引脚来控制高低电平,从而控制设备 5、SD卡算外存设备,相当于提前在SD卡中烧写了一个小型的系统,用于启动引导 6、寄存器的八种模式: user用户:唯一非特权、正常程序运行的工作模式 sys系统:和用户模式一起属于非异常模式,用于操作系统(特权),和用户模式类似,但可以切换到其他模式 irq中断:用于中断请求处理,只有在IRQ异常响应才进入该模式 fiq快中断:用于快速中断请求处理,只有在FIQ异常响应模式才进入该模式 svc管理:供操作系统使用的一种保护模式,操作系统大部分代码都在内核,运行模式为SVC。应用层的到了系统运行,都是在svc模式 abort中止:用于虚拟内存 undefined未定义:软件仿真 moniter:cotex内核,不常用 7、寄存器:通用寄存器r0-r15(包括sp pc 等特殊寄存器,不包括CPSR、SPSR等程序状态寄存器) 8、汇编存在的意义:为C程序的运行做准备 9、异常触发过程:异常-触发异常-切换对应异常模式-异常向量表-异常处理函数 10、中断触发过程:当系统产生中断,就到irq中断模式处理 |
文章来源地址https://www.toymoban.com/news/detail-805652.html
到了这里,关于ARM day5、day6 硬件编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!