Wddz 发表于 2023-12-30 14:44:26

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

在定时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 intuiIRTimeCnt1 = 0;   /*光控触发时去抖动延时计数器*/
unsigned char ucIRLock1 = 0;      /*光控触发后自锁的变量标志*/

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

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

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

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

//unsigned intuiVoiceCnt = 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口模式定义 */
voidInit_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口初始状态定义 */
voidInit_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;   /*开总中断*/

}

/* 系统初始化 */
voidInit(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();
                }
}



Wddz 发表于 2024-1-2 08:04:31

完了,帖子要沉底了。。。。

乘风飞扬 发表于 2024-1-2 10:04:30

本帖最后由 乘风飞扬 于 2024-1-2 10:15 编辑

我将你的程序复制到项目里编译后烧录到STC8G1K08芯片里测试
P55口每次拉低,P32都会产生一次低电平脉冲信号:

第一次1ms左右,之后是20ms左右,这跟你的初始化设置有关:
unsigned intHVDTcnt = 3000;         //输出延时 时间(mS)HVDTcnt只有定义时设置了一次初值,之后就没有再重新赋值,减到0后下次就从65536开始计算。

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

Wddz 发表于 2024-1-2 19:41:08

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

Wddz 发表于 2024-1-3 10:59:12

乘风飞扬 发表于 2024-1-2 10:04
我将你的程序复制到项目里编译后烧录到STC8G1K08芯片里测试
P55口每次拉低,P32都会产生一次低电平脉冲信号 ...

今天 测试了一下,问题就是在这儿,赋的这个初值有问题,3000这个数只有大约1ms左右,而我一直误当做3秒,另外一个问题就是没有重新赋值,如果这里直接用延时哪个函数就没有问题。为什么有延时函数还搞这么多花样,因为是学习,没有实际案例做,所以在找到一个实例后,故意用不同的写法,目的是就是练习,加深理解,现在看,这么做还是有收获的,再次感谢大佬的指点,
页: [1]
查看完整版本: 我这个程序是定时器有问题吗?STC8G1K08A | 已解决