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

📄 chongdianqi.c

📁 STC单片机万能充电器程序
💻 C
字号:

//---------------------------------------------------------------------
//#include <REG52.H>
#include <intrins.H>
#include "NEW_8051.H"
//WDT_CONTR  //狗
//---------------------------------------------------------------------
typedef    unsigned char   INT8U;
typedef    unsigned int    INT16U;
//定义常量
//pulse_width_MAX = pulse_width_MIN  时, 输出脉冲宽度不变。 
#define     pulse_width_MAX  0x65         //PWM 脉宽最大值, 占空比 =75% 
#define     pulse_width_MIN  0x45          //PWM 脉宽最小值, 占空比 =25% 
//#define   step             0x38          //PWM 脉宽变化步长 
#define    pulse_width  0x30H 

#define ADC_Power_On_Speed_Channel_0   0xE0    //P1.0 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_1   0xE1    //P1.1 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_2   0xE2    //P1.2 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_3   0xE3    //P1.3 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_4   0xE4    //P1.4 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_5   0xE5    //P1.5 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_6   0xE6    //P1.6 作为 A/D 输入 
#define ADC_Power_On_Speed_Channel_7   0xE7    //P1.7 作为 A/D 输入 




sbit B_LED         =    P3^4;//
sbit B_LED2        =    P1^4;
sbit B_ON          =    P3^5;
sbit B_PW          =    P3^7; 

INT8U con_state,ADC_Channel_2_Result_date,T_N;
INT16U  AD_date,S_N;


  
//#define ADC_YUCHONGDIAN             0x39    //1.12V,6V
//#define ADC_YUCHONGDIAN_0           0x3E    //1.21,6.4V
//#define ADC_JIESHU                  0x51    //1.58,8.4V
//#define     ADC_YUCHONGDIAN           0x4D   //1.51V,8V
//#define     ADC_YUCHONGDIAN_0         0x55    //1.65,8.8V
//#define     ADC_JIESHU                0x74    //2.26,12V
//#define     ADC_KONG                  0x8D      //2.82,15V
//#define     ADC_DUANLU                 0x30
//#define ADC_YUCHONGDIAN          0x40    //1.12V,6V      
//#define ADC_YUCHONGDIAN_0        0x44    //1.21,6.4V     
//#define ADC_JIESHU               0x58    //1.58,8.4V     
#define     ADC_21           0x89   //21V
#define     ADC_24           0x9c   //24V

#define     ADC_27         0xB0    //27V
#define     ADC_28                0xB7    //28V
#define     ADC_KONG                  0xC8      //2.82,15V
#define     ADC_DUANLU                 0x30		 
#define     ADC_135           0x58   //21V
#define     ADC_13           0x54   //0.153,21V     
/***********************
		init port
***********************/
void INITAL_port(void)
{
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;
}
/***********************
		 init PCA
************************/
void initiate_pca (void);


void delay(INT8U delay_time)        // 延时函数
{
    INT16U n;
    while(delay_time--) 
    { 
        n = 6000;
        while(--n);
    }
}

/***********************
		 init AD
************************/
//-------------------------------------------------------------- 
void ADC_Power_On(void) 
{
    
     ADC_CONTR|=0x80;          //开 A/D 转换电源 
    
     delay(20);                   //开 A/D 转换电源后要加延时,1mS 以内就足够了 
 }  
 

void Set_P12_Open_Drain(void) //设置 P1.2,设置 A/D 通道所在的 I/O 为开漏模式 
    {
    
    P1M0|=  0x4; 
    P1M1|=  0x4;     
    }


void Set_ADC_Channel_2(void)
{
    ADC_CONTR=ADC_Power_On_Speed_Channel_2; 
                    //选择 P1.2 作为 A/D 转换通道 
                    //更换 A/D 转换通道后要适当延时, 使输入电压稳定 
                    //以后如果不更换 A/D 转换通道的话, 不需要加延时 
   delay(5);        //切换 A/D 转换通道,加延时 20uS~200uS 就可以了,与输入电压源的内阻有关 
                    //如果输入电压信号源的内阻在 10K 以下,可不加延时 
     
}
void initiate_AD (void)
{
     ADC_Power_On ();             //开 ADC 电源, 第一次使用时要打开内部模拟电源                                    ;开 ADC 电源, 可适当加延时,1mS 以内就足够了 
    Set_P12_Open_Drain ();       //设置 P1.2 为开漏 
    Set_ADC_Channel_2();         //设置 P1.2 作为 A/D 转换通道 
 }   
//---------------------------------------------------------- 
INT8U Get_AD_Result(void)
{
                   
    ADC_DATA=0; 
    //ADC_CONTR = AD_SPEED;
    //ADC_CONTR = 0xE0;               //1110,0000 清 ADC_FLAG, ADC_START 位和低 3 位
    //ADC_CONTR |= channel;           //选择 A/D 当前通道
    Set_ADC_Channel_2(); 
    delay(1);   
    
    ADC_CONTR|= 0x08;     //启动 AD 转换 
            //判断 AD 转换是否完成 
     while (1)                       //等待A/D转换结束
    {
        if (ADC_CONTR & 0x10)       //0001,0000 测试A/D转换结束否
        { break; }
    }
     
    ADC_CONTR&=0xE7;     //清 0 ADC_FLAG, ADC_START 位, 停止 A/D 转换 
    return ADC_DATA;    
    
}





    

//---------------------------------------------------------------------
void Send_Byte(INT8U one_byte)      //发送一个字节
{
    TI = 0;                         //清零串口发送中断标志
    SBUF = one_byte;
    while (TI == 0);
    TI = 0;                         //清零串口发送中断标志
}

//------------------------------------------------------------ 
void timer_start(void)
{
	ET0 =1;
	TR0 =1;
}
void timer_stop(void)
{
	ET0 =0;
	TR0 =0;
}
//------------------------------------------------------------ 
void PWM (INT8U width)
{
 
   	
          CCAP0H=width;    // 示例程序核心语句
          PCA_PWM0=0x00  ; //示例程序核心语句P3.7
          PCA_PWM1=0x03;
          delay(5);   	   
}

void pwm_stop(void)
{
  PCA_PWM0=0x03  ;//释放本行注释,PWM输出就一直是0,无脉冲;------------------------- 
  PCA_PWM1=0x03  ;
  delay(250);
}
//------------------------------------------------------------ 



void initiate_RS232 (void)          //串口初始化
{
                               
    SCON = 0x50;                    //可变波特率. 8位无奇偶校验
    TMOD = 0x21;
    TH1  = 0xe7;//5.8mhz 600/s
    TL1 = 0xe7;		   
    AUXR &= 0xBF;
    TR1  =1;
    ES = 0;                         //禁止串口中断
}

//---------------------------------------------------------------------
void initiate_pca (void)
{
   CMOD=0x82;
                     //PCA 在空闲模式下停止 PCA 计数器工作         ;PCA 时钟模式为fosc/12         
                     //禁止 PCA 计数器溢出中断
   CCON=0x00;        //禁止 PCA 计数器工作, 清除中断标志、计数器溢出标志 
   CL  =0x00;        //清 0 计数器 
   CH  =0x00; 
           
                     //设置模块 0 为 8 位 PWM 输出模式, PWM 无需中断支持。脉冲在 P3.7(第 11 脚)输出 
   CCAPM0 =0x42;     //示例程序核心语句 0100,0010 
                     //PCA_PWM0=0x00H;  //示例程序核心语句P3.7; 
   PCA_PWM0=0x03;    //释放本行注释,PWM输出就一直是0,无脉冲;------------------------- 
   
                     //设置模块 1 为 8 位 PWM 输出模式, PWM 无需中断支持。脉冲在 P3.5(第 9 脚)输出 
   //CCAPM1=0x42;      //示例程序核心语句 0100,0010 
   //PCA_PWM1=0x00;  //示例程序核心语句 P3.5
   //PCA_PWM1=0x03;    //释放本行注释, PWM 输出就一直是 0, 无脉冲。
   //B_MO_1=0;
   EPCA_LVD=1;      //开pca中断
   EA=1;
   CR=1;            //将 PCA 计数器打开 
}
//---------------------------------------------------------------------

//**********************************************
void Initial_T0(void)
{
  TH0=0x4C        ;//设置定时器0 自动重装数 11M
  TL0=0x00       ;//500uS
    
  //AUXR&=0xBF;         //定时器1 工作在12T 模式,与普通的8051 相同 

  ET0=0;
  TR0=0;                       //启动定时器1     
} 

void timer_init(void)
{
  TH0=0x4C        ;//设置定时器0 自动重装数 11M
  TL0=0x00       ;//50MS
  ET0=1;
  TR0=1;       
}    
//--------------------------------------- 
void con (void)
{ 
AD_date=AD_date+Get_AD_Result();
AD_date=AD_date>>1;
if (AD_date<ADC_DUANLU)
   				{
   					 
             con_state=4;                  
   				}   
	switch(con_state)
   {
   	case 0:
   		   
	       if (AD_date < ADC_21)
			   {
   					         S_N=60000;
                 
                     PWM(pulse_width_MAX) ;//为输出脉冲宽度设置初值。 
                     timer_init();
                     con_state=1;                  
   				}
   			else
   				{
   					if (AD_date<ADC_28)
   					con_state=2;
   				}
   				  	
   	break;
    case 1:
   		  
   			if (AD_date>ADC_21)
   				{
   					 
             con_state=2;                  
   				}
   			if (S_N==0)
   				{
   					 
             con_state=2;                  
   				}
   				  	
   	break;	
   	
    case 2:
    	       S_N=60000;         
             
                 
             PWM(pulse_width_MAX) ;//为输出脉冲宽度设置初值。 
             timer_init();
             con_state=3;              				  	
   	break;	
    case 3:
    	       if(AD_date>ADC_28)
    	       	{ 
    	       
              
              con_state=4; 
              } 
             if (S_N==0)
   				   {
   					 
             con_state=4;                  
   				   }             				  	
   	break;	
    case 4:  //如果没有电池或者在很长一段时间后重新启动初始化
    	      
    	       	pwm_stop();               
              TR0=0;
              ET0=0; 
              
              con_state=5;
              B_LED=0; 
			  B_LED2=0;
             
    break;
    case 5:  //如果没有电池或者在很长一段时间后重新启动初始化
    	      
          if (AD_date>ADC_KONG  )
   				{     
              con_state=0; 
              B_LED=1;
			  B_LED2=1;                  
   				}   
    break;


   

         
default:
   		
   		break;  
       } 
     
}

//--------------------------------------- 
void timer0(void) interrupt 1
{
 INT8U ACC_temp;

   ACC_temp= ACC;  
   TR0=0; 
   if(S_N!=0) 
   	{
   	S_N--;	
   	} 
   if(T_N==0&con_state!=5) 
   	{
   	B_LED=~B_LED;
	B_LED2=~B_LED2;
   	T_N=10;
   	} 
   T_N--;
   timer_init();
   ACC= ACC_temp;    
}
 //------------------------------------------------------------ 
void serial()interrupt 4
{	INT8U ACC_temp;
	if(RI==0)
		TI=0;
	else 
		{
			RI=0;
			ES=0;
			ACC_temp=ACC ;
			
			//RS_do(SBUF);
			ACC=ACC_temp ;
			ES=1;   
		}
}
   

//---------------------------------------------------------------------
void main()

{     INT8U n;
      INITAL_port();
      T_N=0;
	  B_PW= 0 ; 
	  n=0;
	 
    
    initiate_pca();
    initiate_RS232();               //波特率 = 600
     
    initial_T0();
    //Send_Byte(0xAA);          //为便于观察, 发送 2 个 0xAA
    
    B_LED=0;
	B_LED2=0;
	      
    delay(0x250);
    B_LED=1; 
	B_LED2=1;
    initiate_AD();
    ES=1;
    con_state=0;
    AD_date=Get_AD_Result();
    
    //Send_Byte(AD_date); 
    while(1)
    {     
     con();
     WDT_CONTR=0x3f;          //看门狗	
	 if(n>10)
	 {
	Send_Byte(AD_date); 
	n=0;
	 }
    n++;
     
    }
} 


⌨️ 快捷键说明

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