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

📄 warter heater_v1.c

📁 快热式电热器工程 软件部分 单片机控制程序
💻 C
字号:
/*---------------------------------
文 件 名:  water heater_v1.c
文件说明:  快热式热水器程序 
作    者: cjy 
时    间: 2008年5月14日 12:36
修改记录:
----------------------------------*/

#include<ht46r24.h>
#define MAX 0
#define MIN 1

#define INT    _pd0 //外部中断输出,调试用
#define BELL   _pa4 //蜂鸣器控制信号
#define RELAY  _pc3 //继电器控制信号


//#define KEY0    _pa6 //要wake up  开下降沿唤醒
#define KEY1   _pa7  //要上拉     关进入睡眠


#define TRIAC  _pc4 //光耦控制信号,0时导通
 

#define RELOAD0_L  0x00 
#define RELOAD0_H  0x00

#define RELOAD1_L  (65535-2000)%256  //定时2ms
#define RELOAD1_H  (65535-2000)/256


//需经过实验测得,温度0点标定,满量程标定
#define N0       226  //温度为0时,  单片机采集的ad模拟量
#define N100     34   //温度为100时,单片机采集的ad模拟量

#define StartAdConversion()\
 _start = 0;\
 _start = 1;\
 _start = 0

#define OpenHeater()\
_emi = 1;\
_eei = 1\

#define CloseHeater()\
_eei =  0;\
_et0i = 0;\
TRIAC = 1\

//函数说明 
void SafeguardInit(void);
void ConfigureTimer0(void);
void ConfigureTimer1(void);
void ConfigureAd(void);
void InitPort(void);
unsigned char SampleAd(unsigned char, unsigned char);
unsigned char KeyScan (void);
unsigned char GetWaterTemperature(void);
void Display(unsigned char);
unsigned char WatchWaterTemperature(unsigned char);
void HeaterControl(unsigned char, unsigned char);
void DelayN50ms(unsigned long );

//数码管驱动码
const unsigned char table[] = 
{
    0x22,   // 0
    0xFA,   // 1
    0x16,   // 2
    0x52,   // 3
    0xCA,   // 4
    0x43,   // 5
    0x03,   // 6
    0xF2,   // 7
    0x02,   // 8
    0x42,   // 9
    0xFF,   // N
    0xDF,   // -
    0x8A,   // H
    0x07,   // E
};

//温度表(单位:摄氏度)
const unsigned char ad_temperature_table[] = 
{
    0,  0 , 0 , 1 , 1,  1,  2,  2,  2,  3,
    3,  4,  5,  5,  6,  6,  7,	8,	8,	9,
    9,  10, 10, 11, 11, 12, 12, 13, 13,	14,
    14, 15, 15, 16, 16, 17, 17, 18, 18, 19,
    19, 20, 20, 20, 21, 21, 22, 22, 23, 23,
    24, 24, 25, 25, 26, 26, 26, 26, 27, 27,
    28, 28, 28, 29, 29, 30, 30, 30, 31, 31,
    32, 32, 32, 33, 33, 34, 34, 34, 35, 35,
    36, 36, 36, 37, 37, 38, 38, 38, 39, 39,
    39, 40, 40, 41, 41, 41, 42, 42, 43, 43,
    43, 44, 44, 45, 45, 45, 46, 46, 47, 47,
    47, 48, 48, 49, 49, 49, 50, 50, 51, 51,
    52, 52, 52, 53, 53, 54, 54, 55, 55, 55,
    56, 56, 57, 57, 58, 58, 59, 59, 60, 60,
    61, 61, 62, 62, 62, 63, 63, 64, 64, 65,
    66, 66, 67, 67, 68, 68, 69, 69, 70, 70,
    71, 72, 72, 73, 73, 74, 75, 75, 76, 77,
    77, 78, 79, 79, 80, 81, 81, 82, 83, 84,
    84, 85, 86, 87, 88, 88, 89, 90, 91, 92,
    93, 94, 95, 96, 97, 98, 99, 100,102,103,
    104,105,107     					

};
 

//功率控制表
const unsigned char power_table[] = 
{   
    
    0xdc,0xd7, // 延时9ms触发->1/10 p 
    0xe0,0xbf, // 延时8ms触发->2/10 p    
    0xe4,0xa7, // 延时7ms触发->3/10 p
    0xe8,0x8f, // 延时6ms触发->4/10 p
    0xec,0x77, // 延时5ms触发->5/10 p
    0xf0,0x5f, // 延时4ms触发->6/10 p
    0xf4,0x47, // 延时3ms触发->7/10 p
    0xf8,0x2f, // 延时2ms触发->8/10 p
    0xfc,0x17  // 延时1ms触发->9/10 p,延时越短,功率越大
};

//功率档显示灯表,这个需要改 /*PA0-PA2=>3个LED灯
const unsigned char led_table[] =
{
    //全灭                             全亮
    0b11111111,0b11111110,0b11111100,0b11111000
};

const unsigned char sbit[] = {0b111111101,0b11111110};//数码管位选码

//全局变量说明
unsigned char g_power_scale; //功率挡位
unsigned char g_temp[2];     //温度暂存
unsigned char g_count;       //计数
 
 void main()
{
 
    unsigned char scale_new = 0;   //用户调节的档位
    
    unsigned char scale_old = 0; 
    unsigned char scale_new_temp= 0;
    unsigned char t = 15;      //水温初值
    unsigned char temov = 0;   //超温度标志
    bit flag = 1;

//全局变量初始化    
    g_power_scale = 5;        //系统功率初始化值
    g_count = 0;
    g_temp[0] = 11; 
    g_temp[1] = 11;
    
    
    if(_to == 1)
    {
        _pa3 = 0;//点亮
        _pc &= 0b11111100;
        _delay(5000);
    }
    SafeguardInit();        					
    InitPort();
   
    ConfigureTimer0();
    ConfigureTimer1();
    ConfigureAd();
     
 
    while(1)
    {
 
      
       if(  flag == 1 || KEY1 == 0 || _to == 1)
       {
            if(KEY1 == 0)
    		{
                BELL = 0; 
                DelayN50ms(3);
                BELL = 1;
    		}
            _pb = 0xff;
            _pa0 = 1;//熄灭
            _pc &= 0b11111100;
            //进入睡眠前所有I/O口处理
            _emi = 0;
         _halt();
         _halt();
    
        BELL = 0; 
        DelayN50ms(3);
        BELL = 1;	
    		 
       }
     
         flag = 0;
        _emi = 1;
        _t1on = 1;
        scale_new_temp =  KeyScan();
        scale_new = KeyScan();
        if(scale_new == scale_new_temp)
        { 
     
          if(scale_new != scale_old)
          {
            scale_old = scale_new;
            g_temp[0] = scale_old/10;
            if(g_temp[0] == 0)g_temp[0] = 14;
            g_temp[1] = scale_old % 10;
     
            
            DelayN50ms(20);
     
    		
    	 }
         HeaterControl(scale_old,temov); 	 
       }
    	
        t = GetWaterTemperature();//这个所要经过的时间,知道所用时间
        g_temp[0] =t/10;
        g_temp[1] =t%10;
    	
        temov = WatchWaterTemperature(t); 
        _clrwdt(); 
      
    }    
} 


//中断向量
#pragma vector IntExternal @ 0x04
#pragma vector IntTimer0   @ 0x08 
#pragma vector IntTimer1   @ 0x0c
#pragma vector IntAd       @ 0x10

//外部中断服务程序
void IntExternal()
{   
     
    INT = !INT;
    _tmr0l = power_table[2*g_power_scale-1];  //可控硅导通延时角
    _tmr0h = power_table[2*g_power_scale-2];
    _et0i = 1;//中断允许
    _t0on = 1;//启动定时器*/
}

//定时器0中断服务程序 
void IntTimer0()
{
  
    TRIAC  = 0;
   _t0on = 0;//停止计数
   _et0i = 0;//关定时器中断
   _delay(50);
   TRIAC = 1;
    
}

 
void IntTimer1()
{
    _t1on = 0;
    _pc |= 0b00000011;//熄灭
     
 
    _pb = table[g_temp[g_count]];
    _pa3 =  ( table[g_temp[g_count]] & 0b00000001 == 0x01?1:0 );
    
    _pc &= sbit[g_count];//打开  
    g_count++;
    if(g_count == 2)g_count = 0;
    _tmr1l = RELOAD1_L;
    _tmr1h = RELOAD1_H;
    _t1on = 1;
 
     

}

//安全初始化寄存器
void SafeguardInit(void)
{
        _intc0 = 0;
        _tmr0c = 0;
        _tmr0l = 0;
        _tmr0h = 0;
        _tmr1c = 0;
        _tmr1h = 0;
        _tmr1l = 0;
       
        _pac = 0xff;
        _pbc = 0xff;
        _pcc = 0xff;
        _pdc = 0xff;
}

//端口初始化程序
void InitPort(void)
{  

    _pac = 0b00110000; 
   
     
    _pbc = 0b11100000;
    _pcc = 0b00000000; //I/O输出
    _pa5 = 1;    //外部中断口,不能加上拉
    //

}

//配置定时器0
void ConfigureTimer0(void)
{
    _t0m1 = 1;//定时模式,内部时钟
    _t0m0 = 0;

    _t0psc2 = 0;// FInt = FSys/4  1Mhz,1us计一个数
    _t0psc1 = 1;
    _t0psc0 = 0;
    
    _tmr0l = RELOAD0_L;//先写L,在写H  
    _tmr0h = RELOAD0_H;//            
    
    _et0i = 1;//定时器0中断允许
    //_t0on = 0;//开启定时器0
}
//配置定时器1
void ConfigureTimer1(void)
{
    _t1m1 = 1;//定时模式,内部时钟
    _t1m0 = 0;
    //时钟源FSys/4Mhz,固定
    _et1i = 1;
    //_t1on = 0;
}

//配置AD
void ConfigureAd(void)
{
    _pcr2 = 0; //PB0-AN0,PB1-AN1,PB0其他IO口 
    _pcr1 = 1;
    _pcr0 = 0;
    
    _adcs1 = 0;//ad转化时钟源为FSys/2
    _adcs0 = 0;
    
    //_eadi = 0;

}

//采集通第channel通道ad值n次
unsigned char SampleAd(unsigned char channel, unsigned char n)//n只能在0-20之间, 输入的channel只能在0-7 
{
    unsigned char i;
    unsigned char ad_buffer[20];
    unsigned long int total = 0;//除数类型要求,要有初值
    ad_buffer[MAX] = 0;
    ad_buffer[MIN] = 255;
    
    _adcr &= 0b11111000;//通道选择
    _adcr |= channel;
    for(i = 0; i < n; i++)
    {
        //StartAdConversion();
        _start = 0;
        _start = 1;
        _start = 0;
        while(_eocb);
        
         total += _adrh;
        if(_adrh > ad_buffer[MAX])
    	{
            ad_buffer[i]   = ad_buffer[MAX];
            ad_buffer[MAX] = _adrh;
    	}
        else if(_adrh < ad_buffer[MIN])
    	{
            ad_buffer[i]   = ad_buffer[MIN];
            ad_buffer[MIN] = _adrh;
    	}
        else
    	{
            ad_buffer[i] = _adrh;
    	}
    	 
   }

   total = total - ad_buffer[MAX] - ad_buffer[MIN] ;
   return ( total / (n - 2) );
}

//旋钮等级扫描函数
unsigned char KeyScan(void)
{
    unsigned char data, power_scale_temp=0;
    data = SampleAd(1, 18);//采集通道1
    
    if( data >= 0x00 && data < 0x19)//分界值需要修改
    {
        power_scale_temp = 0;// 0/10P
    }
    else if(data <= 0x33)
    {
        power_scale_temp = 1 ;// 1/10 P
    }
    else if(data <= 0x4c)
    {
        power_scale_temp = 2; 
    }
    else if(data <= 0x66)
    {
        power_scale_temp = 3;
    }
    else if(data <= 0x80)
    {
        power_scale_temp = 4;
    }
    else if(data <= 0x99)
    {
        power_scale_temp = 5;
    }
    else if(data <= 0xb3)
    {
        power_scale_temp = 6;
    }
    else if(data <= 0xcc)
    {
        power_scale_temp = 7;
    }
    else if(data <= 0xe6)
    {
        power_scale_temp = 8;
    }
    else if(data <= 0xff)
    {	
        power_scale_temp = 9;
    }
    
    return (power_scale_temp);//返回用户调节的加热功率档位

}

//加热控制程序
void HeaterControl(unsigned char power_scale_temp, unsigned char temov)
{
    if(power_scale_temp == 0 || temov == 1 )//档位为0或温度超出,关闭,熄灭
    {
        CloseHeater();
       // _p = led_table[0];//熄灭档位, 需要修改
    }
    else
    {
        g_power_scale = power_scale_temp;//设置加热档位
        OpenHeater();
       //_pc = led_table[power_scale_temp];//显示档位,需要修改
       
    }
    

}

//动态扫描函数
 
//测量水温函数
unsigned char GetWaterTemperature(void)
{
    unsigned char data, t;
    data = SampleAd(0, 10);
    t = ad_temperature_table[N0 -data];
    return t;
}

//监控水温函数 
unsigned char WatchWaterTemperature(unsigned char t)
{
    unsigned char temov;
    if(t > 65)
    {
        CloseHeater();
        BELL = 0;
        temov = 1;//置超温标志
    	 
    }
    else if( t < 45) 
    {
    	
        BELL = 1;
        temov = 0;
    }
    
    return temov;
}

void DelayN50ms(unsigned long n )
{
    unsigned  long i;
    for(i = 0; i < n; i++)
    {
        _delay(50000);
    }
}

⌨️ 快捷键说明

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