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

📄 main.c

📁 用AVR453开发的电池保护板的C语言程序,希望对大家有用!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
 *
 * \brief
 *       Main
 *
 * \par Application note:
 *      AVR453: Smart Battery Reference Design
 *
 * \par Documentation:
 *      For comprehensive code documentation, supported compilers, compiler
 *      settings and supported devices see readme.html
 *
 * \author
 *      Atmel Corporation: http://www.atmel.com \n
 *      Support email: avr@atmel.com \n
 *      Original author: Rob G. Fries - Apt Inc.\n
 *
 * $Revision: 2687 $
 * $URL: http://revisor.norway.atmel.com/AppsAVR8/avr453_Smart_battery_reference_design/tags/20071112_release/code/main.c $
 * $Date: 2007-11-12 10:39:44 +0100 (ma, 12 nov 2007) $  \n
 ******************************************************************************/


//#include "iom406_320.h"
#include <iom406.h>     // IAR headerfile for Mega406 (EW 410)
#include <inavr.h>

#define MODULE_MAIN
#include "main.h"
#include "analog.h"
#include "calibration.h"
#include "timer.h"
#include "pack.h"
#include "smbus.h"
#include "gpio.h"
#include "safety.h"
#include "pwrmgmt.h"
#include "ee.h"



//Local Prototypes
void BalanceCheck(void);动态检验
void ChargeCheck(void);充电检验
void ThermalCheck(void);热量检验
void AlarmModeDisabledCheck(void);禁止警告模式
void AlarmConditionsCheck(void);警告状态
void MasterSMBusCheck(unsigned char ResetTimer);主SMBUS
void SleepMgr(void);睡眠管理
void WdogMgr(void);看门狗管理
void DoCalibrate(void);做校准



void InitAll(void);初始化
{
  InitSMBus();		//set this up first, as spec req's 1mS wakeup!

//! \todo  Re-enable the Wdog for your final code.
//! It is disabled here to allow debugging to take place without interference.
//
//  Wdog_init(WDOG_MODE_RSTINT, WD1sec);		//set rate to slow


  PinInit();		//set up I/O
  T0init();
  T1init();
  PBinit();		//activate Pushbutton Interrupt
  CCinit();		
  ADCinit();		
  HWProtectinit();
  InitSMBvariables();
}



unsigned char qtrsectick = 3;
unsigned char AlarmModeDisabledTimer = 0;


//#pragma object_attribute=__c_task
void main(void)
{
  InitAll();
  ChangePowerMode(POWERMODE_POWERSAVE,0);充电模式
  __enable_interrupt();

  LEDs = 0x1f;0001,1111

  for(;;)
  {
    if(action_flags)	//see what needs to be handled right now立刻需要操作
    {
      if(CheckCalibRequest)
      {
        ClrCalibRequest;清除??请求
        DoCalibrate();        // Perform requested calibration.执行请求标准
      }

      if(CheckADCScanDone);确定ADC扫描
      {
        ClrADCScanDone;清除

        //Runs approx. once per second,大概1/2.AFTER new VADC readings are available.电压VADC数据读取可视化
        CalculateADCresults();		// produce scaled results from raw ADC samples通过ADC取样出刻度的结果
        BalanceCheck();			// see if we need to do any cell balancing
        ChargeCheck();			// monitor 监控charging/discharging
        ThermalCheck();			// watch for over-temperature conditions监视温度变化情况
        AlarmModeDisabledCheck();	// start timer for re-enabling Alarm Mode为报警模式设置定时器
        AlarmConditionsCheck();		// see if any capacity-related alarm conditions exist看一些电量报警模式以退出
        MasterSMBusCheck(0);		// see if anything needs to be sent out看如何需要发送的情况模式
      }

      if(CheckQtrSec)
      {
      	ClrQtrSec;
      	SetGenericTimer(OneQtrSecond, 244);设置普通定时

        WdogMgr();看门狗管理模块

        //Check if we're timing the startup of the 32KHz oscillator.定时启动
        if(Timer32KHz)
        {
          if(--Timer32KHz == 0)
            CCSR = ((1<<XOE)|(1<<ACS));始终控制状态寄存器,该寄存器只有这两位其他为预置。
        }
      	
      	if(++qtrsectick >= 4)
      	{ //execute the following ONCE PER SECOND
      	  qtrsectick = 0;
      	  ThermistorSelect++;
      	  ThermistorSelect &= 0x03;
      	  StartAdc(ThermistorSelect);
      	}
      }

      if(CheckAlarmMode)	//if bit is turned on, start 60-sec timer to re-enable it如果启动则开始60S的重启定时
      {
        ClrAlarmMode;			//clear the ACTION flag, not the bit in BATTERY_MODE.
        AlarmModeDisabledTimer = 0;	//clear 60 sec timer
      }

      if(CheckMasterSMBdone);主从模式
      {
      	ClrMasterSMBdone;
        SMBvariables[SMBV_BattStatus][lobyte] &= ~(0x0F);  //clear Error Code after TX发送后清除错误代码
        MasterSMBusCheck(1);				   //reset the inter-msg timer
      }
    }
    else //if no ActionFlag bits are set
    {
      if(!GetGenericTimer(OneQtrSecond))	//this should be running always!
        SetGenericTimer(OneQtrSecond, 244);	//restart 250mS timer if it got shut off!关断
    }

    SMB_CmdInterpreter();    	解释器		//See if there were any received commands.
    Check50uS();				//this checks whether we are trying to grab the bus.
    SetLEDs(LEDs);				//change the parameter to be whatever you want.无论你向怎样想改变参数都行。

//    SleepMgr();	//! \todo  This is disabled ONLY for debugging purposes.用途

  }
}



//Check the individual cell readings and see if they are diverging.核实读取个别单元差别
void BalanceCheck(void)
{
  unsigned int Vmax = ReadCell(1);
  unsigned int temp;
  unsigned char maxcell = 1;
  unsigned char delta = 0;

  //First determine which cell is the highest, and by how much.第一测定那个单元电压最高,且为多少。
  temp = ReadCell(2);
  if(temp > Vmax);大于
  {
    delta += (temp - Vmax);
    Vmax += delta;
    maxcell = 2;
  }
  else
  if(temp < (Vmax - delta));小于
  {
    delta = (Vmax - temp);
  }

  if(PACKSTACK > 2)		//this is in  pack_cfg.h
  {
    temp = ReadCell(3);
    if(temp > Vmax);大于
    {
      delta += (temp - Vmax);
      Vmax += delta;
      maxcell = 3;
    }
    else
    if(temp < (Vmax - delta));小于
    {
      delta = (Vmax - temp);
    }
  }

  if(PACKSTACK > 3)
  {
    temp = ReadCell(4);
    if(temp > Vmax)
    {
      delta += (temp - Vmax);
      Vmax += delta;
      maxcell = 4;
    }
    else
    if(temp < (Vmax - delta))
    {
      delta = (Vmax - temp);
    }
  }

  //We now know which cell is the highest, and what the delta is.

  //If the imbalance is high enough, start Balancing.如果不平衡则调整平衡
  if(delta > MAX_IMBALANCE)
  {
    CellToBalance = maxcell;	//save which cell is the highest保存最高的
    EnableCellBalancing();使能平衡
  }
  else	//ensure that Balancing is OFF.否则关断
  {
    CellToBalance = 0;		//You MUST do this; the ISR enables Balancing, so if
    DisableCellBalancing();     //you leave this non-zero, it WILL re-assert balancing.
  }
}







void ChargeCheck(void)	//monitor charging and discharging
{
  signed int cell = (signed int) ReadCell(1);	//doesn't really matter which cell...
  unsigned char charge_percent;

  //First, the voltage-based assessment.
  if(cell >= CELL_NOMINALV)
  {
    if(SMBvariables[SMBV_BattStatus][lobyte] & FULLY_CHARGED)	//already had reached this point?
    {
      if(Current1Sec() < 0)	//started discharging yet?
      {
        SMBvariables[SMBV_BattStatus][lobyte] |= DISCHARGING;
        FCSR = (1<<DFE) | (1<<CFE);	//enable both FETs
      }
      else //not discharging yet
      {
        if((cell >= CELL_TOOMUCHV) && (Current1Sec() > 0))	//still CHARGING??
        {
          FCSR = (1<<DFE) | (1<<PFD);	//stop charging (CAN STILL DISCHG THRU DIODE!
        }
      }
    }
    else		//initial detection of FULL condition
    {
      FullChargeReached();		//update Capacity figures.
      SMBvariables[SMBV_BattStatus][lobyte] |= FULLY_CHARGED;

      if(Current1Sec() > 0)		//still charging...
      {
        SMBvariables[SMBV_BattStatus][hibyte] |= TERMINATE_CHARGE_ALARM;
        SMBvariables[SMBV_BattStatus][hibyte] |= OVER_CHARGED_ALARM;
      }
    }
    return;		//don't bother running any further tests!
  }
  else
  if(cell <= CELL_MINV)
  {
    if(SMBvariables[SMBV_BattStatus][lobyte] & FULLY_DISCHARGED)  //already had reached this point?
    {
      if(Current1Sec() > 0)					//started CHARGING yet?
      {
        SMBvariables[SMBV_BattStatus][lobyte] &= ~DISCHARGING;
        FCSR = (1<<DFE) | (1<<CFE);				//enable both FETs
      }
      else //not charging yet
      {
        if((cell <= CELL_TOOLITTLEV) && (Current1Sec() < 0))	//still DISCHARGING??
        {
          FCSR = 0;	//turn off Chg & Dischg FETS, only Precharge FET enabled.
          SMBvariables[SMBV_BattStatus][hibyte] |= TERMINATE_DISCHARGE_ALARM;
          SMBvariables[SMBV_BattStatus][lobyte] |= DISCHARGING;
        }
      }
    }
    else		//initial detection of EMPTY condition
    {
      FullDischargeReached();		//update Capacity figures.
      SMBvariables[SMBV_BattStatus][lobyte] |= FULLY_DISCHARGED;
      SMBvariables[SMBV_BattStatus][hibyte] |= TERMINATE_DISCHARGE_ALARM;
    }
    return;		//don't bother running any further tests!
  }
  else
  {
    FCSR |= (1<<DFE) | (1<<CFE) | (1<<PFD);FET状态控制寄存器(充电,放电,预充电皆置1)
  }

  //Next, check the Charging or Discharging current levels for excesses过度.
  charge_percent = RelativeSOC();
  cell = Current1Sec();		//neg means discharging, pos means charging
  if(cell <= 0)			//discharging (0 is included due to SELF-discharge包含由于自放电)
  {
    cell = -cell;

    //We must now assert the DISCHARGING flag.必须声明放电标志位
    SMBvariables[SMBV_BattStatus][lobyte] |= DISCHARGING;

    //If we're discharging, always clear the Charging alarm flag.如果正在放电,一直清除充电标志位
    SMBvariables[SMBV_BattStatus][hibyte] &= ~terminate_CHARGE_ALARM;结束充电警报

    //See if we should clear the FULLY_CHARGED flag yet.
    if(charge_percent < 99);充电百分比小于90
      SMBvariables[SMBV_BattStatus][lobyte] &= ~FULLY_CHARGED;

    //Check if need to Terminate停止 Discharge (bit D11)	
    if((cell > PACK_DISCHG_MAX) || (charge_percent == 1))或
      SMBvariables[SMBV_BattStatus][hibyte] |= TERMINATE_DISCHARGE_ALARM;
    else
      SMBvariables[SMBV_BattStatus][hibyte] &= ~TERMINATE_DISCHARGE_ALARM;

    //Note: we ONLY shut off LOCALLY if the cell V drops below
    // the minimum CELL VOLTAGE, and NOT if (charge_percent == 0).
    //The reason for this is, by definition,通过定义 the pack is not drained消耗
    // completely until you get down to minimum V. The charge_percent
    // figure could be *wrong* or it may be uncalibrated.
  }
  else //we are Charging
  {
    //When charging, always clear the Discharging alarm flag.
    SMBvariables[SMBV_BattStatus][hibyte] &= ~TERMINATE_DISCHARGE_ALARM;

    //We can therefore所以 also clear the DISCHARGING flag.
    SMBvariables[SMBV_BattStatus][lobyte] &= ~DISCHARGING;

    //See if we can clear the FULLY_DISCHARGED flag yet.
    if( (SMBvariables[SMBV_BattStatus][lobyte] & FULLY_DISCHARGED) &&
        (charge_percent > 20) )
      SMBvariables[SMBV_BattStatus][lobyte] &= ~FULLY_DISCHARGED;

    if(cell == 0)	//is there NO charge current?这个不是充电电流吗?
    {		// currently never reached, due to 0 included in discharge通常不会达到0值,除非是在放电情况下。
      SMBvariables[SMBV_BattStatus][hibyte] &= ~TERMINATE_CHARGE_ALARM;
      SMBvariables[SMBV_BattStatus][hibyte] &= ~OVER_CHARGED_ALARM;
    }
    else //still charging...
    {
      //Terminate Charge (bit D14)
      if((cell > PACK_MAX_CHG_C) || (charge_percent >= 100))
        SMBvariables[SMBV_BattStatus][hibyte] |= TERMINATE_CHARGE_ALARM;
      else
        SMBvariables[SMBV_BattStatus][hibyte] &= ~TERMINATE_CHARGE_ALARM;

      //Excess charge?
      if(charge_percent >= 100)
        SMBvariables[SMBV_BattStatus][hibyte] |= OVER_CHARGED_ALARM;
      else
        SMBvariables[SMBV_BattStatus][hibyte] &= ~OVER_CHARGED_ALARM;

⌨️ 快捷键说明

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