一、如何操作寄存器
1、访问内存
读出寄存器的值,修改,写回去。(操作复杂)
int * p;
int Val;
p = (0x40010C00 + 0x0C);
Val = *p;
Val |= (1<<3);
*p = Val;
2、访问寄存器
直接写寄存器。(操作简单)
int * p;
p = (0x40010C00 + 0x0C);
*p |= (1<<3);
二、谁来调用main函数
硬件复位后,程序第一步执行复位处理程序。
在复位处理程序中,首先执行SystemInit初始化函数,这个函数用户可以自己写,不是keil给封装的。然后调用main函数。
知道了main函数的调用过程,就可以自己编写系统的启动过程了。因为main函数是个C函数,所以需要用到栈空间,所以还要指定栈空间。
上图是官方启动文件中设置堆栈空间。
这个是自己编写的启动代码,在复位后,先执行__Vectors向量表,注册Reset_Handler
函数,然后执行复位函数,在复位函数中,声明外部函数main
,然后设置栈空间,最后跳转到main
函数去执行函数。
栈空间可以在官方的手册中查找或者在keil中选择对应芯片之后查看。
三、实验代码
1、相关寄存器
开启时钟寄存器
因为是直接操作寄存器,所以不需要包含一堆头文件。直接操作对应寄存器即可。
开启外设时钟的实质是开启对应外设总线APB1和APB2的时钟使能寄存器RCC_APB2、1ENR
的相关位。
系统若不进行进行时钟配置,则上电后默认系统时钟来源是HSI,8MHz。
引脚配置寄存器
GPIO引脚的模式配置寄存器有两个,一个是CRL、CRH分别是控制一组GPIO的低八位和高八位。比如GPIOB_CRL是引脚0-7的模式配置;GPIOB_CRH是8-15引脚的模式配置。
GPIOB_ODR是个32位寄存器,低16位有效,相关位置1则对应引脚输出高电平。
2、具体代码
1、定义指针指向具体寄存器
unsigned int * pAPB2En = ( unsigned int * )(0x40021000 + 0x18);
unsigned int * pGPIOCrl = ( unsigned int * )(0x40010C00 + 0);
unsigned int * pGPIOOdr = ( unsigned int * )(0x40010C00 + 0X0c);
2、通过配置寄存器
*pAPB2En |= (1<<3);//寄存器第3位置1,使能GPIOB时钟
*pGPIOCrl |= (1<<0);//寄存器第0位置1,设置GPIOB10MHz开漏输出
*pGPIOOdr |= (1<<0);//设置寄存器第0位置1,GPIOB_PIN0输出高电平,灯灭
3、LED闪烁
while(1)
{
delay();//延时
*pGPIOOdr &= ~(1<<0);//GPIOB_PIN0输出低电平,灯亮
delay();//延时
*pGPIOOdr |= (1<<0);//GPIOB_PIN0输出高电平,灯灭
}