没有合适的资源?快使用搜索试试~ 我知道了~
首页【精品】飞思卡尔MC9S12XS128单片机重点模块讲解
【精品】飞思卡尔MC9S12XS128单片机重点模块讲解
需积分: 33 271 浏览量
更新于2023-05-26
评论 1
收藏 1.51MB PDF 举报
基于飞思卡尔 MC9S12XS128MCU 的模块讲解及测试,写的极好,自己做了书签。文中详细介绍了端口集成模块、定时器模块、脉冲宽度调制模块、数模转换模块等相关寄存器的含义及使用方法,还有例程可供参考。
资源详情
资源评论
资源推荐

基于飞思卡尔
基于飞思卡尔
基于飞思卡尔
基于飞思卡尔MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
刘昌元
刘昌元
刘昌元
刘昌元
概述:
飞思卡尔单片机的端口名称和51系列单片机有区别, 51单片最经典的通用I/O口名称是P0
口、P1口、P2口、P3口。而飞思卡尔128单片机是由A口、B口、K口、E口等标称的
,
熟悉51单片的同学在此学习飞思卡尔单片时要知道变通,同样的对于学习其他单片机也是
一样的,先熟悉端口名称,再熟悉其端口功能,再熟悉其寄存器。C语言的编程语法和算法
思路是通用的。 现在功能强悍一点的单片都在内部集成了很多现成的模块, 我们可以通过对
其模块寄存器编程配置我们需要的功能即可, 此处的128单片机就是这样一款单片机, 在此
我就我个人学习的一些心得写出来, 仅供交流与参考, 同时我也希望帮助新手能够很快得上
手。 具体更深层的内容大家还需要去参考芯片的技术手册和其他参考书。 以下我就分模块来
讲解, 大家在学习的过程中也需要一个模块一个模块的来学习和测试。 其实我个人觉得买过
来的开发板用途不是很大,因为很多端口被其在PCB设计时固化了,留给我们的端口并不
多, 使用起来极不方便, 所以我个人建议大家可以买个带有最小系统的模块, 自己用排针和
插槽焊一个程序调试板,再焊一排共阴极的发光二极管(最好能发不同颜色光的) ,再焊几
个开关电路和按键电路即可。 我们在代码的各个位置通过点亮发光二极管来知道程序走到哪
一步了。 下面我提供的测试例程也是这么来的,节省硬件就是节省开支啊,多动脑子, 多想
办法可以克服很多困难的。
注: 一个寄存器的多个位可以一次性写入配置的, 但是为了使大家读程序理解方便我对寄存
器的每一位几乎一位一位配置的,我麻烦了,不过可以给大家读程序带来方便。
第一章:PIM模块(端口集成模块)
一、端口主要功能概述:
1:端口A、B、K作为通用的输入输出口使用
2:端口E整合了1个外部IRQ(可屏蔽的)和XIRQ(不可屏蔽的)中断输入模块
3:端口T整合了1个定时器TIM模块
4:端口S整合了2个SCI(串行通信)和1个SPI(串行外设)模块
5:端口M整合了1个MSCAN(CAN总线)模块
6:端口P连接到内部的PWM(脉宽调制)模块,即PWM信号可以通过P口输出,同时P
口的输入也可以作为外部中断信号的输入。
7:端口H和J在作为通用输入输出口使用的同时也可以作为外部中断信号的输入口。
8:端口AD口整合了一个16通道的ATD模块即模拟量转数字量的模块。
二、通用输入输出口(GPIO)
以端口A和端口B为例讲解,以上是我截取的技术手册上的,从上来看A口和B口各
有8个口,且A0-A7;B0-B7全部作为GPIO(通用输入输出口)使用。此处A口和B口
使用方法是一样的,我姑且就以端口A来讲解。
A口和B口作为通用输入输出口使用时我们只需要掌握4个寄存器即可。 PORTA(A口
212

基于飞思卡尔
基于飞思卡尔
基于飞思卡尔
基于飞思卡尔 MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU 的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
安徽工业大学
安徽工业大学
安徽工业大学
安徽工业大学 自动化系
自动化系
自动化系
自动化系 刘昌元
刘昌元
刘昌元
刘昌元
数据寄存器 ) 、 DDRA(A 口数据方向寄存器 ) 、 PUCR( 引脚上拉控制寄存器 ) 、 RDRIV( 低
功耗驱动寄存器 ) 这些寄存器都是 8 位的寄存器,其名称可以直接在程序中使用,当然
也可以只使用其中的个别数据位。
DDRA 由如下 8 位构成,任何一位置 1 时对应端口为输出,置 0 时对应端口为输入。
这一点和 51 单片机的 I/O 口有区别,在典型的 51 单片中 P0 口内部没有上拉电阻,但作 为
I/O 口使用时需要外接排阻 。 其他 P1-P3 口则可以直接作为双向口使用 , 51 单片在上电复位
后端口被默认的置 1. 在 51 单片中端口的某一位置 0 时端口作为输出口使用,置 1 时作为输
入口使用 。 例如如果我们想把 P1 作为输出口使用时我们可以在程序开始时写 P1=0x00; 如果
我们想把 P1 口作为输入口使用时我们可以写 P1=0xff; 这一点正好和飞思卡尔的 128 单片机
相反 , 另外 128 单片有专门的数据方向寄存器 DDRA 或者 DDRB 等来管理各个端口的输入
输出选择, 51 单片没有。如果我们想把端口 A 作为输入口使用,我们只需写 DDRA=0x00;
即所有位都置 0 ,如果我们想把端口 A 作为输出口使用,我们只需要写 DDRA=0xff; 即所有
位都置 1 ,而如果我们想要把端口 A 的高四位做输入口,低 4 位做输出口时我们就 写
DDRA=0x0f; 当我们需要将该端口的某一位做输出或者输入口使用时只需要将该端口对应的
方向位置 1 或者置 0 即可。例如我们想把 A3 口作输入口, A4 口作输出口使用时我们只需
要写: DDRA_DDRA3=0; DDRA_DDRA4=1; 即可。
对于数据方向寄存器的使用只要记住:置 1 —— 输出 置 0 —— 输入
PORTA 数据寄存器也是由 8 位组成,任何时候都可以对它进行读写操作。
例如在 DDRA=0xff ; A 口想全部输出高电平的话我们只要写 PORTA=0xff; 想全部输出低电
平的话我们只要写 PORTA=0x00; 如果想让某一位输出高电平或者低电平的话我们只需要
将该端口对应的数据寄存器位置 1 或者置 0 即可 , 例如 : PORTA_PA2=1; 此时 A2 口输出高
电平, PORTA_PA3=0; 此时 A3 口输出低电平。其他端口作为输入输出口使用时类似。
对于数据寄存器的使用只要记住:置 1 —— 高电平 置 0 —— 低电平
PUCR 上拉控制寄存器是由 A 、 B 、 E 、 K 口共用的,当端口作为输入口使用时用来控
制端口是否允许接上拉电阻。当端口做输出口使用时该寄存器无效。
当我们将 A 口作输入口使用时需要设置 A 口内置上拉电阻时首先写 PUCR_PUPAE=1;
当我们将 B 口作输入口使用时需要设置 B 口内置上拉电阻时首先写 PUCR_PUPBE=1;
当我们将 E 口作输入口使用时需要设置 E 口内置上拉电阻时首先写 PUCR_PUPEE=1;

基于飞思卡尔
基于飞思卡尔
基于飞思卡尔
基于飞思卡尔 MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU 的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
安徽工业大学
安徽工业大学
安徽工业大学
安徽工业大学 自动化系
自动化系
自动化系
自动化系 刘昌元
刘昌元
刘昌元
刘昌元
当我们将 K 口作输入口使用时需要设置 K 口内置上拉电阻时首先写 PUCR_PUPKE=1;
对于上拉控制寄存器的使用只要记住:置 1 —— 设置上拉 置 0 —— 禁止上拉
RDRIV 低功耗驱动寄存器,这个寄存器由 A 、 B 、 E 、 K 口共用。
此低功耗驱动寄存器可以在任意时刻进行读 、 写操作 。 其中 RDPA 、 RDPB 、 RDPE 、 RDP K
作为低功耗选择位分别负责对 A 口 、 B 口 、 E 口 、 K 口低功耗驱动的选择 , 注意只有在该端
口被选择作为输出口使用时低功耗设置才有效 , 作为输入口使用时是无效的 。 一旦选择低功
耗后其输出功耗将近乎正常功耗的 1/5 。 例如我们想要把端口 A 作为低功耗输出 , 我们只需
在程序初始化的时候写入如下几条指令即可:
DDRA=0xff; // 设置 A 口方向寄存器为数据输出
RDRIV_RDPA=1; // 选择 A 口为低功耗驱动
对于低功耗驱动寄存器的使用只要记住 : 置 1 —— 选择低功耗输出 置 0 —— 正常功耗
输出
到此为止关于端口作为 GPIO 使用时需要用到的四个端口寄存器我已经介绍完毕 , 虽然
只以端口 A 为例讲解的,但是其他端口的使用方法是一样的,只是改一下寄存器名而
已 , 所以我们要学会举一反三 。 关于 GPIO 的使用最常见的就是输出高低电平或者读入
高低电平,不要小看这个高低电平,这个高低电平作为输出可以用来控制 LED 、加上
驱动之后可以用来控制电机 、 可以用来驱动继电器等其他一些控制回路 , 作为输入时可
以用来查询外部的传感或者触发信号 , 可以来读取按钮或者来自键盘的信号等 。 此处为
了方便我们就用它的输出来控制发光二极管的点亮,可以用来程序测试发光二极管 , 达
到灯似流水的效果 , 当年可以用程序把发光二极管控制随心所欲的时候 GPIO 你就入门
了。如下我给出我写的测试代码,这是针对 PORTB 即 B 口的,当你把 B0 到 B5 口按
顺序接到共阴极接法的 6 只发光二极管上时可以看到灯似流水的效果。
源代码 : (基于 128 单片机)
/*------------------ 流水灯测试程序 ------------------------------*/
#include <hidef.h> // 头文件包含
#include "derivative.h"
#define LED PORTB // 定义 LED 为 B 口
#define uchar unsigned char // 宏替换
#define uint unsigned int
#define time 300 // 延时时间宏替换
/*--------------------- 延时函数 ---------------------------------*/
void delay(uint a)
{
uint i,j;
for(i=0;i<a;i++)
for(j=0;j<a;j++)
;

基于飞思卡尔
基于飞思卡尔
基于飞思卡尔
基于飞思卡尔 MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU 的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
安徽工业大学
安徽工业大学
安徽工业大学
安徽工业大学 自动化系
自动化系
自动化系
自动化系 刘昌元
刘昌元
刘昌元
刘昌元
}
/*--------------------- 主函数 ------------------------------------*/
void main(void)
{
DDRB=0x3f; // 定义 B0-B5 口为输出
LED=0x01; // 点亮第一只灯
EnableInterrupts; // 允许中断
while(1)
{
delay(time); // 延时
LED<<=1; // 高电平信号左移一位
delay(time);
if(LED==0x20) // 判断高电平信号是否移到第 6 位
LED=0x01; // 重新赋初始值
}
}
源代码 : (基于 STC52RC 单片机)
#include "reg52.h"
#define LED P1 // 选择 P1 口作为通用输出口
#define uchar unsigned char
#define uint unsigned int
void delay(uint a)
{
uint i,j;
for(i=0;i<a;i++)
for(j=0;j<a;j++)
;
}
void main()
{
LED=0x01; // 点亮第一只发光二极管
while(1)
{
LED=LED<<1; // 让高电平信号进行左移一位

基于飞思卡尔
基于飞思卡尔
基于飞思卡尔
基于飞思卡尔 MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU
MC9S12XS128MCU 的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
的模块讲解及测试
安徽工业大学
安徽工业大学
安徽工业大学
安徽工业大学 自动化系
自动化系
自动化系
自动化系 刘昌元
刘昌元
刘昌元
刘昌元
delay(500);
if(LED==0x80)
LED=0x01;
}
}
综合以上的两段代码看在 52 单片机和 128 单片机上编程思路基本上没大的区别,唯一的区
别就是 128 单片机有数据方向寄存器来管理 I/O 口。
将部分端口做输入口使用 , 另外一部分端口做输出口使用时 : 例如我们将 PORTB 的端
口 B7 用来做输入口, B0-B5 口做输出指示,测试代码如下:
源代码 : (基于 128 单片机)
/*------------------------ 端口作为输入口使用时 -------------------------------*/
/*----- 程序功能 : 当端口 7 检测到高电平时 6 只发光二极管闪烁 , 否则发光二极管不亮 ----*/
#include <hidef.h> // 头文件包含
#include "derivative.h"
#define INPUT PORTB_PB7 // 将 B7 口作为输入信号的检测口
#define uchar unsigned char // 数据类型宏替换
#define uint unsigned int
/*------------------------ 延时函数 --------------------------------------*/
void delay(uint a)
{
uint i,j;
for(i=0;i<a;i++)
for(j=0;j<a;j++)
;
}
/*-------------------------- 指示灯闪烁函数 -------------------------------*/
void light()
{
while(INPUT) // 判断输入电平的高低
{
PORTB=0x3f; //6 只灯全点亮
delay(500); // 延时一段时间
PORTB=0x00; //6 只灯全熄灭
delay(500); // 延时一段时间
}
}
剩余52页未读,继续阅读











安全验证
文档复制为VIP权益,开通VIP直接复制

评论0