平凡 发表于 2025-3-19 18:00:57

擎天柱单片机定时器程序失效,请指导一下是硬件问题还是源代码问题

编了一个倒计时程序,非常简单,一秒跳一格,只运行一次。编译正常,上机以后瞬间跑完。
麻烦各位老师指导一下。
、、、c
#include "ai8051u.h"      //调用头文件

// 定义P2和P3的各个引脚
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;

sbit StartKey = P3^3; // 定义P33为开始键

// 定时器初始化函数,1秒@24.000MHz
void Timer0_Init(void)
{
    TM0PS = 0x7F;            //设置定时器时钟预分频为127(24MHz时钟下,每个机器周期41.666ns,定时器时钟周期=41.666ns*127=5.304us)
    AUXR &= 0x7F;            //定时器时钟12T模式
    TMOD &= 0xF0;            //设置定时器模式
    TL0 = 0xFC;                //设置定时初始值(低8位)
    TH0 = 0x03;                //设置定时初始值(高8位)
    TF0 = 0;                //清除TF0标志
    TR0 = 1;                //定时器0开始计时
}

// 定时器0中断服务程序
void Timer0_ISR(void) interrupt 1
{
    TF0 = 0;                //清除TF0标志
    TL0 = 0xFC;                //重新加载定时初始值
    TH0 = 0x03;                //重新加载定时初始值
}

// 检测按键是否按下,返回1表示按下,0表示未按下
bit CheckStartKey()
{
    StartKey = 1; // 设置为高电平,准备检测按键
    Timer0_Init(); // 使用定时器消抖
    while(!TF0); // 等待定时器溢出
    TF0 = 0; // 清除TF0标志
    if(StartKey == 0) // 检测到低电平表示按键按下
    {
      Timer0_Init(); // 再次使用定时器消抖
      while(!TF0);
      TF0 = 0;
      if(StartKey == 0) // 确认按键是否仍然按下
            return 1; // 按下返回1
    }
    return 0; // 未按下返回0
}

void main(void)
{
    WTST = 0;                                          //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
                              //提高访问XRAM速度

    P2M1 = 0x00;   P2M0 = 0x00;// 设置P2为推挽输出
    P3M1 = 0x00;   P3M0 = 0x00;// 设置P3为输入模式

    while(1)
    {
      if(CheckStartKey()) // 检测到开始键按下
      {
            
            {
                // 无限循环
                P20 = 0; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.0,延时1秒
                P20 = 1; P21 = 0; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.1,延时1秒
                P20 = 1; P21 = 1; P22 = 0; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.2,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 0; P24 = 1; P25 = 1; P26 = 1; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.3,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 0; P25 = 1; P26 = 1; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.4,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 0; P26 = 1; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.5,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 0; P27 = 1; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.6,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 0; Timer0_Init(); while(!TF0); TF0 = 0; // 只点亮P2.7,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; // 熄灭所有LED
            }
      }
    }
}

国芯人工智能 发表于 2025-3-19 18:03:00

根据您描述的现象,定时器程序在编译正常的情况下,上机后瞬间跑完,可能的原因有以下几点:<br><br>1. 定时器配置问题:检查定时器的初始化配置是否正确,包括定时器模式、时钟源、计数初值等。确保定时器的计数值设置合理,以达到预期的定时效果。<br><br>2. 中断处理问题:如果使用了定时器中断,请确认中断服务程序(ISR)是否正确编写,并且中断优先级和中断使能位是否设置正确。<br><br>3. 硬件连接问题:检查单片机的晶振频率是否与程序中设定的时钟频率一致,确保硬件电路连接无误,特别是定时器相关的引脚。<br><br>4. 电源稳定性:电源不稳定可能导致单片机工作异常,建议检查电源电压是否在正常范围内。<br><br>5. 程序逻辑问题:确认倒计时程序的逻辑是否正确,特别是循环和条件判断部分,确保程序按预期执行。<br><br>建议您从以上几个方面逐一排查,可以先通过仿真调试工具检查程序运行情况,再结合硬件测试确认问题所在。如果仍无法解决,可以提供更详细的代码和硬件配置,以便进一步分析。<br><br>[本文内容由国芯人工智能辅助生成,仅供参考]

lzzasd 发表于 2025-3-19 18:38:29

// 定时器0中断服务程序
void Timer0_ISR(void) interrupt 1
{
    TF0 = 0;                //清除TF0标志
    TL0 = 0xFC;                //重新加载定时初始值
    TH0 = 0x03;                //重新加载定时初始值
}
中断里面什么都没做    你怎么看定时失效???
还有while(!TF0); TF0 = 0;   这句    硬件是先进中断,处理完后跳出来继续执行   你中断都把TF0 = 0置0了   所以while(!TF0);永远不成立
最基本的硬件中断还要锻炼下      

soma 发表于 2025-3-19 18:47:52

没看到EA=1.有开中断吗?

ercircle 发表于 2025-3-19 19:05:07

ET0 = 1;也没有哇

ercircle 发表于 2025-3-19 19:13:01

大致这样改,嗯参考:

#include "./ai8051u.h"


// 定义P2和P3的各个引脚
sbit P20 = P2^0;
sbit P21 = P2^1;
sbit P22 = P2^2;
sbit P23 = P2^3;
sbit P24 = P2^4;
sbit P25 = P2^5;
sbit P26 = P2^6;
sbit P27 = P2^7;

sbit StartKey = P3^3; // 定义P33为开始键
unsigned char timeCnt;
unsigned char lastTimeCnt;

void Timer0_Init(void)                //10毫秒@24.000MHz
{
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TMOD |= 0x01;                        //设置定时器模式
        TL0 = 0xE0;                                //设置定时初始值
        TH0 = 0xB1;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        timeCnt = 0;
        ET0 = 1;
}



// 定时器0中断服务程序
void Timer0_ISR(void) interrupt 1
{
    //TF0 = 0;                //清除TF0标志
        TL0 = 0xE0;                                //设置定时初始值
        TH0 = 0xB1;                                //设置定时初始值
       
        timeCnt++;
       
        if(timeCnt>=100){
                ET0 = 0;
        }
}
void tiemrSleep(){
        Timer0_Init();
        while(timeCnt<100);
}

// 检测按键是否按下,返回1表示按下,0表示未按下
bit CheckStartKey()
{
    if(StartKey == 0) // 检测到低电平表示按键按下
    {
                        StartKey = 1; // 设置为高电平,准备检测按键
      tiemrSleep(); // 再次使用定时器消抖
      if(StartKey == 0) // 确认按键是否仍然按下
            return 1; // 按下返回1
    }
    return 0; // 未按下返回0
}

void main(void)
{
    WTST = 0;                                          //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
                              //提高访问XRAM速度

    P2M1 = 0x00;   P2M0 = 0x00;// 设置P2为推挽输出
    P3M1 = 0x00;   P3M0 = 0x00;// 设置P3为输入模式
               
                P2=0xFF;
                lastTimeCnt = 0;
                timeCnt = 0;
                Timer0_Init();
//        ET0 = 1;
                EA=1;
               
       
    while(1)
    {
      if(CheckStartKey()) // 检测到开始键按下
      {
            
            {
                // 无限循环
                P20 = 0; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; tiemrSleep(); // 只点亮P2.0,延时1秒
                P20 = 1; P21 = 0; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; tiemrSleep(); // 只点亮P2.1,延时1秒
                P20 = 1; P21 = 1; P22 = 0; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; tiemrSleep(); // 只点亮P2.2,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 0; P24 = 1; P25 = 1; P26 = 1; P27 = 1; tiemrSleep(); // 只点亮P2.3,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 0; P25 = 1; P26 = 1; P27 = 1; tiemrSleep(); // 只点亮P2.4,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 0; P26 = 1; P27 = 1; tiemrSleep(); // 只点亮P2.5,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 0; P27 = 1; tiemrSleep(); // 只点亮P2.6,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 0; tiemrSleep(); // 只点亮P2.7,延时1秒
                P20 = 1; P21 = 1; P22 = 1; P23 = 1; P24 = 1; P25 = 1; P26 = 1; P27 = 1; // 熄灭所有LED
            }
      }
    }
}

平凡 发表于 2025-3-20 23:22:30

谢谢各位,学习了!
页: [1]
查看完整版本: 擎天柱单片机定时器程序失效,请指导一下是硬件问题还是源代码问题