打印
[51单片机]

为什么会延时不准确

[复制链接]
822|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
可可球|  楼主 | 2015-10-14 14:27 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
os, ui, TE, hz, While
本帖最后由 可可球 于 2015-10-14 16:05 编辑

最近用C8051做了块板子,发现延时不准确,不知道什么原因,求助大神们采用的是外部晶掁22.1184MHZ,二分频,应该是11.0592MHz
#include<c8051f020.h>

#define uint unsigned int         //数据类型的宏定义
#define uchar unsigned char

void delay_ms(uint);
void delay_us(uint);

void main()
{
           uint i;
           WDTCN = 0xde;
           WDTCN = 0xad; // 禁止内部看门狗
           XBR2  = 0x40;                                /*使能交叉开关*/
           P2MDOUT  =0xff;
           P74OUT |= 0xf3;
           OSCXCN = 0x77;      // start external oscillator with 22.1184MHz crystal,
                                                          //启用外部晶掁,晶掁22.1184MHZ,二分频,SYSCLK定义为11.0592                                 
           for (i=0; i < 256; i++)       // XTLVLD blanking interval (>1ms)   
           while (!(OSCXCN & 0x80))      // Wait for crystal osc. to settle      
           OSCICN = 0x88;                 // select external oscillator as SYSCLK     
           while(1)
                {
                        delay_us(10);
                        P2=0xff;
                        delay_us(10);
                        P2=0x00;
                }

}

//***********************************************************************
//      延时子程序us
//***********************************************************************
void delay_us(uint us)
{
        uchar k=us;
        while(k--);

}
//***********************************************************************
//      延时子程序ms
//***********************************************************************
void  delay_ms(uint ms)
{
    uchar i,j;
        for(i=0;i<ms;i++)
        {
                for(j=0;j<10;j++)
                delay_us(150);
        }
}




以下是主函数里的
while(1)
                {
                        delay_us(10);
                        P2=0xff;
                        delay_us(10);
                        P2=0x00;
                }
在 delay_us()函数给不同的值时,示波器测得的波形
发现delay_us(1)的时候,波形是2.6us,delay_us(10)是8.24us,delay_us(500)是160us

1us.jpg (3.49 MB )

1us.jpg

10us.jpg (3.51 MB )

10us.jpg

500us.jpg (3.4 MB )

500us.jpg

相关帖子

沙发
ayb_ice| | 2015-10-14 14:35 | 只看该作者
delay_us
看反汇编,考虑参数传递,函数调用,函数返回,中间循环指令,灵活插入NOP指令补偿

不过意义不是很大,这些都受中断影响,一般是通过定时中断产生滴答时钟,利用滴答延时,
短延时可以用这种软件延时,比如模拟时序,用NOP指令代替

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
可可球 + 3
板凳
ningling_21| | 2015-10-14 14:55 | 只看该作者
C语言写的延时都不会太准确,精确延时最好用汇编来写且不要开中断

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
可可球 + 1
地板
可可球|  楼主 | 2015-10-14 16:06 | 只看该作者
我没有开中断,只是一个简单的延时啊
//***********************************************************************
//      延时子程序us
//***********************************************************************
void delay_us(uint us)
{
        uchar k=us;
        while(k--);

}

使用特权

评论回复
5
NE5532| | 2015-10-14 16:46 | 只看该作者
C写软件延时,只能靠试,要精确,只有写汇编。而且用C还得注意编译器优化设置问题,最好把优化关了,否则随着编译可能会变。

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
可可球 + 3
6
oldzhang| | 2015-10-14 17:06 | 只看该作者
要准确定时,用硬件定时器

使用特权

评论回复
7
专注于嵌入式| | 2015-10-14 21:10 | 只看该作者
软件定时,你还想准???睡醒了么?;P

使用特权

评论回复
8
ywlzh| | 2015-10-15 09:27 | 只看该作者
这种延时的措施本身就是为了其延时作用的,要想准是很难的

使用特权

评论回复
9
可可球|  楼主 | 2015-10-18 19:40 | 只看该作者
但是这差距也太大了,关键是差距大

使用特权

评论回复
10
元方义城| | 2015-10-19 09:39 | 只看该作者
软件定时误差还是很大的。用定时器要好一些,想精确汇编吧,正如楼上说的,要是时间充裕不想用汇编,定时器,那么用示波器改一下调一下哈哈

使用特权

评论回复
评分
参与人数 1威望 +3 收起 理由
可可球 + 3
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

97

主题

675

帖子

1

粉丝