找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1589|回复: 18
打印 上一主题 下一主题
收起左侧

这里想问各位大佬一个51单片机的问题 delay函数延时不能达到预期的一秒,反而非常快

  [复制链接]
跳转到指定楼层
楼主
ID:1079470 发表于 2023-5-23 22:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
其实代码是在视频上抄的,但是delay函数延时不能达到预期的一秒,反而非常快,求解答!

代码如下

void UART_INIT() {

PCON |= 0x80; //波特率不倍速
SCON = 0x40; //8位数据,可变波特率
TMOD &= 0x0F; //设置定时器模式
TMOD |= 0x20; //设置定时器模式
TL1 = 0xF3; //设置定时初始值
TH1 = 0xF3; //设置定时重载值
ET1 = 0; //禁止定时器中断
TR1 = 1; //定时器1开始计时
TR0 = 1;

}

void UART_SendByte(unsigned int Byte) {
SBUF = Byte;
while(TI == 0);
TI = 0;
}

unsigned int sec = 0;

void main() {
UART_INIT();

while(1) {
UART_SendByte(sec);
sec++;
P2_0 = ~P2_0;
Delay(1000);
}
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1079470 发表于 2023-5-23 22:35 | 只看该作者
delay函数放在别的代码里就没有问题,这里如果把TMOD换成定时器0,就会变得非常慢,总之不管怎么样都不会按照1秒的预期去执行
回复

使用道具 举报

板凳
ID:744809 发表于 2023-5-24 09:00 | 只看该作者
delay函数都没贴出来
回复

使用道具 举报

地板
ID:526543 发表于 2023-5-24 12:32 | 只看该作者
void Delay(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 120; j++) {
            // 空循环进行延时
        }
    }
}
回复

使用道具 举报

5#
ID:1079470 发表于 2023-5-24 21:04 | 只看该作者
123156fsadf 发表于 2023-5-24 09:00
delay函数都没贴出来

void Delay(unsigned int xms) {
        xms = xms * 1000;
        while(xms--);
}
回复

使用道具 举报

6#
ID:1031129 发表于 2023-5-24 21:12 | 只看该作者
delay函数要贴出来
回复

使用道具 举报

7#
ID:1079470 发表于 2023-5-24 22:00 | 只看该作者
2763537317 发表于 2023-5-24 21:12
delay函数要贴出来

贴啦,在您楼上
回复

使用道具 举报

8#
ID:744809 发表于 2023-5-24 22:41 | 只看该作者
2763537317 发表于 2023-5-24 21:12
delay函数要贴出来

你这个delay函数有问题,unsigned int 最大只有65535,你delay(1000),xms = 1000*1000,导致溢出了,你用4楼提供的delay试试
回复

使用道具 举报

9#
ID:155507 发表于 2023-5-24 22:43 | 只看该作者
dhj646315174 发表于 2023-5-24 21:04
void Delay(unsigned int xms) {
        xms = xms * 1000;
        while(xms--);

你是个变量是unsigned int, 他只能从 0~65535
Delay(1000);
是 1000 * 1000 = 1000000 超过了65535 当然会快
回复

使用道具 举报

10#
ID:213173 发表于 2023-5-25 06:26 | 只看该作者
dhj646315174 发表于 2023-5-24 21:04
void Delay(unsigned int xms) {
        xms = xms * 1000;
        while(xms--);

相同的代码在不同的单片机运行结果未必相同。标准51系列12T单片机,12MHz晶振条件下运行这个延时函数t大致延时时间长度 T=t*9+16us
void delay(unsigned int t)
{      
        while(t--);
}
如果是51增强型1T单片机运行上述这个延时函数大致延时时间长度是上述的1/10。可以参考下面程序
void Delay_ms(unsigned int t)//1T@12MHz
{
        unsigned int i,j;
        for(i=t;i>0;i--)
                for(j=1200;j>0;j--);
}

何况你xms = xms * 1000;数据溢出,while(xms--);中xms实际只得到16960,根本得不到1秒延时。
回复

使用道具 举报

11#
ID:879348 发表于 2023-5-25 10:47 | 只看该作者
定时可以开一个定时器,就非常精确了
回复

使用道具 举报

12#
ID:647261 发表于 2023-5-25 16:22 | 只看该作者
要精确的1秒,除了楼上各位说的
还要计算一下这个循环需要的指令周期
不过要计算可能不太好算,最好示波器量一下
回复

使用道具 举报

13#
ID:330059 发表于 2023-5-25 19:46 | 只看该作者
参数xms是unsigned int类型,范围是0-65535,Delay(1000)的话函数内部参数的计算结果已经大于最大值了,所以会出现问题,可以修改成为unsigned long
回复

使用道具 举报

14#
ID:1079470 发表于 2023-5-25 21:08 | 只看该作者
感谢楼上各位大佬的讲解,这里就不一一回复了,十分感谢!
回复

使用道具 举报

15#
ID:73833 发表于 2023-5-27 14:34 | 只看该作者
    使用for循环配合  ++,--,之类的语句,是很难得到精确的延时的。
     这里提供一个方法或许有用:
           开一个可以自动重装的定时器,设好定时时间,比如10毫秒,再定义  一个全局变量TIME,仅 把"TIME++;"放在那个定时器的中断函数里。这就准备好了。
     在工程的任何地方(函数里),要延时都很方便,比如要延时1秒,只要 TIME=0;while(TIME<100);
这就精确的延时 了 1秒。
   像STC15W系列单片机有模式3的定时器,使用起来会更精确,更方便。
    了1秒。  
回复

使用道具 举报

16#
ID:73833 发表于 2023-5-27 14:45 | 只看该作者
使用for循环和++,--之类的语句基本很难得到精确的定时。这里提供一个方法或许有用。
比如 要定时一秒:
  开一个能自动重装的定时器,设定定时时间10毫秒,再定义一个全局变量TIME,仅把TIME++;放在那个定时器的中断函数里,基本就OK。
  在任何函数里可以:TIME=0;While(TIME<100);这就得到1秒的精切延时。
像STC15W单片机有模式3的定时器,用起来更方便,更精确。
回复

使用道具 举报

17#
ID:712097 发表于 2023-5-27 15:20 | 只看该作者
用STC-ISP软件的“软件延时计算器”功能
选择对应的指令集,以及延时时长,就可以了。
以下是STC-Y5指令集(适合STC15系列大部分芯片)12MHz下延时1000ms(1秒)的函数

void Delay1000ms()                //@12.000MHz
{
        unsigned char data i, j, k;

        _nop_();
        _nop_();
        i = 46;
        j = 153;
        k = 245;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}
回复

使用道具 举报

18#
ID:1090832 发表于 2023-8-6 20:30 | 只看该作者
void Delay(unsigned char xms)
{
     unsigned char i,j;
     while(xms--)
     {
           i=2;
           j=199;
          do
          {
               while(--j);
          }while(--i);
     }
}
回复

使用道具 举报

19#
ID:1090832 发表于 2023-8-6 20:32 | 只看该作者
void Delay(unsigned char xms)
{
     unsigned char i,j;
     while(xms--)
     {
           i=2;
           j=199;
          do
          {
               while(--j);
          }while(--i);
     }
}
那这个呢,有啥问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表