飞思卡尔MC9S12XS128单片机各模块使用方法及寄存器配置

更新时间:2024-04-06 00:23:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

飞思卡尔MC9S12XS128单片机各模块使用方法

及寄存器配置

手把手教你写S12XS128程序--PWM模块介绍

该教程以MC9S12XS128单片机为核心进行讲解,全面阐释该16位单片机资源。本文为第一讲,开始介绍该MCU的PWM模块。

PWM 调制波有 8 个输出通道,每一个输出通道都可以独立的进行输出。每一个输出通道都有一个精确的计数器(计算脉冲的个数),一个周期控制寄存器和两个可供选择的时钟源。每一个 PWM 输出通道都能调制出占空比从 0—100% 变化的波形。

PWM 的主要特点有: 1、它有 8 个独立的输出通道,并且通过编程可控制其输出波形的周期。 2、每一个输出通道都有一个精确的计数器。 3、每一个通道的 PWM 输出使能都可以由编程来控制。 4、PWM 输出波形的翻转控制可以通过编程来实现。 5、周期和脉宽可以被双缓冲。当通道关闭或 PWM 计数器为 0 时,改变周期和脉宽才起作用。

6、8 字节或 16 字节的通道协议。 7、有 4 个时钟源可供选择(A、SA、B、SB),他们提供了一个宽范围的时 钟频率。

8、通过编程可以实现希望的时钟周期。 9、具有遇到紧急情况关闭程序的功能。

10、每一个通道都可以通过编程实现左对齐输出还是居中对齐输出。 1、PWM启动寄存器PWME

PWME 寄存器每一位如图 1 所示:

复位默认值:0000 0000B

图 1 PWME 寄存器

每一个PWM 的输出通道都有一个使能位 PWMEx 。它相当于一个开关,用来启动和关闭相应通道的 PWM 波形输出。当任意的 PWMEx 位置 1,则相关的 PWM 输出通道就立刻可用。

用法: PWME7=1 --- 通道7 可对外输出波形

PWME7=0 --- 通道7 不能对外输出波形

注意:在通道使能后所输出的第一个波形可能是不规则的。当输出通道工作在串联模式时(PWMCTL 寄存器中的 CONxx 置1),那么)使能相应的 16 位 PWM 输出通道是由 PWMEx 的高位控制的,例如 :设置

PWMCTL_CON01 = 1,通道0、1级联,形成一个16位 PWM 通道,由通道 1 的使能位控制 PWM 的输出。

2、PWM时钟选择寄存器PWMCLK

PWMCLK 寄存器每一位如图3 所示:

复位默认值:0000 0000B

图2 PWMCLK 寄存器

S12的PWM 共有四个时钟源,每一个 PWM 输出通道都有两个时钟可供选择(ClockA、ClockSA 或Clock B、ClockSB))。其中0、1、4、5 通道可选用ClockA和ClockSA,2、3、6、7 通道可选用ClockB、ClockSB 通道。该寄存器用来实现几个通道时钟源的选择。

用法: PCLK0 = 1 --- 通道0(PTP0)的时钟源设为ClockSA PCLK2 = 0 --- 通道2(PTP2)的时钟源设为ClockB 1、PWM预分频寄存器PWMPRCLK

PWMPRCLK 寄存器每一位如图3 所示:

复位默认值:0000 0000B

图 3 PWMPRCLK 寄存器

PWMPRCLK 寄存器包括ClockA预分频和ClockB预分频的控制位。ClockA、

ClockB的值为总线时钟的1/2n (0≤n≤7),具体设置参照图4和图5

图 4 Clock A 预分频设置

图5 Clock B 预分频设置

PCKB0~PCKB2 是对ClockB进行预分频。 PCKA0~PCKA2 是对ClockA进行预分频。 2、PWM分频寄存器PWMSCLA、PWMSCLB

PWMSCLA 寄存器每一位如图 6所示:

图6 PWMSCLA寄存器

Clock SA 是通过对 PWMSCLA 寄存器的设置来对ClockA 进行分频而产生的。其计算公式为:

Clock SA=Clock A /(2*PWMSCLA)

PWMSCLB 寄存器与PWMSCLA 寄存器相似,Clock SB 就是通过对PWMSCLB 寄存器的设置来对 ClockB 进行分频而产生的。其计算公式为: Clock SB=Clock B /(2*PWMSCLB) 1、PWM极性选择寄存器PWMPOL

PWMPOL 寄存器每一位如图7 所示:

该寄存器是0~7通道PWM输出起始极性控制位,用来设置PWM输出的起始电平。 用法:PWMPOL_PPOL0=1--- 通道 0 在周期开始时输出为高电平,当计数器等于占空比寄存器的值时,输出为低电平。对外输出波形先是高电平然后再变为低电平。

2、PWM波形对齐寄存器PWMCAE

PWMCAE 寄存器每一位如图 8 所示:

图 8 PWMCAE 寄存器

PWMCAE 寄存器包含 8 个控制位来对每个 PWM 通道设置左对齐输出或中心对齐输出。

用法: PWMCAE_CAE0 = 1 --- 通道0 中心对齐输出 PWMCAE_CAE7 = 0 --- 通道7 左对齐输出 注意:只有输出通道被关闭后才能对其进行设置,即通道被激活后不能对其进行设置。

1、PWM控制寄存器PWMCTL

PWMCTL 寄存器每一位如图 9 所示:

图 9 PWMCTL 寄存器

该控制寄存器设定通道的级联和两种工作模式:等待模式和冻结模式。这两种模式如图10和图11所示。

图10 等待模式

图11 冻结模式

只有当相应的通道关闭后,才能改变 这些控制字。 用法:

PWMCTL_CON67=1 --- 通道 6、7 级联成一个16位的PWM通道。此时只有 7 通道的控制字起作用,原通道7的使能位、PWM输出极性选择位、时钟选择控制位以及对齐方式选择位用来设置级联后的PWM输出特性

PWMCTL_CON67=0 --- 通道 6,7 通道不级联 CON45、CON23、CON01 的用法同 CON67 相似。设置此控制字的意义在于扩大了 PWM 对外输出脉冲的频率范围。

PSWAI=1 --- MCU 一旦处于等待状态,就会停止时钟的输入。这样就不会因时钟在空操作而费电;当它置为 0,则 MCU 就是处于等待状态,也允许时钟的输入。 PFRZ=1 --- MCU 一旦处于冻结状态,就会停止计数器工作。

S12微控制器PWM模块是由独立运行的8位脉冲计数器PWMCNT、两个比较寄存器PWMPER和PWMDTY组成。 1、左对齐方式

在该方式下,脉冲计数器为循环递增计数,计数初值为0 。

当PWM使能后,计数器PWMCNT从0开始对时钟信号递增计数,开始一个输出周期。当计数值与占空比常数寄存器PWMDTY相等时,比较器1输出有效,将触发器置位,而PWMCNT继续计数;当计数值与周期常数寄存器PWMPER相等时,

比较器2输出有效,将触发器复位,同时PWMCNT也复位,结束一个输出周期。原理参照图14:

图14 PWM左对齐方式

2、中心对齐方式

在该方式下,脉冲计数器为双向计数,计数初值为0 。

当PWM使能后,计数器PWMCNT从0开始对时钟信号递增计数,开始输出一个周期。当计数器与占空比常数寄存器PWMDTY相等时,比较器1输出有效,触发器翻转,而PWMCNT继续计数,当计数值与周期常数PWMPER相等时,比较器2输出有效,此时改变PWMCNT的计数方向,使其递解计数;当PWMCNT再次与PWMDTY相等时,比较器1再一次输出有效,使触发器再次翻转,而PWMCNT继续递减计数,等待PWMCNT减回至0,完成一个输出周期。原理参照图15:

图15 中心对齐方式

3、周期计算方法

左对齐方式:

输出周期 = 通道周期 × PWMPERx 中心对齐方式:

输出周期 = 通道周期 × PWMPERx × 2 4、脉宽计算方法

左对齐方式:

占空比 = [ (PWMPERx - PWMDTYx) / PWMPERx ] × 100% 中心对齐方式:

占空比 = [ PWMDTYx / PWMPERx ] × 100%

1、PWM通道计数寄存器 PWMCNTx

PWMCNTx 寄存器共有 8个,每一个通道都有一个8位PWM加/减双向计数器,通道级联后可变成16位PWM加/减双向计数器。下面以PWMCNT0为例对 PWMCNTx 寄存器进行介绍。 PWMCNT0 寄存器如图 12 所示:

图 12 PWMCNT0 寄存器

计数器以所选时钟源的频率运行。计数器在任何时候都可以被读,而不影响计数,也不影响对 PWM 通道的操作。

任何值写入 PWMCNT0 寄存器都会导致计数器复位置 0,且其计数方向会 被设置为向上计数,并且会立刻从缓冲器载入任务和周期值,并会根据翻转极性的设置来改变输出。当计数器达到计数值后,会自动清零。只有当通道使能后,计数器才开始计数。

2、PWM通道周期寄存器PWMPERx PWMPERx 寄存器共有 8 个,每一个通道都有一个这样的周期寄存器。这个 寄存器的值就决定了相关 PWM 通道的周期。每一个通道的周期寄存器都是双缓 冲的,因此如果当通道使能后,改变他们的值,将不会发生任何作用,除非当下列情况之一发生:

*有效的周期结束。

*对计数器进行写操作(计数器复位) *通道不可用(PWMEx = 0)

这样就会使 PWM 输出波形要么是新波形要么是旧波形,并不会在两者之间 进行交替变换。如果通道不可用,那么对周期寄存器进行写操作,将会直接

导致 周期寄存器同缓冲器一起闭锁。图 13 所示的是 PWMPER0 寄存器:

图 13 PWMPER0 寄存器 3、PWM通道占空比寄存器PWMDTYx

PWMDTYx 寄存器也有 8 个,每一个通道都有一个这样的占空比常数寄存 器。这个寄存器的值就决定了相关 PWM 通道输出波形的占空比。每一个通道的 占空比寄存器都是双缓冲的,因此如果当通道被激活后,改变他们的值将不会发生任何作用,除非当下列情况之一发生:

*有效的周期结束。

*对计数器进行写操作(计数器复位) *通道不可用(PWMEx = 0) 这样就会使 PWM 输出波形要么是新波形要么是旧波形,并不会在两者之间 进行交替变换。如果通道没有被激活,那么对占空比常数寄存器进行写操作,将会直接导致周期寄存器同缓冲器一起闭锁。 当计数值与占空比常数 PWMDTY 相等时,则比较输出器有效,这时就会将触发

器置位,然后 PWMCNT 继续计数,当计数值与周期常数 PWMPER 相等时,比较器输出有效,将触发器复位,同时也使 PWMCNT 复位,结束一个输出周期。 S12微控制器PWM模块是由独立运行的8位脉冲计数器PWMCNT、两个比较寄存器PWMPER和PWMDTY组成。 1、左对齐方式

在该方式下,脉冲计数器为循环递增计数,计数初值为0 。

当PWM使能后,计数器PWMCNT从0开始对时钟信号递增计数,开始一个输出周期。当计数值与占空比常数寄存器PWMDTY相等时,比较器1输出有效,将触发器置位,而PWMCNT继续计数;当计数值与周期常数寄存器PWMPER相等时,比较器2输出有效,将触发器复位,同时PWMCNT也复位,结束一个输出周期。原理参照图14:

图14 PWM左对齐方式

2、中心对齐方式

在该方式下,脉冲计数器为双向计数,计数初值为0 。

当PWM使能后,计数器PWMCNT从0开始对时钟信号递增计数,开始输出一个周期。当计数器与占空比常数寄存器PWMDTY相等时,比较器1输出有效,触发器翻转,而PWMCNT继续计数,当计数值与周期常数PWMPER相等时,比较器2输出有效,此时改变PWMCNT的计数方向,使其递解计数;当PWMCNT再次与PWMDTY相等时,比较器1再一次输出有效,使触发器再次翻转,而PWMCNT继续递减计数,等待PWMCNT减回至0,完成一个输出周期。原理参照图15:

图15 中心对齐方式

3、周期计算方法

左对齐方式:

输出周期 = 通道周期 × PWMPERx 中心对齐方式:

输出周期 = 通道周期 × PWMPERx × 2

4、脉宽计算方法

左对齐方式:

占空比 = [ (PWMPERx - PWMDTYx) / PWMPERx ] × 100%

中心对齐方式:

占空比 = [ PWMDTYx / PWMPERx ] × 100%

PWM 初始化步骤总结

1、禁止PWM PWME = 0

2、选择时钟 PWMPRCLK,PWMSCLA,PWMSCLB,PWMCLK 3、选择极性 PWMPOL 4、选择对齐方式 PWMCAE

5、选择占空比和周期 PWMDTYx, PWMPERx 6、使能PWM PWME = 1 【例程1】

//------------------------------------------------------------------------------------------------------------------// //功能说明:MC9S12XS128--PWM例程

//使用说明:实现通道3(PTP3)输出频率为1KHz,占空比为50%的方波,用示波器观察

//程序设计:电子设计吧【www.dzsj8.com】 //设计时间:2010.01.21

//----------------------------------------------------------------------------------------------------------------//

#include /* common defines and macros */

#include \ //--------------初始化函数----------------// //-----时钟初始化程序--------//

void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) { //锁相环时钟=2*16*(2+1)/(1+1)=48MHz REFDV=1; //总线时钟=48/2=24MHz SYNR=2;

while(!(CRGFLG&0x08));

CLKSEL=0x80; //选定锁相环时钟 }

//-----PWM初始化程序------// void PWM_Init(void) {

PWME_PWME3=0x00; // Disable PWM 禁止 PWMPRCLK=0x33; // 0011 0011 A=B=24M/8=3M 时钟预分频寄存器设置 PWMSCLA=150; // SA=A/2/150=10k 时钟设置

PWMSCLB=15; // SB=B/2/15 =100k 时钟设置 PWMCLK_PCLK3=1; // PWM3-----SB 时钟源的选择 PWMPOL_PPOL3=1; // Duty=High Time 极性设置

PWMCAE_CAE3=0; // Left-aligned 对齐方式设置 PWMCTL=0x00; // no concatenation 控制寄存器设置 PWMPER3=100; // Frequency=SB/100=1K 周期寄存器设置

PWMDTY3=50; // Duty cycle = 50% 占空比寄存器设置 PWME_PWME3=1; // Enable PWM 使能 }

//-----------------主函数--------------------// void main(void) {

/* put your own code here */ PLL_Init(); PWM_Init();

EnableInterrupts; for(;;) {

_FEED_COP(); /* feeds the dog */ } /* loop forever */

/* please make sure that you never leave main */ }

手把手教你写S12XS128程序--A/D转换模块介绍 1、A/D转换原理

A/D转换的过程是模拟信号依次通过取样、保持和量化、编码几个过程后转换为数字格式。 a)取样与保持

一般取样与保持过程是同时完成的,取样-保持电路的原理图如图16所示,由输入放大器A1、输出放大器A2、保持电容CH和电子开关S组成,要求 AV1 * AV2 = 1。原理是:当开关S闭合时,电路处于取样阶段,电容器充电,由于 AV1 * AV2 = 1,所以输出等于输入;当开关S断开时,由于A2输入阻抗较大而且开关理想,可认为CH没有放电回路,输出电压保持不变。

图16 取样-保持电路

取样-保持以均匀间隔对模拟信号进行抽样,并且在每个抽样运算后在足够的时间内保持抽样值恒定,以保证输出值可以被 A/D 转换器精确转换。

b)量化与编码

量化的方法,一般有舍尾取整法和四舍五入法,过程是先取顶量化单位Δ,量化单位取值越小,量化误差的绝对值就越小,具体过程在这里就不做介绍了。将量化后的结果用二进制码表示叫做编码。 2、A/D转换器的技术指标

a)分辨率

分辨率说明A/D转换器对输入信号的分辨能力,理论上,n位A/D转换器能区分的输入电压的最小值为满量程的1/2n 。也就是说,在参考电压一定时,输出位数越多,量化单位就越小,分辨率就越高。S12的ATD模块中,若输出设置为8位的话,那么转换器能区分的输入信号最小电压为19.53mV。 b)转换时间

A/D转换器按其工作原理可以分为并联比较型(转换速度快ns级)、逐次逼近型(转换速度适中us级)、双积分型(速度慢抗干扰能力强)。

不同类型的转化的A/D转换器转换时间不尽相同,S12的ATD模块中,8位数字量转换时间仅有6us,10位数字量转换时间仅有7us。

S12内置了2组10位/8位的A/D模块:ATD0和ATD1,共有16个模拟量

输入通道,属于逐次逼近型A/D转换器(这个转换过程与用天平称物的原理相似)。

1、功能结构图

图17 A/D 模块功能结构图

图17所示的是 A/D 模块的功能结构,这个功能模块被虚线划分成为图示所示的虚线所隔离的三个部分:IP 总线接口、转换模式控制/寄存器列表,自定义模拟量。

IP 总线接口负责该模块与总线的连接,实现 A/D 模块和通用 I/O 的目的, 还起到分频的作用;

转换模式控制寄存器列表中有控制该模块的所有的寄存器,执行左右对齐运 行和连续扫描。

自定义模拟量负责实现模拟量到数字量的转换。包括了执行一次简单转换所 需的模拟量和数字量。

2、 HCS12 中A/D转化模块特点 8/10 位精度;7 us, 10-位单次转换时间.;采样缓冲放大器;可编程采样时间; 左/右对齐, 有符号/无符号结果数据;外部触发控制;转换完成中断;模拟输入 8 通道复用;模拟/数字输入引脚复用;1 到 8 转换序列长度;连续转换模式;多通 道扫描方式。

ATD 模块有模拟量前端、模拟量转换、控制部分及结果存储等四部分组成。其中模拟前端包括多路转换开关、采样缓冲器、放大器等,结果存储部分主要有8个 16 位的存储器和反映工作状态的若干标志位。 1、ATD0控制寄存器2---ATD0CTL2

ATD0CTL2主要控制ATD0的启动、状态标志以及上电模式,对寄存器进行写操作时,将中断当前的转化过程。寄存器ATD0CTL2如图18所示:

图18 ATD0CTL2寄存器

ADPU:A/D 使能控制位,相当于一个开关,用来启动/禁止A/D转换

1 = A/D 模块上电 0 = 禁止 A/D,以减少功耗

AFFC:A/D 快速转换完成标志位清零

1 = 快速标志位清零顺序,每次读取结果寄存器自动清零 0 = 正常标志位清零顺序,需要软件方式对状态标志位清零 AWAI:A/D 等待模式

1 = 等待模式下,ATD继续运行

0 = 等待模式下,ATD停止运行,以降低功耗 ETRIGP、ETRIGLE、ETRIGE: 描述 ETRIGLE ETRIGP ETRIGE x 0 0 1 1 x 0 1 0 1 0 1 1 1 1 忽略外部触发 下降沿触发 上升沿触发 低电平触发 高电平触发 【注意】ETRIGE:外部触发使能控制位,该功能借助引脚AN7,当AN7接收到外部触发时,启动A/D转换,否则不进行转换。0--忽略外部触发;1--有外部触发时开始转换,此时AN7不能用于A/D转换。 ASCIE:A/D 转化序列转换结束中断使能控制位 1 = 允许ATD转换序列转换结束后发生中断

0 = 禁止ATD 中断

ASCIF:A/D转换序列转换结束中断标志,只用于读。

1 = 发生中断 0 = 为发生中断

2、ATD0控制寄存器3---ATD0CTL3

ATD0CTL3主要控制结果寄存器的映射,设置转换序列的长度,还可以暂时冻结ATD0模块,尤其确定ATD0在BDM状态下的行为。寄存器ATD0CTL3如图19所示:

图19 ATD0CTL3寄存器

S1C、S2C、S4C、S8C:转换序列长度选择位控制位

【注意】ATD的每次启动要进行若干次扫描循环,每次扫描循环称为一个转换

序 列。

FIFO:结果寄存器 FIFO模式控制位,

1 = 结果寄存器映射到转换序列 0 = 结果寄存器没有映射到转换序列

FRZ0、FRZ1:背景调试冻结控制位 FRZ Response 00 01 Ignore IFREEZE(冻结模式下继续转换) Reserved(冻结模式下保留) 10 11 Finish conversion then freeze(完成转换后冻结) Freeze Immediately(冻结模式下立刻冻结) 3、ATD0控制寄存器4---ATD0CTL4 ATD0CTL4用于选择时钟,选择采样转换时间以及选择8位/10位转换方式。寄存器ATD0CTL4如图20所示:

图20 ATD0CTL4寄存器

SRES8 : A/D 精度选择控制位

1 = 将采集到的模拟量以8位二进制数表示 0 = 将采集到的模拟量以10位二进制数表示

SMP0、SMP1 : 采样时间选择控制位 采样时间 SMP [1:0] 00 01 10 11 2 A/D 时钟周期 4 A/D 时钟周期 8 A/D 时钟周期 16 A/D 时钟周期 PPS[0:4] : 5 位 模数计数器预分频器 - 分频系数从 2 到 64

- A/D时钟计算公式 :ATDClock = BusClock/(PRS + 1) × 0.5 - A/D时钟频率应满足:

【注意】对于AD转换来说,它的转换周期包括采样时间和运算时间。如果频率太高,则采样时间过短。这对于输出阻抗比较大或信号频率比较高的信号来说,就会产生较大的采样误差,那么AD转换的精度就会受较大的影响。

4、ATD0控制寄存器4---ATD0CTL5

ATD0CTL5用于选择转换方式,选择转换通道,设置单/多通道转换和单次/连续转换模式以及对齐方式。寄存器ATD0CTL5如图20所示: 5、ATD0状态寄存器5---ATD0START0、ATD0START0

ATD0START0反映当前的转换通道、A/D转换是否结束、是否有外部触发等; ATD0START1反映转换序列中相应的转换是否完成。寄存器ATD0START0、ATD0START1如图21所示:

SCF ---转换序列完成标志

在单次转换模式时,当转换完成后置位 (SCAN = 0) 在连续转换模式时,当第一次转换完成后置位 (SCAN = 1),当AFFC = 0,写 1 清零。

ETORF ---外部触发覆盖标志

如果在转换过程中高/低电平出现,置位 FIFOR

当结果寄存器在读出之前已经被写入时,置位 ( CCF 没有清零) CC[2:0]转换计数器---3位计数器指向下一个将要转换的通道

CCF7 -CCF0 ---独立通道转换完成标志位每个相应的通道转换结束后置位,当相应的 A/D 结果寄存器被读出时,清零,注意当 AFFC 位不同时的情况

第十六讲:A/D转换应用实例

要让 ATD 开始转换工作,必须经过以下三个步骤: 1.将 ADPU 置 1,使 ATD 启动;

2.按照要求对转换为数、扫描方式、采样时间、时钟频率及标志检查等方式 进行设置;

3.发出启动命令;

如果上电默认状态即能满足工作要求,那么只要将 ADPU 置 1,然后通过控 制寄存器发出转换命令,即可实现转换。

【例程2】

程序描述:由通道ATD0进行单通道A/D转换,转换值在B口显示 程序如下:

#include /* common defines and macros */ #include /* derivative information */ #pragma LINK_INFO DERIVATIVE \ /******定义变量********/

word AD_wValue;//AD转换结果 /*时钟初始化*/

void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) { //锁相环时钟=2*16*(2+1)/(1+1)=48MHz

REFDV=1; //总线时钟=48/2=24MHz SYNR=2;

while(!(CRGFLG&0x08)); CLKSEL=0x80; }

/*AD初始化*/

void AD_Init(void) {

ATD0CTL2=0xC0; // 启动A/D, 快速清零, 无等待模式, 禁止外部触发, 中断禁止

ATD0CTL3=0x20; // 转换序列长度为4, No FIFO, Freeze模式下继续转换 ATD0CTL4=0x85; // 8位精度, 2个时钟,

ATDClock=[BusClock*0.5]/[PRS+1]=2MHz;PRS=5,divider=12 ATD0CTL5=0xA0; // 右对齐无符号,单通道采样,通道0 ATD0DIEN=0x00; // 禁止数字输入 }

/*读取AD转换结果*/

void AD_GetValue(word *AD_wValue) {

*AD_wValue=ATD0DR0; //读取结果寄存器的值 }

/**********主函数**************/ void main(void) {

PLL_Init();

AD_Init(); DDRB=0xFF; PORTB=0x00; EnableInterrupts; for(;;) {

while(!ATD0STAT1_CCF0); // 等待转换结束while(ATDOSTAT1_CCF0==1)

AD_GetValue(&AD_wValue); // 读取转换结果 PORTB = (byte)AD_wValue; // 在B口显示转换值 } }

手把手教你写S12XS128程序(17)--Timer模块介绍1

1、简述

MC9S12XS128定时器模块与MC9S12DG128 ECT部分功能完全类似,以下均以ECT模块介绍xs128定时器模块。

HC12 增强型捕捉计时器模块在HCS12标准定时器的基础上增加了一些特点,用以扩展它的应用范围,特别是在汽车 ABS 方面。

基准计时器的核心仍然是一个 16 位的可编程计数器,其时钟源来自一个预分频器。该计时器可以被应用于多个方面,包括在对输入波形进行测量的同时产生一个输出波形。波形的脉宽可以在几微秒到数秒的范围内变化。

增强型定时器模块(ECT)的结构框图如下,ECT功能相当于高速的I/O口,由一个4位预分频器、一个16位自由运行计数器,8个16位IC/OC通道,2个16位脉冲累加器以及一个16位模数递减计数器组成。

ECT实际上是一个16位的可编程计数器,它的基本时钟频率可以通过预分频器设置,用于产生波形输出,测量输入波形,统计脉冲个数,可以作为定时中断功能和独立时钟基准。 2、运行模式

停止:由于时钟停止,计时器和计数器均关闭。 冻结:计时器和计数器均保持运行,直到 TSCR($06)的 TSFRZ 位被置 1。

把手教你写S12XS128程序(18)--Timer模块介绍2

IC 通道组

IC 通道组由四个标准的缓冲通道 IC0-IC3 和四个非缓冲通道 IC4-IC7 组成, 两部分的基本功能都是捕捉外部事件发生的时刻,但是缓冲通道除了 IC/OC 寄存器 TCn 外,还设有保持寄存器 TCnH,此外还在入口设置了延迟计数器,用来提高抗干扰能力。非缓冲通道没有保持寄存器,入口也没有延迟计数器,但每个通道入口设置了一个 2 输入端的多路器,事件触发信号可以是来自本通道的输入引脚 PORTn,也可以是来自其关联通道 PORT(n-4)的延迟计数器输出,使用更 加灵活。当延迟功能有效时,输入引脚检测到一个有效的边沿后,延迟计数器开 始对 P 时钟(模块时钟)进行计数,当到达设定的计数值后,延迟计数器在其输出 端有条件地产生一个脉冲,这个条件就是延迟前后的引脚电平相反。这样可以避免对窄输入脉冲做出反应。延迟计数结束后,计数器自动清除。输入信号两个有 效边沿之间的持续时间必须大于设定的延迟时间。

在 ECT 中,所有 IC 通道均设置了覆盖保护功能,可以通过寄存器 ICOVW设置是否允许某个通道用新的捕捉结果覆盖上一个结果。

对于缓冲的 IC 通道 PT0-PT3,还具有锁存与队列两种工作方式。在锁存方 式下,每个有效的引脚事件只将自由定时器的值放入捕捉寄存器 TCn,而 TCn 到保持寄存器 TCnH 的传送必须依赖递减模数计数器回 0 或者其他强制锁存命令 才能实现,这时 IC 的工作情形与第 6 章的 TIM 模块相似。在队列方式下(图 7-2), TCn 与 TCnH 形成了一个类似先进先出的队列,每个捕捉结果从 TCn 进入,然 后随着下一个捕捉结果的到来移入 TCnH,程序可以从 TCnH 取得结果,然而这 个队列是开放的,即程序也可以直接从 TCn 取得捕捉结果。队列方式为 CPU 提 供了充分的响应时间。

由于 PAC0-3 与 IC0-3 共享相同的引脚,而且共享入口的逻辑,因此在两种 方式下,PAI 与 IC 都可以同时工作,对同一引脚进行记录,前者记录脉冲或者 边沿的数量,后者记录具体的时刻。

模数递减计数器

16位递减模数计数器(MDC)可以用作时钟基准,产生周期性的中断请求, 也可用于将 IC 寄存器和脉冲累加器的值锁存到各自的保持寄存器中。锁存动作 可以通过程序设定为周期性的或一次性的。MDC 的时钟频率可通过独立的定标 器设定,内部设有定时常数寄存器,可以实现自动重装载,但 MDC 的常数寄存 器与 MDC 计数器使用相同的地址,加载时通过特殊的时序实现。

每当 MDC 回 0 时,将在给定的时间段内控制贮和 PAI 寄存器的内容向各自 的缓冲寄存器传输。反映了 MDC 在 IC、PAI 系统中的作用。

脉冲累加器

脉冲累加器由 4 个 8 位的通道 PAC0-PAC3 组成,可以通过级联形成两个 16 位通道 PACA、PACB,它可以统计输入引脚上出现的有效边沿的数量,也可以统计有效电平出现的累计时间。各个通道的 8 位保持寄存器是与 4 个缓冲 IC 通 道相关联的,它们共享边沿检测与延迟电路。当 IC 工作在两种不同的队

列方式 时, PAC 保持寄存器也处于不同的工作状态,在锁存方式下,PCnH 的加载依 靠 MDC 计数器或者强制命令实现,而在队列方式下,则依靠 IC 通道的 TCnH 读命令。可见在 ECT 模块下, IC 与 PAI 的工作联系更加紧密。

此外,脉冲累加器还有饱和记忆功能,当 8 位的脉冲累加器计数超过$FF 后 记忆保持,而不回滚到 0,这时,计数值$FF 意味着计数已经达到或超过 255, 如不需要,该功能可以关闭。这可以用来监视某个通道的计数值是否已经达到预 定的目标值。

值得注意的是,PACl、PAC0 级联后,输入引脚为 PT0,而 PAC3、PAC2 级 联后,输入引脚并不是 PT2,而是 PT7,这样可以与那些无 ECT 的 MCU 保持一 致性。

手把手教你写S12XS128程序(19)--Timer寄存器说明1

1、定时器/计数器系统控制寄存器 1(TSCR1)

寄存器偏移量:$0006 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TEN TSWAI TSFRZ TFFCA 0 0 0 0 可在任何时候读或写。 TSCR1 寄存器是定时器模块的总开关,它决定模块是否启动以及在中断等待、BDM 方式下的行为,还包括标志的管理方式。其各位的意义如下:

TEN:定时器使能位,此外它还控制定时器的时钟信号源。要使用定时器模块的 IC/OC 功能,必须将 TEN 置位。如果因为某种原因定时器没有使能,脉冲累加器也将得不到 ECLK/64 时钟,因为 ECLK/64 是由定时器的分频器产生的,这种情况下,脉冲累加器将不能进行引脚电平持续时间的累加。 0:定时器/计数器被禁止,有利于降低功耗。 1:定时器/计数器使能,正常工作。

TSWAI:等待模式下计时器关闭控制位。

【注意】定时器中断不能用于使 MCU 退出等待模式。 0:在中断等待模式下允许 MCU 继续运行。

1:当 MCU 进入中断等待模式时,禁止计时器。

TSFRZ:在冻结模式下计时器和计数器停止位。 0:在冻结模式下允许计时器和计数器继续运行。

1:在冻结模式下禁止计时器和计数器,用于仿真调试。 【注意】TSFRZ 不能停止脉冲累加。 TFFCA:定时器标志快速清除选择位。

0:定时器标志普通清除方式。 1:对于 TFLGl($0E)中的各位,读输入捕捉寄存器或者写输出比较寄存器会自动清除相应的标志位 CnF。对于 TFLG2($0F)中的各位,任何对 TCNT 寄存器($04、$05)的访问均会清除 TOF 标志;任何对 PACN3 和 PACN2 寄存器($22,$23)的访问都会清除 PAFLG 寄存器($21)中的 PAOVF 和 PAIF 位。任何对

PACN1 和 PACN0 寄存器($24,$25)的访问都会清除 PBFLG 寄存器($21)中的 PBOVF 位。

【说明】这种方式的好处是削减了另外清除标志位的软件开销。此外,必须特别注意避免对标志位的意外清除。

2、计时器系统控制寄存器 2(TSCR2)

寄存器偏移量:$000D Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TOI 0 0 0 TCRE PR2 PR1 PR0 可在任何时候读或写。 TOI:定时器/计时器溢出中断使能。 0:中断被禁止。

1:当 TOF 标志被置位时发出硬件中断请求。 【注意】TOF标志位在TFLG中

TCRE:定时器/计数器复位使能。

该位在通道 7 成功输出比较之后允许时钟计数器复位。该操作模式类似于递增型计数器。

0:计数器复位禁止,计数器自由计数。

1:通道 7 成功输出比较后计数器将被复位。

【说明】如果 TC7=$0000 并且 TCRE=1,TCNT 将继续保持$0000。

如果 TC7=$FFFF 并且 TCRE=1,当 TCNT 从$FFFF 到$0000 之间被

复位后TOF 将永远不被置位。

PR2,PR1,PR0:计数器预分频选择。

这三位所决定的分频因子如下表所示。分频因子选择 PR2 PR1 PR0 PrescaleFactor 0 0 0 1 0 0 1 2 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 4 8 16 32 64 1 1 1 128 【说明】新设定的分频因子不会立即起作用,直到下一个触发沿到来那里所有预分频计数器值均为零。

手把手教你写S12XS128程序(20)--Timer寄存器说明2

3、控制寄存器(TCTLl-TCTL4)

TCTLl-TCTL4 分为两组,分别对 IC 和 OC 电路进行设定,每组 16 个二进制位,每两个二进制位管理一个通道。其中 TCTLl、TCTL2 设定各个 OC 通道 匹配时的动作,包括切断 OC 与输出引脚的联系,而 TCTL3、TCTL4 设定 IC 响 应引脚的何种动作,包括禁止 IC 的响应。

TCTL1 寄存器偏移量:$0008 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 OM7 OL7 OM6 OL6 OM5 OL5 OM4 OL4 TCTL2 寄存器偏移量:$0009 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 OM3 OL3 OM2 OL2 OM1 OL1 OM0 OL0 可在任何时候读或写。

OMn、OLn 分别设定输出方式和输出电平,这 8 对控制位(OM7、OL7---OMO、 OL0)编码后用于指定通道比较成功后的输出动作。如果每对当中至少有一个为 1,对应引脚就固定为相应通道的输出,而与 DDRT 中的对应位无关。 当二者同时为 0 时,OC 与输出引脚断开。 输出比较动作设置 OMn OLn 动作 0 0 定时器与引脚断开 0 1 OCn输出翻转 1 0 OCn输出清零 1 1 OCn输出置1

TCTL3 寄存器偏移量:$000A

Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 EDG7B EDG7A EDG6B EDG6A EDG5B EDG5A EDG4B EDG4A TCTL4 寄存器偏移量:$000B

Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 EDG3B EDG3A EDG2B EDG2A EDG1B EDG1A EDG0B EDG0A 可在任何时候读或写。 各个控制位的作用如下:

EDGnB、EDGnA 输入捕捉边沿控制位,这 8 对控制位(EDG7B、EDG7A—EDG0B、EDG0A)对输入捕捉的边沿检测电路进行设置。当二者同时为 0 时,IC 与输入引脚断开。

输入捕捉边沿检测电路设置 边沿检测电路设EDGnB EDGnA 置 0 0 1 1 0 1 0 1 禁止捕捉 捕捉上升沿 捕捉下降沿 上升沿下降沿均捕捉 【注意】为了使 OMn、OLn 指定的引脚动作有效,OC7M 中的对应位必须清 0。若要使用 16 位脉冲累加器 A 和 B,并使它们分别独立于 IC/OC7 和 IC/OC0,必须设置对应的 IOSn:1、OMn=0、OLn=0,同时寄存器 OC7M 中的OC7M7、OC7M0 位必须清 0。

手把手教你写S12XS128程序(21)--Timer寄存器说明3

4、主定时器中断标志寄存器(TFLG1、TFLG2)

TFLG1 寄存器偏移量:$000E Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 C7F C6F C5F C4F C3F C2F C1F C0F TFLG2 寄存器偏移量:$000F BitBit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 0 TOF 0 0 0 0 0 0 0 所示的 TFLG1、TFLG2 为中断标志寄存器,其中 TFLG1 对应 8 个 IC/OC 通道,当某 CnF=1 时说明对应的 IC/OC 通道有动作,表明该通道有中断事件发生。TFLG2 只有一个标志位 TOF,作为核心计数器的中断请求标志。当 TOF=1 时说明核心计数器溢出。要清除某个标志位,只需向该位写 1,向某位写 0 不影响该位的状态。当 TSCR 中的 TFFCA 位置位时,读 IC 通道或写 OC 通道 ($10-$1F)将自动清除该通道标志CnF,对 TCNT 的任何访问将自动清除 TFLG2。

CnF:IC/OC 通道中断请求标志。

0:上次清除标志以来,IC/OC 通道没有有效动作。

1:IC/OC 通道已经出现动作。将寄存器 ICSYS($2B)中的 TFMOD 位和 ICOVW 寄存器($2A)联合使用,可以使定时器在两次捕捉后才产生中断,而不是每次捕捉均产生动作。两次捕捉结果分别在捕捉和保持寄存器里面。

TOF:定时器溢出标志,当 16 位自由定时器从$FFFF 回滚到$0000 时,该位 置位。将$80 写入到 TFLG2 将自动清除该位(写1清零)。详见前面关于 TMSK2 中 TCRE 控制位的解释。

5、计时器中断使能寄存器(TIE)

寄存器偏移量:$000C Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 C7I C6I C5I C4I C3I C2I C1I C0I 可在任何时候读或写。

TIE 寄存器中的位与状态寄存器 TFLG1 中的标志位相对应。如果将 TIE 中的某位清 0,相应的标志位就不能引起硬件中断。如果被置 1,相应的标志位就可以引起中断。

C7I-C0I:输入捕捉/输出比较“x”中断使能。

手把手教你写S12XS128程序(22)--Timer寄存器说明4

6、IC/OC 选择寄存器(TIOS)

寄存器偏移量:$0000 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 IOS7 IOS6 IOS5 IOS4 IOS3 IOS2 IOS1 IOS0 TIOS 寄存器用于指定各个通道的功能,即工作于 IC 还是 OC 方式。当某位 IOSn=0 时,对应的通道 n 为输入捕捉(1C)通道,否则当 IOSn=1 时,通道 n为输出比较(OC)通道。其中的各位可以在任何时候写入或读出。

【说明】上电后该寄存器默认为$00,TSCR 中的 TEN 默认也为 0,这时所有通道处于通用 I/O 方式,将 TEN 置位后各个通道进入 IC 方式,要将某些通道设置成 OC 方式,必须对 TIOS 进行设置,即将有关位置 1。设置成 OC 的通道其引脚具有降功率驱动功能,设置成 IC 的通道具有内部上拉功能,但上电后均处于关闭状态,可以根据需要启用。

7、IC/OC 寄存器(TC0-TC7)

每个 IC 或 OC 通道都设置有一个 16 位的寄存器,对于 IC(输入捕捉)通道, 当通道的边沿探测器检测到由 EDGnA、EDGnB 指定的条件时,将自由定时器的值捕捉到寄存器 TCn,随后程序可以读取和处理;对于 OC(输出比较)通道,程序将预定的时刻写入到 TCn,当自由定时器的值与其相等时,触发由 OMn、OLn 所指定的输出动作。定时器模块共有 TC7-TC0 等 8 个 16 位 IC/OC 寄存器。 TC0 寄存器偏移量:$0010-$0011 Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC1 寄存器偏移量:$0012-$0013 Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC2 寄存器偏移量:$0014-$0015 Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC3 寄存器偏移量:$0016-$0017 Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC4 寄存器偏移量:$0018-$0019 Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC5 寄存器偏移量:$001A-$001B Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC6 寄存器偏移量:$001C-$001D Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 TC7 寄存器偏移量:$001E-$001F Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

手把手教你写S12XS128程序(23)--Timer寄存器说明5

8、定时器核心寄存器(TCNT) 寄存器偏移量:$0004-$0005 Bit15 Bit14 Bit13 Bit12 Bit11 Bit10 Bit9 Bit8 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0

TCNT 是递增计数器,它不停地对内部时钟信号计数、程序可随时读取,但在普通模式下禁止写入。TCNT 应按字访问,分别访问高、低字节可能得到错误的结果。

【说明】在特殊模式下,TCNT 可写,但因为写操作与预分频器时钟不同步,TCNT寄存器写入后,其第一个周期可能是一个不同的值。

9、输出比较通道 7 屏蔽寄存器(OC7M) 寄存器偏移量$0002 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 OC7M7 OC7M6 OC7M5 OC7M4 OC7M3 OC7M2 OC7M1 OC7M0 可在任何时候读或写。

前面已经说明,OC7 具有特殊地位,它匹配时可以直接改变其他 7 个输出引脚的状态,并覆盖各个引脚原来的匹配动作结果,寄存器 OC7M 决定哪些通道将处于 OC7 的管理之下。OC7M 中的各位与 PORTT 口寄存器的各位一一对应。当通过 TIOS 将某个通道设定为输出比较时,将 OC7M 中的相应位置 1,对应的引脚就是输出状态,与 DDR 中的对应位的状态无关。但 OC7Mn 并不改变 DDR 相应位的状态。

OC7M 具有更高的优先级,它优于通过 TCTL1 和 TCTL2 寄存器中的 OMn 和 OLn 设定的引脚动作,若 OC7M 中某个位置 1,就会阻止相应引脚上由 OM 和 OL 设定的动作。

10、输出比较通道 7 数据寄存器(OC7D) 寄存器偏移量:$0003 Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 OC7D7 OC7D6 OC7D5 OC7D4 OC7D3 OC7D2 OC7D1 OC7D0

可在任何时候读或写。

OC7M 对于其他 OC 输出引脚的管理限于将某个二进制值送到对应引脚,这个值保存在寄存器 OC7D 中的对应位中。当 OC7 匹配成功后,若某个 OC7Mn=1, 则内部逻辑将 OC7Dn 送到对应引脚。

OC7D 中的各位与 PORTT 口寄存器的各位一一对应。当通道 7 比较成功时,如果 OC7M 中的某个位为 1,OC7D 中的对应位将被输出到 PORTT 的对应引脚。 当 OC7M 中的某个位为 1 时,通道 7 匹配成功的动作如果与通道 6-0 的动作发生在同一个周期,前者将覆盖后者。因此各个通道的动作将依赖于 OC7D中各个位的设置。

把手教你写S12XS128程序(24)--Timer模块应用实例1

输入捕捉(IC)编程步骤:

初始化函数

TIOS---选择工作方式为IC

TCTLx---设置对应位输入捕捉的方式(x=3、4,高位是3,低位是4) TSCRx---控制寄存器设置,包括工作使能、确定工作方式(x=1)、中断允许、预分频

TIE---中断使能 中断函数

清除标志位---TFLG1 处理函数

【例程3】

//---------------------------------------------------------------------------// //功能说明:利用PP3通道产生40Hz,占空比为50%的方波 // 利用PT0采集方波的个数,并在PB口显示 //程序设计:电子设计吧 //设计时间:2010.01.13

//---------------------------------------------------------------------------// #include /* common defines and macros */ #include /* derivative information */ #pragma LINK_INFO DERIVATIVE \

unsigned int Input_Num;

//----------------------时钟初始化------------------------------//

void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) { //锁相环时钟=2*16*(2+1)/(1+1)=48MHz REFDV=1; //总线时钟=48/2=24MHz SYNR=2;

while(!(CRGFLG&0x08)); CLKSEL=0x80; }

//--------------------通道0输入捕捉初始化-------------------// void ECT0_Init(void) {

TSCR2=0x06; //禁止溢出中断,分频系数64(24/64MHz) TIOS_IOS0=0; //通道0为输入捕捉 TCTL4=0x01; //捕捉上升沿

TIE_C0I=1; //通道0输入捕捉中断允许 TSCR1=0x80; //使能定时器 }

//---------------------PWM通道3初始化程序-------------------// void PWM_Init(void) {

PWME_PWME3=0x00; // PWW is disabled 禁止 PWMPRCLK=0x33; // 0b0011 0011 A=B=24M/8=3M 时钟预分频寄存器设置

PWMSCLA=150; // SA=A/2/150=10k 时钟设置 PWMSCLB=150; // SB=B/2/15 =10k 时钟设置

PWMCTL=0x00; // no concatenation 控制寄存器设置 PWMCLK_PCLK3=1; // PWM3-----SB 时钟源的选择 PWMPOL_PPOL3=1; // Duty=High Time 极性设置 PWMCAE_CAE3=0; // left-aligned 对齐方式设置 PWMPER3=250; // Frequency=SB/250=40 周期寄存器设置

PWMDTY3=125; // Duty cycle = 50% 占空比寄存器设置

PWME_PWME3=1; // enable 使能 }

//----------------------主函数-------------------------// void main(void) {

PLL_Init(); PWM_Init(); ECT0_Init(); DDRB=0XFF; PORTB=0X00; EnableInterrupts; for(;;) {

} /* wait forever */

/* please make sure that you never leave this function */

}

//--------------------转速计算:-------------------------------// //

//智能车转速子函数 //

//----------------------------------------------------------------//

#pragma CODE_SEG NON_BANKED //定时器通道0输入捕捉中断 void interrupt 8 Timer0_Onput(void) {

TFLG1_C0F=1; //清中断标志位 Input_Num++;

PORTB=Input_Num; if(Input_Num>=255) {

Input_Num=0; } }

手把手教你写S12XS128程序(25)--Timer模块应用实例2

输出比较(OC)编程步骤:

初始化函数

TIOS---选择工作方式为OC

TCx---通道x的OC寄存器赋初值,经过N秒后进入第一次中断

TCTLx---设置对应位输入捕捉的方式(x=1、2,高四位是1,低四位是2) TSCRx---控制寄存器设置,包括工作使能、确定工作方式(x=1)、中断允许、预分频

TIE---中断使能 中断函数

清除标志位---TFLG1 重新赋初值TCx 【例程4】

//---------------------------------------------------------------------------// //功能说明:利用PT0的输出比较功能,定时进入中断 // 利用PORTB显示定时的时间 //程序设计:电子设计吧 //设计时间:2010.01.15

//---------------------------------------------------------------------------//

#include /* common defines and macros */ #include /* derivative information */

#pragma LINK_INFO DERIVATIVE \

//利用定时器输出比较功能产生定时中断

//----------------------变量定义----------------------// static unsigned int waittime = 0;

//---------------------时钟初始化-------------------//

void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) { //锁相环时钟=2*16*(2+1)/(1+1)=48MHz REFDV=1; //总线时钟=48/2=24MHz SYNR=2;

while(!(CRGFLG&0x08)); CLKSEL=0x80; }

//--------------------定时器初始化------------------// void ECT0_Init(void) {

TIOS=0x01; //定时器通道0设置为输出比较

TC0=0x00ee; //赋初值,当TCNT从0计数到此值时第一次进入中断 TCTL2=0x02; //其他七路与定时器断开 执行的动作时:0通道输出清零 TSCR2=0x86 //溢出中断禁止 24M/64=2.67微秒,计一个数用2.67微秒 TSCR1=0x80; //使能定时器

TIE=0x01; //通道0输出比较中断允许 }

//-----------------------主函数------------------------// void main(void) {

PLL_Init(); ECT0_Init(); DisableInterrupts; DDRB=0xff; PORTB=0x00; for(;;) {

EnableInterrupts; } }

//-----------------------中断函数处理-------------------// #pragma CODE_SEG NON_BANKED

void interrupt 8 Timer0_ISR(void) //8为定时器通道0的中断标号

{

unsigned int m;

TFLG1_C0F=1;//清中断标志位 DisableInterrupts; m=TCNT;

TC0=m+37500; //37500*2.67us=10ms定时时间 waittime++;

if(waittime>=255) {

waittime=0; }

PORTB=waittime; }

手把手教你写S12XS128程序(26)--SCI寄存器说明1

1、波特率控制寄存器(SCIBDH、SCIBDL)

IREN:红外调制模式使能位

1 使能 0 禁止

TNP[0..1]:窄脉冲发射位 SBR[0..12]:波特率设置位

When IREN = 0 then,

SCI baud rate = SCI bus clock / (16 x SBR[12:0]) When IREN = 1 then,

SCI baud rate = SCI bus clock / (32 x SBR[12:1])

【说明】波特率发生器在复位后是禁止的,在设置TE、RE(在SCICR2寄存器中)后才会工作。当(SBR[12:0] = 0 and IREN = 0) 或者 (SBR[12:1] = 0 andIREN = 1),波特率发生器不工作。

【注意】在未写入SCIBDL,写SCIBDH没有反应。一般地,设置IREN=0,SR=52(总线频率8MHz),波特率为9600。

2、数据寄存器(SCIDRH、SCIDRL)

SCI 内部分别设有发送和接收两个数据寄存器,其低位都通过 SCIDRL 访 问,读操作返回接收数据寄存器 RDR 的内容,写操作数据置入发送数据寄存器。TDR。当 M=1 即运行在 9 位数据模式时,SCIDRL 和 SCIDRH 形成 9 位的 SCI数据字,这时必须先写入 SCIDRH,以便与低位字节(SCIDRL)一起进入发送移 位器。如果 M=0 即 SCI 只用于 7 位或 8 位的数据传送,可以只访问 SCIDRL。 当 PE=1 即奇偶校验允许时,奇偶校验位由硬件负责,无需软件干预。

R8:接收到的位 8,该位写操作无效。当 SCI 设置成 9 位数据运行模式时,该位是从串

行数据流中接收到的第 9 位。

T8:发送位 8,任何时候可写。当 SCI 设置成 9 位数据模式时,该位是送到串行 数据流

的第 9 位。该位不必为每个数据重新设置,每次发送可重复使用。 R[0..7]T[0..7]:收/发数据位 7-0,读操作返回只读寄存器 RDR 的内容,写操 作写入只写寄存器 TDR。

手把手教你写S12XS128程序(27)--SCI寄存器说明2

3、控制寄存器(SCICR1)

LOOPS: 在LOOP模式下,RXD引脚与SCI接收部分断开,发射部分输出在内部和接收部分

相连接,此时RXD可作为普通IO口,TXD输出SCI信号。

1 LOOP模式使能 0 正常模式

SCISWAI:等待模式下 SCI 停止位 0:在等待模式下允许 SCI

1:在等待模式下禁止 SCI

RSRC:接收器信号源选择位,当 LOOPS=1 时,RSRC 决定接收器的内部反馈信号路径。

0:接收器的输入在内部连接到发送器输出(并非 TxD 引脚)。 1:接收器的输入连接到 TxD 引脚。

M:方式选择位(选择字符帧格式)。

0:1 个起始位,8 个数据位,1 个停止位。

1:1 个起始位,8 个数据位,第 9 个数据位,1 个停止位。 WAKE:唤醒选择位。

0:介质空闲唤醒。

1:地址标志(最后一个数据位为 1)唤醒。 ILT:空闲检测方式选择位,该位在 SCI 接收器可以使用的两种空闲检测方式中 选择一种。

0:快速检测,SCI 在一个帧的开始位后立即开始对“1”计数,因此停止位以及停止位前面的任何“1”均被计算在内,这样可以提前检测到空闲状态。

1:保守检测,SCI 在停止位后才开始对“1”计数,因此最后一个字节的停止位以及该位以前的各个为“广的位,对检测的时间长短无影响。 PE:奇偶校验允许位。

0:禁止奇偶校验。 1:允许奇偶校验。

PT:奇/偶校验选择位,如果奇偶校验允许,该位决定收发器使用奇校验还是偶校验。

0:选择偶校验。 1:选择奇校验。

4、控制寄存器2(SCICR2)

TIE: 发送中断允许位,清 0 时禁止 TDRE 产生中断,若置 1 则允许 TDRE 位置 1 时 产生 SCI 中断请求。

TCIE:发送结束中断允许位,清 0 时禁止 TC 产生中断,若置 1 则允许 TC 位置1 时产

生SCI 中断请求。 RIE:接收中断允许位,清 0 时禁止 RDRF 和 OR 产生中断,若置 1 则允许 RDRF或 OR

置 1 时产生 SCI 中断请求。

ILIE:空闲中断允许位,清 0 时禁止 IDLE 产生中断,若置 1 则允许 IDLE 位置1 时产

生 SCI 中断请求。

TE:发送允许位。该位由 0 置 1 时可用来发送空闲报头。

0: 发送器禁止。

1: 允许 SCI 发送部分工作,TxD 引脚(PSl/PS3)用于发送。 RE:接收允许位。

0: 接收器禁止。

1; 允许 SCI 接收器工作。 RWU:接收器唤醒控制位

0:SCI 接收器正常工作。

1:允许唤醒功能,禁止接收器中断。通常,硬件通过自动清除该位来唤醒接收器。 SBK:中止符发送允许位。只要该位保持为 1,发送器就不停地发出“0”;如果 变为 0,

当前的全“0”帧发送结束后,TxD 引脚将变成空闲状态。如果 SBK 开 关一次,发送器将只发出 10(11)个“0”,然后复原,处于空闲或发送数据状态。 0: 中止符产生器关闭。

1: 产生中止符,至少 10 或 11 个连续的“0”。

【说明】该寄存器主要完成收发中断的控制、收发的允许等操作。

手把手教你写S12XS128程序(28)--SCI寄存器说明3

5、状态寄存器 1(SCISR1)

TDRE: 发送保持器空标志位。发送前必须读 SCISR1,并确认 TDRE=1,然后将新的数

据写入发送保持器以开始发送过程。复位后该位为 1。 0:SC0DR 处于忙状态

1:发送保持器的数据已被传送到发送移位器,这时可以向发送保持器写入新的数据 TC:发送结束标志。该位在发送器空闲(无发送动作)时置位。读 SCISRl,然后写 SCIDR 将

清除该位。

0:发送器忙,正在发送

1:发送器空闲,无发送

RDRF:接收数据就绪标志。当收到的字符已经在 SCIDR 中就绪时,RDRF 置 1, 顺次

读取 SCISRl 和 SCIDR 将会自动清除 RDRF。该位被清除后,必须等到 RxD 线变为活动,然后重新变成空闲以后,IDLE 位才会被再次置 1。 0:SCIDR 空,数据寄存器无数据

1:SCIDR 中数据已就绪,数据寄存器数据有效

IDLE: 空闲标志。检测到接收器 RxD 端空闲(收到 10 或者 11 个以上连续的 “1”)。

当 RWU 位为 1 时,空闲状态不会使该位置 1。该位被清除后,必须等到 RDRF 置位(RxD 线变为活动,然后重新变成空闲),IDLE 位才会被再次置 1。 0:RxD 线活动。 1:RxD 线空闲。

OR:重叠错误标志。如果接收数据寄存器中的数据尚未读取(RDRF=1),接受移位寄存器又

准备向其传送新的数据,则称为重叠错误,该位被置 1。必须清除该位,才能使新的数据进入接收数据寄存器。 0:无重叠。

1:出现重叠错误。

NF:噪声错误标志。噪声错误出现时,该位与 RDRF 在同一个周器内置位,但如果同时或

已经出现重叠错误,该位不置位。 0:采样结果一致。

1:在起始位、数据位或停止位接收期间检测到噪声。

FE:帧格式错误。如果在应该出现停止位的时刻,检测到 0,则该位置位。顺次读取寄存

器 SCISRl 和 SCIDR 将清除 FE 标志。 0:检测到停止位。

1:在预期的停止位处检测到 0。

PF:奇偶错误标志。指示收到数据的奇偶性与校验位是否一致。奇偶校验允许(PE=1)时,该

标志才有意义。所要求的奇偶性由 SC0CR1 中的 PT 位决定。 0:奇偶校验正确。 1:奇偶校验错误。

【说明】该寄存器显示SCI运行情况,收发数据是否满、空,是否出错等

6、状态寄存器2(SCISR2)

BRK13:中止符长度控制位。

0:中止符长度为 10 或 11 位。 1:中止符长度为 13 或 14 位。

TXDIR:单线模式下发送管脚数据方向控制位。

0:单线模式下 TxD 脚用于输入。 1:单线模式下 TxD 脚用于输出。

RAF:接收器活动标志位。反映接收器是否处于活动状态。在搜索起始位的 RT1 期间该位置 1,当接收器器检测到空闲状态或者出现一个伪起始位(通常由于噪 声或波特率匹配错误引起)时,该位清 0。

手把手教你写S12XS128程序(29)--SCI模块应用

//------------------------------------------------------------------------------------------------------------------// //功能说明:MC9S12XS128--SCI例程 //使用说明:实现PC→MCU→PC通信,用户可以根据需要修改程序,实现PC→MCU或者MCU→PC通信

//程序设计:电子设计吧【www.dzsj8.com】 //设计时间:2010.01.21

//----------------------------------------------------------------------------------------------------------------//

#include /* common defines and macros */

#include \//unsigned char txt[]={\void delay(unsigned int time) {

unsigned int i,j,k; for(i=0;i<125;i++) for(j=0;j<125;j++)

for(k=time;k>0;k--); }

//-----------------------初始化SCI0----------------------------// void SciInit() {

SCI0BD=52; //9600bps Baud Rate=BusClock/(16*SCIBD) SCI0CR1=0; //正常8位模式,无奇偶校验 SCI0CR2=0X2C; //发送允许 接受中断允许 }

//----------------------读SCI数据-----------------------------// unsigned char SciRead() {

if(SCI0SR1_RDRF==1) //表明数据从位移寄存器传输到SCI数据寄存

{

SCI0SR1_RDRF=1; //读取数据寄存器会将RDRF清除 重新置位 return SCI0DRL; //返回数据寄存器的数据 } }

//-----------------写SCI数据---------------------------------// void SciWrite(unsigned char sendchar) {

while (!(SCI0SR1&0x80)); SCI0DRH=0;

SCI0DRL=sendchar; }

//------------------------main----------------------------------// void main(void) {

SciInit();

EnableInterrupts;

for(;;) {

} /* wait forever */

/* please make sure that you never leave this function */ }

//---------------------------接收中断函数-----------------------// #pragma CODE_SEG NON_BANKED

void interrupt 20 SCI0_re(void) {

unsigned char ch; ch=SciRead(); SciWrite(ch) ; }

本文来源:https://www.bwwdw.com/article/ioor.html

Top