我这个程序是定时器有问题吗?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();
}
}
完了,帖子要沉底了。。。。 本帖最后由 乘风飞扬 于 2024-1-2 10:15 编辑
我将你的程序复制到项目里编译后烧录到STC8G1K08芯片里测试
P55口每次拉低,P32都会产生一次低电平脉冲信号:
第一次1ms左右,之后是20ms左右,这跟你的初始化设置有关:
unsigned intHVDTcnt = 3000; //输出延时 时间(mS)HVDTcnt只有定义时设置了一次初值,之后就没有再重新赋值,减到0后下次就从65536开始计算。
如果这个程序在你那里测不到P32口的低电平脉冲信号的话,建议检查一下硬件,看看有没有虚焊或者短路。 感谢大佬指正,并亲自测试,HVDTcnt只有定义时设置了一次初值,之后就没有再重新赋值,看到这里恍然大悟,由于只用万用表测了一下P32,电压会波动一下,看不到别的东西,一直怀YI是定时器中断没有写对,导致没检测到P55的状态,这下明白 了,另外这个延时这么写也有问题,它不会一直在while里面运行,而是运行一次就走了,所以一至没有延时效果,,明天改一下程序再试一下,这个问题应该是解决了, 乘风飞扬 发表于 2024-1-2 10:04
我将你的程序复制到项目里编译后烧录到STC8G1K08芯片里测试
P55口每次拉低,P32都会产生一次低电平脉冲信号 ...
今天 测试了一下,问题就是在这儿,赋的这个初值有问题,3000这个数只有大约1ms左右,而我一直误当做3秒,另外一个问题就是没有重新赋值,如果这里直接用延时哪个函数就没有问题。为什么有延时函数还搞这么多花样,因为是学习,没有实际案例做,所以在找到一个实例后,故意用不同的写法,目的是就是练习,加深理解,现在看,这么做还是有收获的,再次感谢大佬的指点,
页:
[1]