嵌入式
红绿灯控制系统(模拟)
一、摘要:
交通信号灯用于道路平面交叉路口,通过对车辆、行人发出行进或停止的指令,使人与人、车与车之间尽可能减少相互干扰,从而提高路口的通行能力,保障路口畅通和安全。本文介绍了一种城市十字路口交通信号灯控制系统。该系统采用了以8051为内核的单片机芯片AT89s51作为核心控制器,以嵌入式操作系统RTX51为软件开发平台,通过控制城市十字路口的交通信号灯来指挥交通。该系统具有制作简单、成本低、功能实用等特点。
关键词:单片机 嵌入式操作系统 交通信号灯控制
二、 引言:
随着经济发展,汽车保有量急剧增加,城市道路日渐拥挤,交通拥塞已成为一个城市管理的难题。十字路口的红绿灯指挥着行人和车辆的安全通过,实现红绿灯自动指挥是城市管理自动化的重要课题:
[1];围绕这一课题,多年来有众多设计方案来实现这一功能,随着数字技术、软件编程的发展和进步,实现这一功能的新的设计方案更是层出不穷。就目前而言,在这一方面,比较普遍使用而又技术先进的主要是以CPLD为核心的实现方案和以MCU为核心的实现方案。
[2]但是将两者与嵌入式操作系统RTX51微控器软件相结合构成完整的交通信号灯控制系统的设计方案还比较少。本人与导师近年来一直从事这方面的研究,通过努力,我们已将本设计方案优化、完善并应用于实际,且效果较好。现本文将着力介绍基于MCU和嵌入式操作系统RTX51微控器软件相结合的这一交通信号灯控制系统。
三、 设计原理:
1、LED 灯具的应用及优点
LED 照明灯具在近期得到飞跃的发展,LED 作为绿色环保的清洁光源得到广泛的认可。LED 光源使用寿命长、节能省电、应用简单方便、使用成本低,因而在LED 手电筒、LED 矿灯及便携照明;在建筑照明、装饰照明、标识牌照明;在汽车的仪表板背光、前后雾灯、第三刹车灯、方向灯、尾灯;以及在家庭照明都会得到海量的应用,欧司朗光学半导体公司2008 年调查统计,全球每年家庭照明灯座出货量约为500 亿个。LED 光源的技术日趋成熟,每瓦发光流明迅速增长,促使其逐年递减降价。以1W LED 光源为例,2008 年春的价格已是2006 年春的价格三分之一,2009 年春将降至2006 年的四分之一。
LED 绿色灯具的海量市场和持续稳定数年增长需求将是集成电路行业继VCD、DVD、手机、MP3 之后的消费电子市场的超级海啸!LED 灯具的高节能、长寿命、利环保的优越性能获得普遍的公认。
LED 高节能:节能能源无污染即为环保。直流驱动,超低功耗(单管0.03瓦-1 瓦)电光功率转换接近100%,相同照明效果比传统光源节能80%以上。
LED 长寿命:LED 光源被称为长寿灯。固体冷光源,环氧树脂封装,灯体内也没有松动的部分,不存在灯丝发光易烧、热沉积、光衰快等缺点,使用寿命可达5 万到10 万小时,比传统光源寿命长10 倍以上。
LED 利环保:LED 是一种绿色光源,环保效益更佳。光谱中没有紫外线和红外线,热量低和无频闪,无辐射,而且废弃物可回收,没有污染不含汞元素,冷光源,可以安全触摸,属于典型的绿色照明光源。
照明用LED 光源的VF 电压都很低,一般VF =2.75-3.8V,IF 在15-1400mA;因此LED 驱动IC 的输出电压是VF X N 或VF X 1, IF 恒流在15-1400mA。LED灯具使用的LED 光源有小功率(IF=15-20mA)和大功率(IF>200mA))二种,小功率LED 多用来做LED 日光灯、装饰灯、格栅灯;大功率LED 用来做家庭照明灯、射灯、水底灯、洗墙灯、路灯、隧道灯、汽车工作灯等。功率LED 光源是低电压、大电流驱动的器件,其发光的强度由流过LED 的电流大小决定,电流过强会引起LED 光的衰减,电流过弱会影响LED 的发光强度,因此,LED的驱动需要提供恒流电源,以保证大功率LED 使用的安全性,同时达到理想的发光强度。在LED 照明领域,要体现出节能和长寿命的特点,选择好LED 驱动IC 至关重要,没有好的驱动IC 的匹配,LED 照明的优势无法体现。
(1)LED 工作的主要参数是VF、IF,其它相关的是颜色/色温/波长/亮度/发光角度/效率/功耗等。LED 是一个P-N 结二极管,只有施加足够的正向电压才能传导电流。VF 正向电压是为LED 发光建立一个正常的工作状态,IF 正向电流是促使LED 发光,发光亮度与流过的电流成正比例。LED VF 标称电压:3.4V± 0.2V 。
(2)LED IF 工作电流按应用需要选用,各档不能混用。LED 灯用各档LED 电流:大功率照明用LED 其封装从成品来看是单颗芯片的,其实是用N 颗LED管芯封装在一个单位里的。它们的排列组合是串并联,它们是N 个串联,再N个并联,然后由二点联接电源。选用时要特别注意它的VF 和IF。
2、 LED 灯具驱动原理:
LED 灯具驱动需要先将高压的交流电变换成低压的交流电(AC/AC),然后、将低压的交流电经桥式整流变换成低压的直流电(AC/DC),再通过高效率的DC/DC 开关稳压器降压和变换成恒流源,输出恒定的电流驱动LED 光源。
LED光源是按灯具的设计要求由小功率或大功率LED 多串多并而组成。每串的IF 电流是按所选用的LED 光源IF 要求设计,总的正向电压△VF 是N 颗LED 的总和。LED 灯具选用36V 以下的交流电源可以考虑非隔离供电,如选用220V 和100V 的交流电源应考虑隔离供电。
(3)、目前 MR11、MR16 射灯、水底灯、洗墙灯、路灯、隧道灯、汽车工作灯等LED 灯具大多选用散热较好的自带铜基或铝基板的1W、3W 大功率LED 光源,使用AC/DC12-36V 电源,因而需要使用DC/DC 的降压(Buck)+ 恒流给LED提供VF 和IF。LED 灯具大多使用低压电源,因此在这类灯具的电路设计上,LED的串联个数在1-9 颗,尤以1-3 颗为常见。串联的总△VF 应低于电源Vin。如三颗LED 串联,△VF=3.4V X 3=10.2V。在Vin>12V,能正常工作。MR11、MR16射灯常见的是1W X 3 串联或3W X 1;水底灯常见的是1W X 3 串联2-3 并,三个一组;洗墙灯常见的是1W X 7-9 串联;路灯常见的是1W X 9 串联3 并,4--6个一组;、汽车工作灯常见的是1W X 3-6 串联3 并。当然LED 的串并联的方案是多种多样的,串联个数与其工作电压(Vin)有关,这里就DC12-36V 工作电压而言。目前1W 的LED 光源散热较好,因此选用较多。
LED 灯具对低压驱动芯片的要求:
1)驱动芯片的标称输入电压范围应当满足DC5-40V,以覆盖应用面的需要,耐压如能大于40V 更好;AC 12V 或24 V 输入时简单的桥式整流器输出电压会随电网电压波动,特别是电压偏高时输出直流电压也会偏高,驱动IC 如不能适应宽电压范围,往往在电网电压升高时会被击穿,LED 光源也因此被烧毁。
2)驱动芯片的标称输出电流要求大于1.2-1.5A,作为照明用的LED 光源,1W功率的LED 光源其标称工作电流为350mA,3W 功率的LED 光源其标称工作电流为700mA,功率大的需要更大的电流,因此LED 照明灯具选用的驱动IC 必需有足够的电流输出,设计产品时必需使驱动IC 工作在满负输出的70-90%的最佳工作区域。使用满负输出电流的驱动IC 在灯具狭小空间散热不畅,容易疲劳和早期失效。
3)驱动芯片的输出电流必需长久恒定,LED 光源才能稳定发光,亮度不会闪烁;同一批驱动芯片在同等条件下使用,其输出电流大小要尽可能一致,也就是离散性要小,这样在大批量自动化生产线上生产才能有效和有序;对于输出电流有一定离散性的驱动芯片必选在出厂或投入生产线前分档,调整PCB 板上电流设定电阻(Rs)的阻值大小,使之生产的LED 灯具恒流驱动板对同类LED 光源的发光亮度一致,保持最终产品的一致性。
4)驱动芯片的封装应有利于驱动芯片管芯的快速散热,如将管芯(Die)直接绑定在铜板上,并有一Pin 直接延伸到封装外,便于直接焊接在PCB 板的铜箔上迅速导热如在一个类似4X4mm 的硅片管芯上,要长时间通过300-1000mA 的电流,必然有功耗,必然会发热,芯片本身的物理散热结构也是至关重要的。
5) 驱动芯片本身的抗 EMI、噪音、耐高压的能力也关系到整个LED 灯具产品能否顺利通过CE、UL 等认证,因此驱动芯片本身在设计伊始就要选用优秀的Die塑封铜板
6) 驱动芯片自身功耗要求小于 0.5W,开关工作频率要求大于120Hz,以免工频干扰而产生可见闪烁是一颗可应用于多种LED 灯具驱动的芯片,如路灯、水底灯、洗墙灯、泛光灯、隧道灯、汽车工作灯等。简单实用低成本LED 灯具方案。可将3- 9 颗1W LED 串联,其ΔVF=3.4 V X N, IF=350mA 。当 Vin=12VDC时,3 颗LED 串联, ΔVF=10.2V,工作效率较佳。并可3 串并联应用,ΔIF=3 X350mA=105LED
结合Bipolar高压和BCD高压制程工艺的XL4001、XL4002、XL4101、XL4102产品,输入电压可以做到5V-40V,具有恒流,恒压功能,内置过压、过流、短路、过温保护。针对LED驱动、MR16驱动(1W/3W LED 最高到10颗串联)的市场应用,外围电路简单、性能稳定。持续恒流源输出,最大电流可以做到3A。52kHz 的固定开关频率 .输入/输出电压变化时,负载电流变化范围在± 1%之内. 串接多个LED 时,效率可以达到80%~95%.过温保护(120摄氏度) HVBCD的工艺的高压,大电流,恒流LED升压驱动IC有XL6003、XL6005、XL5002。可以支持16串1W/3W LED串联使用。 XL6003是一颗突破传统电路拓扑结构,结合HVBCD工艺,大电流,高压DC/DC升压恒流LED驱动IC,
(1)它具有较宽的直流3.6V到36V输入电压范围(低压可以兼顾锂电供电)
(2)最高升压可到42V,可驱动串联12颗1W LED(同比其它品牌多驱动4~5颗LED) XL6003最高可以12个LED灯串联,市场其它最高输出只能够8个LED灯串联。
(3)大电流1050mA持续电流输出,可驱动1W LED12串3并或3W LED12串
(4)EN脚可实现PWM调光,且自带软启动功能
(5)低至0.2V参考电压,可以有效提高系统效率
(6)输出42V过压保护功能 .内置过热保护功能
优势:宽电压输入,大电流输出,外围电路简单。XL6003应用简单,普通DC/DC升压拓扑结构,效率高达92%,适用于基于LED的汽车、路灯、 太阳能灯及LED背光驱动的应用.
3、 LED的驱动程序:
#ifndef __KERNEL__
# define __KERNEL__
#endif
#ifndef MODULE
# define MODULE
#endif
#include
#include
#include
#include
#include /* printk() */
#include /* kmalloc() */
#include /* everything... */
#include /* error codes */
#include /* size_t */
#include
#include /* O_ACCMODE */
#include /* COPY_TO_USER */
#include /* cli(), *_flags */
#include
#define DEVICE_NAME "demo"
#define led_MAJOR 212
#define led_MINOR 0
static int MAX_BUF_LEN=1024;
static char drv_buf[1024];
static int WRI_LENGTH=0;
static char combuf[2];
char base = 0x70;
char off = 0x07;
/************************************************** /
static ssize_t led_write(struct file *filp,const char *buffer, size_t count, loff_t *ppos)
{
copy_from_user(drv_buf , buffer, count);
combuf[0]=drv_buf[0];
combuf[1]=drv_buf[1];
WRI_LENGTH = count;
printk("user write data to driver\n");
IIC_WriteSerial(base, off, combuf, 2);
return count;
}
/******************************************/
static ssize_t led_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
return count;
}
/*****************************************/
static int led_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
printk("ioctl runing\n");
switch(cmd){
case 1:printk("runing command 1 \n");break;
case 2:printk("runing command 2 \n");break;
default:
printk("error cmd number\n");break;
}
return 0;
}
/******************************************/
static int led_open(struct inode *inode, struct file *file)
{
sprintf(drv_buf,"device open sucess!\n");
printk("device open sucess!\n");
return 0;
}
/******************************************/
static int led_release(struct inode *inode, struct file *filp)
{
MOD_DEC_USE_COUNT;
printk("device release\n");
return 0;
}
/******************************************/
static struct file_operations demo_fops = {
owner: THIS_MODULE,
write: led_write,
read: led_read,
ioctl: led_ioctl,
open: led_open,
release: led_release,
};
/******************************************/
#ifdef CONFIG_DEVFS_FS
static devfs_handle_t devfs_demo_dir, devfs_demoraw;
#endif
/********************************************/
static int __init led_init(void)
{
int result;
SET_MODULE_OWNER(&demo_fops);
result = register_chrdev(led_MAJOR, "demo", &demo_fops);
if (result < 0) return result;
printk(DEVICE_NAME " initialized\n");
return 0;
}
/***********************************************/
static void __exit led_exit(void)
{
unregister_chrdev(led_MAJOR, "demo");
//kfree(demo_devices);
printk(DEVICE_NAME " unloaded\n");
}
/*****************************************/
module_init(led_init);
module_exit(led_exit);
//////////////////////////////////////////////////////////////////////////////
下面是程序说明,不是代码部分:
重要的数据结构
struct file数据结构
定义位于include/fs.h
struct file结构与驱动相关的成员
mode_t f_mode 标识文件的读写权限
loff_t f_pos 当前读写位置
unsigned int_f_flag 文件标志,主要进行阻塞/非阻塞型操作时检查
struct file_operation * f_op 文件操作的结构指针
void * private_data 驱动程序一般将它指向已经分配的数据 struct dentry* f_dentry 文件对应的目录项结构
设备驱动程序接口( struct file_operations), 标记化方法:
static struct file_operations demo_fops = {
owner: THIS_MODULE,
write: demo_write,
read: demo_read,
ioctl: demo_ioctl,
open: demo_open,
release: demo_release,
};
设备驱动程序接口( struct file_operations )
通常所说的设备驱动程序接口是指struct file_operations{ },它的定义位于include/linux/fs.h中。
在嵌入式系统的开发中,通常只要实现如下几个接口函数就能完成系统所需要的功能
init 加载驱动程序(insmod)时,内核自动调用
read 从设备中读取数据
write 向字符设备中写数据
ioctl 控制设备,实现除读写操作以外的其他控制命令
open 打开设备并进行初始化
release 关闭设备并释放资源
exit 卸载驱动程序(rmmod)时,内核自动调用
驱动程序注册过程(动态分配主设备号)
insmod module_name ;加载驱动程序,运行init函数(register_chrdev(dev_Major, “module_name”, * fs ))
查看/proc/devices
mknod /dev/module_name c/b 主设备号 次设备号
rmmod module_name ;卸载驱动,运行 exit函数(unregister_chrdev(dev_Major, “module_name”, * fs ))
3、交通灯的设计原理:
一般来说,十字路口处的两条相交叉的道路是有主次之分的,其中车流量较大的称为主干道;而车流量相对较小的称为次干道。有主、次干道交叉口的城市道路,四个方向都设有红、绿、黄三色信号灯。红灯亮表示禁止通行;绿灯亮表示可以通行;在绿灯亮转变为红灯亮之前,先要求黄灯亮几秒,以便让交叉口停车线以外的车辆停止通行,而交叉口停车线以内的车辆快速通过交叉口,并且主干道红灯亮的时间等于次干道绿灯亮时间和黄灯亮时间之和。同理,次干道红灯亮时间等于主干道绿灯亮时间与黄灯亮时间之和。完成以上系统设计方法有多种。用MCU实现该系统设计,相对而言是最简单的,因MCU最适宜于对物理对象的控制,通过控制器编程,很容易达到设计要求且成本较低、易于操作。
四、 交通信号灯控制电路的硬件设计:
首先,要设计一个信号灯控制电路方案,实现对红、黄、绿三色信号灯的控制,用发光二极管模拟十字路口的红、黄、绿三色信号灯。某城市道路十字路口交通信号灯控制方案如表1:
表1:
表1交通信号灯控制方案 :
路口街道 主干道 次干道
信号灯 R Y G r y G
主红支绿30s 1 0 0 0 0 1
主红支黄5s 1 0 0 0 1 0
主绿支红40s 0 0 1 1 0 0
主黄支红5s 0 1 0 1 0 0
由表1可知,主干道车辆通行时间是30s,次干道为20s,红绿灯转换之间黄灯亮5s,控制三色灯的信号为开关信号,约定逻辑0表示灯灭,逻辑1表示灯亮。设计控制电路图如图1所示。
由图可知,这是一个非常简单的微控制器最小系统,其中的AT89S51具有高效的8051内核,8KB FLASH EEPROM,256字节的RAM,符合本系统实际应用的要求。其中,发光二极管实际为若干发光二极管组成的阵列,每个发光二极管只是一个像素点,能显示红、黄、绿三种颜色,这是因为每个发光二极管封装内包含两个发光二极管。仅当Red亮时,灯显红色,仅当Green亮时,灯显绿色,当两者同时点亮时,由混色原理可知,灯显黄色。
五、 交通信号灯控制电路的软件设计:
根据城市道路十字路口交通信号灯控制方案,结合硬件电路,可以得出十字路口交通信号灯的状态变换关系如图2由上图可知,信号灯的状态共有4个,每个状态停留的时间是不同的,软件要完成的任务就是按照状态关系控制主干道和次干道红、黄、绿三色信号灯变化。这是一个典型的按照时间原则控制系统在4个状态之间循环。基于嵌入式操作系统RTX51的微控制器软件很容易实现这种要求。该软件可以实现实时和多任务控制,并可以利用操作系统函数os_wait(K_IVL,ticks)来实现精确定时,通过MCU的I/O端口实现对信号灯的控制[4]。根据以上分析,可以把软件要完成的功能分成两部分:
任务0:系统初始化。将6个信号灯全部熄灭,然后启动任务1。
任务1:按照设计方案控制信号灯状态。当是同处于某种状态时,条用系统操作函数os_wait(K_IVL,ticks)实现经确定时,使这一状态保留特定的时间后转到下一状态。4种状态都完成后再回转到状态1,并无限循环下去。使用keil V7.0软件[5],采用C51高级语言编程,用户应用程序如下:
#include
#include
sbit main_red=p0^0
sbit main_yellow=p0^1
sbit main_green=p0^2
sbit branch_red=p0^5
sbit branch_yellow=p0^6
sbitbranch_green=p0^7
/************************************/
/任务0 系统初始化,将六个灯全部熄灭,然后启动任务1
/************************************/
Void int(void)_task0
{
main_red=1;
main_yellow=1;
main_green=1;
branch_red=1;
branch_yellow=1;
branch_green=1;
os_create_task(1);
os_delete_task(0);
************************************/
任务1 按时间原则控制信号灯
/************************************/
void ledcontrol(void)_task1
While(1)
main_red=0;
main_yellow=1;
main_green=1;
branch_red=1;
branch_yellow=1;
branch_green=0;
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250); main_red=0;
main_yellow=1;
main_green=1;
branch_red=1;
branch_yellow=0;
branch_green=1;
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
main_red=1;
main_yellow=1;
main_green=0;
branch_red=0;
branch_yellow=1;
branch_green=1;
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
so_wait2(k_ivl,250);
main_red=1;
main_yellow=0;
main_green=1;
branch_red=0;
branch_yellow=1;
branch_green=1;
六、总结 :
本文详尽介绍了交通信号灯MCU控制系统的设计思路、硬件及软件的构成。硬件电路为一个MCU最小系统,设计十分简单,而且MCU仅仅使用了很少的IO口,留下了很多没用到的IO口资源,这保证了系统功能扩展时有足够的硬件资源。软件部分由于采用了越来越受广大电子设计工作者青睐的实时嵌入式操作系统软件,并且使用C语言编程,使整个系统软件部分同硬件部分一样简捷。交通信号灯控制系统实际运行结果表明,实时操作系统能保证对外界信息进行足够迅速的处理。
七、 本系统的创新之处:
传统的微控制器应用大多采用结构化编程思想,对单任务控制能达到编程简单、思路清晰、开发周期短的要求。但面对多任务、实时性要求高、相对复杂的系统,采取传统的结构化编程方法,所编写的用户程序可能非常复杂,这无疑给设计人员带来了较大的困难;嵌入式实时操作系既能够保证对外界的信息以足够快的速度进行处理,又能并行地运行多个任务,具有实时性和并行性的特点。嵌入式实时操作系统的使用降低了软件编程的复杂程度、编写的程序有较好的可读性和可移植性、提高了开发效率,而且系统维护和功能扩展非常方便。
八、参考文献:
[1]尹宏宾,徐建闽.道路交通控制技术.广州:华南理工大学出版社.2000.
[2]刘智勇.智能交通控制理论及其应用.北京:科学出版社.2003.
[3]何立民.单片机高级教程[M].北京:北京航空航天大学出版社.2000.
[4]晨风.嵌入式实时多任务软件开发基础[M].北京:清华大学出版社.2004.
[5]彭秀华.Keil V7.0单片机高级语言编程.北京:电子工业出版社.2005
[6]网络
1