




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第五章 节 拍 定 时 器5.1 节拍定时器概述STM32F10x内核中有一个节拍定时器。节拍定时器为一个24位递减计数器,节拍定时器设定初值并使能后,每经过1个系统时钟周期,计数值就减1。当计数值递减到0时,节拍定时器自动重装初值,并继续向下计数,同时内部的COUNTFLAG标志会置位,触发中断(如果中断使能)。节拍定时器,其功能简单,只能提供一个节拍定时用,一般作为系统的嘀嗒。在使用外部晶振为8MHz,9倍频,系统时钟为72MHz,节拍定时器的递减频率可以设为9MHz(如HCLK/8)。在这个条件下,把系统定时器的初始值设置成90000,就能够产生10ms的时间基值,如果开启中断,则产生10ms的中断。利用ST的函数库使用systick的方法1、调用SysTick_CounterCmd() 失能SysTick计数器2、调用SysTick_ITConfig () 失能SysTick中断 3、调用SysTick_CLKSourceConfig() 设置SysTick时钟源。4、调用SysTick_SetReload() 设置SysTick重装载值。5、调用SysTick_ITConfig () 使能SysTick中断6、调用SysTick_CounterCmd() 开启SysTick计数器下面部分我们分别来介绍这几个库函数。5.2 库函数介绍5.2.1 函数SysTick_CLKSourceConfig SysTick_CLKSourceConfig函数,其功能为设置SysTick时钟源。表5-2-1. 描述了函数SysTick_CLKSourceConfig 函数名SysTick_CLKSourceConfig函数原形void SysTick_CLKSourceConfig(u32 SysTick_CLKSource)功能描述 设置SysTick时钟源 输入参数 SysTick_CLKSource:SysTick时钟源 输出参数无 返回值无先决条件无被调用函数无表5-2-2 列举了SysTick_CLKSource 参数允许取值范围 表5-2-2 SysTick_CLKSource值SysTick_CLKSource参数可取的值描述 SysTick_CLKSource_HCLK_Div8SysTick时钟源为AHB时钟除以8SysTick_CLKSource_HCLKSysTick时钟源为AHB时钟 例:设置系统定时器时钟为AHB时钟 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); 5.2.2 函数SysTick_SetReload 函数SysTick_SetReload的功能为设置SysTick重装载值。表5-2-3描述了函数SysTick_SetReload 函数名SysTick_SetReload 函数原形void SysTick_SetReload(u32 Reload) 功能描述 设置SysTick重装载值输入参数 Reload:重装载值,该参数取值必须在1和0x00FFFFFF之间 输出参数无 返回值无先决条件无被调用函数无例:设定系统定时器的重载值为90000SysTick_SetReload(90000); 5.2.3 函数SysTick_CounterCmd 函数SysTick_CounterCmd的功能为使能或者失能SysTick计数器表5-2-4. 描述了函数SysTick_CounterCmd 函数名SysTick_CounterCmd 函数原形void SysTick_CounterCmd(u32 SysTick_Counter) 功能描述 使能或者失能SysTick计数器输入参数 SysTick_Counter:SysTick计数器新状态输出参数无 返回值无先决条件无被调用函数无表5-2-5列举了SysTick_Counter参数可取的值。表5-2-5. SysTick_Counter值SysTick_Counter参数可取的值描述SysTick_Counter_Disable失能计数器SysTick_Counter_Enable使能计数器SysTick_Counter_Clear清除计数器值为0例: 使能系统定时器SysTick_CounterCmd(SysTick_Counter_Enable); 5.2.4 函数SysTick_ITConfig 函数SysTick_ITConfig的功能是使能或者失能SysTick中断。表5-2-6. 描述了函数SysTick_ITConfig 函数名SysTick_ITConfig函数原形void SysTick_ITConfig(FunctionalState NewState)功能描述 使能或者失能SysTick中断 输入参数 NewState:SysTick中断的新状态,这个参数可以取:ENABLE或者DISABLE输出参数无 返回值无先决条件无被调用函数无例:使能系统定时器中断 SysTick_ITConfig(ENABLE); 5.2.5 函数SysTick_GetCounter 函数SysTick_GetCounter的功能是获取SysTick计数器的值。表5-2-7 描述了函数SysTick_GetCounter 函数名SysTick_GetCounter函数原形u32 SysTick_GetCounter(void)功能描述 获取SysTick计数器的值 输入参数 无输出参数无 返回值SysTick计数器的值 先决条件无被调用函数无例:获取系统定时器的计数值u32 SysTickCurrentCounterValue; SysTickCurrentCounterValue = SysTick_GetCounter(); 5.3 节拍定时器试验1嘀嗒实例5.3.1 实验要求利用节拍定时器,每10毫秒中断一次,每500毫秒跳变一次LED8。5.3.2 软件结构在程序中,需要初始化节拍定时器,使节拍定时器每10ms重载一次,并开启节拍定时器中断。在中断程序中,每进入一次中断,让一计数变量加1,然后判断是否有50次,如果有50次,则跳变一下LED8灯,同时把计数变量清0。这样程序运行时LED8灯就不停地闪烁。图5-3-1是程序的流程图。 图5-3-1 软件流程图5.3.3 实例代码以队列收发数据为基础,来进行添加。首先创建E:OpenM3V开发板测试程序SysTicksys_delay文件夹,把E:OpenM3V开发板测试程序USARTUSART3文件夹中的工程,复制到E:OpenM3V开发板测试程序SysTicksys_delay文件夹中,,编译下载,看程序复制是否正确,这一步很关键,在作任何更改前,必须验证前一步的正确和完整性。 对其的态度是,宁愿认为其是错误的,也不要去假设它是正确的。所有正确的东西,必须要实际测试后才能确定。有时看似麻烦的东西,却能节省好多时间和精力,并给我们对下一步的信心。验证通过后,点击图标,在编辑对话框中出现一个新的空白文档,在这个文档中加入以下这部分内容,然后点击存盘,文件保存在本工程文件所在地文件夹中,命名为systic.c。这个文件中,存放系统定时器初始化有关的所有程序代码和函数。同时把这个文件加入到文件组USER中。下面是systic.c文件中系统定时器初始化的程序清单:#include stm32f10x_lib.hunsigned char sys_nub; /系统定时器中断计数变量/SysTick设置void SysTick_Config(void) /失能SysTick定时器 SysTick_CounterCmd(SysTick_Counter_Disable); /失能SysTick中断 SysTick_ITConfig(DISABLE); /设置SysTick时钟源 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); /设置SysTick重载值,10ms重载一次,在72Mhz时钟下 SysTick_SetReload(90000); /开SysTick中断 SysTick_ITConfig(ENABLE); /开SysTick定时器 SysTick_CounterCmd(SysTick_Counter_Enable); 点击图标,在编辑对话框中出现一个新的空白文档,在这个文档中加入以下这部分内容,然后点击存盘,文件保存在本工程文件所在地文件夹中,命名为systic.h。void SysTick_Config(void);extern unsigned char sys_nub;在stm32f10x_it.c文件中,加入头函数systic.h,在系统中断定时器中断函数void SysTickHandler(void)中加入以下程序代码:void SysTickHandler(void) sys_nub+; /系统定时器中断计数变量加1 if(sys_nub 49) /计数到50时 sys_nub = 0; /清0计数变量 LED8B(); /跳转LED8灯 在主函数中加入头文件systic.h,并加入系统定时器初始化函数SysTick_Config()。程序代码分析:在main函数中,首先启动时钟和初始化嵌套向量中断控制器(NVIC),然后再调用I/O口、串口系统定时器初始化函数。在系统定时器中断中计数中断次数,当达到50次时,跳转LED8灯。5.3.4 编译下载和调试通过ProjectRebuild All命令进行编译。编译通过后,在其工程文件夹下DebugExe目录下有一个.HEX后缀的文件,此为可执行文件,使用ST提供的下载工具,以ISP方式把程序下载到芯片中。复位系统,可以看到LED8每秒钟闪烁一次。打开串口调试助手,可以看到,PC机发送什么数据,串口也能接收到相同的数据。5.4 有实际应用意义的键盘实例5.4.1 实验要求有了这个节拍定时器实验后,回过头来看前面的按键和串口还有LED灯,下面来做一个把三者结合起来的实验。实验设计要求是,实现真正的按键功能,每按一次键,系统只识读一次,而不管按多长时间。前面讲叙的按键识别没有进行防抖处理,在这里,使用系统定时器,来实现键盘防抖功能。具体要求是:每按K1键一次,LED1灯翻转一次,同时通过串口1发送0X31这个数据;每按K2键一次,LED2灯翻转一次,同时通过串口发送0X32这个数据;每按K7键一次,LED7灯翻转一次,同时通过串口1发送0X37这个数据。5.4.2 软件结构在这个键盘扫描程序的逻辑有点复杂,可以利用串口,把中间变量传出来,查看程序的流程和变量的值,方便调试,找出错误所在。在这本书中,对于程序的调试,没有使用仿真器调试的方法,使用的是用LED灯指示程序的运行状态,用串口输出程序中的中间变量和过程变量。这种方法,跟实际的运行结果一样,只是在最终版本中,把串口输出和LED指示部分注销就行,不必做任何的更改,同时能很好的观察到中断的运行情况,也能把程序运行的事件状况如实的表现出来。由于stm32f10x系列的芯片的FLASH可以烧写上千次(现在的FLASH基本都能达到上千次的烧写),使得我们每次改动都能下载验证,而不必担心FLASH会很快烧坏。这样对于学习单片机的费用就大大减少,不需要昂贵的仿真器,只需要一个根串口线就可以了。回到这个实例上来,这个键盘处理逻辑比较复杂。当一个键按下后,首先要判断是否有键按下,还要判断这个键是否处理过,还要判读是否延时过,只有经过这些判读处理后才能真正实现我们所要的功能。图5-4-1是键盘扫描的流程图。 图5-4-1 按键流程图 5.3.3 实例代码以嘀嗒实例为基础,来进行添加。首先创建E:OpenM3V开发板测试程序SysTickkey_usart文件夹,把E:OpenM3V开发板测试程序SysTicksys_delay文件夹中的工程,复制到E:OpenM3V开发板测试程序SysTickkey_usart文件夹中,,编译下载验证,看程序复制是否正确,这一步很关键,在作任何更改前,必须验证前一步的正确和完整性。在gpio.c文件中,加入键盘扫描函数和按键执行函数,具体函数如下: void key1(void) LED1B(); uart_trxuart_rx=0x31; uart_rx+; uart_rx &= 0xf; void key2(void) LED2B(); uart_trxuart_rx=0x32; uart_rx+; uart_rx &= 0xf; void key3(void) LED3B(); uart_trxuart_rx=0x33; uart_rx+; uart_rx &= 0xf; void key4(void) LED4B(); uart_trxuart_rx=0x34; uart_rx+; uart_rx &= 0xf; void key5(void) LED5B(); uart_trxuart_rx=0x35; uart_rx+; uart_rx &= 0xf; void key6(void) LED6B(); uart_trxuart_rx=0x36; uart_rx+; uart_rx &= 0xf; void key7(void) LED7B(); uart_trxuart_rx=0x37; uart_rx+; uart_rx &= 0xf; void key_work(void) unsigned char key_data; key_data = GPIO_ReadInputData(GPIOE); /读取PE输入端口值 key_data &= 0x7f if(key_data 0x7F) /如果小于0X7F,说明有按键按下 /LED2ON(); /设置一个调试状态指示LED,有键按下亮。 if(!(key_bit & 0x02) /判断按键是否被处理,按键没有被处理,执行IF if(key_bit & 0x01) /如果已经延时了 key_bit &= 0x01; /清延时标志 key_bit |= 0x02; /置位按键已处理标志 / uart_trxuart_rx = key_bit; /把标志变量功过串口传出来 / uart_rx+; / uart_rx &= 0x3f; / uart_trxuart_rx = key_data; /把按键值通过串口传出来 / uart_rx+; / uart_rx &= 0x3f; switch(key_data) case 0x7E : key1(); break; /调用key1()函数 case 0x7D : key2(); break; /调用key2()函数 case 0x7B : key3(); break; /调用key3()函数 case 0x77 : key4(); break; /调用key4()函数 case 0x6F : key5(); break; /调用key5()函数 case 0x5F : key6(); break; /调用key6()函数 case 0x3F : key7(); break; /调用key7()函数 else /如果没有延时 key_bit |= 0x04; /置位要延时标志 else /如果没有键按下,执行else key_bit &= 0x07; /清所有的标志位 /LED2OFF(); /无键按下LED灭。 在系统定时器中断中,加入相应的防抖程序代码,具体如下:if(key_bit & 0x04)/如果允许延时标志被置位的话 if(key_bit & 0x80) /加入这个判断,只有当两次进入中断后才置位延时标志 key_bit |= 0x01; /置位延时标志,表明经过延时 key_bit &= 0x04; /清 允许延时标志位置位 标志位 else /如果第7位没有置位,说明是第一次进入中断 key_bit |= 0x80; /第一次进入时,把key_bit第7位置位。 在上面的程序中,加入了调试指示灯和中间变量输出部分。里面有个非常关键的标志变量key_bit,在这个标志变量中,包含着许多信息,充分利用对不同位的判断来解析这些信息,为程序服务。5.4.4 编译下载和调试通过ProjectRebuild All命令进行编译。编译通过后,在其工程文件夹下DebugExe目录下有一个.HEX后缀的文件,此为可执行文件,使用ST提供的下载工具,以ISP方式把程序下载到芯片中。复位系统,可以看到LED8每秒钟闪烁一次。打开串口调试助手,可以看到,PC机发送什么数据,串口也能接收到相同的数据。同时按K1键LED1灯跳变一次,同时串口有0X31数据输出(如果是ASC码方式,则输出为1),按其他键,则对应的LED等跳变,串口有相应的数据输出。 那么这个比较复杂的程序是不是一气写成的呢,答案是否定的。下面把我写这个程序的过程向大家介绍一下。把E:OpenM3V开发板测试程序SysTicksys_delay文件夹中的工程,复制到E:OpenM3V开发板测试程序SysTickkey_usart文件夹中,下载到实验板中,灯是否闪烁,串口是否有数据输出。 由于需要用串口传出数据,所以串口功能的完善是必须保证的。首先实现第一步目标是,有键按下时,LED1灯亮,松开时LED1灯灭,同时判断按键处理位,如果没有被处理,则让LED2跳转一次,并置位按键处理标志位。这样只要按键被处理标志位置位就不会来跳转LED2灯,达到一次按键只处理一次的结果。具体程序如下: key_data = GPIO_ReadInputData(GPIOE); /读取PE输入端口值 key_data &= 0x7f if(key_data 0x7F) /如果小于0X7F,说明有按键按下 LED1ON(); /LED1灯亮 if(!(key_bit & 0x02) /如果按键没有被处理 LED2B(); /跳转LED2灯 key_bit |= 0x02; /置按键处理标志 else LED1OFF(); /LED1灯灭 编译下载后,发现按下键后LED1灯亮,松手后就灭。但不论按多少次,LED2灯就翻转一次。程序哪里出问题了,很显然,程序没有执行if(!(key_bit & 0x02)语句下的内容,在这条语句前加上串口输出部分,把key_bit的值传出来看看,是什么内容。加上以下语句。uart_trxuart_rx = key_bit ; /把数据写入串口队列中uart_rx+;uart_rx &= 0x3f;编译下载,打开串口调试软件,设置成38400,8,N,1,16进制显示,清空接收区域。连接好串口线,打开实验板电源,按下任一键,可以看到串口出来一大串数据,LED1灯亮,LED2灯跳转一次,松开按键,LED1灯灭,串口也没有数据输出,在串口调试软件接收区,发现满篇都是0X02,我们找到数据头,发现第一个数据是0x00。扫描多少次键盘,就有多少个串口数据输出。我们把PC机上的串口调试软件的接收区域清零,然后再按一下任意键,当然LED1灯会亮,松手就灭,可LED2灯不跳转。我们来看看输出的数据,全为0X02,找到第一个,也是0X02。也就是说,在这次扫描过程中,按键程序把这次按下的键当作已经处理过。问题出在哪,出在当松按键时,我们没有及时的清零按键处理标志位。在else语句中加上以下这句就行了。 key_bit &= 0x02; /清零按键处理标志编译下载,上面的BUG没有了,程序能按照我们设想去运行了。在这里我们充分的利用了LED指示灯和中间变量的输出,来分析程序问题。当然用仿真器单步或断点也会很快找出问题,只是仿真器调试的速度不一定有这里所介绍方法快。首先我们使用LED2后,可以发现问题,同时可以判断程序错在哪,找出问题在哪,这就解决了一半的问题。接下来,加入按键的延时防抖部分,思路是,利用系统定时器溢出间隔中断来延时防抖,这样就提高了程序的运行效率,不会在按键程序中死等20MS。怎样才能很好的利用这个系统定时器来延时呢,如果只是简单在系统定时器中断中置位延时标志位的话,就没有任何意义。必须得有一个标志位,来允许置延时标志。第一次扫描到有按键按下时,延时标志肯定为空,那么我们在此置位一个标志位,来允许系统定时器中置位延时标志,这样就解决了这个问题。软件的逻辑结构是:如果没有延时,则置位允许延时标志置位标志(这句话有点拗口)。可以这样理解,首先是置位标志位,那么这个标志位是干什么的呢,如果它置位的话,在系统定时器溢出中断中,就可以置位延时标志位,有点向指向指针的指针的意识。如果已经延时,处理按键值。下面这段程序加入了对延时标志判断的处理if(!(key_bit & 0x02) /如果按键没有被处理 if(key_bit & 0x01) /如果已经延时了 key_bit &= 0x01; /清延时标志位 LED2B(); /跳转LED2灯 key_bit |= 0x02; /置按键处
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工程概预算培训
- 对称剪纸教学课件
- 基本句型趣味课件
- 课件服务器问题
- 课件最后一页底图
- 广东护理自考考试题目及答案
- 矿山钻工考试题及答案
- 2025年中国木屑筛选器数据监测研究报告
- 口译听力考试题及答案
- 教师招聘之《小学教师招聘》通关考试题库(夺分金卷)附答案详解
- 金融销售技巧培训课件
- 2025届云南中考道德与法治真题试卷【含答案】
- 尿毒症并发心衰的护理
- 电力安全生产法律法规培训
- 国际田径邀请赛行业深度调研及发展项目商业计划书
- 渐冻症患者的麻醉管理要点
- 校园校车消防管理制度
- 中医治疗失眠课件
- 2025年高校图书馆建设项目可行性研究报告
- TD/T 1017-2008第二次全国土地调查基本农田调查技术规程
- 出血性疾病诊疗规范
评论
0/150
提交评论