当前位置:文档之家› Freescale单片机原理与设计(TPM模块应用编程)

Freescale单片机原理与设计(TPM模块应用编程)

XX科技大学Freescale单片机原理与设计实验报告实验项目TPM编程应用【实验目的】1、理解HCS08的定时器/PWM模块TPM(Timer/Pulse-Width Modulator)模块原理2、学会TPM模块设计3、进一步认识“对MCU外部管脚/内部模块的控制正是通过Regs的控制来实现”【实验原理】MC9S08AW60系列中的定时器系统包括两个独立的TPM:一个6通道的TPM1和一个2通道的TPM2。

TPM模块管脚和I/O 管脚复用。

定时器系统总共8个通道,每一个通道都可作为输入捕捉、输出比较、或带缓冲的边缘对齐PWM。

每一个TPM的所有通道都可以配置成为带缓冲的中心对齐脉宽调制CPWM (buffered, center-aligned pulse-width modulation)。

每一个TPM预分频器的时钟源都可以独立选择总线时钟、固定系统时钟或外部管脚对每个TPM,每个通道一个中断,还有一个计数中止中断。

定时器系统的内部结构为:两个独立的TPM每个TPM都由1个16位的计数器与n(n=6 or 2)个输入/输出通道组成;每一个通道都可作为输入捕捉、输出比较、或带缓冲的边缘对齐PWM。

TPM模块自由计数定时核心是一个16位的计数器。

三种时钟源之一经过分频之后的脉冲即作为定时器的计数脉冲;每过一个计数脉冲,Counter便自动+1,Counter加到FFFF后翻转到$0000,同时置溢出标志位TOF为1,然后重新开始计数;溢出时若TOIE为1,还会产生中断请求。

Fbus和分频比的不同可以产生不同的溢出时间间隔;但是这种自由计数定时方式定时有限。

只读的16位TPM计数寄存器由两个字节寄存器TPMxCNTH和TPMxCNTL构成。

TPM预置计数定时:向16位模数计数寄存器TPMxMODH:TPMxMODL写入一个确定的数值,则计数器每进行一次计数都会将计数和模数计数寄存器的值进行比较,如果相同就产生溢出,同时置溢出标志位TOF为1,然后重新开始计数,溢出时若TOIE为1,还会产生中断请求。

TPM每个自由计数器包含三个寄存器:一个8位状态控制寄存器(TPMxSC),一个16位计数器(TPMxCNTH:TPMxCNTL,一个16位模数寄存器(TPMxMODH:TPMxMODL)。

其中,x=1/2 (1)定时器x状态控制寄存器(TPMxSC)如下图:其中,TOF为溢出标志位,为0则没有达到预置计数寄存器中的值没有溢出,为1则达到了预置计数寄存器中的值溢出。

TOIE 为定时溢出中断允许位,可读/可写位用来允许定时器的溢出中断。

TOIE为1,TOF为1时允许中断,复位清TOIE。

定时器x状态控制寄存器(TPMxSC)CLKS[B:A]与PS[2:0]功能如下图:(2)定时器x计数寄存器(TPMxCNTH:TPMxCNTL)只读的16位TPM计数寄存器由两个字节寄存器TPMxCNTH和TPMxCNTL构成。

读两个字节中的任何一个字节都会把两个字节内容锁存进内部缓冲器,直到另外一个字节也被读取为止。

这允许以任何顺序读取连贯的16位寄存器。

如下图:(3)定时器x模数寄存器(TPMxMODH:TPMxMODL)。

可读/写的TPM模数寄存器中包含TPM计数器的模数值。

当TPM计数器到达这个模数值后,TPM计数器在下一个时钟要么重新从0x0000开始计数(CPWMS=0),要么从这个模数值往下减1计数(CPWMS=1),同时溢出标志TOF(Timer Overflow Flag)变为1。

只写TPMxMODH或者TPMxMODL其中的一个会抑制住TOF和溢出中断直到些另外一个字节也被写为止,因此两个寄存器一定都要写,不能只写一个而不管另一个。

复位会使TPM模数寄存器为0x0000,相当处于自由运行定时器计数模式(模数禁止)。

如下图:【实验装置】Freescale HC08单片机,CodeWarrior开发环境【实验内容】⑴利用TPM,编程实现下列功能:利用两个七段数码管,实现00-59秒显示:自动从00开始,每一秒钟,数字加1;加到59之后,自动回到00,重复开始;⑵外接IRQ按键,平时00-59自动加数显示,按IRQ按键一次后,加数显示停止,再按一次IRQ按键,继续加数显示。

【结果分析】实验(1)最终实现了用TPM2模块精确定时半秒,再利用半秒产生秒的各位和十位,并把秒的各位和十位送到两位数码管上显示。

数码管采用动态扫描的方式显示。

TPM2_ISR每隔500ms 清零一次,对秒钟的高地位进行加处理。

对TPM2溢出标志清零首先读标志位,然后写0到标志位。

实验结果显示正确。

实验(2)在(1)的基础上,增加了IRQ中断模块。

每按一次IRQ按键FLAG计数加1,然后取FLAG的最低位。

若最低位为0,则停止秒计时,数码管显示时间保持不变;若最低位为1,则正常计时、显示。

这样就实现了按IRQ按键一次后,加数显示停止,再按一次IRQ按键,继续加数显示。

【实验代码】(1)INCLUDE MC9S08AW60.INC; 包含头文件ORG $0070Half_Sec DS 1;半秒时间变量SEG_Select DS 1;数码管位选变量Second_L DS 1;秒钟低位Second_H DS 1;秒钟高位NUM DS 1COUNT DS 1ORG $1860LED_Table: DC.B $c0,$f9,$a4,$b0,$99,$92,$82,$f8 ;LED 字形码表DC.B $80,$90recycle: MOV #70t,NUM ;软件延时5msDBNZ NUM,*RTSDelay_5ms:MOV #38t,COUNTrecall:BSR recycleDBNZ COUNT,recallMOV #07t,COUNTDBNZ COUNT,*RTSIO_Init: ;IO初始化模块MOV #$FF, PTGD ; 初始化输出端口的数据寄存器MOV #$FF, PTDD ; 初始化输出端口的数据寄存器MOV #$FF, PTAD ; 初始化输出端口的数据寄存器LDA #%11111111STA PTADD ; 初始化PTA口的八个管脚作为输出STA PTDDD ; 初始化PTD口的八个管脚作为输出STA PTGDD ; 初始化PTG口的八个管脚作为输出RTS ;子程序返回TPM2_Init: ;TPM2模块中断方式初始化子程序MOV #$4E,TPM2SC ;BUSCLK为TPM2时钟源,64分频,允许TPM2中断MOV #$7A,TPM2MODHMOV #$12,TPM2MODL ;500ms对应模数值CLI ; 开总中断RTSTPM2_ISR: ;TPM2溢出中断服务子程序LDA TPM2SC ;先读标志位TEF BCLR 7,TPM2SC ;写0到TEF清TEF 标志位INC Half_SecLDA Half_SecCMP #2T ;是否到了1S BNE TPM2_ENDMOV #$00,Half_Sec ;到则秒钟加一,半秒清零INC Second_LLDA Second_LCMP #10T ;秒钟是否加到10BNE TPM2_ENDMOV #$00,Second_L :到则秒钟各位清零,十位加1INC Second_HLDA Second_HCMP #6T ;秒钟十位是否到6 BNE TPM2_ENDMOV #$00,Second_H ;到则秒钟10位清零TPM2_END:RTIMain:CLRXCLRACLRHSTA $1802 ;禁止COPMOV #$00,Half_SecMOV #$00,Second_H ;秒高位初始化MOV #$00,Second_L ;秒低位初始化JSR IO_Init ;对PTD,PTG,PTA 端口初始化JSR TPM2_Init ;TPM2初始化AGAIN:CLRHMOV #%11111110,PTAD ;位选低位LDA Second_L ;读秒低位CLRHTAXLDA LED_Table,X ;查字形码表STA PTGD ;输出秒低位NSASTA PTDDJSR Delay_5ms ;延时5msMOV #$FF,PTDD ;熄灭数码管,避免宇辉MOV #%11111101,PTAD ;位选数码管高位LDA Second_H ;读秒高位CLRHTAXLDA LED_Table,XSTA PTGDNSASTA PTDD ;显示秒高位JSR Delay_5msMOV #$FF,PTGDJMP AGAINORG $FFE2DC.W TPM2_ISRORG $FFFEDC.W Main INCLUDE MC9S08AW60.inc ; 包含头文件(2)INCLUDE MC9S08AW60.INC; 包含头文件ORG $0070Half_Sec DS 1;半秒时间变量SEG_Select DS 1;数码管位选变量Second_L DS 1;秒钟低位Second_H DS 1;秒钟高位FLAG DS 1 ;IRQ中断计数标志NUM DS 1COUNT DS 1ORG $1860LED_Table: DC.B $c0,$f9,$a4,$b0,$99,$92,$82,$f8 ;LED 字形码表DC.B $80,$90recycle: MOV #70t,NUM ;软件延时5msDBNZ NUM,*RTSDelay_5ms:MOV #38t,COUNTrecall:BSR recycleDBNZ COUNT,recallMOV #07t,COUNTDBNZ COUNT,*RTSIO_Init: ;IO初始化模块MOV #$FF, PTGD ; 初始化输出端口的数据寄存器MOV #$FF, PTDD ; 初始化输出端口的数据寄存器MOV #$FF, PTAD ; 初始化输出端口的数据寄存器LDA #%11111111STA PTADD ; 初始化PTA口的八个管脚作为输出STA PTDDD ; 初始化PTD口的八个管脚作为输出STA PTGDD ; 初始化PTG口的八个管脚作为输出RTS ;子程序返回IRQ_Init: ;IRQ中断初始化模块MOV #$00, FLAG ;FLAG清零LDA #%00010010STA IRQSC ; IRQ功能允许,仅下降沿触发,允许中断RTSIRQ_ISR:INC FLAGI ;计数加一LDA FLAGAND #%00000001 ;取最低位STA FLAGBSET 2, IRQSC ;向IRQACK位写1以清零IRQFRTITPM2_Init: ;TPM2模块中断方式初始化子程序MOV #$4E,TPM2SC ;BUSCLK为TPM2时钟源,64分频,允许TPM2中断MOV #$7A,TPM2MODHMOV #$12,TPM2MODL ;500ms对应模数值CLI ; 开总中断RTSTPM2_ISR: ;TPM2溢出中断服务子程序LDA TPM2SC ;先读标志位TEF BCLR 7,TPM2SC ;写0到TEF清TEF 标志位INC Half_SecLDA Half_SecCMP #2T ;是否到了1S BNE TPM2_ENDMOV #$00,Half_Sec ;到则秒钟加一,半秒清零LDA FLAGLDA FLAGCMP #0T ;FLAG不为0,则停止计数BNE TPM2_ENDINC Second_LLDA Second_LCMP #10T ;秒钟是否加到10 BNE TPM2_ENDMOV #$00,Second_L :到则秒钟各位清零,十位加1INC Second_HLDA Second_HCMP #6T ;秒钟十位是否到6 BNE TPM2_ENDMOV #$00,Second_H ;到则秒钟10位清零TPM2_END:RTIMain:CLRXCLRACLRHSTA $1802 ;禁止COPMOV #$00,Half_SecMOV #$00,Second_H ;秒高位初始化MOV #$00,Second_L ;秒低位初始化JSR IO_Init ;对PTD,PTG,PTA 端口初始化JSR TPM2_Init ;TPM2初始化JSR IRQ_Init ;IRQ初始化AGAIN:CLRHMOV #%11111110,PTAD ;位选低位LDA Second_L ;读秒低位CLRHTAXLDA LED_Table,X ;查字形码表STA PTGD ;输出秒低位NSASTA PTDDJSR Delay_5ms ;延时5msMOV #$FF,PTDD ;熄灭数码管,避免宇辉MOV #%11111101,PTAD ;位选数码管高位 LDA Second_H ;读秒高位CLRHTAXLDA LED_Table,XSTA PTGDNSASTA PTDD ;显示秒高位JSR Delay_5msMOV #$FF,PTGDJMP AGAINORG $FFFADC.W IRQ_ISRORG $FFE2DC.W TPM2_ISRORG $FFFEDC.WMain。

相关主题