⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbelectronic.txt

📁 本程序是一个基于单片机智能充电器的程序
💻 TXT
字号:
#include<reg925.h>
#define uchar unsigned char
#define uint unsigned int

//-----------------------------------------------
//Global Variable Definitions
//---------------------------------------------

uint data RTC_Counter_AD;         //RTC count for AD convert
uint data AD_Convert_Speed;       //AD convert interval
uint data RTC_Counter;            //RTC count for delay
uchar data RTC_Counter_Minute;    // minutes counter for dalay
bit data LED_Flag, AD_Flag, Battery_On_Socket;
bit data Pre_Charge_Status, Constant_Current_Charge, Constant_Voltage_Charge;
uint data AD1_1,AD1_2,AD1_3;      //AD1.1-Battery V+, AD1.2-temp., AD1.3-I detect

//-----------------------------------------------
//Constant Definitions
//-----------------------------------------------
#define RED P1.4
#define GREEN P1.6
#define YELLOW P1.7
#define STOP_CHARGE_DELAY 50       // define delay time when charge I <60mA, x Minutes

//***************************************************************************
//* Functions
//***************************************************************************
void main(void); // main loop
void init(void); // part initialization
void ad_convert(void);

void main ()
{
 EA = 0;
 init();
 EA = 1;
 for( RTC_Counter = 1; RTC_Counter < 1700; );
 RTC_Counter = 0;
 for(;;)
  {
    if( ( AD_Flag == 1 ) && ( Battery_On_Socket == 1 ))
                  // start AD convert and PWM control, with pre-set AD convert speed
   {               // AD_Flag control AD convert speed
    ad_convert();
    AD_Flag = 0;
   }
   if( RTC_Counter_Minute == STOP_CHARGE_DELAY )    // If delay ended, stop charge
    {
     EA = 0;            //shut down interrupt, so AD_Flag can not be set
     KB7 = 0;           //Shut down PWM
     RED=0;             //LED stable RED
     GREEN=1;
     YELLOW=1;
     }
   }
}



void init(void)
{
 SP = 0x30;              //Set SP from 50H to 7FH
//-----------------------------------------------
//Config P0 I/O
//-----------------------------------------------
  P0M1 = 0x86;       // Set P0.2/3/4 for Input Only, 0001 1100
  P0M2 = 0xF9;       // Set P0.1 for PP, ^1 for led drive, 1110 0011, others all pp
//-----------------------------------------------
//Config P1 I/O
//-----------------------------------------------
  P1M1 = 0x20;        // ^5 Input only 0010 0100
  P1M2 = 0xDF;        // set ^2 open drain 1101 1111 others all pp
//-----------------------------------------------
//Config P2 I/O (P2 not used)
//-----------------------------------------------
   P3M1 = 0x00;       // All PP
   P3M2 = 0xFF;
   KB7 = 0;          //set p0.7 = 0 can forfid T1 PWM
   P1 = 0x00;        
   P2 = 0x00;
   
   RTC_Counter = 0x00;
   
   RED=1;
   GREEN=1;
   YELLOW=1;

   AD1_0 = 0;
   AD1_1 = 0;
   AD1_Flag = 0;
   
   AD_Flag = 0;
   Pre_Charge_Status = 0;
   Constant_Current_Charge = 0;
   Constant_Voltage_Charge = 0;
   RTC_Counter_Minute = 0;
   Battery_On_Socket = 1;
   AD_Convert_Speed = 10;
//-----------------------------------------------
//Initialize RTC for time delay counter
//-----------------------------------------------
   WDCON &= 0xE0;       //Shut down WDT
   RTCH = 0x01;        //Set 16bit counter for RTC, about 8.9ms
   RTCL = 0xFF;
   RTCCON = 0x63;      //RTC Enable, CCLK use Internal RC oscillator
   EWDRT = 1;          //Enable RTC/WD Interrupt
//-----------------------------------------------
//Initialize T0 for PWM
//-----------------------------------------------
   TMOD=0x20;         //Set T1mode 6
   TAMOD=0x10;        //For PWM, 0x01
   TH0 = 255;         //Duty cycle = 256 - TH0
   AUXR1 = 0x20;      //Enable toggling pin P1.2
   TR1 = 1;           //Enable T1
//----------------------------------------------------------------------
//Enable the A/D Converter and use the CPU clock as the A/D clock.
//----------------------------------------------------------------------
  ADMODA = 0x10;     //AD1 single mode no boundary interrupt
  ADMODB = 0xA0;     //AD "A0" for CCLK/6, 12/6=2M
  ADINS = 0x30;      //Enable AD10,AD11
  ADCON1 = 0x04;     //Enable AD1 with timer no start occurs mode, no completed & boundary                          interrupt
}

void ad_convert ()
{
  uchar temp = 0;
  ADCON1 = 0x01;               //Enable AD convert
  AD1_0=(256/5)*AD10;
  AD1_1=(256/5)*AD11;
  while( !(ADCON1 & 0x08) );   //waiting for AD to end
  ADCON1 &= ~0x08;

//-----------------------------------------------
//AD11 for battery voltage detect
//-----------------------------------------------
  if( AD1_0 > 237 ) // If Vout > 4.64v
   {                // Prevent battery plug out during charging
    KB7=0;
    Battery_On_Socket = 0;   // forbid AD convert
    RTC_Counter = 5000;      //Delay 15's, then enable AD convert in RTC_Interrupt()
    YELLOW=0;               // indicate error status-battery not in socket
    RED=1;
    GREEN=1;
    }
    else if( AD1_0 <= 52 )   // If Vout <1V,battery shortage
           {
            KB7=0;          //Set p0.7 = 0, forbid PWM, shut down output
            YELLOW=0;       // indicate error status
            RED=1;
            GREEN=1;
            }
    else if( AD1_0 <154)    //If Vout<= 3V
           {
            KBI=1;     // Enable P0.7 PWN
            TH0 = 250;    // 初始化预充电流~50mA
            GREEN=0;     // indicate charging status
            RED=1;
            YELLOW=1;
         if( Constant_Current_Charge == 0 ) Pre_Charge_Status = 1; // Set Precharge status
         }
    else if( AD1_0 < 218)      // detect Vout = battery voltage + 0.4*1 =4.27V
         {
          KB7=1;
          GREEN=0;    // indicate charging status
          RED=1;
          YELLOW=1;
          if( Constant_Voltage_Charge == 0)
            {
             Constant_Current_Charge = 1;   // Set Constant Current Charge status
             Pre_Charge_Status = 0;     // forbid Precharge status
             }
            }
     else         // If 4.26V < Vout <4.6V
         {
           KB7=1;
           GREEN=0;      // indicate charging status
           RED=1;
           YELLOW=1;
           Constant_Voltage_Charge = 1;   // Set Constant Voltage Charge status
           Constant_Current_Charge = 0;   // forbid Constant Current Charge status
           Pre_Charge_Status = 0;         // forbid Precharge status
           }
          temp = AD1_0;
          AD1_0 = 0;      // reset AD1_1
//-----------------------------------------------
//AD11 for charge current detect
//-----------------------------------------------
    if( Pre_Charge_Status == 1 )
      {
        if( ( AD1_1 > 3) && ( TH0 < 250 ) )    // ensure Pre-charger current < 60mA
          { TH0++;}
       }
      else if( Constant_Current_Charge == 1 )
             {
              if( AD1_1 < 21)      //400mV  (I charge = 400mA)
                {                  // if I charge < 400mA, pwm++
                if( TH0 < 2 )
                  {
                   TH0 = 1;
                   if( RTC_Counter == 0 )    //start 20 minutes delay to end charge
                     { RTC_Counter = 1; }   //this case happened for charged battery,
                                              if Vout < 2.6v
                                           //while Ibat can't achieve400mA, even max PWM
                   }
                else
                   { TH0 = TH0 - 1; }
               }
     else if( AD1_1 > 21)
            {                     //if I charge > 400mA, pwm--
             if( TH0 > 253 )
             { TH0 = 254; }
          else
             {
              TH0 = TH0 + 1;
              }
               }
    }
    else if( Constant_Voltage_Charge == 1 )
           {
            if( AD1_1 <= 3 )      // Charge current is < 60mA
              {
               if( RTC_Counter == 0 ) { RTC_Counter = 1; } //start 50 minutes delay to end                                                              charge
               }
            if( temp > 216 )    //temp=AD1_0, if Vout is > 4.23v(achieve 4.23v), -- PWM
              {
               if( TH0 < 255)
                 {TH0++;}
                }
             else if( temp <= 216)    // if Vout is < 4.23v (achieve 4.21v), ++PWM
                    {
                     if( TH0 > 1 )
                       { TH0--;}
                      }  
              }
               AD1_1 = 0; // reset AD1_1
    }
     else
         {
          AD1_1 += AD1DAT1;
          AD1_2 += AD1DAT2;
          AD1_3 += AD1DAT3;
           }
  }

void RTC_Interrupt (void) 
{
  if( RTC_Counter != 0 ) { RTC_Counter++; }
  RTC_Counter_AD++;

  if ( RTC_Counter_AD == AD_Convert_Speed )
     {
      AD_Flag = 1;
      RTC_Counter_AD = 0;
      }
  if ( RTC_Counter == 6750)     // delay for 1 minute
    {
     RTC_Counter_Minute++;
     RTC_Counter = 1;
    if( Battery_On_Socket == 0)   // complete 15's delay for battery not in socket
      {
       Battery_On_Socket = 1;
       RTC_Counter = 0;
       }
     }
     RTCCON = 0x63;            //Clear RTCCON.7-RTCF
 }
 
    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -