專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

STC12C2052AD做的手機(jī)電池充電器

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2011年03月31日   【字體:
 /*******************
 C語(yǔ)言運(yùn)算符優(yōu)先級(jí) 
 

   1級(jí)優(yōu)先級(jí) 左結(jié)合    
  () 圓括號(hào)   [] 下標(biāo)運(yùn)算符   -> 指向結(jié)構(gòu)體成員運(yùn)算符   . 結(jié)構(gòu)體成員運(yùn)算符      
   
   2級(jí)優(yōu)先級(jí) 右結(jié)合     
  ! 邏輯非運(yùn)算符   ~ 按位取反運(yùn)算符  ++ 自增運(yùn)算符  -- 自減運(yùn)算符  - 負(fù)號(hào)運(yùn)算符 (類(lèi)型) 類(lèi)型轉(zhuǎn)換運(yùn)算符 * 指針運(yùn)算符 & 地址與運(yùn)算符 sizeof 長(zhǎng)度運(yùn)算符
           
   3級(jí)優(yōu)先級(jí) 左結(jié)合     
  * 乘法運(yùn)算符   / 除法運(yùn)算符   % 取余運(yùn)算符     
   
   4級(jí)優(yōu)先級(jí) 左結(jié)合    
  + 加法運(yùn)算符   - 減法運(yùn)算符 

   5級(jí)優(yōu)先級(jí) 左結(jié)合     
  << 左移運(yùn)算符   >> 右移運(yùn)算符 

   6級(jí)優(yōu)先級(jí) 左結(jié)合    
  <、<=、>、>= 關(guān)系運(yùn)算符 

   7級(jí)優(yōu)先級(jí) 左結(jié)合    (注意"等于"運(yùn)算符== ) 
  == 等于運(yùn)算符   != 不等于運(yùn)算符 
         
   8級(jí)優(yōu)先級(jí) 左結(jié)合     
  & 按位與運(yùn)算符 

   9級(jí)優(yōu)先級(jí) 左結(jié)合   
  ^ 按位異或運(yùn)算符 

   10級(jí)優(yōu)先級(jí) 左結(jié)合  
  | 按位或運(yùn)算符 

   11級(jí)優(yōu)先級(jí) 左結(jié)合    
  && 邏輯與運(yùn)算符 
   
   12級(jí)優(yōu)先級(jí) 左結(jié)合  
  || 邏輯或運(yùn)算符    
   
   13級(jí)優(yōu)先級(jí) 右結(jié)合    
  ? : 條件運(yùn)算符 

   14級(jí)優(yōu)先級(jí) 右結(jié)合 (賦值運(yùn)算符) 
  =+ =- =*   =/ =% =   >= < <=   &= ^= |= 全為賦值運(yùn)算符 

   15級(jí)優(yōu)先級(jí) 左結(jié)合  
  , 逗號(hào)運(yùn)算符 
 *******************************/
#include <stc12c2052ad.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define AD_SPEED   0x60 //0110,0000   1      1     270個(gè)時(shí)鐘周期轉(zhuǎn)換一次, 
//少占魚(yú)制作  河北正定歡迎您   長(zhǎng)沙航空職業(yè)技術(shù)學(xué)院  2010 年QQ:41165643 
//
sbit M=P1^5; //過(guò)壓指示燈 
sbit N=P1^6; //欠壓指示燈 
sbit LED=P1^7; //充滿(mǎn) 指示燈 
sbit  REF=P1^0;
sbit PWM=P3^7;

bit START =0;

uchar timeL=0x90;
uchar timeH=0x90;
/****************************************************************/
void pwm();
void delayms(uint);          
void ADC();
void InitADC();
//void baohu();

float voltage=0.0; 
const float Uref=2.500 ;

/***8**************************************************************/
 void main()
{  
  
 PWM=1;
   delayms(700);
 START=0;
 PWM=0;
 LED=0;
 REF=0;
 delayms(9000);

 delayms(1000);
 M=0;
 N=0;
 LED=0;
  delayms(7000);
 M=1;
 N=1;
   LED=1;
    delayms(7000);
 PWM=1;
    delayms(1000);//延時(shí) 
  pwm();
    InitADC();
    delayms(6000);
    START=0;

   while(1)
   {
     ADC();

  if(START)
  {
  pwm();
  delayms(2000);
     }
   }
    
}
//
//
 void pwm()

{ 
   CR=0; 
   START=0;

    //PCA模塊工作于PWM模式 C程序   

   CMOD = 0x02; //用定時(shí)器0溢出做PCA脈沖     
   CL = 0x00; //PCA定時(shí)器低8位 地址:E9H    
   CH = 0x00; //PCA高8位 地址 F9H   
   CCON=0x00;

   CCAP0L = timeL; //PWM模式時(shí)他倆用來(lái)控制占空比   
   CCAP0H = timeH; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     

   CCAPM0 = 0x42; //0100,0010 Setup PCA module 0 in PWM mode
               // ECOM0=1使能比較 PWM0=1 使能CEX0腳用作脈寬調(diào)節(jié)輸出
/*********************
PCA 模塊工作模式設(shè)置 (CCAPMn 寄存器 n= 0-3四種)
 7     6        5        4       3       2     1      0
 -   ECOMn   CAPPn     CAPNn   MATn     TOGn   PWMn   ECCFn
選項(xiàng): 0x00 無(wú)此操作
       0x20 16位捕捉模式,由 CEXn上升沿觸發(fā)
       0x10 16位捕捉模式,由CEXn下降沿觸發(fā)
       0x30 16位捕捉模式,由CEXn的跳變觸發(fā)
       0x48 16位軟件定時(shí)器
       0x4c 16位高速輸出
       0x42  8位PWM輸出
 每個(gè)PCA模塊另外還對(duì)應(yīng)兩個(gè)寄存器:CCAPnH和CCAPnL 。  捕獲或者比較時(shí),它們用來(lái)
保存16位計(jì)數(shù)值,當(dāng)工作于PWM模式時(shí),用來(lái)控制占空比    
*******************************/      

   CR=1; //Start PCA Timer.

}


//AD轉(zhuǎn)換初始化 ----打開(kāi)ADC電源 
void InitADC()
{
P1=0xff;
ADC_CONTR|=0x80;
delayms(3);
//這兩個(gè)寄存器用來(lái)設(shè)置 P1口四種狀態(tài),每一位對(duì)應(yīng)一個(gè)P1引腳 ,按狀態(tài)組合操作 

/*****************
 P1M0 和P1M1 寄存器位  7      6     5    4     3      2     1     0 
                     P1.7  P1.6  P1.5  P1.4  P1.3  P1.2  P1.1  P1.0 
 同理P3M0  P3M0 也是。因?yàn)镾TC12C2052AD只有兩個(gè)P口,所以只有這倆組  STC12C5410AD還多P2M0 P1M0 有三組    
  P1M0   P1M1                 高 
    0   0     普通I0口 (準(zhǔn)雙向)        P1寄存器位  7      6     5    4     3      2     1     0 
 0      1     強(qiáng)推挽輸出 (20MA電流 )盡量少用      P1.7  P1.6  P1.5  P1.4  P1.3  P1.2  P1.1  P1.0 
 1  0     僅做輸入  A/D轉(zhuǎn)換時(shí)可用此模式     
 1      1    開(kāi)漏 ,A/D轉(zhuǎn)換時(shí)可用此模式 
  

  例如: 
  要設(shè)置P1.1為 AD 輸入口 
  則 P1M0=0X02 ;
     P1M1=0X02;   開(kāi)漏即可 
  當(dāng)不用AD時(shí),最好 關(guān)閉ADC電源 ,恢復(fù)為IO口狀態(tài) 
********************************/
P1M0=0x06;//這兩個(gè)寄存器用來(lái)設(shè)置 P1口四種狀態(tài),每一位對(duì)應(yīng)一個(gè)P1引腳 ,按狀態(tài)組合操作 
P1M1=0x06;//設(shè)置P1.1 P1.2開(kāi)漏狀態(tài) 

 }

 

// AD轉(zhuǎn)換程序 
void  ADC() 
{ 
    float V0,V1;

    ADC_DATA   = 0; //清除結(jié)果 

    ADC_CONTR = 0x60;      //轉(zhuǎn)換速度設(shè)置  0x60  最快速度 

    ADC_CONTR = 0xE0;               //1110,0000 清 ADC_FLAG, ADC_START 位和低 3 位 

    ADC_CONTR |= 0x01;           //選擇 A/D 當(dāng)前通道   P1.1 
    delayms(1);                       //使輸入電壓達(dá)到穩(wěn)定 
   ADC_CONTR |= 0x08;              //0000,1000 令 ADCS = 1, 啟動(dòng)A/D轉(zhuǎn)換,  

    while(!(ADC_CONTR & 0x10)); //!的優(yōu)先級(jí)比&高太多了  
   //養(yǎng)成經(jīng)常加括號(hào)的習(xí)慣 ,沒(méi)壞處 。也不浪費(fèi)速度 
 /***************
 這里while 不能改成while(ADC_CONTR & 0x10==0) ;就錯(cuò)誤了,因?yàn)閮?yōu)先級(jí) ==比&高 ,所以要加括號(hào) 
  while( (ADC_CONTR & 0x10)  ==0)    或者非一下  while(!(ADC_CONTR & 0x10)); //!的優(yōu)先級(jí)比&高太多了  
    while( (ADC_CONTR & 0x10)  ==1)注意 if while這類(lèi)判斷邏輯真假的語(yǔ)句,用“==1”時(shí) 注意前面是否是后面的1,
 后面的1可是0x01啊,前面要是0x02===1,這是不會(huì)成立的。但是去掉后面的==1就可以用了。多此一舉反而帶來(lái)麻煩  
 *****************************/
    ADC_CONTR &= 0xE7;     //1111,0111 清 ADC_FLAG 位, 關(guān)閉A/D轉(zhuǎn)換,  

    V0=  ADC_DATA; //返回 A/D 10 位轉(zhuǎn)換結(jié)果 


    ADC_DATA   = 0; //清除結(jié)果 

    ADC_CONTR = 0x60;      //轉(zhuǎn)換速度設(shè)置  0x60  最快速度 

    ADC_CONTR = 0xe0;               //1110,0000 清 ADC_FLAG, ADC_START 位和低 3 位 
   ADC_CONTR =0xe2;
   //  ADC_CONTR |= 0x02;           //選擇 A/D 當(dāng)前通道   P1.2 
    delayms(1);                       //使輸入電壓達(dá)到穩(wěn)定 
    ADC_CONTR = 0xea;
   // ADC_CONTR |= 0x08;              //0000,1000 令 ADCS = 1, 啟動(dòng)A/D轉(zhuǎn)換,  

    while(!(ADC_CONTR & 0x10)); //!的優(yōu)先級(jí)比&高太多了  
   //養(yǎng)成經(jīng)常加括號(hào)的習(xí)慣 ,沒(méi)壞處 。也不浪費(fèi)速度 

 ADC_CONTR =0xe2;
    //ADC_CONTR &= 0xE7;     //1111,0111 清 ADC_FLAG 位, 關(guān)閉A/D轉(zhuǎn)換,  
 V1=  ADC_DATA; //返回 A/D 10 位轉(zhuǎn)換結(jié)果 

 voltage=V1/V0*Uref*3.000;

   

   if( voltage>4.180)
    {
     M=0;//過(guò)壓燈 
     N=1;
     LED=1;
 timeL=timeL+0x08;
 timeH=timeH+0x08;
 START=1;
 LED=0;
    }
   if(voltage<3.601)
    { 
    N=0;//欠壓燈 
 M=1;
 LED=1;
 timeL=timeL-0x01;
 timeH=timeH-0x01;
 START=1;
    }

 if(voltage>=3.601&&voltage<=4.155)
 {
  M=1;
  N=1;
  LED=1;
 }  
 
    if(voltage>=4.110&&voltage<=4.155)
   {
    timeL = 0xa2; //PWM模式時(shí)他倆用來(lái)控制占空比
    timeH = 0xa2; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出) 
    START=1;
 LED=0;
    }

     if(voltage>=4.155&&voltage<=4.180)
   {
    timeL = 0xb2; //PWM模式時(shí)他倆用來(lái)控制占空比
    timeH = 0xb2; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出) 
    START=1;
 LED=0;
    }

  /**************************
     if( voltage<3.772&&(timeL!=0xf0))
    {
   timeL = 0xf0; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0xf0; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     
   START=1;
    }

   if( voltage<4.052&&voltage>3.772&&(timeL!=0xf2))
    {
   timeL = 0xf2; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0xf2; //0xc0 64/256=25% 占空比(溢出) 高電平時(shí)間     
   START=1;
     M=1;
  N=1;
  LED=1;
    }
  
   if( voltage>4.052&&voltage<4.167&&(timeL!=0xfd))
    {
   timeL = 0xfd; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0xfd; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     
   START=1;
     M=1;
  N=1;
  LED=1;
    }

    if( voltage>4.167&&voltage<4.208&&(timeL!=0x60))
   {
   timeL = 0x80; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0x80; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     
   START=1;
     M=1;
  N=1;
  LED=1;
    }

   if(voltage>4.2050&&voltage<4.235)
   {
    timeL = 0x96; //PWM模式時(shí)他倆用來(lái)控制占空比
    timeH = 0x96; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出) 
    START=1;
 LED=0;
    }

   ****************************************************/

 

} 


 /**********
// 保護(hù)函數(shù) 
   void baohu()
   {
   
      if( voltage>4.231)
    {
     M=0;//過(guò)壓燈 
     N=1;
     LED=1;
    }
   if(voltage<3.501)
    { 
    N=0;//欠壓燈 
 M=1;
 LED=1;
    }

     if( voltage<3.772&&(timeL!=0xcf))
    {
   timeL = 0xcf; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0xcf; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     
   START=1;
    }

   if( voltage<4.052&&voltage>3.772&&(timeL!=0x60))
    {
   timeL = 0x60; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0x60; //0xc0 64/256=25% 占空比(溢出) 高電平時(shí)間     
   START=1;
    }
  
   if( voltage>4.052&&voltage<4.167&&(timeL!=0xb0))
    {
   timeL = 0xb0; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0xb0; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     
   START=1;
    }

   if( voltage>4.167&&voltage<4.218&&(timeL!=0xe0))
   {
   timeL = 0xe0; //PWM模式時(shí)他倆用來(lái)控制占空比
   timeH = 0xe0; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     
   START=1;
    }

   if(voltage>4.220&&(timeL!=0xf2))
   {
    timeL = 0xf2; //PWM模式時(shí)他倆用來(lái)控制占空比
    timeH = 0xf2; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出) 
    START=1;
 LED=0;
    }

 


 }

***************************/

//延時(shí)函數(shù) 
void delayms(uint k)
{
uint data i,j;
for(i=0;i<k;i++)
  {
    for(j=0;j<600;j++)
     {;}
   }
}

 
關(guān)閉窗口

相關(guān)文章