找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3304|回復(fù): 4
收起左側(cè)

關(guān)于單片機IO檢測充電問題請教下

[復(fù)制鏈接]
ID:1005692 發(fā)表于 2022-7-19 11:32 | 顯示全部樓層 |閱讀模式
想要實現(xiàn)的功能同步檢測和輸出,檢測到充電3次高電平,IO口開啟輸出高電平等待200ms關(guān)閉輸出,充電工作原理必須開關(guān)一次,才能繼續(xù)循環(huán)充電,太菜了沒寫出來,退而求其次寫了一個 檢測3次 定時器定時3s開啟IO口輸出,輸出的時候定時200ms就關(guān)閉 ,現(xiàn)在遇到一個問題 IO輸出高電平有時會出現(xiàn)2次波形如圖,想要解決這個高電平2次問題,單片機代碼不知道怎么去優(yōu)化沒思路了
  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)   // 充電開關(guān)入口
  23.     {                  
  24.        if(time_200ms_ok) //定時器中斷200ms進入一次 IO口關(guān)
  25.         {
  26.          time_200ms_ok=0;
  27.          KG=0;     //IO端口 0關(guān)閉輸出 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;  //充電開關(guān)標志位     
  42.    CH_flag=1;   //充電閃燈3下標志位  
  43.    KG=0;

  44.                                 }
  45.                   
  46.                if(time_4s_ok)  //定時器中斷 4S進一次  無線充開關(guān)標志位
  47.                {
  48.    time_4s_ok=0;
  49.                                         if(CH_flag)
  50.                     {  
  51.    CH_flag=0;   //閃燈3下標志位                  
  52.    tmb_CD=!tmb_CD;  //取反充電開關(guān)標志位
  53.                     }
  54.                     else
  55.                     {
  56.    tmb_CD=0;  //關(guān)閉充電開關(guān)標志位
  57.    KG=0;     

  58.                     }
  59.                  
  60.                }
  61.      }        
  62.    }
復(fù)制代碼

充電檢測IO口高電平

充電檢測IO口高電平

IO口輸出波形

IO口輸出波形
回復(fù)

使用道具 舉報

ID:161164 發(fā)表于 2022-7-19 13:31 | 顯示全部樓層
代碼不全
單看你提供的代碼
KG在三秒內(nèi)只會出現(xiàn)一次高電平
懷疑time_3s_ok被重復(fù)置1
回復(fù)

使用道具 舉報

ID:1005692 發(fā)表于 2022-7-19 13:51 | 顯示全部樓層
lkc8210 發(fā)表于 2022-7-19 13:31
代碼不全
單看你提供的代碼
KG在三秒內(nèi)只會出現(xiàn)一次高電平

time_3s_ok置1 只有在定時器中斷到時間后才置1 其余代碼都是配置 設(shè)置不影響 目前功能就是寫了我上面發(fā)的這些,我把定時器中斷的代碼也發(fā)出來
  1. /*-------------------------------------------------
  2. *  函數(shù)名:interrupt ISR
  3. *        功能:  中斷處理函數(shù)
  4. *  輸入:  無
  5. *  輸出:  無
  6. --------------------------------------------------*/
  7. void interrupt ISR(void)                                //PIC_HI-TECH使用
  8. {
  9.    
  10.                 if(EPIF0 & 0x28)                       
  11.                 {
  12.                        
  13.                          EPIF0 |= 0xFF;                           //寫1清中斷0響應(yīng)標志位
  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. }  
復(fù)制代碼
回復(fù)

使用道具 舉報

ID:401564 發(fā)表于 2022-7-19 18:09 | 顯示全部樓層
其實這個是可以很簡單的去實現(xiàn)的,你這個搞得看起來好恐怖方便的話,把硬件電路上傳一下,把涉及商業(yè)機密抹去就行如果是直接檢測充電電源的話,中斷是一定會有抖動的
那么,中斷被觸發(fā)之后,只作清除標志位和置位一個觸發(fā)標志位,用來告訴主程序:充電線插入或者拔出了,并清除定時器控制的某個變量

主函數(shù)再通過定時器變量和觸發(fā)標志位來進行操作
這是我一個8051的充電檢測,只有高電平充電檢測,沒有拔出檢測,但原理是差不多的,你參考一下就知道了
如果是要檢測插入和拔出,就增加對應(yīng)的檢測就可以了

KEY為中斷端口
void main(void)
{               
        Mcu_Rst();                                                        //單片機初始化       
while(1)
        {                                                                                                                                                
                if(key_press&&(key_10ms>=30)&&KEY)key_disp();        //處理
                //key_press中斷觸發(fā)標志位,只在key_disp();函數(shù)中清除
        }       
}


//───────────────────────────────────────────────
void Int0_isr() interrupt 0        //外部中斷0
{       
        key_press=1;                          //中斷觸發(fā)
        key_10ms=0x00;                //每次進入中斷都清除定時器變量,這樣定時器就會在抖動之后才開始計時,從最后一次退出中斷開始計時
        IE0=0;//清除中斷標志位
}
//────────────────────────────────────────────────
void key_disp()//處理
{                       
        key_press=0;        //清標志位               
}


回復(fù)

使用道具 舉報

ID:474386 發(fā)表于 2022-7-20 08:57 | 顯示全部樓層
樓上的,用心去評論,非常到位非常牛逼。我很少夸人,不得不給你點贊。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復(fù) 返回頂部 返回列表