模拟路灯控制系统(2组LED).doc
《模拟路灯控制系统(2组LED).doc》由会员分享,可在线阅读,更多相关《模拟路灯控制系统(2组LED).doc(21页珍藏版)》请在冰点文库上搜索。
2009年全国大学生电子设计竞赛设计报告
模拟路灯控制系统(I题)
【高职高专组】
参赛学校:
湖南铁道职业技术学院
参赛队员:
李亚飞段敏成琼
2009年9月
目录
摘要 1
1方案设计与比较 1
1.1LED恒流源设计方案 1
1.2移动物体通过检测方案 1
1.3整体方案 1
2理论分析与计算 2
2.1功率数据采集原理分析 2
2.2功率调节原理分析 2
2.3调节误差分析 2
3电路设计 2
3.1系统框图 2
3.2显示器模块电路 3
3.3光传感器模块 3
3.4时钟电路 4
3.5红外对管检测电路 4
3.6声光报警电路 4
3.7A/D电路 4
3.8D/A转换电路 5
3.9串口电路 5
4程序设计 5
4.1物体通过检测实现 5
4.2功率调节的实现 5
4.3程序流程图 6
5系统测试 7
5.1测试仪器 7
5.2测试方案 7
5.3测试结果 7
5.4结果分析 7
6总结 8
参考文献 8
附件1:
支路控制器系统电路图 9
附件2:
单元控制器系统电路图 10
附件3:
恒流源电路图 11
附件4:
主要PCB图 12
附件5:
主要元器件清单 14
附件6:
部分程序清单 15
模拟路灯控制系统
摘要:
本系统采用3片Atmel公司的AT89S51单片机作为系统的控制器件,其中支路控制器为主控制器,两个单元控制器作为从控制器。
支路控制器接显示器和键盘组成人机界面,可通过外部时钟模块进行开关灯定时控制,可通过光敏传感器和电压比较器检测环境明暗程度,可通过7对红外对管检测交通情况,从而控制LED的亮灭。
在单元控制器中,采用OP07集成运放接大功率场效应管设计了LED压控恒流源,可由单片机通过D/A方便地控制恒流源的输出电流和功率,并由A/D芯片将功率数据反馈到单片机,形成闭环自动控制系统。
支路控制器与单元控制器之间采用485工业串口进行通信,推广到实际应用中。
关键词:
路灯 89S51单片机 恒流源
1方案设计与比较
1.1LED恒流源设计方案
方案一:
分立元件设计法。
LED恒流源可以采用三极管、稳压管加电阻等分立元件进行设计,具有电路简单、成本低等优点,但是性能较差,单片机不好控制。
方案二:
专用芯片设计法。
市面上有不少专用LED恒流源的驱动芯片,如美国安森美公司的CAT4201以及UCT4611,SN3350等。
采用专用芯片电路简单可靠、性能好,通过PWM可控制输出电流大小,但是功率数据不易采集。
方案三:
运放设计法。
采用OP07集成运放接大功率场效应管等元器件组成压控恒流源,这种方案具有电路简单可靠、性能好、单片机容易控制、功率数据易于采集等优点,故采用此种方案。
1.2移动物体通过检测方案
方案一:
超声波检测法。
利用超声波发射接收的时间差不同,可用来检测是否有物体通过。
该方法简单有效,但由于声波的发散特性,精度达不到题目要求。
方案二:
反射式红外传感器检测法。
利用红外线发射接收的时间差不同,也可来检测是否有物体通过。
该方法同样简单有效,而且精度较高,但是检测距离过短,只有10几cm,而且价格很高。
方案三:
红外对管检测法。
采用位于同一直线上面对面放置的一个红外发射管和一个红外接收管(即红外对管),可以用来检测是否有物体通过其间。
只需通过检测流过红外接收管的电流大小,可以方便地掌握物体通过情况。
该方法简单易行,检测距离远、精度高,成本低,故本系统采用该方案。
1.3整体方案
方案一:
单MCU控制法。
单从题目功能的实现,采用单MCU方案是可行的。
支路控制器采用单MCU设计,所有外部接口(包括键盘、显示器、时钟模块、光电传感器、红外对管、AD、DA等)都挂在这个MCU上。
两个单元控制器不带MCU,只设计恒流源。
两个恒流源的控制及功率数据采集由支路控制器中的MCU通过双通道的A/D、D/A来完成。
这种方案单元控制器电路相当简单,支路控制器电路较为复杂,MCU工作负荷大,I/O资源紧张。
整体方案成本较低,易于实现,但不符合实际情况,不满足题意。
方案二:
主从机协同控制法。
支路控制器、单元控制器各采用1片MCU进行控制,支路控制器的主MCU与单元控制器的从MCU之间采用串口通信进行数据交换。
支路控制器只用于人机界面、开关灯时间设定、自动亮度识别、道路通过检测及故障报警等,而各个LED恒流源及其控制、数据采集电路均集成到单元控制器电路中,并由其内部的从MCU通过串口接收主MCU的指令进行控制。
此方案各MCU分工合理,协同工作,负荷不高,电路、程序都较简单。
同时采用工业串口,传输距离远,可推广到实际应用中,故本系统采用该方案。
2理论分析与计算
2.1功率数据采集原理分析
单元控制器采集当前LED的输出功率数据分两步进行:
一、采集通过LED的电流值。
由于本系统采用压控恒流源,故通过LED的电流即为通过采样电阻的电流,因为采样电阻阻值为1Ω,所以电流等同于采样电阻上的电压。
又因为前级运放OP07接成电压跟随器,该值即为D/A输出的电压值,在单元控制器在设定LED输出功率时已知。
二、采集LED两端的电压值。
该值由LM358接成减法器直接在LED两端取得,经A/D转换送给从机。
将这两个值相乘,即得到当前LED的功率值。
2.2功率调节原理分析
设定功率时,单元控制器并不能一步到位。
必须先通过D/A输出一个初始的LED电流值,然后通过A/D把LED两端电压读回来,将电流与电压相乘得到的功率值与需设定值进行比较,如果小于设定值,则增加D/A的输出;如果大于,则减小D/A的输出。
通过这种闭环系统,使当前输出功率值逐步逼近设定功率值。
2.3调节误差分析
D/A设定恒流源电流值、A/D采集电压数据都将带来转换误差,这是A/D、D/A器件本身硬件带来的,不可避免。
A/D、D/A位数越高,转化误差越小,调节误差也越小。
本系统采用12位的A/D、D/A器件,转换误差小于0.1%,而功率误差由电流转化误差与电压转换误差共同决定,由于他们之间是乘积关系,因此误差的数量级不会上升,总的调节误差小于0.5%,精度完全符合题目要求。
3电路设计
3.1系统框图
系统框图如图1所示。
支路控制器
(主机)AT89S51
单元控制器
(从机1)
AT89S51
单元控制器
(从机2)
AT89S51
恒流源1
显示器
时钟模块
光传感器
红外对管检测模块
按键
A/D
D/A
恒流源2
A/D
D/A
串口
串口
串口
LED1
LED2
声光报警模块
图1系统框图
3.2显示器模块电路
该模块采用2个4位一体共8位共阴数码管显示器连接而成,段码数据线共用,采用138译码作为数码管位选,用于显示开关灯时间、恒流源输出功率值及百分比、故障LED编号等数据。
数码管显示具有亮度高、可视距离远、直观、功耗低、使用方便、性价比高等特点。
电路如图2所示。
图2数码管显示电路
3.3光传感器模块
采用光敏电阻作为敏感元件,当环境亮度较高时,光敏电阻R1阻值很小,P17为低电平;当环境亮度较低时,光敏电阻R1阻值很大,P17为高电平。
电路如图3所示。
图3光传感器电路图4DS1302时钟电路
3.4时钟电路
时钟模块用于给MCU提供精确时间数据,从而使支路控制器能够准确控制LED的开关灯时间。
该模块采用具有SPI接口的DS1302来进行设计,只占用MCU3个I/O,该模块电路如图4所示。
3.5红外对管检测电路
系统采用555接成施密特触发器来对红外接收管的阳极电压进行监控,当无物体通过对管其间时,红外管接收管D2导通,D2阳极电压为低,CH1输出高电平;当有物体通过其间时,红外管D2截止,D2阳极电压为高,CH1输出低电平。
电路如图5所示。
图5红外对管检测电路图6声光报警电路
3.6声光报警电路
采用一个普通发光二极管加一个蜂鸣器实现,当LED出现故障时的声光报警提示功能。
如图6所示为声光报警电路。
3.7A/D电路
该模块采用美国国家半导体公司8位并行ADCADC0809实现,用于采集LED上电压值到从机。
其电路如图7所示:
图7A/D转换电路图8D/A转换电路
3.8D/A转换电路
该模块采用Linear公司12位串行DACLTC2622实现,用于设定恒流源的输出电流及功率。
电路如图8所示。
3.9串口电路
本系统采用工业串口485进行主机与从机间的通信,其接口电路如图9所示。
图9串口接口电路
4程序设计
4.1物体通过检测实现
物体通过的检测是通过道路两边垂直道路方向摆放的7对红外对管实现的。
S、S’两点分别放置两对管,B点位置摆放3对管。
这样,通过不同管子检测物体的时间先后关系,可以方便地判断出物体的移动位置和移动方向。
即不论物体是前进还是后退,管子都可以检测出来。
红外对管检测精度很高,识别误差小于2cm。
4.2功率调节的实现
当调节功率时,单元控制器并不能一步到位,立即使当前功率值等于设定功率值。
必须先通过D/A输出一个初始的LED电流值,然后通过A/D把LED两端电压读回来,将电流与电压相乘得到的功率值与需设定值进行比较,如果小于设定值,则增加D/A的输出;如果大于,则减小D/A的输出。
通过这种闭环系统,使当前输出功率值逐步逼近设定功率值。
4.3程序流程图
主机的主程序流程图、从机主程序流程图、从机中断服务程序流程图分别如图10、11、12所示。
图10主机主程序流程图
图11从机主程序流程图图12从机中断服务程序流程图
5系统测试
5.1测试仪器
DS-1双通道直流稳压源、C31-A型高精度指针式毫安表、C31-V型高精度指针式电压表
5.2测试方案
功能逐项测试法:
根据题目要求,依次逐项测试系统功能。
数据实测计算法:
使用精密毫伏表、电压表,实时测试通过LED的电流及其两端的电压,再计算出LED的输出功率,并将其与控制器设定的功率值进行比较,以计算出调节误差。
5.3测试结果
1)功能完成情况
经测试,系统可完成题目的基本及发挥部分全部功能。
2)指标完成情况
本题的指标主要是恒流源输出功率的调节误差。
经测试,测试数据及计算结果如表1所示:
表1恒流源的功率数据及调节误差表
设定功率百分比
仪器测量电流值(mA)
仪器测量电压值(V)
实际功率计算值(W)
调节误差
20%
65.82
2.82
0.1850
1.50%
48%
156.23
2.98
0.4656
1.44%
80%
248.44
3.16
0.7851
1.49%
100%
306.02
3.21
0.9823
1.77%
5.4结果分析
通过测试、计算和分析,系统完成题目的基本及发挥部分全部功能,并在设定调节LED输出功率的指标上达到题目发挥部分要求,整体性能达到题目发挥部分要求。
6总结
本系统采用3片Atmel公司的AT89S51单片机作为系统的控制器件,其中支路控制器为主控制器,两个单元控制器作为从控制器。
支路控制器接显示器和键盘组成人机界面,可通过外部时钟模块进行开关灯定时控制,可通过光敏传感器和电压比较器检测环境明暗程度,可通过7对红外对管检测交通情况,控制LED的亮灭。
在单元控制器中,采用OP07集成运放接大功率场效应管设计了LED压控恒流源,可由单片机通过D/A方便地控制恒流源的输出电流和功率,并由A/D芯片将功率数据反馈到单片机,形成闭环自动控制系统。
支路控制器与单元控制器之间采用485工业串口进行通信,可推广到实际应用中。
所有功能和指标均达到或部分超过题目要求。
参考文献
[1]宋文绪,杨帆.自动检测技术.北京:
高等教育出版社,2008.
[2]高吉祥.全国大学生电子设计竞赛培训系列教程.北京:
电子工业出版社,2007.
[3]周坚.单片机C语言轻松入门.北京:
北京航空航天出版社,2006.
[4]孙传友等.测控电路及装置.北京:
北京航空航天大学出版社,2002.
[5]李朝青著.单片机原理及接口技术.北京航空航天大学出版社,2005.
9
附件1:
支路控制器系统电路图
附件2:
单元控制器系统电路图
附件3:
恒流源电路图
附件4:
主要PCB图
1)恒流源与数码管显示PCB图
2)主控电路
3)从机电路
附件5:
主要元器件清单
序号
元器件名称
型号、规格
数量
1
单片机
AT89S51
3
2
路灯LED
1W
2
3
ADC
ADC080
2
4
DAC
LTC2622
2
5
数码管
SM410361K
2
6
74LS138
1
7
LM358
2
8
OP-07
1
9
晶振
11.0592M
3
10
按键
4
11
大功率电阻
1欧5W
2
12
继电器
2
13
场效应管
IRFZ44N
2
14
三端稳压器
7809
2
15
各类电阻
若干
16
各类电容
若干
附件6:
部分程序清单
(1)从机部分程序
19
#include
#include
#include
typedefunsignedcharUINT8;
typedefunsignedintUINT16;
#defineADDR0x02
UINT8Buf[2];
UINT16ADCDat[2],kcw;
UINT8Vol;
floatTemp;
bitRecFlag,clok;
sbitST=P2^7;
sbitOE=P2^6;
sbitEOC=P2^5;
sbitIN7=P2^3;
sbitDA_CS=P2^2;
sbitDA_SCK=P2^0;
sbitDA_SDI=P2^1;
sbitLED=P1^6;
sbitREDE=P3^2;
voidSystem(void)
{
SCON=0xf0;
TMOD=0x21;
TH1=0xFD;
TL1=0xFD;
TH0=0xdc;
TL0=0x32;
TR0=1;
ET0=1;
TR1=1;
EA=1;
ES=1;
}
voidSendChar(UINT8c)
{
REDE=1;
TI=0;
TB8=0;
SBUF=c;
while(TI==0);
TI=0;
REDE=0;
}
voidReceiv(void)interrupt4
{
staticUINT8num=0;
UINT8c;
if(RI==0)
return;
RI=0;
c=SBUF;
if(RB8==1)
{
if(c==ADDR)
SM2=0;
else
{
SM2=1;
num=0;
}
}
Buf[num]=SBUF;
num++;
if(num==2)
{
RecFlag=1;
num=0;
}
}
voidWrite_LTC2622(UINT8Data)
{
UINT8i,Temp;
DA_CS=1;
DA_SCK=0;
DA_SDI=1;
_nop_();
_nop_();
DA_CS=0;
Temp=0x21;
for(i=0;i<8;i++)
{
if((Temp&0x80)==0x80)
DA_SDI=1;
else
DA_SDI=0;
DA_SCK=1;
_nop_();
DA_SCK=0;
_nop_();
Temp<<=1;
}
Data<<=4;
for(i=0;i<16;i++)
{
if((Data&0x8000)==0x8000)
DA_SDI=1;
else
DA_SDI=0;
DA_SCK=1;
_nop_();
DA_SCK=0;
_nop_();
Data<<=1;
}
_nop_();
_nop_();
DA_CS=1;
DA_SCK=0;
}
UINT16Vcontrol(UINT8v)
{
Temp=1240;
Temp=(1/Temp)*4096*v*3;
kcw=floor(Temp);
return(kcw);
}
voidDAC0809(void)
{
UINT8a;
IN7=1;
ST=0;
OE=0;
ST=1;
ST=0;
while(EOC==0);//查询转换结束
OE=1;
a=P0;
OE=0;
Temp=256;
Temp=(1/Temp)*5*a; //单位v
Vol=floor(Temp);
}
voidmain()
{
UINT8i;
System();
while
(1)
{
if(clok)
{
clok=0;
if(Vol>3)
{
SendChar('o');
}
else
{
SendChar('n');
}
}
if(RecFlag)
{
switch(Buf[1])
{
case1:
LED=0; //亮灯
break;
case2:
LED=1;
break;
case4:
Write_LTC2622(Vcontrol(i));
i++;
break;
}
Buf[1]=0;
}
}
}
voidtimer0()interrupt1
{
staticUINT8num;
TH0=0xdc;
TL0=0x32;
num++;
if(num==100)
{
num=0;
DAC0809();
clok=1;
}
}
(2)主机部分程序
#include
typedefunsignedcharUINT8;
typedefunsignedintUINT16;
#defineS10x38
#defineS20x34
#defineS30x2c
#defineS40x1c
codeUINT8SELECT[]={7,6,5,4,3,2,1,0};
codeUINT8SEGMENT[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xc8/*n*/,0x8e/*F*/,0xff};
UINT8Second=0,Minite=30,Hour=12,slave,SDR,Ap,Bp;
UINT8Bsecond,Bminite,Bhour,SETVALUE,SETADDR,Sphour,Spminite,Sthour,Stminite,Sphour2,Spminite2,Sthour2,Stminite2;
sbitclk=P2^4;
sbitio=P2^5;
sbitrst=P2^6;
sbitREDE=P2^7;
sbitACC0=ACC^0;
sbitACC7=ACC^7;
sbitSpeaker=P3^7;
sbitAutochk=P1^7;
bitflag,SETBIT,READBIT,flag1,clock,page,FS=1,FS1,FS2;
voidmain()
{
UINT8c;
System();
init1302();
Read1302();
while
(1)
{
led_dsp();
if(Autochk==1)
{
if(FS)
{
FS=0;
SendChar(1,2); //关灯
SendChar(2,2); //检测光线
FS2=1;
}
}
else
{
if(FS2)
{
FS2=0;
SendChar(1,1); //熄灯
SendChar(2,1); //检测光线
FS=1;
}
}
if(READBIT==1)
{
READBIT=0;
Read1302(); //读1302时间
}
c=Scankey();
if(SETBIT)
{
switch(c)
{
caseS2:
SETADDR++;
if(slave==0)
{
SETADDR%=2;
if(SETADDR==0){SDR=0x82;}//分钟0x03
elseif(SETADDR==1){SDR=0x84;}//时钟0x04
if(SDR==0x82)
{
SETVALUE=((read1302(SDR)&0x70)>>4)*10+(read1302(SDR)&0x0f);
}
elseif(SDR==0x84)
{
SETVALUE=((read1302(SDR)&0x30)>>4)*10+(read1302(SDR)&0x0f);
}
}
elseif(slave==4)
{
SETADDR%=2;
}
else
{
SETADDR%=4;
if(SETADDR<2){page=1;}
else{page=0;}
if((slave==1)||(slave==2))
{
switch(SETADDR)
{
case0:
SET