论坛元老
 
- 积分
- 10653
- 金钱
- 10653
- 注册时间
- 2017-4-14
- 在线时间
- 2780 小时
|
发表于 2018-3-1 21:14:19
|
显示全部楼层
本帖最后由 275891381 于 2018-3-1 21:36 编辑
volatile u64 xitong_haomiao; //2^64/1000/3600/24/365=584942417年会复位
static u8 fac_us=0; //us延时倍乘数
//SYSTICK的时钟固定为HCLK时钟的1/8
//中断时间time = ( SysTick->LOAD + 1 ) / f f = AHB或AHB/8 (9000-1+1)/9M=1ms
void delay_init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8 9M 计数器减1为1/9000000秒
fac_us=SystemCoreClock/8000000; //9
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //开启SYSTICK中断
SysTick->LOAD=fac_us*1000-1; //每1/1000s中断一次
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启SYSTICK
while(xitong_haomiao==0);
}
//nus:0~2^32=4294967296(最大值即2^32/fac_us@fac_us=1)
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD; //LOAD的值
ticks=nus*fac_us; //需要的节拍数
tcnt=0;
told=SysTick->VAL; //刚进入时的计数器值
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow; //这里注意一下SYSTICK是一个递减的计数器就可以了.
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break; //时间超过/等于要延迟的时间,则退出.
}
}
}
//nms:0---2^32/1000=4294967.296
void delay_ms(u32 nms)
{
delay_us((u32)(nms*1000)); //普通方式延时
}
void SysTick_Handler(void)
{
xitong_haomiao++;
if(xitong_haomiao%20==0)//20ms扫描一下按键
Key=KEY_Scan(0);
}
//注意此函数有响应优先级,WK_UP>KEY1>KEY2>KEY3
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//-1,没有任何按键按下
//0,WK_UP按下 WK_UP
//1,KEY1按下
//2,KEY2按下
//3,KEY3按下
u8 KEY_Scan(u8 mode)
{
static u8 flag=0;
static s8 key_up=1;//按键按松开标志
if(Key==KEY_NO_PRES)
{
if(mode)key_up=1; //支持连按
if(flag==0)
{
if(key_up&&(KEY_UP==0||KEY_DOWN==0))
flag=1;
else if(KEY_UP==1&&KEY_DOWN==1)
key_up=1;
}
else if(flag==1)
{
key_up=0;
flag=0;
if (KEY_UP==0) return KEY_UP_PRES;
else if(KEY_DOWN==0) return KEY_DOWN_PRES;
}
return KEY_NO_PRES;// 无按键按下
}
return Key;
}
这样用滴答定时器的好处是main里面可以实现简单调度,也减少delay的使用
if(xitong_haomiao-haomiao_old>=500)//delay_ms(500);
{
haomiao_old=xitong_haomiao;
LED13=~LED13;
}
|
|