找回密码
 立即注册
查看: 879|回复: 4

我这个程序是定时器有问题吗?STC8G1K08A | 已解决

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 18:39:59

6

主题

81

回帖

2122

积分

金牌会员

积分
2122
发表于 2023-12-30 14:44:26 | 显示全部楼层 |阅读模式
在定时1中扫描P55,P31爾个端口,如果P55低电平,P32就输出低电平,如果P31低电平,P33就间隔0.5秒输出高低电平,,现在是P31低电平,P33就可以输出高低电平,但是P55低电平,P32就没反应,我反复检查,甚至重新写了一遍,还是没找到问题,请大佬帮忙破案,
下面是程序,请多指教,谢谢(有些语句没用上,忽略它)


#include <stc8g.h>
#include "intrins.h"
#include  "Timer0.h"
#include  "Timer1.h"
#include  "Delayms.h"
#include  "Delay_Long.h"

/*——————宏定义——————*/
#define FOSC 35000000L

#define const_IR_time1   25        /*光控触发去抖动延时的时间*/
#define const_BLow_time2   20    /*低电压触发去抖动延时的时间*/


/*——————变量函数定义及声明——————*/
unsigned char ucKeySec = 0;                        /*被触发的编号*/

unsigned int  uiIRTimeCnt1 = 0;   /*光控触发时去抖动延时计数器*/
unsigned char ucIRLock1 = 0;      /*光控触发后自锁的变量标志*/

unsigned int  uiBLowTimeCnt2 = 0;   /*低电压触发后去抖动延时计数器*/
unsigned char ucBLowLock2 = 0;      /*低电压触发后自锁的变量标志*/

unsigned int  uiHVTimeCnt = 0;     /*触发后输出延时计数器*/

//unsigned int  uiVoiceCnt = 0;      /*蜂鸣器鸣叫的持续时间计数器*/

unsigned int  HVDTcnt = 3000;           //输出延时 时间(mS)

//unsigned int  uiVoiceCnt = 0;  /*蜂鸣器鸣叫的持续时间计数器*/

/* IO口定义 */
sbit IR_IN = P5^5;        /*定义接收光控输入引脚,光控对射时此脚为高电平*/
sbit IT_OUT = P5^4;            /*定义发射光控输出   方波*/
sbit BUZZER = P3^3;     /*定义蜂鸣器,低电压时发出嘀嘀音,重置满电电池后消声*/
sbit HV_OUT = P3^2;     /*输出引脚,低电平时输出电压给后级*/
sbit BLOW = P3^1;        /*电池电压低于6V检测,蜂鸣报警提醒*/

/* IO口模式定义 */
void  Init_Pin(void)
{
//        P3M0 = 0x08;    //P33,推挽输出,P32高阴输入
//        P3M1 = 0x04;         //P31,P30准双向口
//        P3DR |= 0x0e;
//     P3IE = (P3IE & ~0x08) | 0x06;
        P3M0 = 0x0c;         //P33,推挽输出,P32开渥输入,P3.1双向,P30高阻
        P3M1 = 0x05;


        
        P5M0 = 0x10;   //设置P5.4为推挽输出,P5.5为双向模式
        P5M1 = 0x00;
  }

/* IO口初始状态定义 */
void  Init_IO(void)
{
        BUZZER = 0;
        HV_OUT = 1;
        IR_IN  = 1;
        BLOW = 1;
        IT_OUT = 1;
}


/* 定时器T0初始化为1ms产生中断 @35MHz */
void Timer0Init(void)               
{
        AUXR |= 0x80;        //定时器时钟1T模式
        TMOD &= 0xF0;        //设置定时器模式
        
        TMOD |= 0x01;                    /*set timer0 as mode1 (16-bit)*/
        
//        TL0 = T1MS % 256;                /*initial timer0 low byte*/
//        TH0 = T1MS / 256;                /*initial timer0 high byte*/
        
        TL0 = 0x48;                //设置定时初值 65536-35*1000
        TH0 = 0x77;                //设置定时初值
        
        TF0 = 0;                //清除TF0标志
        
//        ET0 = 1;    //允许定时器T0溢出中断
//        TR0 = 1;        //定时器0开始计时
//        EA = 1;     // 打开总中断
   }



/* 定时器T1初始化为1ms产生中断 @35MHz */
void Timer1Init(void)  //1毫秒@35MHz
{
        AUXR |= 0x40;                       //定时器时钟1T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0x48;                        //65536-35/1000
        TH1 = 0x77;
        
//        TL0 = T1MS % 256;                /*initial timer0 low byte*/
//        TH0 = T1MS / 256;                /*initial timer0 high byte*/
        
        TF1 = 0;
        
//        ET1 = 1;                        //使能定时器中断
//        TR1 = 1;                        //启动定时器
}



/* 固定延时1毫秒 @35MHz */
void Delay1ms()                //@35MHz
{
        unsigned char i, j;

        _nop_();
        _nop_();
        i = 46;
        j = 113;
        do
        {
          while (--j);
        } while (--i);
}

/* n毫秒延时函数 参数给几 就延时几毫秒 */
void delay_ms(unsigned int ms)
{
        while(ms--)
        {
                Delay1ms();
        }
}


/**
* @brief  打开定时器
* @param  无
* @retval 开定时器
**/
void Init_Peripheral(void)
{
        ET0 = 1;    /*允许定时中断*/
        TR0 = 1;    /*启动定时中断*/
        
        ET1 = 1;    /*允许定时中断*/
        TR1 = 1;    /*启动定时中断*/
        
        EA = 1;     /*开总中断*/

}

/* 系统初始化 */
void  Init(void)    //初始化
{
         Init_Pin();
         Init_IO();
         Timer0Init();
         Timer1Init();
//         Init_Peripheral();

}
void Key_Scan(void);

/* 定时器T0中断处理函数,输出  方波 */
void TM0_Isr() interrupt 1
{
        static unsigned int cnt = 0;
        static bit flag = 0;
        cnt++;
       if(cnt >= 10)
        {
           cnt = 0;
           flag = ~flag;
           IT_OUT = flag;
           }
        TF0 = 0;
        TL0 = 0x48;                //设置定时初值 65536-35*1000
        TH0 = 0x77;                //设置定时初值
  }

/* 检测P55,P31口是否为低电平 */
void TM1_Isr() interrupt 3
{
        Key_Scan();   //检测P55口为低电平时,P32输出低电平,p31为低电平时,p33间隔0.5秒输出高低电平
}

/* 扫描光控和低电压输入,低电平为有动作 */
void Key_Scan(void)   //扫描P55,P31口函数
{
        /*扫描P55,光控对射中间物体有无检测*/
  if(IR_IN == 1)        /*如果光控中间没有遮挡(3脚P55为高电平),将一些标志位及时清零*/
        {
                ucIRLock1 = 0;     /*光控自锁标志位清0*/
                uiIRTimeCnt1 = 0;  /*光控触发去抖动延时计数器清零*/
            }
        
        else if(ucIRLock1 == 0)  /*如果光控中间有被遮挡,(外部给3脚P55拉低为低电平),*/
        {
                uiIRTimeCnt1 ++;
                if(uiIRTimeCnt1 > const_IR_time1)          //消抖
                {
                        uiIRTimeCnt1 = 0;
                        ucIRLock1 = 1;         /*自锁标志位置位,避免一直触发*/

                        ucKeySec = 1;      /*触发*/
//                        uiVoiceCnt = const_voice_short;  /*蜂鸣器短叫*/        
                }
        }
                        
//  }
//         }
        
        /*扫描P31,电池电压大于6.1V时为高电平*/
        if(BLOW == 1)                        /*电池电压大于6.1V时此Pin为高电平,将一些标志位及时清零*/
          {
                ucBLowLock2 = 0;                        /*低电压自锁标志位清0*/
                uiBLowTimeCnt2 = 0;                /*低电压去抖动延时计数器清零*/

           }
        
         else if(ucBLowLock2 == 0)          /*如果电池电压低于6.1V, 外部给P31拉低为低电平;*/
           {
                uiBLowTimeCnt2 ++;
                if(uiBLowTimeCnt2 > const_BLow_time2)
                 {
                        uiBLowTimeCnt2 = 0;
//                        ucBLowLock2 = 1;     /*自锁标志位置位,避免一直触发*/
                        ucKeySec = 2;          /*低电压触发*/
                   }
             }        
}

/**
* @brief  服务函数
* @param  无
* @retval 根据扫描得到的值,进行处理
**/
void key_Service(void)
{
        switch(ucKeySec)
        {
                case 1: /*触发*/
                                   
//                                HV_OUT = 0;         //输出低电平,打开PMOS管
                                while(--HVDTcnt)
                                {  
                                  HV_OUT = 0;         //输出低电平,打开PMOS管,给后面电路供电
//                   uiHVTimeCnt ++;
//                if(uiHVTimeCnt > count_HV_time1)                //输出低电平延时
//                {
//                      uiHVTimeCnt = 0;
                                  }
                        HV_OUT = 1;
                              ucKeySec = 0;     /*响应光控触发服务处理程序后,编号清零,避免一直触发*/
                    break;

                case 2:   /*电压低于6V,蜂鸣器断续响提示*/
                       if(BLOW == 0)
                           {
                                BUZZER = !BUZZER;
                               delay_ms(500);
                            }
                           
                                else if(BLOW == 1)
                                {
                                        BUZZER = 0;
                                        ucKeySec = 0;
                                 }
                   break;                        
        }
  }

void main()                //主函数
{
        Init();
//        Delay_Long(100);
        Init_Peripheral();

        while(1)
        {
            key_Service();
                //Key_Scan();
                }
}



20231230_140446.png
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 18:39:59

6

主题

81

回帖

2122

积分

金牌会员

积分
2122
发表于 2024-1-2 08:04:31 | 显示全部楼层
完了,帖子要沉底了。。。。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6843

积分

论坛元老

积分
6843
发表于 2024-1-2 10:04:30 | 显示全部楼层
本帖最后由 乘风飞扬 于 2024-1-2 10:15 编辑

我将你的程序复制到项目里编译后烧录到STC8G1K08芯片里测试
P55口每次拉低,P32都会产生一次低电平脉冲信号:
截图202401020954153560.jpg
第一次1ms左右,之后是20ms左右,这跟你的初始化设置有关:
  1. unsigned int  HVDTcnt = 3000;           //输出延时 时间(mS)
复制代码
HVDTcnt只有定义时设置了一次初值,之后就没有再重新赋值,减到0后下次就从65536开始计算。

如果这个程序在你那里测不到P32口的低电平脉冲信号的话,建议检查一下硬件,看看有没有虚焊或者短路。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 18:39:59

6

主题

81

回帖

2122

积分

金牌会员

积分
2122
发表于 2024-1-2 19:41:08 | 显示全部楼层
感谢大佬指正,并亲自测试,HVDTcnt只有定义时设置了一次初值,之后就没有再重新赋值,看到这里恍然大悟,由于只用万用表测了一下P32,电压会波动一下,看不到别的东西,一直怀YI是定时器中断没有写对,导致没检测到P55的状态,这下明白 了,另外这个延时这么写也有问题,它不会一直在while里面运行,而是运行一次就走了,所以一至没有延时效果,,明天改一下程序再试一下,这个问题应该是解决了,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:456
  • 最近打卡:2025-05-02 18:39:59

6

主题

81

回帖

2122

积分

金牌会员

积分
2122
发表于 2024-1-3 10:59:12 | 显示全部楼层
乘风*** 发表于 2024-1-2 10:04
我将你的程序复制到项目里编译后烧录到STC8G1K08芯片里测试
P55口每次拉低,P32都会产生一次低电平脉冲信号 ...

今天 测试了一下,问题就是在这儿,赋的这个初值有问题,3000这个数只有大约1ms左右,而我一直误当做3秒,另外一个问题就是没有重新赋值,如果这里直接用延时哪个函数就没有问题。为什么有延时函数还搞这么多花样,因为是学习,没有实际案例做,所以在找到一个实例后,故意用不同的写法,目的是就是练习,加深理解,现在看,这么做还是有收获的,再次感谢大佬的指点,
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 20:46 , Processed in 0.122607 second(s), 73 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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