空调控制电路.docx
《空调控制电路.docx》由会员分享,可在线阅读,更多相关《空调控制电路.docx(32页珍藏版)》请在冰豆网上搜索。
空调控制电路
基于AVR单片机的汽车空调控制系统
摘要:
AVR单片机功能强大,用AVR单片机开发各种控制系统只需很少的外部器件就可以实现强大的功能。
本文介绍的就是利用Atmega16、CodeVisionAVRC开发环境、Proteus仿真软件开发汽车空调自动控制系统。
关键字:
AVR单片机、空调自动控制、CodeVisionAVRC、Proteus仿真
1前言
Atmega16是美国ATMEL公司的高档8位单片机,采用Flash存储器,可以擦写10000次以上、内部集成
、四通道PWM、集成8路10位精度ADC、片内经过标定的RC振荡器、采用精简指令集,具有32个通用工作寄存器,具有只需两个时钟周期的硬件乘法器,运算速度快等。
由于其集成度高、处理速度快,使得利用AVR单片机进行系统开发只需很少(甚至没有)的外部器件即可实现强大的功能,逐渐在各种场合得到广泛应用,取代其它8位单片机。
利用它来开发汽车空调控制系统,只需热电阻、液晶显示模块和一些继电器及其驱动芯片即可实现。
2工作原理
本系统可以分为五大部分:
热电阻温度采集、运行状态显示、继电器控制、键盘输入、风向步进电机控制。
2.1热电阻温度采集
热电阻传感器以其温度特性稳定、测量精
图1Pt1000热电阻温度测量电路
度高的特点,在大型中央空调得到了广泛的应用。
采用Pt1000热电阻作为温度传感器的测量电路原理图如图1所示。
热电阻Rt与三个电阻接成电桥。
当温度变化时,使得运算放大器的同相输入端的电位发生变化,经过运算放大器放大之后输入到Atmega16单片机进行AD转换。
由于单片机采用5V电压作为ADC的参考电源,而电桥在温度变化为0~100°C时,输出电压范围为0~0.7V,所以确定运算放大电路的放大倍数为7,以获得最佳的测量结果。
运算放大电路的电阻按以下公式确定:
取
。
输出电压变化范围大致是0~5V。
由于ADC的转换精度为10,故当输入电压为5V时,其采样值为1023,根据电桥平衡原理,可得到以下公式:
(1)
其中,N——ADC数据寄存器的值,
U——电桥电源电压,
——Pt1000在0°C时的电阻1000
。
Pt1000热电阻的阻值按以下公式计算:
:
(2)
Rt——温度为t时铂热电阻的电阻值,Ω;
t——温度,℃;
——Pt1000在0°C时的电阻1000
。
A——分度常数,A=0.0038623139728
B——分度常数,B=-0.00000065314932626
用VisualBasic.Net根据以上公式
(1)、
(2)生成用N来查找温度t的程序表格,其代码如下:
PrivateSubPt1000()
Me.Cursor=Cursors.WaitCursor
txtTab.Clear()
DimUAsInteger=9'电桥电源电压
'热电阻0度时的电阻值
DimPt1000_R0AsInteger=1000
DimnAsInteger
DimsngTAsSingle
DimsngRtAsSingle
txtTab.AppendText("constfloatPt1000Tab[]={"&Chr(13)&Chr(10))
Forn=0To1023
sngRt=(10000*n+7161000*U)/(7161*U-10*n)
sngT=(-const_A+Sqrt(const_A^2-4*const_B*(1-sngRt/Pt1000_R0)))/(2*const_B)
Ifn<1023ThentxtTab.AppendText(Format(Abs(sngT),"0.0")&",/*"&n&"*/")
ElsetxtTab.AppendText(Format(Abs(sngT),"0.0")&"/*"&n&"*/"&Chr(13)&Chr(10)&"};")
EndIf
IfnMod5=0Then
txtTab.AppendText(Chr(13)&Chr(10))
EndIf
Next
txtTab.SelectAll()
txtTab.Copy()
Me.Cursor=Cursors.Default
EndSub
生成的程序常数表格(1024个值)部分如下:
constfloatPt1000Tab[]={
0.0,/*0*/0.1,/*1*/0.2,/*2*/0.2,
……
63.4,/*696*/63.5,/*697*/
……
99.3,/*1022*/99.4/*1023*/
};
2.2运行状态显示
本系统采用一块16×4的字符型液晶模块,这种类型的LCD应用很广泛,其控制驱动主芯片为HD44780及其扩展驱动芯片HD44100(或兼容芯片),少量阻、容元件,结构件等装配在PCB板上而成。
字符型液晶显示模块目前在国际上已经规范化,无论显示屏规格如何变化,其电特性和接口形式都是统一的。
因此只要设计出一种型号的接口电路,在指令设置上稍加改动即可使用各种规格的字符型液晶显示模块。
odeVisionAVR集成开发环境集成这种类型LCD的函数,可方便实现LCD的读写,其部分函数及功能简单介绍如下,更详细的资料可查阅各种文献。
函数原型:
voidlcd_init(unsignedcharlcd_columns)
功能:
初始化LCD模块,清屏并把显示坐标设定在0列0行。
LCD模块的列必须指定(例如:
16)。
这时不显示光标。
在使用其它高级LCD函数前,必须先调用此函数。
函数原型:
voidlcd_clear(void)
功能:
清屏并把显示坐标设定在0列0行。
函数原型:
voidlcd_gotoxy(unsignedcharx,unsignedchary)
功能:
设定显示坐标在x列y行。
列、行。
函数原型:
voidlcd_putchar(charc)
功能:
在当前坐标显示字符c。
函数原型:
voidlcd_puts(char*str)
功能:
在当前坐标显示SRAM中的字符串str。
函数原型:
voidlcd_putsf(charflash*str)
功能:
在当前坐标显示FLASH中的字符串str。
在对LCD进行写入显示数据之前,需要对它进行初始化,设定显示参数。
#include
/*使用PORTB连接LCD模块*/
#asm
.equ__lcd_port=0x18;PORTB
#endasm
voidmain(void){
//定义字符数组
uchararr[5];
//初始化,指定列数为16
lcd_init(16);
//设定显示坐标为(0,1)
lcd_gotoxy(0,1);
/*在(0,1)显示字符串,注意:
此字符串存储在Flash只读存储器中*/
lcd_putsf("RunMode:
");
/*调用“浮点数转换成字符串”函数,
函数原型:
voidftoa(floatn,unsignedchardecimals,char*str)
data为浮点数*/
ftoa(data,1,arr);
//设定显示坐标为(0,2)
lcd_gotoxy(0,2);
//显示RAM中字符串数组arr的内容
lcd_puts(arr);
while
(1);
}
2.3继电器控制
Atmega16输出缓冲器具有对称的驱动特性,可以输出和吸收大电流,直接驱动LED,但是仍然不能直接驱动更大电流的器件,如继电器,所以必须接入较大功率的驱动器。
常用的驱动方法有74系列功率集成电路驱动、MOC系列光耦合过零触发双向晶闸管驱动、固态继电器驱动等。
本系统采用ULN2003芯片来驱动继电器。
其内部结构如图2所示。
ULN2003是达林顿阵列,是专门用来驱动继电器的芯片,甚至在芯片内部做了一个消线圈
图2ULN2003内部结构图
反电动势的二极管。
ULN2003的输出端允许通过IC电流200mA,饱和压降VCE约1V左右,耐压BVCEO约为36V。
采用集电极开路输出,输出电流大,故可以直接驱动继电器或固体继电器(SSR)等外接控制器件,也可直接驱动低压灯泡,共可以驱动7路,减少了电路板的连线数量,成本较低,广泛应用于各种工控板,其驱动原理如图3所示。
图3驱动原理
压缩机离合器继电器采用RS触发器和ULN2003一起控制,这样做的好处是:
当单片机受到外界干扰而不断复位或看门狗超时复位时,保证压缩机始终处于开启或关闭状态,有助于延长压缩机的寿命。
2.4键盘输入
本系统采用3×3矩阵式键盘。
通过键盘可以控制系统工作方式(关闭、送风、制冷)、风向步进电机(水平送风、倾斜送风、扫风)、温度设定等。
键盘的行由PD0、PD1、PD2(使能内部上拉电阻)控制,而列则由PC3、PC4、PC5控制,如图4所示。
采用程序扫描的方式识别键码,其工作过程如下:
(1)判断键盘中有无键按下。
通过以下代码实现:
PORTC&=~0x20;
if((PIND&0x07)!
=0x07){//……}
首先置PC5为“0”,再判断PD0、PD1、PD2是否都为“1”。
如果全为“1”,则表明第3列无键按下,否则有键按下,进入消除抖动程序;再置PC4为“0”,再判断PD0、PD1、PD2是否都为“1”。
如果全为“1”,则表明第2列无键按下,否则有键按下,进入消除抖动程序;再置PC3为“0”,再判断PD0、PD1、PD2是否都为“1”。
如果全为“1”,则表明第1列无键按下,否则有键按下,进入消除抖动程序。
图43×3矩阵式键盘
(2),消除抖动。
当发现有键按下时,延时一段时间再判断键盘状态,若仍有键保持按下状态,则可以确定有键按下,否则认为是抖动。
通过以下代码实现:
delay();
if((PIND&0x07)!
=0x07){//……}
(3)判断键码。
以下是识别为“Key2-3”(第2行第3列)的程序代码,其它按健类似。
if((PIND&0x07)==0x05)
{//Key2-3
//ucharkey_num[]="K23";
//等待按键释放
while((PIND&0x07)==0x05);
//判断换气风机是否在运行
if(ventilator_state==1)
{
ventilator_state=0;
//关闭换气风机
stop_ventilator();
//在LCD上的(12,3)显示“OFF”lcd_gotoxy(12,3);
lcd_putsf("OFF");
}
else
{
ventilator_state=1;
//开启换气风机
start_ventilator();
//在LCD上的(12,3)显示“Run”
lcd_gotoxy(12,3);
lcd_putsf("Run");
}
return;//识别完毕,返回主程序
}
2.5风向步进电机控制
Atmega16的定时器能够输出PWM,编程简单,精度高。
编程让定时器2工作于相位可调模式,产生高精度的PWM波形输出,调节占空比,以达到控制步进电机不同转角的目的。
初始化设置如下:
ASSR=0x00;
/*相位可调PWM模式,比较匹配时清零OC2,计数为0xff时置位OC2*/
TCCR2=0x64;
TCNT2=0x00;
OCR2=0x00;
TIMSK=0x80;//使能匹配中断
图5相位可调PWM模式的时序图
图6水平送风模式下的PWM波形
图6倾斜送风模式下的PWM波形
3仿真
Proteus是目前最好的模拟单片机及外围器件的仿真软件,可以仿真51系列、AVR,PIC等常用的MCU及其外围电路,如LED、LCD、RAM、ROM、键盘、马达、继电器、AD/DA、部分SPI器件、部分
器件、74系列、
COMS4000系列芯片等。
利用Proteus可以大大提高开发效率、降低投资,在没有硬件的情况下让开发人员能像Pspice仿真模拟/数字电路那样仿真MCU及外围电路。
Proteus提供的可调电阻是“十级可调”而不是“无级可调”,所以本系统采用三个可调电阻模拟Pt1000热电阻,以实现“粗调”、“中调”、“细调”,更真实反映热电阻阻值的细微变化。
图7换气风机、压缩机、蒸发器风机处于工作状态
图8LCD显示结果
4.结语
本系统采用AVR单片机实现汽车空调的自动控制(双位控制),具有电路结构简单、分立元件少、系统界面友好、操作简单等优点,能满足一般精度要求的公交车空调的自动控制。
参考文献
[1]ATMEL公司的ATmega16产品文档(
[2]刘汧《CodeVisionAVRC库函数介绍》
[3]王幸之钟爱琴王雷王闪《AT89系列单片机原理与接口技术》北京航空航天大学出版社2004
附:
电路原理图和程序源代码
/*****************************************************
Project:
汽车空调控制系统
Version:
1
Date:
2005-12-13
Author:
Benny
Blog:
Company:
509
Chiptype:
ATmega16L
Programtype:
Application
Clockfrequency:
8.000000MHz
Memorymodel:
Small
ExternalSRAMsize:
0
DataStacksize:
256
*****************************************************/
#include
#include
#include"Pt1000Tab.h"
#include"inc.h"
#asm
.equ__lcd_port=0x18;PORTB
#endasm
#include
bitboolean;
ucharventilator_state;
ucharfan;
ucharblow;
ucharrun_mode;
uchartemp;
ucharsetting_value;
interrupt[TIM2_COMP]voidtimer2_comp_isr(void)
{
//产生PWM,控制步进电机
if(fan==1)
{
OCR2=64;
}
elseif(fan==2)
{
OCR2=128;
}
}
#defineFIRST_ADC_INPUT0//第一通道
#defineLAST_ADC_INPUT1//最后一通道,最大值为7,共8个通道
unsignedintadc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1];
#defineADC_VREF_TYPE0x40
//ADC中断服务程序
//自动扫描模拟量输入端口,
interrupt[ADC_INT]voidadc_isr(void)
{
registerstaticunsignedcharinput_index=0;
//读取转换结果
adc_data[input_index]=ADCW;
//选择转换通道
if(++input_index>(LAST_ADC_INPUT-FIRST_ADC_INPUT))
input_index=0;
ADMUX=(FIRST_ADC_INPUT|ADC_VREF_TYPE)+input_index;
//启动AD转换
ADCSRA|=0x40;
}
voidmain(void)
{
floatcurrent_temp;//保存当前温度
//PortA初始化
//Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
//State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
PORTA=0x00;
DDRA=0x00;
//PortB初始化
//Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
//State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
PORTB=0x00;
DDRB=0x00;
//PortC初始化
//Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
//State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
PORTC=0x38;
DDRC=0x38;
//PortD初始化
//Func7=InFunc6=InFunc5=InFunc4=InFunc3=InFunc2=InFunc1=InFunc0=In
//State7=TState6=TState5=TState4=TState3=TState2=TState1=TState0=T
PORTD=0x1f;
DDRD=0xF8;
//用T2产生PWM,控制风向步进电机
//Timer/Counter2initialization
//Clocksource:
SystemClock
//Clockvalue:
Timer2Stopped
//Mode:
Normaltop=FFh
//OC2output:
Disconnected
ASSR=0x00;
TCCR2=0x64;
TCNT2=0x00;
OCR2=0x00;
//Timer(s)/Counter(s)Interrupt(s)initialization
TIMSK=0x80;
//AnalogComparatorinitialization
//AnalogComparator:
Off
//AnalogComparatorInputCapturebyTimer/Counter1:
Off
ACSR=0x80;
SFIOR=0x00;
//ADCinitialization
//ADCClockfrequency:
125.000kHz
//ADCVoltageReference:
AVCCpin
//ADCAutoTriggerSource:
FreeRunning
ADMUX=FIRST_ADC_INPUT|ADC_VREF_TYPE;
ADCSRA=0xEE;
SFIOR&=0x1F;
//LCDmodule初始化
lcd_init(16);
//开启全局中断
#asm("sei")
dis_character();
setting_value=25;
run_mode=0;
ventilator_state=0;
lcd_gotoxy(12,3);
lcd_putsf("OFF");
while
(1)
{
scan_key();//扫描键盘
blow_mode();//设定送风方式
display();//显示状态参数
if(run_mode==2)
{
current_temp=Pt1000Tab[adc_data[0]];
if(current_temp{
stop_compressor();
//lcd_gotoxy(10,1);
//lcd_putsf("Blast");
}
else
{
start_compressor();
//lcd_gotoxy(10,1);
//lcd_putsf("Cool");
}
}
}
}
voidstart_compressor(void){
//Start
PORTD|=0x18;
PORTD&=~0x10;
PORTD|=0x18;
}
voidstop_compressor(void){
//Stop
PORTD|=0x18;
PORTD&=~0x08;
PORTD|=0x18;
}
voidstart_ventilator(void){
PORTD|=0x40;//换气风机运行
}
voidstop_ventilator(void){
PORTD&=~0x40;//换气风机停止
}
voidstart_evaporator_fan(void){
PORTD|=0x20;//蒸发器风机运行
}
voidstop_evaporator_fan(void){
PORTD&=~0x20;//蒸发器风机停止
}
/*---------------------------键盘扫描--------------------------*/
voidscan_key(void){
/*
K11K12K13
K21K22K23
K31K32K33
*/
//K13K23K33
PORTC&=~0x20;
if((PIND&0x07)!
=0x07)
{
delay();
if((PIND&0x07)!
=0x07)
{
if((PIND&0x07)==0x06)
{//Key3-3
//ucharkey_num[]="K33";
while((PIND&0x07)==0x06);
switch(blow)
{
case0:
{
blow=1;
lcd_gotoxy(10,2);
lcd_putsf("Mode0");
break;
}
case1:
{
blow=2;
lcd_gotoxy(10,2);
lcd_putsf("Mode1");
break;
}
case2:
{
blo