落尘* 2023-09-13 22:27 采纳率: 40%
浏览 1

延迟循环有问题 不知如何修改

我设置了p34-p36延迟循环6000-9000毫秒
但是这玩意40秒才亮一次


#include <reg52.h>
#include <stdlib.h>

sbit EN = P1^6;               //使能    
sbit A1 = P1^7;
sbit B1 = P1^5;

sbit Key1 = P1^0;
sbit Key2 = P1^1;                //按键
sbit Key3 = P1^2;                //按键

sbit Key4 = P3^7;             //按键!
sbit Key5 = P3^5;             //按键!
sbit Key6 = P3^4;             //按键!
sbit Key7 = P3^6;             //按键!

void delay_ms(unsigned int time_ms) {
    unsigned int i, j;
    for (i = 0; i < time_ms; i++) {
        for (j = 0; j < 1000; j++) {
            // 指令延迟
        }
    }
}

unsigned int generate_random_delay() {
    srand(TL0); // 使用定时器 TL0 的值作为种子
    return (rand() % 3001) + 6000; // 在6000到9000毫秒之间生成随机延迟时间
}

void D_MS(void){
    unsigned int i = 80;     //速度 (快60-10000慢)(B-04螺距为3mm时600=200转/分钟,即每秒滑块走10mm)(B-05螺距为2mm时500=250转/分钟,即8.3mm/S)
    for(; i > 0; i--) {       //(B-05螺距为2mm时1200=100转/分钟,即3.3mm/S)(B-05螺距为2mm时2200=25转/分钟,即2mm/S)
        delay_ms(1);
    }        
}

void RRM(void){    
    EN = 1;  
    A1 = 1;
    D_MS();
    B1 = 1;
    D_MS();
    A1 = 0;
    D_MS();
    B1 = 0;
    D_MS();    
    EN = 0;
}

void LLM(void){    
    EN = 1;
    B1 = 0;
    D_MS();
    A1 = 0;
    D_MS();
    B1 = 1;
    D_MS();
    A1 = 1;
    D_MS();
    EN = 0;
}

void main() {
    A1 = 0;
    B1 = 0;
    EN = 0; 
    while(1) {
        if(Key2 == 0) {
            delay_ms(20); // 按键去抖动
            if(Key2 == 0) {
                RRM();
            }
            while(Key2 == 0) {} // 等待按键释放
        }
        if(Key3 == 0) {
            delay_ms(20); // 按键去抖动
            if(Key3 == 0) {
                LLM();
            }
            while(Key3 == 0) {} // 等待按键释放
        }
        if(Key4 == 0) {
            delay_ms(20); // 按键去抖动
            if(Key4 == 0) {
                RRM();
            }
            while(Key4 == 0) {} // 等待按键释放
        }
        if(Key5 == 0) {
            delay_ms(20); // 按键去抖动
            if(Key5 == 0) {
                LLM();
            }
            while(Key5 == 0) {} // 等待按键释放
        }

        delay_ms(1);

        Key7 = 0;
        delay_ms(600);
        Key7 = 1;

        delay_ms(1);

        Key6 = 0;
        delay_ms(600);
        Key6 = 1;

        delay_ms(generate_random_delay());
    }
}


  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-09-13 22:29
    关注

    引用 皆我百晓生 小程序回复内容作答:

    在你的代码中,延迟函数 delay_ms 中有两个嵌套的循环,用于实现时间延迟。目前,你使用的是一个固定的延迟时间 delay_ms(1)。这会导致每次循环的延迟时间非常短,导致亮灯时间间隔很短,大约40秒才亮一次。

    解决方法是通过修改 delay_ms 函数来实现所需的延迟时间。你可以使用定时器来生成精确的延迟时间。

    以下是修改后的代码示例:

    void delay_ms(unsigned int time_ms) {
        // 使用定时器 T0 来实现延迟
        TMOD |= 0x01; // 设置 T0 为模式 116 位定时器
        TH0 = (65536 - 922); // 设置计数初值,用于延迟大约 1ms
        TL0 = (65536 - 922);
        TR0 = 1; // 启动定时器
        while (time_ms > 0) {
            while (TF0 == 0) {} // 等待定时器溢出
            TR0 = 0; // 停止定时器
            TF0 = 0; // 清除溢出标志
            TH0 = (65536 - 922); // 重新设置初值
            TL0 = (65536 - 922);
            time_ms--; // 减少剩余延迟时间
            TR0 = 1; // 启动定时器
        }
        TR0 = 0; // 停止定时器
    }
    

    在这个修改后的 delay_ms 函数中,我们使用了定时器 T0 来实现精确的延迟时间。通过设置计数初值为 (65536 - 922),每次定时器溢出大约需要 1ms 的时间。通过循环等待定时器溢出,并在溢出时重新设置初值,可以实现精确的延迟时间。

    通过使用这个修改后的延迟函数,在你的主循环中调用 delay_ms 函数时,可以获得所需的延迟时间,以达到你想要的效果。

    评论

报告相同问题?

问题事件

  • 创建了问题 9月13日

悬赏问题

  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp
  • ¥15 自己做的代码上传图片时,报错
  • ¥15 Lingo线性规划模型怎么搭建
  • ¥15 关于#python#的问题,请各位专家解答!区间型正向化
  • ¥15 unity从3D升级到urp管线,打包ab包后,材质全部变紫色
  • ¥50 comsol温度场仿真无法模拟微米级激光光斑
  • ¥15 上传图片时提交的存储类型
  • ¥15 VB.NET如何绘制倾斜的椭圆