static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); / Reload value impossible /
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; / set reload register /
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); / set Priority for Cortex-M0 System Interrupts /
SysTick->VAL = 0; / Load the SysTick Counter Value /
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; / Enable SysTick IRQ and SysTick Timer /
return (0); / Function successful /
}
具体功能就是初始化系统滴答时钟,然后让时钟产生一个很精确的固定定时中断,一般我们可以把这个功能封装成一个很精确的延时函数这个模块的使用很简单,就是一个初始化函数和一个中断服务函数,初始化函数就是上面的那个,都是直接对寄存器进行写入的,这个应该就是你想要的底层代码了,我也是一个初学者,所以我的回答不一定是正确的,但是这个是我查阅过资料之后再加上自己的理解,所以如果有大神看到有问题的地方还望指出,谢谢STM32无sbit关键字,不能单个位 *** 作,一般有两种方式:
1、读改写。2、位段 *** 作。
第一种方法,先从寄存器中读出原来的值,对相应的位修改,再写入寄存器。unsigned int tmp =; tmp &= ;寄存器 = tmp; 缺点:不是原子 *** 作,步骤比较多,3步。原子 *** 作:不会被线程调度机制打断的 *** 作,一旦开始,就一直运行到结束。
第二种方法,位段 *** 作。
目的:对存储空间变相的实现位 *** 作。
片区域能够实现位段 *** 作。(只有标记了BB才可以)0X2000 0000--0X200F FFFF:SRAM区范围1MB。0X4000 0000--0X400F FFFF:APB1、APB2、AHB1。所有外设的寄存器组,范围也是1MB。
原理:将“位段区”的单个bit膨胀(映射)为别名区的一个32位的字,通过向别名区的字整体写1和0,实现对单个bit的写1和0。
位:指实际 *** 作的那个bit,段:指映射后的·那个“字”。一个位 *** 作最终变成了一个字段 *** 作,所以被称为位段 *** 作。
如何 *** 作别名区的膨胀后的字呢。
通过地址,别名区有范围,必须映射到指定地址范围的别名区,不然不能进行位段 *** 作。
SRAM区:0X2200 0000--0X23FF FFFF。
外设区:0X4200 0000--0X43FF FFFF。在ST的内核,别名区属于“保留地址,没有映射实际存储器”。
计算膨胀字的地址。我当年初学的时候也纠结过,后来选择了先学习寄存器 *** 作,后来慢慢的把库函数也学会了,其实都不难。完全可以两个都学,只是你现在选一个先下手而已。
建议你先学寄存器 *** 作,然后学库,以后工作中尽量使用库。
先学寄存器是因为你从51过渡过来,51也是直接控制寄存器,趁你还没有忘记怎么 *** 作寄存器的时候趁热打铁。
用库函数用习惯了你会发现自己会越做越快,但是知其然不知其所以然的感觉很糟糕,这时你再去学寄存器会感觉非常繁琐,完全学不进去。
所以,先学寄存器 *** 作,再学库函数 *** 作。
两个都学是必要的,有时候做工业控制的项目有严格的实时性要求,你用库函数会使速度变慢,这时你得用寄存器。其他时候能用库尽量用库,开发周期短,可读性强,易于跟人配合。
寄存器 *** 作就像手动挡汽车,库函数 *** 作就像自动挡汽车。手动挡会了,自动挡自然也会了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)