MC9S12XS128MAA 教程(完整版)
- 格式:pdf
- 大小:2.06 MB
- 文档页数:36
飞思卡尔MC9S12XS128单片机各模块使用方法及寄存器配置手把手教你写S12XS128程序--PWM模块介绍该教程以MC9S12XS128单片机为核心进行讲解,全面阐释该16位单片机资源。
本文为第一讲,开始介绍该MCU的PWM模块。
PWM 调制波有8个输出通道,每一个输出通道都可以独立的进行输出。
每一个输出通道都有一个精确的计数器(计算脉冲的个数),一个周期控制寄存器和两个可供选择的时钟源。
每一个P WM 输出通道都能调制出占空比从0—100% 变化的波形。
PWM 的主要特点有:1、它有8个独立的输出通道,并且通过编程可控制其输出波形的周期。
2、每一个输出通道都有一个精确的计数器。
3、每一个通道的P WM 输出使能都可以由编程来控制。
4、PWM 输出波形的翻转控制可以通过编程来实现。
5、周期和脉宽可以被双缓冲。
当通道关闭或PWM 计数器为0时,改变周期和脉宽才起作用。
6、8 字节或16 字节的通道协议。
7、有4个时钟源可供选择(A、SA、B、SB),他们提供了一个宽范围的时钟频率。
8、通过编程可以实现希望的时钟周期。
9、具有遇到紧急情况关闭程序的功能。
10、每一个通道都可以通过编程实现左对齐输出还是居中对齐输出。
1、PWM启动寄存器PWMEPWME 寄存器每一位如图1所示:复位默认值:0000 0000B图1 PWME 寄存器每一个PWM 的输出通道都有一个使能位P WMEx 。
它相当于一个开关,用来启动和关闭相应通道的PWM 波形输出。
当任意的P WMEx 位置1,则相关的P WM 输出通道就立刻可用。
用法:PWME7=1 --- 通道7 可对外输出波形PWME7=0 --- 通道7 不能对外输出波形注意:在通道使能后所输出的第一个波形可能是不规则的。
当输出通道工作在串联模式时(PWMCTL 寄存器中的CONxx置1),那么)使能相应的16位PWM 输出通道是由PWMEx 的高位控制的,例如:设置PWMCTL_CON01 = 1,通道0、1级联,形成一个16位PWM 通道,由通道 1 的使能位控制PWM 的输出。
用了一年多飞思卡尔MC9S12XS128这款处理器,现在总结下各个功能模块的驱动.//锁相环时钟的初始化总线频率为40MHz(总线时钟为锁相环时钟的一半)//晶振为11.0592MHzvoid PLL_init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1) { //锁相环时钟= 2*11.0592*(39+1)/(10+1)=80MHz 总线时钟为40MHzREFDV=0x0A;SYNR=0x67; //0110_0111 低6位的值为19,高两位的值为推荐值while(CRGFLG_LOCK != 1);CLKSEL_PLLSEL = 1; //选定锁相环时钟//FCLKDIV=0x0F; //Flash Clock Divide Factor 16M/16=1M}//周期中断定时器的初始化-// //周期中断通道1用于脉冲累加器的定时采样,定时周期为: 10ms= (199+1)*(1999+1)/(40M) (没有使用)//周期中断通道0用于控制激光管的轮流发射,定时周期为: 2000us= (399+1)*(199+1)/(40M)//2011/4/4 15:24 定时时间改为1msvoid PIT_init(void){PITCFLMT_PITE = 0; // 禁止使用PIT模块 PITCFLMT :PIT 控制强制加载微计数器寄存器。
PITCE_PCE0 = 1; // 使能定时器通道0//PITCE_PCE1 = 1; //使能定时器通道1PITMUX = 0; //通道0,和通道1均选择8位微计数器0//修改时间只需要改下面四行PITMTLD0 = 199; //向8位微计数器中加载的值PITLD0 = 199; //向16位计数器中加载的值//PITMTLD1 = 39; //向8位微计数器中加载的值 8位,最大值不要超过255//PITLD1 = 1999; //向16位计数器中加载的值PITINTE |= 0x01; //使能定时器通道0的中断PITCFLMT_PITE = 1;//使能PIT模块}//脉冲累加器的初始化, PT7口外接光电编码器//最新修改: 2011/3/25 16:53void PT7_PulAcc_Init(void){DDRT &= 0x77;//设置PT7,PT3口为输入(硬件上PT7,PT3通过跳线联到了一块)PERT |= 0x80; //使能通道7的上拉电阻PPST &= 0x7f; //电阻设为上拉电阻TCTL4 &= 0x3f; //禁止PT3的输入捕捉功能PACTL = 0x50; //启动脉冲累加计数器,上升沿触发,禁止触发中断和溢出中断,主定时器禁止}//通道1用于控制舵机1 PWM 高电平有效,//通道3用于控制电机1 PWM 低电平有效,这与前两代车高电平有效有区别!!!!!//通道7用于给上排激光管提供PWM信号 PWM高电平有效!!!!!//通道6用于给下排激光管提供PWM信号 PWM高电平有效!!!!!// 2011-03-17 7:56 增加了A端口的使用新增通道6//2011-6-9 23:03 //增加了通道4,5的联合使用,用于控制下排方向舵机 void PWM_init(void){PWME = 0x00;//PWM禁止PWMPRCLK = 0x03; // ClockA=40M/8=5M, Clock B = 40M/1=40M PWMSCLB = 10; // Clock SB= 40/2*10= 2MHz(供电机)PWMSCLA = 5; // SA = Clock A/2*5 = 5M/10 = 500K = SA 用于控制舵机PWMPOL = 0xe2; //1110_0010通道7,通道6与通道1、通道5先输出高电平然后输出低电平,POLx=1先输出高电平后输出低电平; PPOLx=0先输出低电平)PWMCAE = 0x00; // 左对齐输出(CAEx=0为左对齐,反之为中心对齐)//PWMCLK = 0010_1010 (0 1 4 5位控制SA_1;或A_0; 2 3 6 7位控制SB_1 或B_0)//为PWM通道1选择时钟 SA(500KHz),//为PWM通道5选择时钟 SA(500KHz),//为通道3选择时钟 SB(10MHz)//为通道7选择时钟B(40MHz)//为通道6选择时钟B(40MHz)PWMCLK = 0x2A; //0010_1010PWMCTL = 0x70; //0111_0000 CON45=1,把通道4,5联合使用。
MC9S12XS128MAL V2.6系统板说明书一、产品介绍MC9S12XS128MAL V2.6系统板专为智能车竞赛设计,采用全引脚芯片MC9S12XS128MAL,资源丰富。
二、功能及特点1、最高可以超频到96MHz bus clock(不建议);2、BDM 接口;3、复位键;4、PB口上接8 个发光二极管D0-D7(绿);5、电源指示发光二极管(红);6、带有RS232串行接口7、参考可以选择5V 或者3.0V,默认为3.0V,也可以去掉VRH 电阻外接参考电压;8、两个电源接口;9、插针为100mil的整数倍,标准点阵板可以直接插上去;10、板子尺寸:40*45mm。
11、采用双排直插式,布线更方便;12、重新优化EMI/EMC,增强抗干扰能力,Runing 极稳定;13、PCB采用加厚镀金工艺和焊盘阻焊技术,抗氧化能力强;三、接口及使用1、下载接口下载接口如图所示,一定注意:不要将BDM地下载接头插反,不然会烧坏单片机。
2、串行接口单片机开发板将单片机串口1进行了RS232电平转换,可与计算机串口直接相连。
单片机串口2为TTL电平,由IO引脚引出。
RS232串口由白色三针插座引出,T为发,R为收,GND为地,如图所示。
3、AD参考如下图所示,51欧姆电阻为参考电压选择电阻,焊接在5V端,选择板子地供电电压5V作为AD参考电压,焊接在3.3V(实际为3V)端,选择3V电压作为AD参考电压,也可将电阻去掉,从外接引脚上输入自己期望地AD参考电压。
考虑到摄像头的输出电压只有1V左右,实际单片机开发板默认选择3V参考电压。
4、引脚接口单片机开发板的引脚如图所示,所有引脚均已引出,具体引脚定义可参考MC9S12XS256.pdf。
-智能车制作-GND GND AD15AD14 AD13 AD12AD11AD10AD9AD8A7A5A3A1E0E2H0H2E4E6H4H6NC B7 B5 Vcc VRH AD7 AD6 AD5 AD4 AD3 AD2 AD1AD0A6A4A2A0E1E3H1H3E5E7H5H7NC RES B6VRL M6 TXI S3 S5 S7 J6 M4 M2 M0 P7P5P3 P1K3K1T0T2T4T6K5J1B0B2 B4 GND M7 RXO S2 S4 S6 J7 M5 M3 M1 K7P6P4 P2P0K2K0T1T3T5T7K4J0B1 B3单片机开发板引脚定义,具体含义参考MC9S12XS256.pdf。
飞思卡尔MC9S12XS128各模块初始化程序--超详细注释//**************************************************************************// 武狂狼2014.5.1 整理// 新手入门的助手////***************************************************************************注释不详细/*********************************************************/函数名称:void ATD0_init(void)函数功能:ATD初始化入口参数:出口参数:/***********************************************************/void ATD0_init(void){ATD0DIEN=0x00; //使用模拟输入功能|=1;数字输入功能// ATD0CTL0=0x07; //Bit[3:0]WRAP[3:0] 反转通道选择位ATD0CTL1=0x40; // 12位精度,采样前不放电 Bit[7]ETRIGSEL(外部触发源选择位。
=0选择A/D通道AN[15:0] |=1选择 ERTIG3~0)和Bit[3:0]ETRIGCH[3:0]选择外部触发通道// Bit[6:5]SRES[1:0]A/D分辨率选择位。
Bit[4]SMP_DIS =0采样前不放电|=1采样前内部电容放电,这会增加2个A/D时钟周期的采样时间,有助于采样前进行开路检测ATD0CTL2=0x40; // 快速清零,禁止中断,禁止外部触发ATD0CTL3=0x90; // 右对齐,转换序列长度为2,非FIFOATD0CTL4=0x03; // 采样时间4个周期,PRS=31,F(ATDCLK)=F(BUS)/(2(PRS+1))// ATD0CTL5=0x30; //启动AD转换序列//:对每项数据采集时,用到哪个通道采样可在相应子函数内设置某一通道(见Sample_AD.c)while(!ATD0STAT2L_CCF0);/*********************************************************/函数名称:void PIT_init(void)函数功能:初始化PIT 设置精确定时时间(1s)入口参数:无出口参数:无说明:无/***********************************************************/void PIT_init(void){PITCFLMT=0x00; //禁止PIT模块Bit[7] PITE:PIT模块使能位,0禁用|1使能// Bit[6] PITSWAI:等待模式下PIT停止位,0等待模式下,PIT模块正常运行| 1等待模式下,PIT模块停止产生时钟信号,冻结PIT模块// Bit[5] PITFRZ: 冻结模式下PIT计数器冻结位。
飞思卡尔16位单片机MC9S12XS128加密(程序下载不进去,正负极未短路,通电芯片不发烫)后解锁的方法及步骤/*****************************************************************************/ *本人用此法成功解救了4块板子【窃喜!】,此说明是本人边操作边截图拼成的,有些是在别的说明上直接截图【有些图本人不会截取,就利用现成的了,不过那也是本人用豆和财富值换来的】,表达不清之处还望见谅,大家将就着看吧!如能有些许帮助,我心甚慰!!!————武狂狼2014.4.23 /*****************************************************************************/编译软件:CW5.1版本,下载器:飞翔BDMV4.6 【1】,连接好单片机,准备下载程序,单击下载按钮出现以下界面或(图1.1)图 1.1——4中所有弹出窗口均单击“取消”或红色“关闭”按钮依次进入下一界面(图1.2)(图1.3)(图1.4)******************************************************************************* *******************************************************************************【2】单击出现如下图所示下拉列表,然后单击(图2.1)出现下图(图2.2)对话框,按下面说明操作(图2.2)弹出图2.3,单击按钮,依次出现如图2.4--5窗口,均单击(图2.3)(图2.4)******************************************************************************* *******************************************************************************【3】单击出现下拉列表,然后单击下拉列表中单击按钮出现如下界面,单击选择相对应的单片机型号(我选的红色方框里的HCS12X….),单击OK. PS:【此步骤是本人自己试出来的,若不进行此操作,图3.3中下拉列表中无要找选项】(图3.1)(图3.3)(图3.4)(图3.5)红色方框2中默认即为所要选的文件,此步只需单击确认按钮即可,如有不同读者酌情处置。
飞思卡尔16位单片机9S12XS128使用(一些初始化)飞思卡尔16位单片机9S12XS128使用最近做一个关于飞思卡尔16位单片机9S12XS128MAA的项目,以前未做过单片机,故做此项目颇有些感触。
现记录下这个艰辛历程。
以前一直是做软件方面的工作,很少接触硬件,感觉搞硬件的人很高深,现在接触了点硬件发现,与其说使用java,C#等语言写程序是搭积木,不如说搞硬件芯片搭接的更像是在搭积木(因为芯片是实实在在拿在手里的东西,而代码不是滴。
还有搞芯片内部电路的不在此列,这个我暂时还不熟悉)。
目前我们在做的这个模块,就是使用现有的很多芯片,然后根据其引脚定义,搭接出我们需要的功能PCB 板,然后为其写程序。
废话不多说,进入正题。
单片机简介:9S12XS128MAA单片机是16位的单片机80个引脚,CPU是CPU12X,内部RAM8KB,EEPROM:2KB,FLASH:128KB,外部晶振16M,通过内部PLL 可得40M总线时钟。
9S12XS128MAA单片机拥有:CAN:1个,SCI:2个,SPI:1个,TIM:8个,PIT:4个,A/D:8个,PWM:8个下面介绍下我们项目用到的几个模块给出初始化代码1、时钟模块初始化单片机利用外部16M晶振,通过锁相环电路产生40M的总线时钟(9S12XS128系列标准为40M),初始化代码如下:view plaincopy to clipboardprint?1/******************系统时钟初始化****************/2void Init_System_Clock()3{4 asm { // 这里采用汇编代码来产生40M的总线5 LDAB #36 STAB REFDV78 LDAB #49 STAB SYNR10 BRCLR CRGFLG,#$08,*//本句话含义为等待频率稳定然后执行下一条汇编语句,选择此频率作为总线频率11 BSET CLKSEL,#$8012 }13}上面的代码是汇编写的,这个因为汇编代码量比较少,所以用它写了,具体含义注释已经给出,主函数中调用此函数即可完成时钟初始化,总线时钟为40M.2、SCI模块初始化单片机电路做好了当然少不了和PC之间的通信,通信通过单片机串口SCI链接到PC端的COM口上去。
1、定时器IC/OC功能选择寄存器TIOSIOS[7..0]IC/OC功能选择通道0 相应通道选择为输入捕捉(IC)1 相应通道选择为输出比较(OC)2、定时器比较强制寄存器 CFORCFOC[7..0]设置该寄存器某个FOCn位为1将导致在相应通道上立即产生一个输出比较动作,在初始化输出通道时候非常有用。
【说明】这个状态和正常状态下输出比较发生后,标志位未被置位后的情况相同。
3、输出比较7屏蔽寄存器 OC7MOC7M[7..0]OC7(即通道7的输出比较)具有特殊地位,它匹配时可以直接改变PT7个输出引脚的状态,并覆盖各个引脚原来的匹配动作结果,寄存器OC7M决定哪些通道将处于OC7的管理之下。
OC7M中的各位与PORTT口寄存器的各位一一对应。
当通过TIOS将某个通道设定为输出比较时,将OC7M中的相应位置1,对应的引脚就是输出状态,与DDR中的对应位的状态无关,但OC7Mn并不改变DDR相应位的状态。
【说明】OC7M具有更高的优先级,它优于通过TCTL1和TCTL2寄存器中的OMn和OLn设定的引脚动作,若OC7M中某个位置1,就会阻止相应引脚上由OM和OL设定的动作。
4、输出比较7数据寄存器 OC7DOC7D[7..0]OC7M对于其他OC输出引脚的管理限于将某个二进制值送到对应引脚,这个值保存在寄存器OC7D中的对应位中。
当OC7匹配成功后,若某个OC7Mn=1,则内部逻辑将OC7Dn送到对应引脚。
OC7D中的各位与PORTT口寄存器的各位一一对应。
当通道7比较成功时,如果OC7M中的某个位为1,OC7D中的对应位将被输出到PORTT的对应引脚。
【总结】通道7的输出比较(OC7)具有特殊的位置,在OC7Mn和OC7Dn两个寄存器设置以后,OC7成功输出后将会引起一系列的动作。
比如:OC7M0=1,则通道0处在OC7的管理下,在OC7成功后,系统会将OC7D0的逻辑数据(仅限0或者1)反应在PT0端口上。
本教程试图用最少的时间教你飞思卡尔XS128单片机的中断优先级设置方法和中断嵌套的使用,如果是新手请先学习中断的基本使用方法。
先来看看XS128 DataSheet 中介绍的相关知识,只翻译有用的:七个中断优先级每一个中断源都有一个可以设置的级别高优先级中断的可以嵌套低优先级中断复位后可屏蔽中断默认优先级为1同一优先级的中断同时触发时,高地址(中断号较小)的中断先响应注意:高地址中断只能优先响应,但不能嵌套同一优先级低地址的中断下面直接进入正题,看看怎么设置中断优先级:XS128中包括预留的中断一共有128个中断位,如果为每个中断都分配一个优先级寄存器的话会非常浪费资源,因此飞思卡尔公司想出了这样一种办法:把128个中断分为16个组,每组8个中断。
每次设置中断时,先把需要的组别告诉某个寄存器,再设置8个中断优先寄存器的某一个,这样只需9个寄存器即可完成中断的设置。
分组的规则是这样的:中断地址位7到位4相同的中断为一组,比如MC9SX128.h中这些中断的位7到位3都为D,他们就被分成了一组。
0~F正好16个组。
INT_CFADDR就是上面说到的用来设置组别的寄存器:我们需要设置某个组别的中断时,只要写入最后8位地址就行了,比如设置SCI0的中断优先级,就写入0xD0。
设置好组别之后,我们就要该组中相应的中断进行设置,设置中断的寄存器为这其实是一组寄存器,一共有8个,每个都代表中断组中的一个中断。
对应规则是这样的:中断地址的低四位除以2比如还是SCI0,低四位是6,除以二就是3,那么我们就需要设置INT_CFDATA3 往INT_CFDATAx中写入0~7就能设置相应的中断优先级了拿我本次比赛的程序来举个例子:我们的程序中需要3个中断:PIT0,PORTH,SCI0。
PIT0定时检测传感器数值,PORTH连接干簧管进行起跑线检测,SCI0接收上位机指令实现急停等功能。
因此中断优先级要SCI0>PORTH>PIT0。
MC9S12XS128例程SCI程序串行通信时MCU与外部设备之间进行通信的一种简单而有效的硬件方法。
无论用查询方式还是中断方式进行串行通信编程,在程序初始化时均必须对SCI进行初始化。
初始化主要包括波特率设置、通信格式的设置、发送接收数据方式的设置等。
对SCI进行初始化,需要设置如下几部分:(1)定义波特率一般选内部总线时钟为串行通信的时钟源。
通过设置SCI波特率寄存器SCI0BD的波特率选择位SBR[12:0],来选择合适的分频系数。
(2)写控制字到SCI控制寄存器1(SCI0CR1)设置是否允许SCI、数据长度、输出格式、选择唤醒方法、是否校验等。
(3)写控制字到SCI控制寄存器2(SCI0CR2)设置是否允许发送与接收、是中断接收还是查询接收等。
串行通信程序如下:/** write in “Init.h” **/#include /* common defines and macros */#include "derivative.h" /* derivative-specific definitions */ //void InitBusClk(void); //可以不使用锁相环void InitSci(void);/** write in “Init.c” **///初始化程序#include "Init.h"/*//------------初始化Bus Clock------------//void InitBusClk(void) {DisableInterrupts;CLKSEL=0X00; //PLLSEL 1 : Bus Clock=PLLCLK/2// 0 : Bus Clock=OSCCLK/2PLLCTL_PLLON=1; //开启PLLSYNR=0; //OSCCLK=16MHzREFDV=0X0F;//PLLCLK=2*OSCCLK*[(1+SYNR)/(1+REFDV]=32/16=2MHz while(!(CRGFLG_LOCK==1)); //直到LOCK=1,when PLL is ready,退出循环CLKSEL_PLLSEL=1; //PLLSEL 1 : Bus Clock=PLLCLK/2=2MHz/2=1MHz// 0 : Bus Clock=OSCCLK/2=16M/2=8MHz}*///---------------初始化SCI---------------//void InitSci(void){SCI0BD=4545; //设波特率为110//SCI baud rate = SCI module clock/(16*SCIBD)=Bus Clock/(16*SCIBD)// = 8MHz/(16*4545)=500kHz/4545=110bps//SCIBD : SBR12-SBR0,Value from 1 to 8191SCI0CR1=0;SCI0CR2=0X2C; // 0010 1100 RIE=1,TE=1,RE=1// RIE=1 RDRF and OR interrupt requests enabled// TE=1 Transmitter enabled// RE=1 Receiver enabled}/** write in “SCI.h” **///函数声明unsigned char SciRead();void SciWrite(byte);/** write in “SCI.c” **///串行通信程序#include "Init.h"#include "SCI.h"//---------------读SCI数据---------------//unsigned char SciRead(){if(SCI0SR1_RDRF==1){//数据从移位寄存器传送到SCI数据寄存器SCIDRL//SCI0SR1_RDRF==1表明数据寄存器SCI0DRL为满,可以接收新的数据SCI0SR1_RDRF=1; //读取SCI数据寄存器会将RDRF清除,重新置位return SCI0DRL; //返回数据寄存器的数值}}//---------------写SCI数据---------------//void SciWrite(byte sci_value){while(!(SCI0SR1&0X80));//SCI0SR1_TDRE==1表明数据寄存器SCI0DRL为空,可以发送新的数据SCI0DRH=0;SCI0DRL=sci_value; //发送新的数据至数据寄存器SCI0DR}//---------------中断程序-----------------//#pragma CODE_SEG NON_BANKEDinterrupt 20 void Sci_Intrrupt(void){ //SCI的中断向量号为20 byte text;DisableInterrupts; //关中断text=SciRead(); //接收数据寄存器SCI0DRL中的数据asm nop;asm nop;SciWrite(text); //发送数据至数据寄存器SCI0DRLDDRA=0XFF; //设A口为输出,用来显示是否执行中断,可以不用PORTA_PA6=!PORTA_PA6;EnableInterrupts; //开中断}#pragma CODE_SEG DEFAULT/** write in “main.c”” **/#include "Init.h"#include "SCI.h"void main(void) {/* put your own code here */_DISABLE_COP(); //关看门狗DisableInterrupts; //关中断//InitBusClk();InitSci();EnableInterrupts; //开中断for(;;) {// _FEED_COP(); /* feeds the dog */} /* loop forever *//* please make sure that you never leave main */}A/D转换应用实例要让ATD 开始转换工作,必须经过以下三个步骤:1.将ADPU 置1,使ATD 启动;2.按照要求对转换位数、扫描方式、采样时间、时钟频率及标志检查等方式进行设置;3.发出启动命令;如果上电默认状态即能满足工作要求,那么只要将ADPU 置1,然后通过控制寄存器发出转换命令,即可实现转换。
第一章端口整合模块端口A,B和K为通用I/O接口端口E整合了IRQ,XIRQ中断输入端口T整合了1个定时模块端口S整合了2个SCI模块和1个SPI模块端口M整合了1个MSCAN端口P整合了PWM模块,同时可用作外部中断源输入端口H和J为通用I/O接口,同时可用作外部中断源输入端口AD整合了1个16位通道ATD模块大部分I/O引脚可由相应的寄存器位来配置选择数据方向、驱动能力,使能上拉或下拉式装置。
当用作通用IO口时,所有的端口都有数据寄存器和数据方向寄存器。
对于端口T,S,M,P,H,和J有基于每个针脚的上拉和下拉控制寄存器。
对于端口AD有基于每个针脚的上拉寄存器。
对于端口A、B、E和K,有一个基于端口的上拉控制寄存器。
对于端口T,S,M,P,H,J,和AD,有基于每个针脚的降额输出驱动控制寄存器。
对于端口A,B,E,和K,有一个基于端口的降额输出驱动控制寄存器。
对于端口S、M,有漏极开路(线或)控制寄存器。
对于端口P、H和J,有基于每个针脚的中断标志寄存器。
纯通用IO端口共计有41个,分别是:PA[7:0]PB[7:0]PE[6:5]PE[3:2]PK[7,5:0]PM[7:6]PH[7:0](带中断输入)PJ[7:6](带中断输入)PJ[1:0](带中断输入)第二章脉冲宽度调制模块XS128具有8位8通道的PWM,相邻的两个通道可以级联组成16位的通道。
PWME::PWMEPWM通道使能寄存器。
PWMEx=1将立即使能该通道PWM波形输出。
若两个通道级联组成一个16位通道,则低位通道(通道数大的)的使能寄存器成为该级联通道的使能寄存器,高位通道(通道数小的)的使能寄存器和高位的波形输出是无效的。
PWMPOLPWMPOL::PWM极性寄存器。
PPOLx=1,则该通道的周期初始输出为高电平,达到占空比后变为低电平;相反,若PPOLx=0,则初始输出为低电平,达到占空比后变为高电平。
PWMCLK::PWMCLKPWM时钟源选择寄存器。
MC9S12XS128串口操作例程MC9S12XS128 串口操作例程Code Warrior 4.7Target : MC9S12XS128Crystal: 16.000Mhzbusclock: 8.000MHzpllclock:16.000MHz本程序主要包括以下功能:1.设置锁相环和总线频率;2.IO口使用;3.共四路ATD使用及显示方法。
LED计数,根据灯亮可以读取系统循环了多少次************************************************************** ***************************/#include /* common defines and macros */#include /* derivative information */#include#include#include#pragma LINK_INFO DERIVATIVE "mc9s12xs128"#pragma CODE_SEG DEFAULT#define CR_as_CRLF TRUE // if true , you can use "\n" to act as CR/LF,// if false, you have to use "\n\r",but can get a higher speed static int do_padding;static int left_flag;static int len;static int num1;static int num2;static char pad_character;unsigned char uart_getkey(void){while(!(SCI0SR1&0x80)) ; //keep waiting when not emptyreturn SCI0DRL;}/*void uart_init(void) {SCI0CR2=0x0c;SCI0BDH=0x00;//16MHz,19200bps,SCI0BDL=0x1aSCI0BDL=0x34;//16MHz,9600bps,SCI0BDL=0x34}*/void uart_putchar(unsigned char ch){if (ch == '\n'){while(!(SCI0SR1&0x80)) ;SCI0DRL= 0x0d; //output'CR'return;}while(!(SCI0SR1&0x80)) ; //keep waiting when not empty SCI0DRL=ch;}void putstr(char ch[]){unsigned char ptr=0;while(ch[ptr]){uart_putchar((unsigned char)ch[ptr++]);}}static void padding( const int l_flag){int i;if (do_padding && l_flag && (len < num1))for (i=len; i<="" p="">uart_putchar( pad_character);}static void outs( char* lp){/* pad on left if needed */len = strlen( lp);padding( !left_flag);/* Move string to the buffer */while (*lp && num2--) uart_putchar( *lp++);/* Pad on right if needed */len = strlen( lp);padding( left_flag);}static void reoutnum(unsigned long num, unsigned int negative, const long base ){char* cp;char outbuf[32];const char digits[] = "0123456789ABCDEF";/* Build number (backwards) in outbuf */cp = outbuf;do {*cp++ = digits[(int)(num % base)];} while ((num /= base) > 0);if (negative) *cp++ = '-';*cp-- = 0;/* Move the converted number to the buffer and *//* add in the padding where needed. */len = strlen(outbuf);padding( !left_flag);while (cp >= outbuf)uart_putchar( *cp--);padding( left_flag);}static void outnum(long num, const long base ,unsigned char sign)//1, signed 0 unsigned{unsigned int negative;if ( (num < 0L) && sign ){negative=1;num = -num;}else negative=0;reoutnum(num,negative,base);}static int getnum( char** linep){int n;char* cp;n = 0;cp = *linep;while (isdigit(*cp))n = n*10 + ((*cp++) - '0');*linep = cp;return(n);}void printp( char* ctrl, ...){int long_flag;int dot_flag;char ch;va_list argp;va_start( argp, ctrl);for ( ; *ctrl; ctrl++) {/* move format string chars to buffer until a format control is found. */ if (*ctrl != '%') {uart_putchar(*ctrl);#if CR_as_CRLF==TRUEif(*ctrl=='\n') uart_putchar('\r');#endifcontinue;}/* initialize all the flags for this format. */dot_flag = long_flag = left_flag = do_padding = 0;pad_character = ' ';num2=32767;try_next:ch = *(++ctrl);if (isdigit(ch)){if (dot_flag)num2 = getnum(&ctrl);else {if (ch == '0')pad_character = '0';num1 = getnum(&ctrl);do_padding = 1;}ctrl--;goto try_next;}switch (tolower(ch)) {case '%':uart_putchar( '%');continue;case '-':left_flag = 1;break;case '.':dot_flag = 1;break;case 'l':long_flag = 1;break;case 'd':if (long_flag ==1 ){if(ch == 'D') {outnum( va_arg(argp, unsigned long), 10L , 0);continue;}else /* ch == 'd' */ {outnum( va_arg(argp, long), 10L,1);continue;}}else{if(ch == 'D') {outnum( va_arg(argp, unsigned int),10L,0);continue;}else /* ch == 'd' */{outnum( va_arg(argp, int), 10L,1); continue;}}case 'x': // X 无符号,x 有符号if (long_flag ==1 ){if(ch == 'X'){outnum( va_arg(argp, unsigned long), 16L,0); continue;}else /* ch == 'x' */{outnum( va_arg(argp, long), 16L,1); continue;}}else{if(ch == 'X'){outnum( va_arg(argp, unsigned int), 16L,0); continue;}else /* ch == 'x' */{outnum( va_arg(argp, int), 16L,1);continue;}} //如果按照16进制打印,将全部按照无符号数进行continue;case 's':outs( va_arg( argp, char*));continue;case 'c':uart_putchar( va_arg( argp, int));continue;default:continue;}goto try_next;}va_end( argp);}#pragma CODE_SEG __NEAR_SEG NON_BANKED void interrupt 20 SCI0_ISR(void){SCI0CR2_RIE=0;//此处为串口中断需要处理的事情uart_putchar(uart_getkey());PORTA_PA0=~PORTA_PA0;SCI0CR2_RIE = 1;}#pragma CODE_SEG DEFAULT//-----------------------------------------------------void setbusclock(void){CLKSEL=0X00; //disengage PLL to systemPLLCTL_PLLON=1; //turn on PLLSYNR=1;REFDV=1; //pllclock=2*osc*(1+SYNR)/(1+REFDV)=32MHz;_asm(nop); //BUS CLOCK=16M_asm(nop);while(!(CRGFLG_LOCK==1)); //when pll is steady ,then use it;CLKSEL_PLLSEL =1; //engage PLL to system;}//-----------------------------------------------------static void SCI_Init(void){SCI0CR1 =0x00;SCI0CR2 =0x2c; //enable Receive Full Interrupt,RX enable,Tx enable SCI0BD =0x68; //SCI0BDL=busclk/(16*SCI0BDL) //busclk 8MHz, 9600bps,SCI0BD=0x34//busclk 16MHz, 9600bps,SCI0BD=0x68//busclk 24MHz, 9600bps,SCI0BD=0x9C} //busclk 32MHz, 9600bps,SCI0BD=0xD0//busclk 40MHz, 9600bps,SCI0BD=0x106//-----------------------------------------------------void Dly_ms(int ms){int ii,jj;if (ms<1) ms=1;for(ii=0;ii<ms;ii++)< p="">for(jj=0;jj<2670;jj++); //busclk:16MHz--1ms}void main(void){unsigned char LedCnt=0;setbusclock();SCI_Init();DDRA=0xFF;PUCR_PUPBE=1;EnableInterrupts;for(;;){LedCnt=(LedCnt>0XFE?0:++LedCnt);Dly_ms(1000); //修改延时以修改数据发送频率//低电平灯亮用这句,注释掉下面那句PORTA_PA0=~PORTA_PA0;//高电平灯亮用这句,注释掉上面那句//PORTB=LedCnt;putstr("\nhttp:%/%//doc/4115489903.html,");printp("\n Minute elapsed: %03ds",LedCnt); }}</ms;ii++)<>。