Freescale单片机原理与设计(TPM模块应用编程)
- 格式:doc
- 大小:191.00 KB
- 文档页数:18
freescale hcs08单片机原理及应用单片机作为计算机科学领域重要的嵌入式系统组成部分,广泛应用于各个领域,其中Freescale HCS08单片机以其高性能、低功耗和易于开发等特点备受关注。
本文将介绍Freescale HCS08单片机的原理以及其应用。
一、Freescale HCS08单片机原理Freescale HCS08单片机采用基于哈佛结构的8位微处理器单元,具有高速运算能力和丰富的外设接口,能够满足不同领域的需求。
其核心原理包括指令集、片内存储器、时钟系统和外设接口等。
1. 指令集Freescale HCS08单片机的指令集丰富多样,包括数据传送、算术逻辑、位操作、条件转移和中断等多种类型的指令。
指令执行的速度快,能够满足实时性要求高的应用场景。
2. 片内存储器HCS08单片机内部集成了存储器单元,包括程序存储器ROM和数据存储器RAM。
ROM用于存储程序和常量,RAM用于存储变量和中间结果。
片内存储器的设计使得单片机具有较高的存储容量和读写速度。
3. 时钟系统Freescale HCS08单片机的时钟系统采用晶体振荡器作为基准时钟源,通过分频和锁相环等技术生成系统时钟。
时钟系统的设计能够提供稳定的时钟信号,确保单片机的正常运行。
4. 外设接口HCS08单片机提供了多种外设接口,包括通用输入输出引脚、定时器/计数器、串行通信接口等。
通过这些外设接口,单片机可以与外部设备进行数据交换和通信,实现各种功能。
二、Freescale HCS08单片机应用Freescale HCS08单片机在各个领域都有广泛的应用,如工业控制、汽车电子、家电控制、医疗设备等。
以下将介绍几个常见的应用案例。
1. 工业控制Freescale HCS08单片机在工业控制中扮演重要角色。
它能够实现对温度、压力、流量等参数的监测和控制,实现自动化生产线的稳定运行。
同时,单片机的高可靠性和抗干扰能力,使得它能够适应各种恶劣的工业环境。
第3章MC9S08AW60单片机概述Freescale的08系列单片机由于其稳定性高、开发周期短、成本低、型号多种多样、兼容性好而被广泛应用。
本章概要介绍08系列单片机的类型、基本结构,并从总体上阐述其性能特点。
主要内容有:在介绍08系列单片机的命名规则和资源状况的基础上,以MC9S08AW60为例讲述HCS08系列单片机的基本结构和特点。
3.1 08系列单片机简介目前,Freescale的08系列单片机主要有HC08、HCS08 和RS08共3种类型。
HC08是1999年开始推出的产品,种类也比较多,针对不同场合的应用都可以选到合适的型号。
HCS08是2004年左右推出的8位MCU,资源丰富、功耗低、性价比很高,是08系列单片机的发展趋势。
HC08与HCS08的最大区别是调试方法不同与最高频率的变化。
RS08是HCS08构架的简化版本,于2006年推出,其内核体积比传统的内核小30%,带有精简指令集,满足用户对体积更小、更加经济高效的解决方案的需求。
RAM及Flash空间大小差异、封装形式不同、温度范围不同、频率不同、I/O资源差异等形成了不同型号,为嵌入式应用产品的开发提供了丰富的选型。
3.1.1Freescale单片机的命名规则Freescale单片机的型号庞大,但同一系列的CPU是相同的,也就是说具有相同的指令系统,多种型号只是为了适用于不同的场合。
为了方便实际应用时的选型,需要了解Freescale 单片机的命名方法,其基本命名规则如下:XX X XX XX X XXXX①②③④⑤⑥⑦①产品状态。
M C—Fully Qualified(合格);PC—Product Engineering(测试品)。
在实际应用中,通常都是选用MC类型的产品。
如MC908GP32、MC9S08GB60、MC9RS08KA2等。
②存储器类型标志。
“无”表示片内带ROM或片内没有程序存储器;7表示片内带EPROM或一次可编程ROM(one time programmable ROM,OTPROM);8表示片内带EEPROM;9表示片内带闪存Flash EEPROM。
一般性实验实验一普通I/O口操作实验实验目的:1、熟悉SDIDE开发环境,熟悉GP32基本程序结构2、理解Freescale MCU的编程框架3、熟悉编程调试环境,编译、调试、下载运行第一个程序4、掌握I/O的基本编程方法范例程序:① A01_简单IO及程序框架\ FrmMain.ASM② C01_简单IO及程序框架\纯C\prgframe.prj③ C01_简单IO及程序框架\C&ASM混编\prgframe.prj实验要求:1、参看教材6.4节,熟悉实验板结构2、运行并读懂教材第7章的关于I/O口操作的LED灯控制程序3、按下列要求新建一程序:根据PB口低2位(PTB1和PTB0)的状态输出四种不同的LED显示效果,要求用最简洁的语句实现以下各效果。
(1)PTB1=0,PTB0=0时,效果为:8个LED中只有一个灯亮,亮灯顺序是从左到右,再从右到左,一个周期时间长度约4秒。
(效果1)(2)PTB1=0,PTB0=1时,效果为:8个LED中只有两个连在一起的灯亮,亮灯顺序是从左到右,再从右到左,一个周期时间长度约4秒。
(效果2)(3)PTB1=1,PTB0=0时,效果为:8个LED中只有一个灯亮,亮灯顺序是从左到右,再从右到左,一个周期时间长度约8秒。
(效果3)(4)PTB1=1,PTB0=1时,效果自定。
(效果4)实验二串行通信实验实验目的:1、理解串行通信基本原理,掌握MCU串行通信基本编程方法2、理解串行通信的查询方式和中断方式原理及其编程范例程序:1、C02_1串行通信查询方式\ H08SCI_1.prj2、C02_2串行通信中断方式\ H08SCI_2.prj3、A02_1串行通信查询方式\ SCIMain1.asm4、A02_2串行通信中断方式\ SCIMain2.asm5、以上四目录都有VB_SCI目录,该目录是对应Visual Basic6.0程序,运行在PC方,用来接收和发送数据。
第1章 绪 论1.1 微型计算机概述1.1.1 微型计算机的组成一个典型的微型计算机包括:运算器、控制器、存储器和输入/输出接口四部分。
如果把运算器与控制器集成在一个硅片上,则该芯片为中央处理器CPU (Central Processing Unit )。
存储器包括程序存储器和数据存储器两类。
输入/输出接口包括模拟量输入/输出和开关量输入/输出。
软件部分包括系统软件(如操作系统)和应用软件(如字处理软件)。
典型微型计算机的组成如图1-1所示。
⎪⎪⎪⎪⎩⎪⎪⎪⎪⎨⎧⎪⎩⎪⎨⎧⎪⎩⎪⎨⎧⎪⎩⎪⎨⎧)DO /DI (/AO /AI (//CPU 输出开关量输入)输出模拟量输入输出接口输入数据存储器程序存储器存储器控制器运算器)中央处理器(微型计算机 图1-1 典型微型计算机的组成1.1.2 微型计算机的分类微型计算机种类繁多,型号各异。
因此,可以从不同角度对其进行分类。
最常见的是按微处理器的字长和按微型机的构成形式进行分类。
微处理器是微型计算机的核心部件,微处理器的性能(特别是字长)在很大程度上决定了微型机的性能。
1.按微处理器(CPU )字长分类按微处理器字长来分,微型计算机一般分为4位、8位、16位、32位和64位机几种。
(1)4位微型计算机用4位字长的微处理器作CPU ,其数据总线宽度为4位,一个字节数据要分两次来传送或处理。
4位机的指令系统简单、运算功能单一,主要用于袖珍或台式计算器、家电、娱乐产品和简单的过程控制,是微型机的低级阶段。
(2)8位微型计算机用8位字长的微处理器作CPU ,其数据总线宽度为8位。
8位机中字长和字节是同一个概念。
8位微处理器推出时,微型机在硬件和软件技术方面都已比较成熟,所以8位机的指令系统比较完善,寻址能力强,外围配套电路齐全,因而使8位机通用性强,应用宽广,广泛应用于事务管理、工业生产过程的自动检测和控制、通信、智能终端、教育以及家用电器控制等领域。
(3)16位微型计算机用高性能的16位微处理器作CPU,数据总线宽度为16位。
第8章定时器/计数器模块8.1 定时器定时器是主管定时的系统。
MCS08AW60内部包括两个独立的定时器。
定时器的核心是一个16位计数器。
该计数器的时钟由外部晶振时钟或者锁相环模块总线时钟经过预定的分频因子分频得到,相互独立的定时器可以使用不同的分频因子。
同一个定时器的所有动作都以分频后的时钟作为参考,相互之间都有确定的关系。
从单片机的角度看,一个单位时间就是定时器的自由运行计数器计数的时间间隔,所以在任何时候都可以通过读取计数器的值而判断经过了多少时间。
使用预置计数功能可以得到精确的溢出时间,可以在任何时候暂停或清除计数器的计数。
通过定时器的溢出功能可以进行长时间的定时。
定时器具有定时溢出、输入捕捉、输出比较、PWM脉冲输出和DMA直接存储器访问等功能。
定时器应用很广,如利用输入捕捉测量脉宽和频率;输出特定的波形;直接输出脉宽调制波(PWM);使用输入捕捉配合输出比较来输出同步波形以及用于延时等。
下面就以MCS08AW60为例,详细阐述定时器的功能及应用。
8.1.2定时器的结构及基本功能MCS08AW60定时器的功能结构图如图8-1所示。
每个定时器具有两路独立的输入捕捉和输出比较通道;可以实现带缓冲(Buffered)和不带缓冲(Unbuffered)的脉宽调制波;可以得到8种可编程选择的分频因子;可以自由运行计数或预置计数;可以停止或清除计数器计数;定时器溢出可以引发中断,每路通道的输入捕捉和输出比较也可以引发中断。
每一路定时器都由以下寄存器控制:1)一个8位状态和控制寄存器——TPMxSC;2)一个16位计数器寄存器——TPMxCNTH:TPMxCNTL;3)一个16位预置计数器寄存器——TPMxMODH:TPMxMODL;4)控制每个通道的8位状态和控制寄存器——TPMxCnSC;5)每个通道计数器值的16位寄存器——TPMxCnVH:TPMxCnVL。
注:寄存器命名中的“x”表示定时器模块标志。
第一部分基础实验第一章基础理论1.1 单片机程序设计与应用系统开发过程单片机的行为是受程序控制的,因此开发与使用单片机必然会遇到程序设计的问题,单片机设计是一个硬件与软件结合的问题,而其软件设计的工作往往占有更多的成分。
一个完整的嵌入式系统开发过程,除了硬件电路的设计外,软件工作包括程序编辑、汇编或编译、程序下载、程序调试、脱机验证等过程。
程序的编辑就是按照一定的格式,采用汇编或者C等高级语言进行编写。
早期的单片机程序设计在DOS环境下符合一定的格式编辑,然后采用一个合适的软件汇编,生成二进制等CPU能识别的目标代码,将单片机(内带程序存储器的情形)或程序存储器放入编程器,编程器通过串口或USB等接口与PC机相连,将PC机存放的CPU能识别的代码下载到单片机或程序存储器中。
图1-1是一个简单的说明:图1-1 程序设计过程采用以上方式进行开发的情形下,单片机必须是能从电路板上取下来,这对贴片封装的单片机就无能为力了。
此时为了能在线仿真调试,需要昂贵的仿真头和仿真电缆与软件,而且几乎没有仿真器能做到100%的功能仿真,甚至有的问题正是来自于仿真器。
随着技术的发展,采用ISP技术,只要在目标电路板上预留一个接口,通过一个很小的下载器,与PC机串、并口或USB口相连,就可以进行程序的调试与下载,尤其是有的单片机具有JTAG接口,下载调试更加方便,调试尽可能少占用单片机资源,更有甚者,像freescale的单片机,内置背景调试控制器(BDC ,Background Debug Controller),支持一线ISP和程序调试。
目前程序开发需要的各种软件,如编辑、汇编、编译、链接、调试、下载等都集成到一个环境下(集成开发环境IDE),这些开发环境有的是针对某种单片机,由单片机厂商提供,有的则比较通用一些,这些开发环境如Silicon Laboratories,AVR Studio,Keil uVision,Freescale CodeWarrior等。
PWM应用程序/*程序实现功能:PP1口输出PWM方波程序说明:通过改变duty和period ,从而控制PWM周期和占空比duty cycle=duty/periodPWM frequency=1M/(2*period)(Fbus=24M,scla=24)*/#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */void SetBusClock_24MHZ(void);void PWMDisable(byte channel);void PWMEnable(byte channel);void PWMSinglePortSetting(byte channel ,byte period ,byte duty) ;void PWMsinglePortInitial(byte channel, byte clkab,byte clock, byte polarity,byte align) ; void Service_WD(void);void PWMGeneralInitial(byte prclk,byte scla,byte sclb,byte ctl);void PWMConcatenateSetting(byte channel,word period,word duty);void main(void){/* put your own code here *///总线时钟频率设置:24MSetBusClock_24MHZ();//对预分频时钟,分频时钟A,分频时钟B和控制寄存器的配置//0分频01级联PWMGeneralInitial(0,24,0,0x10);//PWM端口寄存器的配置// 1通道SA时钟起始高电平左对齐PWMsinglePortInitial(1,0,1,1,0);//PWM级联输出配置//50HZ 占空比12.5%PWMConcatenateSetting(1,10000,250);//EnableInterrupts;for(;;) {_FEED_COP(); /* feeds the dog */} /* loop forever *//* please make sure that you never leave main */}//*********************************************//函数名:PWMEnable//函数功能:PWM单个端口使能//函数参数:一个byte 类型channel 代表PWM通道号// 返回值:无//********************************************void PWMEnable(byte channel){if(channel>7) channel=7;PWME|=(1<<channel); //选择使能位}//**********************************************//函数名称:PWMDisable//函数功能:PWM单个端口禁止//函数参数:一个byte类型channel 代表PWM通道号//返回值:无//***********************************************void PWMDisable(byte channel){if(channel>7) channel=7;PWME&=~(1<<channel); //选择禁止位}//函数功能:启动看门狗void Service_WD(void){CPMUARMCOP=0x55;CPMUARMCOP=0xAA;}//函数功能:总线时钟设置void SetBusClock_24MHZ(void){CPMUOSC_OSCE=1; //enable osc/*时钟倍频:24MHz BusClock48MHz VCO48MHz PLL*/CPMUSYNR=0x00|0x05; //VCOFRQ[1:0],SYNDIV[5:0]CPMUREFDIV=0x20|0x03;//REFFRQ[1:0],REFDIV[3:0]CPMUPOSTDIV=0x00; //POSTDIV=0;while(!CPMUFLG_LOCK)//等待VCO稳定Service_WD(); //看门狗CPMUCLKS_PLLSEL=1;}//*********************************************//函数名称:PWMSinglePortSetting//函数功能:实现PWM周期寄存器和占空比寄存器通道的单独输出//函数参数:3个byte类型//参数1:channel代表了当前配置的PWM通道//参数2:period 周期配置参数/*Left aligned output (CAEx = 0) PWMx Period = Channel Clock Period * PWMPERxCenter Aligned Output (CAEx = 1) PWMx Period = Channel Clock Period * (2 * PWMPERx)*///参数3:duty 占空比配置参数/*Polarity = 0 (PPOL x =0) Duty Cycle = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%Polarity = 1 (PPOLx = 1) Duty Cycle = [PWMDTYx / PWMPERx] * 100%*///返回值:无//**********************************************void PWMSinglePortSetting(byte channel ,byte period ,byte duty){if(channel>7) channel=7;PWMDisable(channel); //禁止该通道switch(channel){case 0:PWMPER0=period; //设置周期寄存器PWMDTY0=duty; //设置占空比寄存器break;case 1:PWMPER1=period; //设置周期寄存器PWMDTY1=duty; //设置占空比寄存器case 2:PWMPER2=period; //设置周期寄存器PWMDTY2=duty; //设置占空比寄存器break;case 3:PWMPER3=period; //设置周期寄存器PWMDTY3=duty; //设置占空比寄存器break;case 4:PWMPER4=period; //设置周期寄存器PWMDTY4=duty; //设置占空比寄存器break;case 5:PWMPER5=period; //设置周期寄存器PWMDTY5=duty; //设置占空比寄存器break;case 6:PWMPER6=period; //设置周期寄存器PWMDTY6=duty; //设置占空比寄存器break;case 7:PWMPER7=period; //设置周期寄存器PWMDTY7=duty; //设置占空比寄存器break;default:break;}PWMEnable(channel);}//*********************************************//函数名:PWMSinglePortInitial//函数功能:PWM端口寄存器的配置//函数参数:5个byte类型//参数1:channel 代表了当前配置的PWM通道//参数2:clkab 参数2,3决定了时钟源的选择//参数3: clock/*PWM Channel 0,1,4,5PCLKAB[0,1,4,5] PCLK[0,1,4,5] Clock Source Selection0 0 Clock A0 1 Clock SA1 0 Clock B1 1 Clock SBPWM Channel 2,3,6,7PCLKAB[2,3,6,7] PCLK[2,3,6,7] Clock Source Selection0 0 Clock B0 1 Clock SB1 0 Clock A1 1 Clock SA*///参数4:polarity PWM极性选择// 0 开始为低电平,周期计数开始为高电平// 1 开始为高电平,周期计数开始为低电平//参数5:align PWM对齐方式选择// 0 输出左对齐// 1 输出中心对齐//返回值:无//**********************************************void PWMsinglePortInitial(byte channel, byte clkab,byte clock, byte polarity,byte align) {if(channel>7) channel=7;//禁止该通道PWMDisable(channel);// PWM 时钟A/B 选择if(clkab==0) PWMCLKAB&=~(1<<channel);else PWMCLKAB|=(1<<channel);// PWM 时钟选择寄存器设置if(clock==0) PWMCLK&=~(1<<channel);else PWMCLK|=(1<<channel);//PWM 极性选择设置if(polarity==0) PWMPOL&=~(1<<channel) ;else PWMPOL|=(1<<channel);//PWM 对齐方式设置if(align==0) PWMCAE&=~(1<<channel);else PWMCAE|=(1<<channel);}//**********************************************************//函数名:PWMGeneralInitial//函数功能:对预分频时钟,分频时钟A,分频时钟B和控制寄存器的配置//函数参数:4个byte类型//参数1 prclk/*Clock A or Clock B Prescaler SelectsPCKA/B2 PCKA/B1 PCKA/B0 Value of Clock A/B0 0 0 Bus clock0 0 1 Bus clock / 20 1 0 Bus clock / 40 1 1 Bus clock / 81 0 0 Bus clock / 161 0 1 Bus clock / 321 1 0 Bus clock / 641 1 1 Bus clock / 128*///参数2:scla// Clock SA = Clock A / (2 * PWMSCLA)//参数3:sclb// Clock SB = Clock B / (2 * PWMSCLB)//参数4:ctl/*control[CON67,CON45,CON23,CON01,PSWAI,PFRZ]PWM级联控制寄存器CON67,CON45,CON23,CON010 单独一个通道1 两个通道级联PSWAI 0 等待模式禁止时钟输入1 等待模式允许时钟输入PFRZ 0 冻结模式允许PWM时钟输入1 冻结模式禁止PWM时钟输入//返回值:无*///**************************************************************void PWMGeneralInitial(byte prclk,byte scla,byte sclb,byte ctl){//禁止所有的PWM通道PWME=0x00;//设置预分频参数PWMPRCLK=prclk;//设置A分频参数PWMSCLA=scla;//设置B分频参数PWMSCLB=sclb;//级联配置PWMCTL=ctl;}//***********************************************************//函数名称:PWMConcatenateSetting//函数功能:PWM级联输出配置//函数参数:1个byte类型,2个word类型//参数1:channel代表了当前配置的PWM通道//参数2:period 周期配置参数/*Left aligned output (CAEx = 0) PWMx Period = Channel Clock Period * PWMPERxCenter Aligned Output (CAEx = 1) PWMx Period = Channel Clock Period * (2 * PWMPERx)*///参数3:duty 占空比配置参数/*Polarity = 0 (PPOL x =0) Duty Cycle = [(PWMPERx-PWMDTYx)/PWMPERx] * 100%Polarity = 1 (PPOLx = 1) Duty Cycle = [PWMDTYx / PWMPERx] * 100%*///返回值:无//**************************************************************void PWMConcatenateSetting(byte channel,word period,word duty){if(channel>7) channel=7;switch(channel){case 0:case 1:PWMDisable(0); //禁止通道0PWMDisable(1); //禁止通道1PWMPER01=period; //设置周期寄存器PWMDTY01=duty; //设置占空比寄存器PWMEnable(0); //使能通道0;PWMEnable(1); //使能通道1;break;case 2:case 3:PWMDisable(2); //禁止通道2PWMDisable(3); //禁止通道3PWMPER23=period; //设置周期寄存器PWMDTY23=duty; //设置占空比寄存器PWMEnable(2); //使能通道2;PWMEnable(3); //使能通道3;break;case 4:case 5:PWMDisable(4); //禁止通道4PWMDisable(5); //禁止通道5PWMPER45=period; //设置周期寄存器PWMDTY45=duty; //设置占空比寄存器PWMEnable(4); //使能通道4;PWMEnable(5); //使能通道5;break;case 6:case 7:PWMDisable(6); //禁止通道6PWMDisable(7); //禁止通道7PWMPER67=period; //设置周期寄存器PWMDTY67=duty; //设置占空比寄存器PWMEnable(6); //使能通道6;PWMEnable(7); //使能通道7;break;default:break;}}定时器应用程序#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */// 函数声明void OutputCompare_Init(void);;void Service_WD(void);void SetBusClock_24MHz(void);// 全局变量uint Timer7_Cnt=0;void main(void) {/* put your own code here */SetBusClock_24MHz();OutputCompare_Init();EnableInterrupts;for(;;) {_FEED_COP(); /* feeds the dog */} /* loop forever *//* please make sure that you never leave main */}void OutputCompare_Init(void){TSCR1_TEN = 0; /* Disable Timer module before adjusting registers. */ TIOS_IOS7 = 1; /* Set Channel 0 as output compare. */ TCTL1_OM7 = 0; /* Set channel 0 to toggle when a Timer match occurs. */ TCTL1_OL7 = 1; /* Set channel 0 to toggle when a Timer match occurs. */ TC7 = 0x4926; /* Set a value for channel 0 timer compare. */ TIE_C7I = 1; /* Enable channel 0 interrupt, handled by function TIM0ISR. */TSCR1_TSWAI = 1; /* Disables the timer module while in wait mode. */ TSCR1_TSFRZ = 1; /* Disables the timer counter while in freeze mode. */TSCR2_PR = 0x7; /* Set prescaler to divide by 128 */ TSCR2_TCRE = 1;TSCR1_TEN = 1; /* Timer Enable. *///中断周期:0x4926*128/24MHz = 100ms}#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid interrupt VectorNumber_Vtimch7 TIM7_ISR(void){Timer7_Cnt++;TFLG1 = TFLG1_C7F_MASK; /* Clear channel 0 flag. */}#pragma CODE_SEG DEFAULT// 看门狗void Service_WD(void){CPMUARMCOP = 0x55;CPMUARMCOP = 0xAA;}void SetBusClock_24MHz(void){CPMUOSC_OSCE = 1; /* enable ext osc *//*Initialise the system clock from a 16 MHz Crystal,24 MHz Bus CLK (48 MHz VCO, 48 MHz PLL)*/CPMUSYNR = 0x00 | 0x05; /* VCOFRQ[7:6], SYNDIV[5:0] */ CPMUREFDIV = 0x20 | 0x03; /* REFFRQ[7:6], REFDIV[3:0] */ CPMUPOSTDIV = 0x00; /* POSTDIV = 0 FPLL = FVCO */ while(!CPMUFLG_LOCK); /* wait for VCO to stabilize*/ Service_WD();CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */}SCI应用程序#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */// 函数声明void SCI0_Init(void);void SCI0_BR(unsigned long br);void SCI0_SendByte(char ch);void Service_WD(void);void SetBusClock_24MHz(void);// 全局变量char SCI_Flag = 0;char SCI_Rev = 0;void main(void) {/* put your own code here */SetBusClock_24MHz();SCI0_BR(38400);SCI0_Init();EnableInterrupts;SCI0_SendByte(0x01);SCI0_SendByte(0x02);SCI0_SendByte(0x03);for(;;) {_FEED_COP(); /* feeds the dog */if(SCI_Flag==1) {SCI_Flag = 0;SCI0_SendByte(SCI_Rev);}} /* loop forever *//* please make sure that you never leave main */}void Service_WD(void){CPMUARMCOP = 0x55;CPMUARMCOP = 0xAA;}void SetBusClock_24MHz(void){CPMUOSC_OSCE = 1; /* enable ext osc *//*Initialise the system clock from a 16 MHz Crystal,24 MHz Bus CLK (48 MHz VCO, 48 MHz PLL)*/CPMUSYNR = 0x00 | 0x05; /* VCOFRQ[7:6], SYNDIV[5:0] */ CPMUREFDIV = 0x20 | 0x03; /* REFFRQ[7:6], REFDIV[3:0] */ CPMUPOSTDIV = 0x00; /* POSTDIV = 0 FPLL = FVCO */ while(!CPMUFLG_LOCK); /* wait for VCO to stabilize*/Service_WD();CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */}//串口初始化void SCI0_Init(void){SCI0CR1 = 0x00; /* 8 Data Bits, 1 Start Bit, 1 Stop Bit, No Parity */SCI0CR2 = 0x2C; /* 使能接收中断;使能Tx,Rx *//* SCIASR1, SCIACR1, SCIACR2, SCISR1, SCISR2, SCIDRH & SCIDRL left at default values */ }//串口波特率设置void SCI0_BR(unsigned long br){uint brPrescaler;brPrescaler = (uint)(24000000 / (16 * br));/* Set the Baud Rate */SCI0BDH = (uchar)((brPrescaler>>8));SCI0BDL = (uchar)(brPrescaler);}//串口发送字节void SCI0_SendByte(char ch){/* check SCI transmit data register is empty */while(SCI0SR1_TDRE == 0);SCI0DRL = ch;}//串口中断#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid interrupt VectorNumber_Vsci0 SCI0_ISR(void){SCI0CR2_RIE=0;while(SCI0SR1_RDRF == 0);SCI_Rev = SCI0DRL;SCI_Flag = 1;SCI0CR2_RIE = 1;}#pragma CODE_SEG DEFAULTADC应用程序#include <hidef.h> /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */// 函数声明void ADC_Init(void);uint ADC_GetValue(byte ch);void Service_WD(void);void SetBusClock_24MHz(void);void Delay(void);// 全局变量uint AD_Result;uint AD_Result2;void main(void) {/* put your own code here */SetBusClock_24MHz();ADC_Init();EnableInterrupts;for(;;) {_FEED_COP(); /* feeds the dog */AD_Result = ADC_GetValue(7);AD_Result2 = ADC_GetValue(0);} /* loop forever *//* please make sure that you never leave main */// AD初始化void ADC_Init(void){ATDCTL1 = 0x3F; /* 10-Bit resolution ,discharge before sampling. */ATDCTL3 = 0x88; /* Right Justified Data, Single conversion sequence */ATDCTL4 = 0xE1; /* 6 MHz, Notice: 12MHz Max ATD Clock, Fatdlk = FBUS/(2*(PRS+1)) *//* 26 ATD Clock cycles sample time */}// ADC通道采集uint ADC_GetValue(byte ch){ATDCTL5 = 0x0F & ch; /* Start Continuous Conversions on ch */while (!ATDSTAT0_SCF); /* wait for conversion sequence to complete */return ATDDR0;}// 看门狗void Service_WD(void){CPMUARMCOP = 0x55;CPMUARMCOP = 0xAA;}void SetBusClock_24MHz(void){CPMUOSC_OSCE = 1; /* enable ext osc *//*Initialise the system clock from a 16 MHz Crystal,24 MHz Bus CLK (48 MHz VCO, 48 MHz PLL)*/CPMUSYNR = 0x00 | 0x05; /* VCOFRQ[7:6], SYNDIV[5:0] */CPMUREFDIV = 0x20 | 0x03; /* REFFRQ[7:6], REFDIV[3:0] */CPMUPOSTDIV = 0x00; /* POSTDIV = 0 FPLL = FVCO */while(!CPMUFLG_LOCK); /* wait for VCO to stabilize*/ Service_WD();CPMUCLKS_PLLSEL = 1; /* Switch clk to use PLL */ }void Delay(void){uint dummy_ctr;for(dummy_ctr=0; dummy_ctr<0x007f;dummy_ctr++){;}}。
第10章实验系统10.1实验板简介本实验系统采用HCS08系列MC9S08AW60CFGE单片机,实验板集成了以下功能:➢OSBDM:集成OSBDM (HC08及HCS08)➢ADC:1路8/10位模数转换器电位器调节➢PWM:1路pwm控制蜂鸣器➢SCI:1路RS-232通信(DB9接头和TTL电平接口)➢KBI:4路按键中断输入➢数字量输入:4路数字量输入➢数码管:4位8段数码管显示➢LED:8位发光二极管显示➢SPI:一路串行SPI通讯接口(插针引出)10.1.1实验板系统特点➢基于BDM方式调试程序。
➢BDM方式提供给用户各种基本的开发和调试功能,包括程序下载和运行、汇编和反汇编、断点设置、单步执行和内存显示修改等。
➢用户可对自编程序进行实时仿真和在线监测。
➢系统板提供了大量外围功能模块,可辅助完成对并行IO口,键盘和外部中断、AD和SCI等模块的实验和测试。
10.1.2实验板开发套件实验板开发套件包括:➢系统板(内含BDM)➢5V直流电源➢RS-232串口电线➢USB电缆10.1.3实验板系统与PC的连接实验系统与PC的连接如图10-1所示。
BDM编程接口用来给实验板下载程序。
RS-232串行总线用来与实验板进行通讯。
RS-232串行通讯接口HCS08试验板BDM编程接口图10-110.2 实验板接口定义10.2.1 4位数字量输入电路实验板用拨码开关为用户提供了4位数字量输入模块,其原理图如图10-2所示。
图10-2当拨码开关状态为OFF时,输入由内部上拉电阻置高;当拨码开关为ON时,相应的输入为0。
10.2.3 4位按键输入电路实验板用拨码开关为用户提供了4位数字量输入模块,其原理图如图10-3所示。
图10-3按键电路由单片机内部提供上拉电阻,可以通过内部寄存器设置工作在扫描或中断方式。
10.2.4 8位数字量显示电路实验板用LED为用户提供了8位数字量输出模块,其原理图如10-4所示。
体值,而无需用户自己计算。
由于复位矢量位于Flash空间,并且每个复位/中断矢量占用2字节的Flash空间,因此用DC.W伪指令定义。
注意不能用DS伪指令定义Flash常量。
对于有中断服务子程序的源程序,为了在发生中断时能够响应中断进入相应的中断服务子程序,和填写复位向量类似,只需将中断服务子程序的入口地址填入对应的中断复位向量区即可。
3.6.3汇编程序设计3.6.3.1算术/逻辑运算程序设计MCU主要用于控制目的,其数据运算、处理的能力并不强。
但由于HCS08系列MCU具有相应的算术、逻辑指令,因此它可以完成一些简单的算术/逻辑运算功能。
[例3.1] 若字变量Data1和Data2分别存放着两个16位无符号数,编写求这两个数之和的子程序,并将和存放到Sum字节存储空间中。
两个16位无符号数相加,和为17位,至少需要3个字节的存储空间,和按照从高位到低位的顺序依次存放在以Sum为首地址的字节存储单元中。
Add_Pro:CLC ; 清进位标志位LDA Data1+1ADD Data2+1 ; 两数低八位相加STA Sum+2 ; 存低八位之和LDA Data1ADC Data2 ; 高八位带低八位进位加STA Sum+1 ; 存高八位之和ROLAAND #01HSTA Sum ; 存高八位进位位RTS3.6.3.2查表和散转程序HCS08具有变址寻址方式,实现查表操作非常方便。
利用查表可以实现转换、计算等各种功能。
散转是指根据输入数据的不同跳转到不同的程序入口进行处理。
[例3.2] 单字节变量Hex_Byte中存放了一十六进制数,编写子程序将其转换为两位ASCII码,并将结果存至以Result开首的字节存储单元中。
例如4AH的ASCII码为3441H,$F9的ASCII码为4639H。
……ORG 0070H ; 用户变量一定要定位在Ram区域Hex_Byte DS.B 1Result DS.B 2……ORG 0870HASCII_Table DC.B ‘0123456789ABCDEFG’; 常数表格、代码一定要定位在Flash区域……Hex_To_Ascii:LDA Hex_ByteAND #$F0 ; 取出高4位NSA ; (A[3:0]:A[7:4])→ATAX ; A→XLDA ASCII_Table,X ; 查表,得高4位的ASCII码STA Result ; 存高4位的ASCII码LDA Hex_ByteAND #$0F ; 取出低4位TAX ; A→XLDA ASCII_Table,X ; 查表,得低4位的ASCII码STA Result+1 ; 存低4位的ASCII码RTS[例3.3] 设字节变量Num存放在Ram的0070H单元,取值范围为0T~9T,编写查表子程序,查出变量的立方值,并存入Cube字节变量中。
freescale 9s12十六位单片机原理及嵌入式开发技术概述说明1. 引言1.1 概述本文主要介绍freescale 9S12十六位单片机的原理和嵌入式开发技术。
Freescale 9S12单片机是一款广泛应用于嵌入式系统设计中的重要硬件设备,具有强大的性能和丰富的外设功能。
在本文中,我们将深入探讨该单片机的基本原理、架构和指令集,以及它的存储器和外设功能。
同时,我将为您提供有关嵌入式开发技术的概述。
嵌入式系统已经成为现代科技领域中不可或缺的一部分。
了解嵌入式编程语言、工具链以及硬件与软件设计流程对于成功开发复杂系统至关重要。
1.2 文章结构本文共分为五个部分来进行论述。
第一部分是引言,我们将对文章做一个简单的概述以及介绍整篇文章的结构。
第二部分将详细介绍Freescale 9S12单片机的原理,包括概述、架构和指令集、存储器和外设功能等方面内容。
第三部分将提供有关嵌入式开发技术的概述,主要涉及嵌入式系统简介、嵌入式编程语言与工具链、硬件与软件设计流程等内容。
第四部分将探讨如何在Freescale 9S12单片机上进行嵌入式开发实践,包括开发环境的准备和安装、程序设计与调试技巧以及应用案例分析与优化策略。
最后,在第五部分中,我们将对文章进行总结并提出主要观点。
1.3 目的本文的目的是帮助读者了解Freescale 9S12十六位单片机的原理和嵌入式开发技术,并提供相关的实践经验和案例分析。
通过阅读本文,读者将能够全面了解该单片机的基本原理,掌握嵌入式开发技术的基础知识,并能够在实际项目中应用所学到的知识。
同时,本文还旨在激发读者对于嵌入式系统设计和开发的兴趣,并为他们打下坚实的基础。
2. Freescale 9S12单片机原理:2.1 单片机概述:Freescale 9S12是一种十六位单片机,由美国芯片制造商Freescale Semiconductor(现为NXP半导体)设计和生产。
它是嵌入式系统中常用的微控制器之一,广泛应用于汽车电子、消费电子和工业控制等领域。
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。