文章目录
- C工程与寄存器封装
- 1 C语言工程简介
- 2 启动文件
- 3 C语言实现LED闪烁
- 3.1 C语言与汇编分别是怎么操作寄存器的
- 3.2 用C语言实现LED闪烁
- 4 寄存器的封装
- 4.1 第一种封装方式(宏定义)
- 4.2 第二种封装方式(结构体加宏定义)
- 5 寄存器的标准化操作
-
C工程与寄存器封装
1 C语言工程简介
common文件夹下是头文件和.c文件 。
start 是启动文件
interface.c是主函数所在文件。
2 启动文件
直接用就🆗
主要做以下操作
异常向量表所使用地址空间占用(防止其它代码占用)
修改异常向量表地址位置(通过协处理器 cp15)
设置模式为SVC模式,禁止FIO/IRQ(执行重要上电的代码)
关闭MCR,TlLBs
使能计算浮点型协处理器。
关闭MMU
初始化栈
跳转到main
1 .text
2 .global _start
3 _start:
4
7 b reset
8 b .
9 b .
10 b .
11 b .
12 b .
13 b .
14 b .
15
16 reset:
17
20 ldr r0, =_start
21 mcr p15, 0, r0, c12, c0, 0 @Set VBAR
22
23
26 mrs r0, cpsr
27 bic r0, r0, #0x1f
28 orr r0, r0, #0xd3
29 msr cpsr ,r0
30
31
34 mov r0, #0xfffffff
35 mcr p15, 0, r0, c1, c0, 2
36
37
40 mov r0, #0 @Set up for MCR
41 mcr p15, 0, r0, c8, c7, 0 @Invalidate TLBs
42 mcr p15, 0, r0, c7, c5, 0 @Invalidate icache
43
44
47 mov r3, #0x40000000
48 fmxr FPEXC, r3
49
50
53 mrc p15, 0, r0, c1, c0, 0
54 bic r0, r0, #0x00002000 @Clear bits 13 (--V-)
55 bic r0, r0, #0x00000007 @Clear bits 2:0 (-CAM)
56 orr r0, r0, #0x00001000 @Set bits 12 (---I)Icache
57 orr r0, r0, #0x00000002 @Set bits 1 (--A-)Align
58 orr r0, r0, #0x00000800 @Set bits 1 (Z---)BTB
59 mcr p15,0,r0,c1,c0,0
60
61
64init_stack:
65
66 msr cpsr, #0xd3
67
68 ldr sp, _stack_svc_end
69
70
71 msr cpsr, #0xdb
72 ldr sp, _stack_und_end
73
74
75 msr cpsr,#0xd7
76 ldr sp,_stack_abt_end
77
78
79 msr cpsr,#0xd2
80 ldr sp, _stack_irq_end
81
82
83 msr cpsr,#0xd1
84 ldr sp, _stack_fiq_end
85
86
87 msr cpsr,#0x10
88 ldr sp, _stack_usr_end
89
90
91 b main
92
93 _stack_svc_end:
94 .word stack_svc + 512
95 _stack_und_end:
96 .word stack_und + 513
97 _stack_abt_end:
98 .word stack_abt + 512
99 _stack_irq_end:
100 .word stack_irq + 512
101 _stack_fiq_end:
102 .word stack_fiq + 512
103 _stack_usr_end:
104 .word stack_usr + 512
105
106
107 .data
108 stack_svc:
109 .space 512
110 stack_und:
111 .space 512
112 stack_abt:
113 .space 512
114 stack_irq:
115 .space 512
116 stack_fiq:
117 .space 512
118 stack_usr:
119 .space 512
3 C语言实现LED闪烁
3.1 C语言与汇编分别是怎么操作寄存器的
- 汇编语言访问寄存器
(1)读寄存器
LDR R1,[R2]
(2)写寄存器
STR R1,[R2] - C语言访问寄存器
(1)读寄存器
data=*ADDR
(2)写寄存器
ADDR =data
3.2 用C语言实现LED闪烁
详细讲解GPIO操作
12 void Delay(unsigned int Time)
13 {
14 while(Time--);
15 }
16 int main()
17 {
18
19
20
21
22
23 *((unsigned int*)0x11000c40) = 0x10000000;
24
25 while(1)
26 {
27
28
29 *(unsigned int *)0x11000c44 =0x00000080;
30 Delay(1000000);
31
32 *(unsigned int *)0x11000c44 =0x00000000;
33 Delay(1000000);
34
35 }
36
37 return 0;
38 }
4 寄存器的封装
上面的代码不太适合阅读和维护。所以要对其加以封装
4.1 第一种封装方式(宏定义)
41 #define GPX2CON *((unsigned int*)0x11000c40)
42 #define GPX2DAT *((unsigned int *)0x11000c44)
12 void Delay(unsigned int Time)
13 {
14 while(Time--);
15 }
44 int main()
45 {
46
47 GPX2CON=0x10000000;
48
49 while(1)
50 {
51
52
53 GPX2DAT=0x00000080;
54 Delay(1000000);
55
56 GPX2DAT =0x00000000;
57 Delay(1000000);
58
59 }
60 }
4.2 第二种封装方式(结构体加宏定义)
12 void Delay(unsigned int Time)
13 {
14 while(Time--);
15 }
63 typedef struct
64 {
65
66 unsigned int CON;
67 unsigned int DAT;
68 unsigned int PUD;
69 unsigned int DRV;
70 }gpx2;
71 #define GPX2 (*(gpx2*)0x11000c40)
72 int main()
73 {
74 GPX2.CON=0x10000000;
75 while(1)
76 {
77 GPX2.DAT = 0x00000080;
78 Delay(1000000);
79 GPX2.DAT = 0x00000000;
80 Delay(1000000);
81
82 }
83 }
5 寄存器的标准化操作
上面的寄存器操作有局限性,比如 GPX2.DAT = 0x00000080; 我只想操作GPX2_7这个IO,结果把
整组IO口都操作了。
5.1 C语言位操作复习
例子:unsigned int a;将a的第三位置1,其它位保持不变。
a=a | (1<<3);
unsigned int a;将a的第三位置0,其它位保持不变。
a=a & (~(1<<3))
unsigned int a;将a的第[7:4]置为0101,其它位保持不变(分为两步)。
(1)先清零([7:4])
11111111 11111111 11111111 00001111
这个数由
00000000 00000000 00000000 00001111
左移4位
00000000 00000000 00000000 11110000
在按位取反得到
即 a=a & (~(0xF<<4))
(2) 再置位
00000000 00000000 00000000 01010000
这个数由
00000000 00000000 00000000 00000101
左移4位得到
即 a=a | (0x5<<4)
所以 unsigned int a;将a的第[7:4]置为0101,其它位保持不变(分为两步)。
为a= a & (~(0xF<<4)) | (0x5<<4);
根据上述知识,对4.2的代码加以改进如下:
5.2改进代码
12 void Delay(unsigned int Time)
13 {
14 while(Time--);
15 }
63 typedef struct
64 {
65
66 unsigned int CON;
67 unsigned int DAT;
68 unsigned int PUD;
69 unsigned int DRV;
70 }gpx2;
71 #define GPX2 (*(gpx2*)0x11000c40)
72 int main()
73 {
74 GPX2.CON=GPX2.CON & (~(0xF <<28 )) | (0x1 << 28);
75 while(1)
76 {
77 GPX2.DAT = GPX2.DAT|(1<<7);
78 Delay(1000000);
79 GPX2.DAT = GPX2.DAT &(~(1<<7));
80 Delay(1000000);
81
82 }
83 }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)