状态机思想在程序设计中的应用(上).doc_第1页
状态机思想在程序设计中的应用(上).doc_第2页
状态机思想在程序设计中的应用(上).doc_第3页
状态机思想在程序设计中的应用(上).doc_第4页
状态机思想在程序设计中的应用(上).doc_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

题目:状态机思想在程序设计中的应用(上)主讲人:自2008-4 贺龙时间:2011.3.13主讲内容:一:状态机的概念。(简单描述即可)有限状态机(以下用FSM指代)是一种算法思想,简单而言,有限状态机由一组状态、一个初始状态、输入和根据输入及现有状态转换为下一个状态的转换函数组成。状态机的要素 状态机可归纳为4个要素,即现态、条件、动作、次态。这样的归纳,主要是出于对状态机的内在因果关系的考虑。“现态”和“条件”是因,“动作”和“次态”是果。详解如下: 现态:是指当前所处的状态。 条件:又称为“事件”。当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。 如果我们进一步归纳,把“现态”和“次态”统一起来,而把“动作”忽略(降格处理),则只剩下两个最关键的要素,即:状态、迁移条件。状态迁移表二:实例(1):按键扫描#definekey_input PIND.7 /按键输入口 #definekey_state_0 0 #definekey_state_1 1 #definekey_state_2 2 charread_key(void) staticcharkey_state=0; charkey_press,key_return=0; key_press=key_input; /读按键I/O电平 switch(key_state) casekey_state_0: /按键初始态 if(!key_press)key_state=key_state_1; /键被按下,状态转换到键确认态 break; casekey_state_1: /按键确认态 if(!key_press) key_return=1; /按键仍按下,按键确认输出为“1” key_state=key_state_2; /状态转换到键释放态 else key_state=key_state_0; /按键已抬起,转换到按键初始态 break; casekey_state_2: if(key_press)key_state=key_state_0; /按键已释放,转换到按键初始态 break; returnkey_return; # 按键分三个状态:无按键状态,有按键状态,等待释放状态# 不用插入10MS延时,利用定时器产生10ms的标志,每隔10ms再去检测一次按键,这样做CPU的效率很高,要知道10ms单片机可以做很多的事情# 应用实例bitflag_keyscan=0; bit key_value = 0;charread_key(void) . . intmain(void) while(1) if(flag_keyscan)/10MS定时到,调用扫描 flag_keyscan=0; key_value = read_key(); if(key_value)调用键盘处理程序 voidtimer0_init(void)interrupt1 TH0=0XXX;/10ms TL0=0XXX; flag_keyscan=1; 三:实例(2):赛道计时器/*/ /赛道计时器完成任务: /小车通过起跑线时开始计时,并鸣响蜂鸣器 /小车完成一圈再次通过起跑线时停止计时,并鸣响蜂鸣器 /*/ #include #include #defineHC164_dataPORTC.4 #defineHC164_clkPORTC.5 #defineK1PIND.2 #defineK2PIND.3 #defineLED_TPINB.0/发射管 #defineLED_RPIND.0/接收管 #defineFMQPORTD.7/蜂鸣器 #definekey_state_0 0/初始状态 #definekey_state_1 1/消抖动并确认状态 #definekey_state_2 2/等待按键释放状态 unsignedcharLED_STATE=0;/接收管的状态 flashunsignedcharled_7=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90; flashunsignedcharposition4=0x3e,0x3d,0x37,0x3b; unsignedinttime=0; unsignedchardisbuffer4;/数据缓冲区 unsignedcharposit=0; unsignedintcnt1=0;/10MS计时,用于按键扫描和主程序while循环 unsignedintcnt2=0;/10MS计时,用于秒表计数 unsignedintcnt3=0;/2S计时,用于第一次检测到小车后延时 unsignedintcnt4=0;/60MS计时,用于蜂鸣器第一次鸣响时间 unsignedintcnt5=0;/60MS计时,用于蜂鸣器第二次鸣响时间 unsignedchartime_10ms_ok=0; /* -功能描述:读取按键1的值 -隶属模块:按键检测模块 -函数属性:内部 -参数说明:无 -返回说明:为1说明按键按下 -注:该函数10MS扫描一次 */ unsignedcharread_key1() staticunsignedcharkey1_state=0; unsignedcharkey_press,key_return=0; key_press=K1; switch(key1_state) casekey_state_0: if(!K1)key1_state=key_state_1; break; casekey_state_1: if(!K1) key_return=1; key1_state=key_state_2; else key1_state=key_state_0; break; casekey_state_2: if(K1)key1_state=key_state_0; break; returnkey_return; /* -功能描述:读取按键2的值 -隶属模块:按键检测模块 -函数属性:内部 -参数说明:无 -返回说明:为1说明按键按下 -注:该函数10MS扫描一次 */ unsignedcharread_key2() staticunsignedcharkey2_state=0; unsignedcharkey_press,key_return=0; key_press=K2; switch(key2_state) casekey_state_0: if(!K2)key2_state=key_state_1; break; casekey_state_1: if(!K2) key_return=1; key2_state=key_state_2; else key2_state=key_state_0; break; casekey_state_2: if(K2)key2_state=key_state_0; break; returnkey_return; /* -功能描述:74HC164的数据处理 -隶属模块:数码管显示模块 -函数属性:内部 -参数说明:byte为串入并出的数据 -返回说明:无 -注:74HC164核心模块为一个移位寄存器,根据与数码管的接口,先送入低位数据,后送入高位数据 */ voidHC164_send_byte(charbyte) chari; for(i=0;i=1; /* -功能描述:将秒表时间的值送到数据缓冲区 -隶属模块:数码管显示模块 -函数属性:内部 -参数说明:无 -返回说明:无 -注:不用循环结构,加快传输速度 */ voidtime_to_disbuffer(void) unsignedinttemp; temp=time; disbuffer0=temp%10; temp=temp/10; disbuffer1=temp%10; temp=temp/10; disbuffer2=temp%10; temp=temp/10; disbuffer3=temp%10; /* -功能描述:数码管显示缓冲区的数据 -隶属模块:数码管显示模块 -函数属性:内部 -参数说明:无 -返回说明:无 -注:该函数为数码管显示的灵魂,在中断服务程序中2MS调用一次,并显示数码管的某一位 */ voiddisplay() PORTC=0X3F; if(posit=2) HC164_send_byte(led_7disbufferposit&0x7f); else HC164_send_byte(led_7disbufferposit); PORTC=positionposit; if(+posit=4)posit=0; /* -功能描述:TIMER2比较匹配中断服务程序,根据状态标量,让数码管和蜂鸣器显示相应内容 -隶属模块:独立的中断服务 -函数属性:内部 -参数说明:无 -返回说明:无 -注:处理状态机的状态放在MAIN函数里判断,各种状态下的处理内容在中断中处理,效率高 */ interruptTIM2_COMPvoidtimer2_comp_isr(void) display(); cnt1+; if(cnt1=5) cnt1=0; time_10ms_ok=1; if(LED_STATE=0)/等待状态,不计时 time=0; elseif(LED_STATE=1)/计时状态 cnt2+; cnt4+; if(cnt2=5) cnt2=0; time+; if(time=10000) time=0; time_to_disbuffer(); if(cnt4=30) FMQ=0; else /cnt4=0; FMQ=1; elseif(LED_STATE=2)/停止计时 cnt2=0; cnt3=0; cnt5+; time=time; if(cnt5=30) FMQ=0; else FMQ=1; /* -功能描述:初始化,状态机的状态判断 -隶属模块:主函数 -函数属性:内部 -参数说明:无 -返回说明:无 -注:处理状态机时,状态越少越好,防止状态混乱,WHILE循环每10MS循环一次执行各种状态的判断 */ voidmain(void) /端口初始化 DDRC=0x3f; PORTC=0x3f; DDRD=0X80; PORTD=0x80; DDRB=0x02; PORTB=0x02; /TIMER2初始化 TCCR2=0X0C; TCNT2=0X00; OCR2=0X7C; TIMSK=0X80;/允许比较匹配中断 #asm(sei);/开全局中断 while(1) if(time_10ms_ok=1) time_10ms_ok=0; switch(LED_STATE) case0:/等待状态 if(LED_R=1) LED_STATE=1; break; case1:/开始计时 if(+cnt3200) break; elseif(LED_R=1) cnt3=0; LED_STATE=2; break; case2:/等待小车越过终点 if(read_key2() LED_STATE=0; break; default: break; if(read_key1() LED_STATE=1; if(read_key2() LED_STATE=0; 三:总结/!定义状态名称与状态值之间的关系,增加可读性 #defineFSM_START0x00 #defineFSM_STATE_A0x01 #defineFSM_STATE_B0x02 #defineFSM_RESET0xFF boolfsm_example_A(形参列表) staticuint8_ts_chFSMState=FSM_START;/!定义状态变量 switch(s_chFSMState) caseFSM_START: /!这里添加状态机初始化代码 s_chFSMState=FSM_STATE_A;/!进入下一状态 break; caseFSM_STATE_A: /!这里添加状态机A进入下一状态的检测代码 if(某某条件) /!这里做一些进入下一状态时要做的准备工作 s_chFSMState=FSM_STATE_B;/!进入下一状态 break; caseFSM_STATE_B: /!这里添加状态机A进入下一状态的检测代码 if(某某条件) /!这里做一些进入下一状态时要做的准备工作 s_chFSMState=FSM_STATE_A;/!进入下一状态 elseif(某某条件) elseif(某某条件) else break; caseFSM_STOP: caseFSM_RESET: default: /!这里添加状态机复位相关的代码 chFSMState=FSM_START;/!条件状态转移1 检测状态1 无

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论