《匠人手记》推荐网上购书渠道:
  互动出版网(china-pub)   >>>
  当当网(dangdang)   >>>
  卓越亚马逊网    >>>
  淘宝网(taobao)   >>>
  更多购书渠道……   >>> 

设为首页加入收藏联系匠人管理入口21IC首页21IC博客21IC社区侃单片机回复的贴参与的贴

天气预报
百宝日历
载入中...

百宝专栏

载入中...
最新货色

载入中...

粉丝评论

载入中...

载入中...



百宝信息

载入中...

百宝流量

(2006-07-01开始)


匠人手记

单片机程序设计中运用事件驱动机制
程序匠人 发表于 2006-5-27 0:30:00  阅读全文 | 回复(0) | 引用通告 | 编辑

单片机程序设计中运用事件驱动机制

摘要:通过实例说明将事件驱动机制应用到单片机程序中,使中断响应与处理程序分离,可较理想地用硬件定时代替处理程序中的软件定时,从而大幅提高系统对多中断的实时响应能力,降低多中断系统调试的难度。

1 传统单片机程序开发的不足

在传统的单片机程序中,通常是以“过程”和“操作”为中心的结构,程序按规定的过程顺序地执行,与外设的连接一般采用中断方式,在中断服务程序中完成外设的全部处理工作,主程序一般是初始化系统并等待中断的发生。这种结构成熟、易于理解,但有如下不足:

(1)受单片机性能的限制,容易造成系统对其它中断的响应变得迟缓,特别是对于中断源较多、中断处理耗时较多的系统(如:LED显示、键盘扫描等);

(2)中断服务程序过长,在中断服务期间系统无法响应同级的中断;

(3)可能导致代码重入,增大堆栈开销,造成难以预料的结果;

(4)程序调试时,花在各模块定时协调方面的时间、精力随系统的复杂程序大幅增加。

如果在编写单片机程序时,引入Windows程序中的事件驱动机制,把中断响应与事件处理程序分离,中断服务程序的任务只是产生一个中断发生的标志,而事件处理则由处理程序来完成,主程序则负责判断标志和调度处理程序。这样,可大幅缩短中断服务程序的长度,减少断服务程序的耗时,提高系统对多中断的响应能力,从而较好地解决上述矛盾。

2 Windows的事件驱动机制

在Windosw系统中,程序的设计围绕事件驱动来进行。当对象有相关的事件发生时(如按下鼠标键),对象产生一条特定的标识事件发生的消息,消息被送入消息队列,或不进入队列而直接发送给处理对象,主程序负责组织消息队列,将消息发送给相应的处理程序,使相应的处理程序执行相应的动作,做完相应的处理后将控制权交还给主程序。

在这种机制中,对象的请求仅仅是向队列中添加相应的消息,耗时的处理则被分离给处理函数。这种结构的程序中各功能模块界限分明,便于扩充,能充分利用CPU的处理能力,使系统对外界响应准确而及时。

3 事件驱动的单片机程序设计

与Windows系统相比,单片机的资源非常有限,因此,单片机程序中的事件驱动机制只能采取一种简化的方式。当某个中断发生时,中断服务程序设置相应的标志,不同的标导代表不同的中断发生的消息,而主程序不断地判别这些标志,以决定启动哪一个处理函数。相应的处理函数被启动处理完相关的任务后,清除此标志,然后把控制权交还给主程序。采用这种机制,可合理地利用有限资源,使程序调试的工作量大幅下降。对于延时、定时处理(如LED显示、键盘扫描等),更可方便地使用一定时器来完成延时、定时的任务,从而把CPU从这种耗时的任务中解放出来,确保系统对多中断有足够的响应能力。

本文以一IC卡读写机为例,说明事件驱动机制在单片机程序设计中的具体应用。

3.1 硬件结构

本系统以ATMEL公司的89C51为核心(如图1)。89C51价格低廉,性能较好,片内有4KB的可擦写程序存储器,可满足本系统的要求。为简化硬件结构及系统能耗,键盘采用软件扫描的矩阵键盘。LED显示采用段位动态扫描,在任一时刻LED中最多只有一段被点亮。具体是在位选信号送某位LED的公共极时,每隔一个时间片依次输出该位LED的段码(含小数点),输出完成一位后,再逐闪输出下一位。从第一位至第N位LED依次分成8×N个时间片循环扫描显示。串口UART作为系统与外部数据通信的通道,IC卡的读写由MCU模拟I2C协议来实现。

本贴包含图片附件: 

 

3.2 事件驱动机制的单片机程序设计

中断申请标志

在系统中定义一个可位寻址的单元,在此把它命名为Message_Flag,用来记录描述中断事件发生的情况。各位的定义如下:

本贴包含图片附件: 

 

LED显示的实现

显示模块结构见图2。以定时器T0作为LED的动态扫描的定时基准,T0的定时时间最大值Tseg=20ms/(8×N)(其中N为LED位数),改变Tseg的值可改变显示的亮度。T0每隔Tseg时间向MCU申请中断,在T0的中断服务程序中置位相应的标志位(Message_Flag中的D0位)。主程序检测到此标志位被置位后,启动显示模块实现位段的显示输出。

本贴包含图片附件: 

 

键盘输入的实现

键盘模块结构见图3。在LED动态扫描期间,只有被点亮的LED相应的位选线维持大约3ms的低电平,而在系统工作的绝大部分时间内LED的位选线(即键盘的列线)维持高电平。当有键被按下时,将把键盘的行线中某一根拉成高电平,经或非门后,向MCU申请INT1中断,在INT1的中断服务程序中启动定时时间为20ms的定时器T1。T1的定时时间到后向MCU申请T1中断,在T1的中断服务器程序中置位相应的中断申请标志(Message_Flag中的D1位)。主程序检测到此标志位被置位后,启动键盘扫描模块实现键盘输入。键盘输入完成(用户按“确认”键),置位键盘输入确认标志(Message_Flag中的D7位)。

本贴包含图片附件: 

 

IC卡的读写

IC卡的SDA、SCL经卡座分别通过P1.0、P1.1与MCU相连。当IC卡插入卡座时,座上的微动开关使INT0变为低电平,向MCU申请INT0中断。在INT0中断服务程序中置位相应的中断申请标志(Message_Flag中的D2位),主程序检测到此标志位被置位后,启动IC卡的读模块,以软件模块I2C协议来实现读卡操作。在数据处理完成后,同样通过软件模块I2C协议来完成写卡的操作。

串口通讯

实际应用中可把UART转换成RS232C与PC相连或转换成RS485等其它协议组成单片机网。MCU与外部的通讯采用中断方式,在串口的中断服务程序中置位相应的中断申请标志(Message_Flag中的D4位)。主程序检测到此标志位被置位后,启动串口通讯模块,实现与外部的数据通讯。

主程序的设计

综上所述,主程序首先完成系统的初始化,然后循环检测各中断的中断申请标志,如有某标志被置位,则启动相应的处理模块完成相应的任务。程序结构如下(用C51编写):

vnsigned bdata message_flag;

sbit t0_int=message_flag^0;

sbit t1_int=message_flag^1;

sbit int0_int=message_flag^2;

sbit uart_int=message_flag^4;

sbit kb_enter=message_flag^7;

unsigned char kb_buf[8];

unsigned char led_buf[8];

unsigned char ic_buf[8];

unsigned char num_buf[8];

void uum_proc(void); /*数据处理模块*/

void ledbuf_write(unsigned,unsigned int); /*数据处理*/

void system_init(void); /*系统初始化*/

void uart_commune(void); /*串口通讯模块*/

void led_display(void); /*LED显示*/

void kb_scan(void); /*键盘扫描*/

void ic_reader(void); /*读IC卡*/

void ic_writer(void); /*写IC卡*/

void set_timer(unsigned int time_len,unsigned char type,unsigned char id); /*设置定时器*/

void t0_int_sever(void); /*定时器T0中断服务*/

void t1_int_sever(void); /*定时器T1中断服务*/

void int0_int_sever(void); /*INT0中断服务*/

void int1_int_sever(void); /*INT1中断服务*/

void uart_int_sever(void); /*串口中断服务*/

void main(void)

{

system_init();

while(1) {

if (t0_int) led_display();

if (int0_int) ic_reader();

if (t1_int) kb_scan();

if (uart_int) uart_commune();

if (kb_enter){

num_proc();

ic_writer();

ledbuf_write(num_buf,8);

}

}

}

事件驱动的单片机程序设计是通过在中断服务程序中置位相位标志,把耗时的中断服务中的处理部分分离出来,中断返回后,再由主程序根据标志启动相应的处理模块。在任务处理完成后,清除相应的标志。由于中断服务程序短小,所以一般能实时地响应各种中断;而处理程序之间不会被相互调用,所以不会产生代码重入;各模块界限分明,给程序中各模块的统调带来很大的方便。

实践证明,运用事件驱动机制来纺织单片机程序,即使对于要求定时准,耗时多的多中断、多模块系统,也可轻松地完成。

看《匠人手记》,与匠人同行!北航出版,正在热卖!

发表评论:
载入中...

芯片专题

器件专题

软件专题

硬件专题

综合专题

项目专题

原创专题

器件检测
LCD LED
按键 触摸键
E2PROM
电池 电机
电阻 电容 电感

指令系统
软件算法
编程规范
滤波算法
串行通讯

PCB设计
I2C PWM
红外遥控
充电技术
中断 ADC 

匠人手记
匠人夜话
网络心路
一周热点串烧
从零开始玩PIC
DIY旋转时钟

广告5号位 [投放]


学习板、开发板、编程器、下载器、仿真器(查看详情……)

广告3号位 [投放]

站内搜索


站外搜索


百度  google
mp3  歌词 
图片  FLASH 
知道  文档
新闻  词典 
地图  mp3 
软件  天网 
雅虎  爱问 
搜狗  讯雷 
网讯  华军 
天空 

21IC器件搜索
百宝箱分站
  • 《匠人的百宝箱》21IC站
  • 《匠人的百宝箱》21IC笔记团队
  • 《匠人手记》21IC书友会
  • 《匠人的百宝箱》MCUBLOG站
  • 《匠人的百宝箱》MCUBLOG笔记团队
  • 《匠人的百宝箱》EDN站
  • 《匠人手记》EDN书友会
  • 《匠人的百宝箱》与非网站
  • 《匠人的百宝箱》新浪站
  • 《匠人的百宝箱》百度站
  • 《匠人的百宝箱》网易126站
  • 《匠人的百宝箱》网易163站
  • 《匠人的百宝箱》互动出版网站
  • 广告4号位 [投放]

     
     

    匠人原创

    推荐阅读

    往日酷贴

     

    友情连接

     [更多酷站连接]

     

     

     

     

    [欢迎交换连接]

    [百宝箱之与非门分舵]

    [电脑圈圈的家当]

    [IC921的博客]

    [hotpower 的水潭]

    [八楼的呼吸]

    [柔月阁]

    [PIC论坛]

    [SMARTCODE电子书斋]

    [阿摆手记]

    [电子伙伴]

    [xwj的文君阁]

    [所长的BLOG]

    [海边淘沙]

    [单片机开发联盟]

    [数字电视之家]

    [软件开发之窗]

    [unaided的笔记]

    [小飞的笔记]

    [ICC AVR开发网]

    [我爱研发网]

    [infernal的笔记]

    [网址之家]

    [好东西网址大全]

    [美萍中文精选]

    [水牛的仓库]

    [逍遥电子]

    [ningpanda的博客]

    [雄鹰的空中加油站]

    [一网见天下]

    [Armoric]

    [股剩是怎样炼成的]

    [嵌入式365]

    [C-Design]

    [AVR猎手的地盘]

    [中国高校自动化网]

    [SunK]