找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 432|回复: 5
收起左侧

用红外光发射接收管做输入 单片机输出一个低电平的程序问题

[复制链接]
ID:1075398 发表于 2024-1-2 08:25 | 显示全部楼层 |阅读模式
新手,做了一个用红外光发射接收管做输入,用用STC8G1K08A-8P做控制输出一个低电平的程序,就是发射接收中间有东西,STC8G1K08A-8P的P33就输出低电平。
电路和程序做好之后,实际测试发现STC8G1K08A-8P的P55输入低电平之后,P33没有反应,程序编译能通过,不知道什么问题,是光控接收检测的程序有问题吗?但是直接把P55接地,P33也是一样没反应,找不到问题,求教大佬们能不能指点1,2。
电路和程序附上,请多多指教
下面是单片机程序,请多指教,谢谢(有些语句没用上,忽略它)
#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
回复

使用道具 举报

ID:161164 发表于 2024-1-2 10:55 | 显示全部楼层
你的接收处理代码在中断里运行
但又不开启中断
当然没反应
1.png
2024-01-02_105310.png

回复

使用道具 举报

ID:1075398 发表于 2024-1-2 13:46 | 显示全部楼层
lkc8210 发表于 2024-1-2 10:55
你的接收处理代码在中断里运行
但又不开启中断
当然没反应

感谢大佬回复,中断是打开了的,在主程序里面打开的,现在上传的是修改后的,可以有反应了,但是时间很短,但其实程序里写了如果P55低电平,P32就输出低电平3秒时间,就是没找到它为什么不能延时3秒的原因
回复

使用道具 举报

ID:161164 发表于 2024-1-2 15:53 | 显示全部楼层
Lthrwy 发表于 2024-1-2 13:46
感谢大佬回复,中断是打开了的,在主程序里面打开的,现在上传的是修改后的,可以有反应了,但是时间很短 ...

应为那断
                        while(--HVDTcnt)
                        {
                                HV_OUT = 0;         //输出低
                        }
没加延时
所以几十毫秒后就会跳出循环
在循环里加个delay1ms()延时就可以了
回复

使用道具 举报

ID:1075398 发表于 2024-1-2 18:25 | 显示全部楼层
我这样写,while(--HVDTcnt); 它应该延时才对,好像也没延时,
所以就改成这样了
while(--HVDTcnt)
  {
      HV_OUT = 0;         //输出低
                        }
这 样,好像就是一下子就出去了,问题应该就是出在这儿,明天改成delay1ms()再试
回复

使用道具 举报

ID:1075398 发表于 2024-1-3 10:49 | 显示全部楼层
lkc8210 发表于 2024-1-2 15:53
应为那断
                        while(--HVDTcnt)
                        {

确定了,就是延时这里有问题,程序逻辑没有问题,出问题的是赋的初值,3000只有大约1mS左右,而不是我想的3秒,但我一直当是3秒,,学艺不精害人,
再次感谢大佬,
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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