一、裸机编程的思路
思路:
(1)分析原理图
(2)理解硬件的控制原理
(3)找到对应的寄存器
(4)理解寄存器的控制流程
(5)根据地址访问寄存器
(6)实现硬件的控制
二、分析原理图
1.实物图
2.通过丝印层D7~D10,在原理图gec6818_base_V1.1-底板.pdf找到如下。
如果控制D7亮,GPIOE13输出低电平;控制D7 灭,GPIOE13 输出高电平。
三、寄存器配置
找对应的寄存器必须要找到S5P6818芯片数据手册SEC_S5P6818X_Users_Manual_preliminary_Ver_0.00.pdf。
1、找到GPIO输出模式的配置方法
1)配置某个端口某个引脚为输出模式
GPIOE多功能寄存器,设置对应的为b’00(这里是二进制格式)
2)使能当前的引脚输出使能
GPIOE 输出使能寄存器对应的位设置为1
3)输出高低电平
GPIOE输出寄存器对应的位设置为1/0.
2、对应的寄存器
3、多功能选择寄存器
1)多功能寄存器0
这里是GPIO多功能选择寄存器0,主要配置端口的0~15引脚。
2)多功能寄存器1
这里是GPIO多功能选择寄存器1,主要配置端口的16~31引脚。
3)多功能寄存器的ALT Function0~ALT Funciton2功能描述
ALT Function0~ALT Funciton2代表功能要查阅前面的章节2.3.1。
4、输出使能寄存器
5、输出电平寄存器
四、 源码
该源码用于控制D7灯的亮与灭。
1 | //1.定义寄存器 |
五、使用交叉编译器进行编译
1.检查ubuntu是否有交叉编译器。
1 | `/usr/local/arm/5.4.0/usr/bin/arm-linux-gcc` |
使用了volatile关键字之后,告诉编译器谨慎去对待i变量,里面有对i变量操作的代码,都帮我去生成对应的机器代码。
以下反汇编可以看到delay函数有对i变量进行减法运算操作:
1 | 40000000 <delay>: |
3.delay函数无添加volatile关键字
void delay(void)
{
unsigned int i=0x2000000;
while(i--);
}
以下反汇编代码可以看到delay函数变为空函数,优化掉对i变量的操作,直接函数返回,原因在于编译器觉得i变量没有起到作用(编译器是这么想的,只是i变量自己做减法操作,但是没有给其他变量与其他函数使用,无用功般的占用CPU资源),对代码影响不大,直接对它进行删除。
40000000
40000024: e12fff1e bx lr //函数返回
思考2
思考对寄存器某些位进行清零,为什么使用位与、取反的操作。
//对GPIOEOUT13寄存器的第13位进行清零
//假如GPIOEOUT寄存器的初值为0xFFFFFFFF。
GPIOEOUT&=~(1<<13);
1.1<<13的值为如下:
2.~(1<<13)的值为如下:
通过上图可以知道,只要GPIOEOUT寄存器跟~(1<<13)进行相与(跟1与,结果不变;跟0与,结果为0),从而知道只有第13bit位变为0,其他bit位保持不变。
总结:
1)将变量a的第30位置1,其他位保持不变。
a|=1<<30;
2)将变量a的第24、30位置1,其他位保持不变。
a|=(1<<30)|(1<<24);
3)将变量a的第30位取反,其他位保持不变。
a^=(1<<30);
4)将变量a的第30位清零,其他位保持不变。
a&=~(1<<30);