找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2395|回复: 4
收起左侧

关于单片机IO检测充电问题请教下

[复制链接]
ID:1005692 发表于 2022-7-19 11:32 | 显示全部楼层 |阅读模式
想要实现的功能同步检测和输出,检测到充电3次高电平,IO口开启输出高电平等待200ms关闭输出,充电工作原理必须开关一次,才能继续循环充电,太菜了没写出来,退而求其次写了一个 检测3次 定时器定时3s开启IO口输出,输出的时候定时200ms就关闭 ,现在遇到一个问题 IO输出高电平有时会出现2次波形如图,想要解决这个高电平2次问题,单片机代码不知道怎么去优化没思路了
  1. void main(void)
  2.   {
  3.   cd_tice=0;
  4.   CH_flag=0;
  5.    
  6.    while(1)
  7.     {               
  8.   //--------------------------充电----------------------------               
  9.      if(CH)  //IO中断检测
  10.       {               
  11.           if(time_500ms_ok)
  12.          {        
  13.             time_500ms_ok=0;                                                        
  14.             cd_tice++;   
  15.          }
  16.         AD_OPEN=1;                             
  17.      }
  18.            
  19.                 if(time_10ms_ok)   //10ms定时器中断 置1
  20.                 {
  21.       time_10ms_ok=0;
  22.     if(tmb_CD)   // 充电开关入口
  23.     {                  
  24.        if(time_200ms_ok) //定时器中断200ms进入一次 IO口关
  25.         {
  26.          time_200ms_ok=0;
  27.          KG=0;     //IO端口 0关闭输出 1开启输出                                                            
  28.         }        
  29.                      
  30.     if(time_3s_ok)  //定时器中断3s进入一次开
  31.        {
  32.           time_3s_ok=0;
  33.           KG=1;           
  34.        }
  35.                                                                
  36.     }                                          
  37.                 }         
  38.                                 if(cd_tice>3)
  39.                                 {  
  40.    cd_tice=0;  
  41.    tmb_CD=0;  //充电开关标志位     
  42.    CH_flag=1;   //充电闪灯3下标志位  
  43.    KG=0;

  44.                                 }
  45.                   
  46.                if(time_4s_ok)  //定时器中断 4S进一次  无线充开关标志位
  47.                {
  48.    time_4s_ok=0;
  49.                                         if(CH_flag)
  50.                     {  
  51.    CH_flag=0;   //闪灯3下标志位                  
  52.    tmb_CD=!tmb_CD;  //取反充电开关标志位
  53.                     }
  54.                     else
  55.                     {
  56.    tmb_CD=0;  //关闭充电开关标志位
  57.    KG=0;     

  58.                     }
  59.                  
  60.                }
  61.      }        
  62.    }
复制代码

充电检测IO口高电平

充电检测IO口高电平

IO口输出波形

IO口输出波形
回复

使用道具 举报

ID:161164 发表于 2022-7-19 13:31 | 显示全部楼层
代码不全
单看你提供的代码
KG在三秒内只会出现一次高电平
怀疑time_3s_ok被重复置1
回复

使用道具 举报

ID:1005692 发表于 2022-7-19 13:51 | 显示全部楼层
lkc8210 发表于 2022-7-19 13:31
代码不全
单看你提供的代码
KG在三秒内只会出现一次高电平

time_3s_ok置1 只有在定时器中断到时间后才置1 其余代码都是配置 设置不影响 目前功能就是写了我上面发的这些,我把定时器中断的代码也发出来
  1. /*-------------------------------------------------
  2. *  函数名:interrupt ISR
  3. *        功能:  中断处理函数
  4. *  输入:  无
  5. *  输出:  无
  6. --------------------------------------------------*/
  7. void interrupt ISR(void)                                //PIC_HI-TECH使用
  8. {
  9.    
  10.                 if(EPIF0 & 0x28)                       
  11.                 {
  12.                        
  13.                          EPIF0 |= 0xFF;                           //写1清中断0响应标志位
  14.                
  15.                 }
  16.    
  17.           //定时器4的中断处理**********************
  18.         if(T4UIE && T4UIF)                        //500HZ   2ms
  19.         {
  20.                 T4UIF = 1;                            //写1清零标志位   
  21.                         time_10ms++;
  22.             if(time_10ms>=5)//2*5
  23.             {
  24.                 time_10ms=0;
  25.                 time_10ms_ok=1;
  26.                
  27.             }
  28.                         if(time1++>58)  //100ms  
  29.                         {
  30.                                 time1=0;
  31.                                 time_500ms++;
  32.                 time_200ms++;
  33.                                 time_3s++;
  34.                                 time_1s++;   
  35.                 time_100ms_ok=1;        
  36.                        
  37.                         }      
  38.                                 if(time_200ms==3)
  39.                                 {
  40.                                         time_200ms=0;
  41.                                         time_200ms_ok=1;
  42.                                 }            
  43.                                 if(time_3s>48)  //3s
  44.                                 {
  45.                                         time_3s=0;
  46.                                         time_3s_ok=1;
  47.                                 }  
  48.                
  49.          
  50.                         if(time_500ms>4) // 500ms
  51.                         {
  52.                                 time_500ms=0;
  53.                                 time_500ms_ok=1;
  54.                         }
  55.                
  56.                         if(time_1s>10)  //1000ms=1s
  57.                         {
  58.                                 time_1s=0;
  59.                                 time_1s_ok=1;
  60.                 time_5s++;       
  61.                 time_4s++;
  62.                 if(time_4s>5)
  63.                 {
  64.                     time_4s=0;
  65.                     time_4s_ok=1;
  66.                 }       
  67.                 if(time_5s>6)
  68.                 {
  69.                     time_5s=0;
  70.                     time_5s_ok=1;
  71.                 }
  72.                                 if(time_1min++>60)  //1min
  73.                                 {
  74.                                         time_1min=0;
  75.                                         if(time_5min++>6)  //5min
  76.                                         {
  77.                                                 time_5min=0;
  78.                                                 time_5min_ok=1;
  79.                                         }
  80.                                 }
  81.                         }
  82.     }


  83.    
  84. }  
复制代码
回复

使用道具 举报

ID:401564 发表于 2022-7-19 18:09 | 显示全部楼层
其实这个是可以很简单的去实现的,你这个搞得看起来好恐怖方便的话,把硬件电路上传一下,把涉及商业机密抹去就行如果是直接检测充电电源的话,中断是一定会有抖动的
那么,中断被触发之后,只作清除标志位和置位一个触发标志位,用来告诉主程序:充电线插入或者拔出了,并清除定时器控制的某个变量

主函数再通过定时器变量和触发标志位来进行操作
这是我一个8051的充电检测,只有高电平充电检测,没有拔出检测,但原理是差不多的,你参考一下就知道了
如果是要检测插入和拔出,就增加对应的检测就可以了

KEY为中断端口
void main(void)
{               
        Mcu_Rst();                                                        //单片机初始化       
while(1)
        {                                                                                                                                                
                if(key_press&&(key_10ms>=30)&&KEY)key_disp();        //处理
                //key_press中断触发标志位,只在key_disp();函数中清除
        }       
}


//───────────────────────────────────────────────
void Int0_isr() interrupt 0        //外部中断0
{       
        key_press=1;                          //中断触发
        key_10ms=0x00;                //每次进入中断都清除定时器变量,这样定时器就会在抖动之后才开始计时,从最后一次退出中断开始计时
        IE0=0;//清除中断标志位
}
//────────────────────────────────────────────────
void key_disp()//处理
{                       
        key_press=0;        //清标志位               
}


回复

使用道具 举报

ID:474386 发表于 2022-7-20 08:57 | 显示全部楼层
楼上的,用心去评论,非常到位非常牛逼。我很少夸人,不得不给你点赞。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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