|
目的——用SysTick定时器中断实现LED定时亮灭功能 在这之前先要确定几个概念 t=定时时间(中断定时时间) Ticks:多少个时钟周期产生一次中断 f:时钟频率72000000 t=Ticks*1/f=(72000000/100000)*(1/72000000)=10^(-5)s=10us 也就是说我们可以自己设定一个中断的时间t 设LED灯闪烁间隔时间为X t(s)=Ticks*1/f X=t* nTime X与t的值都可提前设计好然后代入,就可以求出SystemFrequency / 100000的分母 将两个板级支持包bsp.SysTick.c和bsp.SysTick.h在Keil工程里导入到USER 在KEIL\Target Option\C/C++\include paths内添加\USER\SysTick\ 进入main.c函数 LED_GPIO_Config(); LED初始化(用到LED灯的都要有这句) 1s=1000ms 1ms=1000us 1us=10^(-6)s 10us=10^(-5)s SysTick_Init(); 中断配置:配置SysTick为10us中断一次 在bsp.SysTikc.c中可以看到SysTick_Init();的定义 SystemFrequency / 1000 1ms中断一次 SystemFrequency / 100000 10us中断一次 SystemFrequency / 1000000 1us中断一次 上述三个中断时间都可以用最开始的公式进行计算 if (SysTick_Config(SystemCoreClock /100000)) 在core_cm3.h里面找到SysTick_Config定义 if (ticks >SysTick_LOAD_RELOAD_Msk) return(1); 如果tisks的值大于2^24,则返回1/* Reload value impossible */ 若小于,则往下继续执行 SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; 将SysTick的数据放到reload register 重装载寄存器中 NVIC_SetPriority (SysTick_IRQn,(1<<__NVIC_PRIO_BITS) - 1); /*set Priority for Cortex-M0 System Interrupts */ 设置systick系统时钟中断优先级(将NVIC向左移4位再减一=15) 为什么左移四位,因为M3只给了中断优先级4位 SysTick->VAL = 0; /* Load the SysTick Counter Value */ 把计数器设置为零 这一句没看懂,为什么设为零? 当使能定时器的时候把LOAD里面的值往下减一,减到零的时候 这里设置时钟来源 SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 设置时钟源为内核时钟FCLK SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; 上面一句使能SysTick IRQ 中断请求和SysTickTimer简易周期定时器权威指南(P101) 以上三句值明白了2句,上1句还不明白什么意思 定时器设置完成后,一旦开始工作就是倒数开始 当倒数到零的时候就产生一个中断 关闭滴答定时器 SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; SysTick的CTRL寄存器清零,即关闭定时器。 具体为什么清零,为什么清零可以关闭滴答定时器我还是不太理解 配置完定时器后回到main.c文件的for循环 For(;;)这里的for循环是不需要条件和退出条件的循环 LED1( ON ); 点亮LED灯 Delay_us(10000); //10000 * 10us = 100ms 进入延时程序 进入bsp.SysTick.c可以看到void Delay_us(__IO u32 nTime) 这里的nTime就是指的10000 TimingDelay = nTime; 赋值 滴答定时器使能 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; 这里怎么做到使能的? 进入while循环,要是不等于零,就一直在这里等待直到为零 while(TimingDelay != 0); 在stm32f10x_.c文件 void SysTick_Handler(void) // SysTick Handler每ms运行一次,下面的TimingDelay递减1 { TimingDelay_Decrement(); } 递减到零的时候延时程序就完成,下面紧接着就是LED灯的熄灭
|