求教 stm8 微秒精确延时问题
求教
我设置的一分频 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIdiv1);
用下边的微秒延时,总是都不出来,有点怀疑是延时问题,哪位大神帮忙分析下
void delay_us(u16 z) //微秒延时
{
while(z--)
{
nop();nop();nop();nop();
}
}
下边的us延时行得通吗?
/****stm2查询法***/
void delay_us(u16 i)
{
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_1,16);
while (i--)
{
TIM2_Cmd(ENABLE);
while (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE )!=1);
TIM2_ClearFlag(TIM2_FLAG_UPDATE);
TIM2_Cmd(DISABLE);
}
}
我倾向与这个方式
/****tim2查询法***/
void delay_us(u16 i)
{
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_1,16);
while (i--)
{
TIM2_Cmd(ENABLE);
while (TIM2_GetFlagStatus(TIM2_FLAG_UPDATE )!=1);
TIM2_ClearFlag(TIM2_FLAG_UPDATE);
TIM2_Cmd(DISABLE);
}
}但是这个代码有点不知道行不行
我会这样写,先初始化,非精确代码,只说思路
void Timer2Init(void)
{
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_1,16);
TIM2_Cmd(ENABLE);
}
初始化好timer2,让它上电之后就开始不停的跑,周期定为高于1us,最好是倍数关系
延时函数
void Delay_us(char us_n)
{
unsigned char time1,time2,temp;
unsigned char delay_time;
delay_time = us_n * TIM2_TIKET; //将us值转换为timer2的计数次数
time1 = TIM2_CNT; //时刻1
do
{
time2 = TIM2_CNT;//时刻2
if( time2 >= time1 ) //计算时间
{
temp = time2 - time1;
}
else
{
temp = 0xFF - (time1 - time2) +1; //timer2溢出1次处理,如果溢出两次,还需要增加其他处理
}
}while( temp < delay_time ) //判断时间是否到达
}
这种方式使用是比较常见的,精确度可以用示波器通过IO口延时一定时间变化电平来测量
我只表达思路,我在STM8里面也这样用过,在其他芯片也可以这样使用。时间还是比较准的。
值得注意的是,如果timer2是8位的,要考虑溢出的情况和最大的延时时间。如果延时us数超过溢出值,最好使用16位计时器。16也同样会溢出。
针对溢出,假设设定timer2最大能延时50us,需要延时100us,那就是调用两次。以此类推。
对不起,忘记回复了。有一段时间没有上线。
哈哈,好像没人回答我来扯两句,
1、先说18B20,它的延迟可以多不可以少不需要灰常精确。
2、这个延迟函数void delay_us(u16 z) //微秒延时
{
while(z--)
{
nop();nop();nop();nop();
}
}我在最新版本的IAR for STM8 2.20.1上仿真了下,每个while循环需要11个时钟周期,进出函数需要20个时钟周期。也就是说delay_us(2)需要20+11*2=42个时钟周期8M的晶振就是42/8=5.25us。同理delay_us(100)需要20+100*11=1120个周期建议去掉只保留1个nop好计算。
3.中断,stm8刚点亮了第一个LED不是很懂,但是考虑进出函数的压栈用时肯定不止一两us,如果延迟都在10us以上没问题如果想精确延迟就1个us还是宏定义nop nop ...的准。
看时序就可以了,网上的例子很多,不需要特别精确
要精确延时用定时器啊骚年