首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

STC12C2052AD手机电池充电器程序

STC12C2052AD手机电池充电器程序

/*******************
C语言运算符优先级





   1级优先级 左结合   

  () 圆括号   [] 下标运算符   -> 指向结构体成员运算符   . 结构体成员运算符      



   2级优先级 右结合     

  ! 逻辑非运算符   ~ 按位取反运算符  ++ 自增运算符  -- 自减运算符  - 负号运算符 (类型) 类型转换运算符 * 指针运算符 & 地址与运算符 Sizeof 长度运算符



   3级优先级 左结合     

  * 乘法运算符   / 除法运算符   % 取余运算符     



   4级优先级 左结合   

  + 加法运算符   - 减法运算符



   5级优先级 左结合     

  << 左移运算符   >> 右移运算符



   6级优先级 左结合   

  <、<=、>、>= 关系运算符



   7级优先级 左结合    (注意"等于"运算符== )

  == 等于运算符   != 不等于运算符



   8级优先级 左结合     

  & 按位与运算符



   9级优先级 左结合   

  ^ 按位异或运算符



   10级优先级 左结合  

  | 按位或运算符



   11级优先级 左结合   

  && 逻辑与运算符



   12级优先级 左结合  

  || 逻辑或运算符   



   13级优先级 右结合   

  ? : 条件运算符



   14级优先级 右结合 (赋值运算符)

  =+ =- =*   =/ =% =   >= < <=   &= ^= |= 全为赋值运算符



   15级优先级 左结合  

  , 逗号运算符

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

#Include <Stc12c2052ad.H>

#Include <Intrins.H>

#Define Uchar Unsigned Char

#Define Uint Unsigned Int

#Define AD_SPEED   0x60 //0110,0000   1      1     270个时钟周期转换一次,

//少占鱼制作  河北正定欢迎您   长沙航空职业技术学院  2010 年QQ:41165643

//

Sbit M=P1^5; //过压指示灯

Sbit N=P1^6; //欠压指示灯

Sbit LED=P1^7; //充满 指示灯

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);//延时

  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; //用定时器0溢出做PCA脉冲     

   CL = 0x00; //PCA定时器低8位 地址:E9H   

   CH = 0x00; //PCA高8位 地址 F9H   

   CCON=0x00;



   CCAP0L = TimeL; //PWM模式时他俩用来控制占空比   

   CCAP0H = TimeH; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     



   CCAPM0 = 0x42; //0100,0010 Setup PCA Module 0 In PWM Mode

               // ECOM0=1使能比较 PWM0=1 使能CEX0脚用作脉宽调节输出

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

PCA 模块工作模式设置 (CCAPMn 寄存器 N= 0-3四种)

7     6        5        4       3       2     1      0

-   ECOMn   CAPPn     CAPNn   MATn     TOGn   PWMn   ECCFn

选项: 0x00 无此操作

       0x20 16位捕捉模式,由 CEXn上升沿触发

       0x10 16位捕捉模式,由CEXn下降沿触发

       0x30 16位捕捉模式,由CEXn的跳变触发

       0x48 16位软件定时器

       0x4c 16位高速输出

       0x42  8位PWM输出

每个PCA模块另外还对应两个寄存器:CCAPnH和CCAPnL 。  捕获或者比较时,它们用来

保存16位计数值,当工作于PWM模式时,用来控制占空比   

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



   CR=1; //Start PCA Timer.



}





//AD转换初始化 ----打开ADC电源

Void InitADC()

{

P1=0xff;

ADC_CONTR|=0x80;

Delayms(3);

//这两个寄存器用来设置 P1口四种状态,每一位对应一个P1引脚 ,按状态组合操作



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

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 也是。因为STC12C2052AD只有两个P口,所以只有这俩组  STC12C5410AD还多P2M0 P1M0 有三组   

  P1M0   P1M1                 高

    0   0     普通I0口 (准双向)        P1寄存器位  7      6     5    4     3      2     1     0

0      1     强推挽输出 (20MA电流 )尽量少用      P1.7  P1.6  P1.5  P1.4  P1.3  P1.2  P1.1  P1.0

1  0     仅做输入  A/D转换时可用此模式     

1      1    开漏 ,A/D转换时可用此模式





  例如:

  要设置P1.1为 AD 输入口

  则 P1M0=0X02 ;

     P1M1=0X02;   开漏即可

  当不用AD时,最好 关闭ADC电源 ,恢复为IO口状态

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

P1M0=0x06;//这两个寄存器用来设置 P1口四种状态,每一位对应一个P1引脚 ,按状态组合操作

P1M1=0x06;//设置P1.1 P1.2开漏状态



}







// AD转换程序

Void  ADC()

{

    Float V0,V1;



    ADC_DATA   = 0; //清除结果



    ADC_CONTR = 0x60;      //转换速度设置  0x60  最快速度



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



    ADC_CONTR |= 0x01;           //选择 A/D 当前通道   P1.1

    Delayms(1);                       //使输入电压达到稳定

   ADC_CONTR |= 0x08;              //0000,1000 令 ADCS = 1, 启动A/D转换,  



    While(!(ADC_CONTR & 0x10)); //!的优先级比&高太多了  

   //养成经常加括号的习惯 ,没坏处 。也不浪费速度

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

这里While 不能改成While(ADC_CONTR & 0x10==0) ;就错误了,因为优先级 ==比&高 ,所以要加括号

  While( (ADC_CONTR & 0x10)  ==0)    或者非一下  While(!(ADC_CONTR & 0x10)); //!的优先级比&高太多了  

    While( (ADC_CONTR & 0x10)  ==1)注意 If While这类判断逻辑真假的语句,用“==1”时 注意前面是否是后面的1,

后面的1可是0x01啊,前面要是0x02===1,这是不会成立的。但是去掉后面的==1就可以用了。多此一举反而带来麻烦  

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

    ADC_CONTR &= 0xE7;     //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,  



    V0=  ADC_DATA; //返回 A/D 10 位转换结果





    ADC_DATA   = 0; //清除结果



    ADC_CONTR = 0x60;      //转换速度设置  0x60  最快速度



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

   ADC_CONTR =0xe2;

   //  ADC_CONTR |= 0x02;           //选择 A/D 当前通道   P1.2

    Delayms(1);                       //使输入电压达到稳定

    ADC_CONTR = 0xea;

   // ADC_CONTR |= 0x08;              //0000,1000 令 ADCS = 1, 启动A/D转换,  



    While(!(ADC_CONTR & 0x10)); //!的优先级比&高太多了  

   //养成经常加括号的习惯 ,没坏处 。也不浪费速度



ADC_CONTR =0xe2;

    //ADC_CONTR &= 0xE7;     //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,  

V1=  ADC_DATA; //返回 A/D 10 位转换结果



Voltage=V1/V0*Uref*3.000;







   If( Voltage>4.180)

    {

     M=0;//过压灯

     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模式时他俩用来控制占空比

    TimeH = 0xa2; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)

    START=1;

LED=0;

    }



     If(Voltage>=4.155&&Voltage<=4.180)

   {

    TimeL = 0xb2; //PWM模式时他俩用来控制占空比

    TimeH = 0xb2; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)

    START=1;

LED=0;

    }



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

     If( Voltage<3.772&&(TimeL!=0xf0))

    {

   TimeL = 0xf0; //PWM模式时他俩用来控制占空比

   TimeH = 0xf0; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     

   START=1;

    }



   If( Voltage<4.052&&Voltage>3.772&&(TimeL!=0xf2))

    {

   TimeL = 0xf2; //PWM模式时他俩用来控制占空比

   TimeH = 0xf2; //0xc0 64/256=25% 占空比(溢出) 高电平时间     

   START=1;

     M=1;

  N=1;

  LED=1;

    }



   If( Voltage>4.052&&Voltage<4.167&&(TimeL!=0xfd))

    {

   TimeL = 0xfd; //PWM模式时他俩用来控制占空比

   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模式时他俩用来控制占空比

   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模式时他俩用来控制占空比

    TimeH = 0x96; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)

    START=1;

LED=0;

    }



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







}





/**********

// 保护函数

   Void Baohu()

   {



      If( Voltage>4.231)

    {

     M=0;//过压灯

     N=1;

     LED=1;

    }

   If(Voltage<3.501)

    {

    N=0;//欠压灯

M=1;

LED=1;

    }



     If( Voltage<3.772&&(TimeL!=0xcf))

    {

   TimeL = 0xcf; //PWM模式时他俩用来控制占空比

   TimeH = 0xcf; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     

   START=1;

    }



   If( Voltage<4.052&&Voltage>3.772&&(TimeL!=0x60))

    {

   TimeL = 0x60; //PWM模式时他俩用来控制占空比

   TimeH = 0x60; //0xc0 64/256=25% 占空比(溢出) 高电平时间     

   START=1;

    }



   If( Voltage>4.052&&Voltage<4.167&&(TimeL!=0xb0))

    {

   TimeL = 0xb0; //PWM模式时他俩用来控制占空比

   TimeH = 0xb0; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     

   START=1;

    }



   If( Voltage>4.167&&Voltage<4.218&&(TimeL!=0xe0))

   {

   TimeL = 0xe0; //PWM模式时他俩用来控制占空比

   TimeH = 0xe0; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)     

   START=1;

    }



   If(Voltage>4.220&&(TimeL!=0xf2))

   {

    TimeL = 0xf2; //PWM模式时他俩用来控制占空比

    TimeH = 0xf2; //0xff-0xc0=0x3f  64/256=25% 占空比(溢出)

    START=1;

LED=0;

    }









}



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



//延时函数

Void Delayms(Uint K)

{

Uint Data I,J;

For(I=0;I<K;I++)

  {

    For(J=0;J<600;J++)

     {;}

   }

}
返回列表