- C工程与寄存器封装
- 1 C语言工程简介
- 2 启动文件
- 3 C语言实现LED闪烁
- 3.1 C语言与汇编分别是怎么操作寄存器的
- 3.2 用C语言实现LED闪烁
- 4 寄存器的封装
- 4.1 第一种封装方式(宏定义)
- 4.2 第二种封装方式(结构体加宏定义)
- 5 寄存器的标准化操作
- 5.1 C语言位操作复习
- 5.2改进代码
common文件夹下是头文件和.c文件 。
start 是启动文件
interface.c是主函数所在文件。
直接用就
主要做以下操作
异常向量表所使用地址空间占用(防止其它代码占用)
修改异常向量表地址位置(通过协处理器 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 5123 C语言实现LED闪烁 3.1 C语言与汇编分别是怎么操作寄存器的
- 汇编语言访问寄存器
(1)读寄存器
LDR R1,[R2]
(2)写寄存器
STR R1,[R2] - C语言访问寄存器
(1)读寄存器
data=*ADDR
(2)写寄存器
ADDR =data
详细讲解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口都操作了。
例子: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);//(寄存器的[31,28](设为输出模式))
75 while(1)
76 {
77 GPX2.DAT = GPX2.DAT|(1<<7);//(第7位为设置为高电平)
78 Delay(1000000);
79 GPX2.DAT = GPX2.DAT &(~(1<<7));//(第7位为设置为低电平)
80 Delay(1000000);
81
82 }
83 }



