飞思卡尔S12G系列芯片Demo程序之按键中断实验
飞思卡尔S12G系列芯片Demo程序之【按键中断实验】

1、按键中断#include <hidef.h>#include "derivative.h"#define LED PORTA#defineLED_dirDDRA#define KEY1PTIJ_PTIJ0#define KEY2PTIJ_PTIJ1#define KEY3 PTIJ_PTIJ2#define KEY4PTIJ_PTIJ3#define KEY1_dirDDRJ_DDRJ0#define KEY2_dir DDRJ_DDRJ1#define KEY3_dir DDRJ_DDRJ2#define KEY4_dir DDRJ_DDRJ3unsigned char data=0x01;unsigned char direction=1; //设置灯亮的方向,0向左,1向右。
unsigned char time=5; //设置灯闪的速度。
/*************************************************************/ /* 延时函数*/ /*************************************************************/ void delay(unsigned int n){unsignedinti,j;for(j=0;j<n;j++)for(i=0;i<40000;i++);}/*************************************************************/ /* 初始化LED灯*/ /*************************************************************/ voidinit_led(void){LED_dir=0xff; //设置为输出LED=~data; //点亮LED1}/*************************************************************/ /* 初始化按键*/ /*************************************************************/ voidinit_key(void){KEY1_dir =0; //设置为输入KEY2_dir=0;KEY3_dir=0;KEY4_dir=0;PPSJ = 0x00; //极性选择寄存器,选择下降沿;PIFJ = 0x0f; //对PIFJ的每一位写1来清除标志位;PIEJ = 0x0f; //中断使能寄存器;}/*************************************************************/ /* 按键中断函数*/ /*************************************************************/ #pragma CODE_SEG __NEAR_SEG NON_BANKEDinterrupt void PTJ_inter(void){if(PIFJ != 0) //判断中断标志{PIFJ = 0xff; //清除中断标志if(KEY1 == 0) //按键1按下{time-=1;if(time==0)time=1;}if(KEY2 == 0){time+=1;if(time>10)time=10;}if(KEY3 == 0)direction=0;if(KEY4 == 0)direction=1;}}#pragma CODE_SEG DEFAULT/*************************************************************/ /* 主函数*/ /*************************************************************/ void main(void){DisableInterrupts;init_led();init_key();EnableInterrupts;for(;;){delay(time);if(direction==1){data=data<<1; //左移一位if(data==0)data=0x01;}else{data=data>>1; //右移一位if(data==0)data=0x80;}LED = ~data;}}2、按键中断#include <hidef.h>#include "derivative.h"#define LEDCPU PORTD_PD3#define LEDCPU_dirDDRD_DDRD3unsigned char single = 0;/*************************************************************/ /* 初始化锁相环*/ /* 使用外部晶振:16MHz */ /* 设置总线频率:16MHz */ /*************************************************************/ void INIT_PLL(void){CPMUPROT=0x26; //解除时钟配置保护CPMUCLKS_PSTP = 0; //禁止PLLCPMUCLKS_PLLSEL = 1; //设置PLLCLK为系统时钟CPMUOSC_OSCE=1; //使能外部晶振CPMUSYNR=0x01; //SYNDIV的值为1,CPMUREFDIV = 0x81; //REFDIV的值为1CPMUPOSTDIV=0x00;CPMUPLL=0x10; //锁相环调频启用,用以减少噪音while(CPMUFLG_LOCK==0); //等待PLLCLK锁定CPMUPROT=0x01; //使能时钟配置保护}/*************************************************************//* 初始化实时中断*//*************************************************************/void INIT_RTI(void){CPMUPROT=0x26; //解除时钟配置保护CPMUCLKS_RTIOSCSEL = 1; //RTI时钟源为晶振时钟CPMUINT = 0x80; //使能实时中断CPMURTI = 0x6f; //设置实时中断的时间间隔为32.768ms,根据机器周期求得CPMUPROT= 0x01; //使能时钟配置保护}/*************************************************************//* 实时中断函数(声明中断函数)*//*************************************************************/#pragma CODE_SEG __NEAR_SEG NON_BANKED/*中断函数置于非分页区内,由于飞思卡尔16位单片机的中断向量是16位所以中断函数只有被置于非分页区内才能被寻址到,这就是第一行的作用*///#pragma主要作用是设定编译器状态,指示编译器完成一些特定动作interrupt void RTI_inter(void){if(CPMUFLG_RTIF == 1)CPMUFLG_RTIF = 1;single +=1;if (single==15){LEDCPU = ~LEDCPU;single = 0;}}#pragma CODE_SEG DEFAULT/*后续代码置于默认区内,由于单片机内部非分页区大小有限,非中断函数一般置于分页区内,最后一行即为此作用*//*************************************************************//* 主函数*//*************************************************************/void main(void){DisableInterrupts;INIT_PLL();INIT_RTI();LEDCPU_dir = 1;LEDCPU = 0;EnableInterrupts;for(;;){}}以上Demo程序已通过本人亲自验证,可实现相关功能,对代码中有疑问的朋友欢迎在主页区留言交流。
键盘中断微机实验报告

键盘中断微机实验报告1. 引言键盘中断是计算机硬件系统中常见的一种输入设备中断方式,其功能是在用户通过键盘输入时,中断处理器正常运行的流程,将键盘输入的数据传递给操作系统供其处理。
本次实验旨在通过搭建一个简单的键盘中断实验系统,加深对键盘中断原理及操作的理解。
2. 实验原理2.1 键盘中断键盘中断是一种异步的硬件中断方式,即键盘通过给中断控制设备发送中断请求信号,从而将中断信息传递给CPU。
一旦发生键盘中断,CPU将停止当前执行的任务,跳转到事先设置好的中断处理程序,处理键盘中断事件。
2.2 实验系统本次实验使用Intel 8086微处理器、键盘控制器8042和键盘作为实验系统的主要硬件设备。
系统的基本结构如下图所示:与中断控制器连接。
- 打开中断屏蔽位,以允许中断请求通过。
3.4 运行实验程序完成前述步骤后,我们可以运行实验程序,测试键盘中断的正常工作。
当用户按下键盘时,键盘中断会触发,并将键盘输入的数据传递给中断处理程序进行处理。
4. 实验结果与分析经过测试,我们发现实验系统能够正确地接收和处理键盘输入的数据。
飞思卡尔S12系列寄存器和中断讲解

S12的输入/输入端口(I/O口)I/O端口功能可设置为通用I/O口、驱动、内部上拉/下拉、中断输入等功能。
设置I/O口工作方式的寄存器有:DDR、IO、RDR、PE、IE和PS。
DDR:设定I/O口的数据方向。
IO :设定输出电平的高低。
RDR:选择I/O口的驱动能力。
PE:选择上拉/下拉。
IE:允许或禁止端口中断。
PS:1、中断允许位置位时,选择上升沿/下降沿触发中断;2、中断禁止时且PE有效时,用于选择上拉还是下拉。
I/O端口设置1、A口、B口、E口寄存器(1)数据方向寄存器DDRA、DDRB、DDREDDRA、DDRB、DDRE均为8位寄存器,复位后其值均为0。
当DDRA=0、DDRB=0、DDRE=0 时A口、B口和E口均为输入口。
否则,A口、B口、E口为输出口。
当DDRA、DDRB、DDRE的任何一位置1时,则该位对应的引脚被设置为输出。
例如,将A口设置为输出口,则其C语言程序的语句为:DDRA=0xff;(2)A口、B口、E口上拉控制寄存器PUCRPUCR为8位寄存器,复位后的值为0。
当PUPAE、PUPBE、PUPEE被设置为1时,A口、B口、E口具有内部上拉功能;为0时,上拉无效。
当A口、B口、E口为地址/数据总线时,PUPAE和PUPBE无效。
(3)A口、B口、E口降功率驱动控制寄存器RDRIVRDRIV为8位寄存器,复位后的值为0,此时,A口、B口、E口驱动保持全功率;当RDPA、RDPB、RDPE为1时,A口、B口、E口输出引脚的驱动功率下降(4)数据寄存器PORTA、PORTB、PORTEPORTA、PORTB、PORTE均为8位寄存器,复位后的值为0,端口引脚输出低电平;要使引脚输出高电平,相应端口对应位应该置1。
由于PE0是/XIRQ、PE1是IRQ,因此,PE0和PE1只能设置为输入。
2、H口寄存器(1)H口I/O寄存器PTH任意时间读/写。
当某一引脚对就的数据方向位设置为1时,读操作返回的是这个端口寄存器的值;否则,读的是引脚的值。
飞思卡尔S12系列单片机系统硬件设计

飞思卡尔S12系列单片机 系统硬件设计By DEMONEmail:Wangpanbao@智能车制作网站出版目录第一节 MC9S12DG128B功能概述 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第1页第二节时钟电路设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第4页第三节S12单片机系统滤波电路设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第6页第四节单片机电源电路设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第8页第五节S12系列单片机IO接口电路设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>第11页第六节单片机复位电路的设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第14页第七节BDM接口电路设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第16页第八节RS232串行通讯电路设计 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第17页第九节S12单片机的运行模式 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第21页第十节使用DXP设计单片机系统 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>第22页第一节 MC9S12DG128B功能概述MC9S12DG128B是飞思卡尔半导体公司的汽车电子类产品,早在飞思卡尔还没有从摩托罗拉分离出来前就已经诞生了。
飞思卡尔单片机实验

/*延时子程序 */void delay(void){ unsigned int i,j;for(i=0;i<100;i++)for(j=0;j<5000;) j++;}void main(void) {/* put your own code here 主程序*/PORTB=0x7f;DDRB=0xff;for(;;){delay();PORTB>>=1;PORTB|=0x80;if(PORTB==0xFF){PORTB=0x7F;}}/*延时子程序 */void delay(void){ unsigned int i,j;for(i=0;i<100;i++)for(j=0;j<5000;) j++;}void main(void){/* put your own code here 主程序*/ int i;PORTB=0x7f;DDRB=0xff;for(;;){for(i=0;i<7;i++){delay();PORTB>>=1;PORTB|=0x80;}for(i=0;i<7;i++){delay();PORTB<<=1;PORTB|=0x01;}}}复位+IO******************************************* 实验内容:MCU复位2011-11-06实验现象:运行后,PB口指示灯连续闪烁五次后灭,按复位键后,再闪烁五次。
******************************************* #include<hidef.h>#include"derivative.h"unsigned char k; //用于计数void delay(void){unsigned int i,j;for(i=0;i<5;i++)for(j=0;j<50000;j++);}void main(void) {DisableInterrupts;DDRB =0xff; //PB口输出PORTB =0xaa; //你可以改变PB口数据,显示不同形式的闪烁,如,x0F,xAA,x55等EnableInterrupts;for(k=0;k<5;k++) //5次闪烁{delay();PORTB=~PORTB;delay();PORTB=~PORTB;}for(;;); //死循环。
飞思卡尔单片机中断

在CW4.6环境下,中断编程主要有两种方式: 第一种是使用“interrupt‖关键字,―interrupt‖关键字是一个非标准ANSI-C的关键字,因此,它不能被所有ANSI-C编译器厂商所支持 。同样,对不同的编译器,interrupt‖关键字的用法可能会改变。“interrupt‖关键字同样会提示编译器下面的函数是一个中断服务例程。 例: void interrupt 20 SCI0_ISR(void); 其中,interrupt表示该函数为终端服务程序,后面的20表示中断号20,在这里SCI0的中断向量号就是20. 这种方法写起来非常简单,但是,在S12单片机实际使用中,中断号并没有在手册中给出,通常需要自己在中断向量表中从上往下 数出来,或者根据中断向量计算得到,很容易出错。 于是有了第二种方法: 在ISR程序之前,使用符号“#pragma TRAP_PROC‖,TRAP_PROC 提示编译器下面的函数是中断服务例程。编译器会用一个特 殊的中断返回指令来结束这个函数。 此时,中断函数的书写如下所示: #pragma TRAP_PROC void SCI0_ISR(void){ ...} 这时候编译器不知道这个ISR指向那个中断向量,我们需要在链接文件即:prm文件中指定之。 使用 VECTOR命令来实现中断向量与ISR程序的连接。 例:VECTOR 0 _Startup //这是系统默认prm文件中自带的,即复位后0号中断即复位中断的ISR为_Startup() 我们可以这样写: VECTOR 20 SCI0_ISR //指定中断号 或者 VECTOR ADDRESS 0xFFD6 SCI0_ISR //直接指定中断向量地址 注:使用#pragma TRAP_PROC与修改prm文件的方法,在中断服务子程序的结尾处必须要手动加入返回主程序的指令,包括取 出堆栈、中断返回两个步骤。 在S12单片机中,可以写作 asm { pula; rti;} 尾注: 两种方法所写的中断服务子程序必须被放在非分页存储区内,即non_blanked code seg. 其中一种常用的方法是在服务子程序前声明://下面代码放在NON_BANKED区 #pragma CODE_SEG NON_BANKED 在中断程序后声明://下面内容按默认放置 #pragma CODE_SEG DEFAULT Freescale Semiconductor Confidential and Proprietary Information. Freescale™ and the Freescale logo are trademarks of Freescale
飞思卡尔S12系列寄存器和中断讲解

S12的输入/输入端口(I/O 口)I/O端口功能可设置为通用I/O 口、驱动、内部上拉/下拉、中断输入等功能。
设置I/O口工作方式的寄存器有:DDR、10、RDR、PE、IE 和 PS。
DDR :设定I/O 口的数据方向。
IO :设定输出电平的高低。
RDR :选择I/O 口的驱动能力。
PE:选择上拉/下拉。
IE:允许或禁止端口中断。
PS: 1、中断允许位置位时,选择上升沿/下降沿触发中断;2、中断禁止时且PE有效时,用于选择上拉还是下拉。
I/O端口设置1、A 口、B 口、E 口寄存器(1)数据方向寄存器 DDRA、DDRB、DDREDDRA、DDRB、DDRE均为8位寄存器,复位后其值均为 0。
当 DDRA=0、DDRB=0、 DDRE=0 时 A 口、B 口和 E 口均为输入口。
否则,A 口、B口、E 口为输出口。
当 DDRA、DDRB、DDRE的任何一位置1时,则该位对应的引脚被设置为输出。
例如,将A 口设置为输出口,则其 C语言程序的语句为:DDRA=0xff ;(2) A 口、B 口、E 口上拉控制寄存器PUCRPUCR 初:PUPKE —— ----- --------- -——RUPEE ——-————-——PUPBE PUR\EWrite: | | |PUCR为8位寄存器,复位后的值为 0。
当PUPAE、PUPBE、PUPEE被设置为1时,A 口、B 口、E 口具有内部上拉功能;为0时,上拉无效。
当A 口、 B 口、E 口为地址/数据总线时,PUPAE和PUPBE无效。
(3)A 口、B 口、E 口降功率驱动控制寄存器RDRIVRDRIV 篇眾?RDPK 口| | 良DPE 口口| 嵐DPB RDPARDRIV为8位寄存器,复位后的值为 0,此时,A 口、B 口、E 口驱动保持全功率;当 RDPA、RDPB、RDPE为1时,A 口、B 口、E 口输出引脚的驱动功率下降(4)数据寄存器PORTA、PORTB、PORTEPORTA、PORTB、PORTE均为8位寄存器,复位后的值为 0,端口引脚输出低电平;要使引脚输出高电平,相应端口对应位应该置1。
飞思卡尔单片机中断

中断嵌套与中断返回
中断嵌套处理
在中断处理过程中,如果再次触发其他中断,需要进行嵌套处理,确保每个中断都能得到及时响应。
中断返回
中断处理完成后,需要返回被中断的程序,继续执行后续操作。在返回过程中,需要注意恢复被中断 程序的现场状态。
04
中断应用实例
定时器中断
定时器中断概述
定时器中断的配置
定时器中断是由单片机内部的定时器产生 的中断,用于在设定的时间间隔内执行特 定的任务。
中断使能与中断屏蔽
中断使能
通过设置中断使能位,可以启用或禁用某个中断源的中断处理功能。
中断屏蔽
通过设置中断屏蔽位,可以禁止某些不希望处理的中断源产生中断。
03
中断处理程序
中断处理程序的编写
初始化中断向量表
根据需要,在程序中初始化中断向量表,以确定不同 中断源对应的处理函数。
编写中断处理函数
根据中断源的不同,编写相应的中断处理函数,实现 中断响应和处理。
硬件结构
01
02
03
中断控制器
中断控制器是单片机中断 系统的核心部件,负责管 理中断的响应、优先级和 向量。
中断源
中断源是指能够触发中断 的信号源,如定时器溢出 、串行通信接收到数据等 。
中断优先级和向量
中断优先级决定了中断的 优先级,而向量则是指中 断处理程序的入口地址。
中断源
定时器溢出
当定时器计数达到最大值时,会触发一个中断,用于定时器 溢出处理。
THANKS。
解决方法
解决中断丢失问题需要从以下几个方面入手:首先,检查中断优先级设置,确保优先级 正确且没有重叠;其次,优化ISR的编写,避免在ISR中执行耗时的操作,确保ISR简洁 高效;最后,如果问题依然存在,可以尝试在外部硬件上加装抗干扰措施,如滤波电容
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
time=1;
}
if(KEY2 == 0)
{
time+=1;
if(time>10)
time=10;
}
if(KEY3 == 0)
direction=0;
if(KEY4 == 0)
direction=1;
}
}
#pragma CODE_SEG DEFAULT
/*************************************************************/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
/*中断函数置于非分页区内,由于飞思卡尔 16 位单片机的中断向量是 16 位
所以中断函数只有被置于非分页区内才能被寻址到,这就是第一行的作用*/
//#pragma 主要作用是设定编译器状态,指示编译器完成一些特定动作
interrupt void RTI_inter(void)
//锁相环调频启用,用以减少噪音 //等待 PLLCLK 锁定 //使能时钟配置保护
}
/*************************************************************/
/*
初始化实时中断
*/
/*************************************************************/
{
DisableInterrupts; INIT_PLL(); INIT_RTI(); LEDCPU_dir = 1; LEDCPU = 0; EnableInterrupts; for(;;) { } }
以上 Demo 程序已通过本人亲自验证,可实现相关功能,对代码中有疑问的朋友
欢迎在主页区留言交流。
/*
初始化锁相环
*/
/*
使用外部晶振:16MHz
*/
/*
设置总线频率:16MHz
*/
/*************************************************************/
void INIT_PLL(void)
{
CPMUPROT=0x26;
//解除时钟配置保护
CPMUCLKS_PSTP = 0; //禁止 PLL
CPMUPROT= 0x01;
//使能时钟配置保护
}
/*************************************************************/
/*
实时中断函数(声明中断函数)
*/
/*************************************************************/
delay(time); if(directita==0)
data=0x01; } else {
data=data>>1; if(data==0)
data=0x80; }
LED = ~data; } }
//左移一位 //右移一位
2、按键中断
#include <hidef.h>
最后一行即为此作用*/
/*************************************************************/
/*
主函数
*/
/*************************************************************/
void main(void)
{
if(CPMUFLG_RTIF == 1)
CPMUFLG_RTIF = 1;
single +=1;
if (single==15)
{
LEDCPU = ~LEDCPU;
single = 0;
}
}
#pragma CODE_SEG DEFAULT
/*后续代码置于默认区内,由于单片机内部非分页区大小有限,非中断函数一般置于分页区内,
unsigned char direction=1; unsigned char time=5;
//设置灯亮的方向,0 向左,1 向右。 //设置灯闪的速度。
/*************************************************************/
/*
延时函数
*/
void INIT_RTI(void)
{ CPMUPROT=0x26;
//解除时钟配置保护
CPMUCLKS_RTIOSCSEL = 1; //RTI 时钟源为晶振时钟
CPMUINT = 0x80;
//使能实时中断
CPMURTI = 0x6f;
//设置实时中断的时间间隔为 32.768ms,根据机器周期求得
CPMUCLKS_PLLSEL = 1; //设置 PLLCLK 为系统时钟
CPMUOSC_OSCE=1;
//使能外部晶振
CPMUSYNR=0x01;
//SYNDIV 的值为 1,
CPMUREFDIV = 0x81; //REFDIV 的值为 1
CPMUPOSTDIV=0x00;
CPMUPLL=0x10; while(CPMUFLG_LOCK==0); CPMUPROT=0x01;
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt void PTJ_inter(void)
{ if(PIFJ != 0)
//判断中断标志
{
PIFJ = 0xff; if(KEY1 == 0)
//清除中断标志 //按键 1 按下
{
time-=1;
if(time==0)
/*
主函数
*/
/*************************************************************/
void main(void)
{
DisableInterrupts;
init_led();
init_key(); EnableInterrupts;
for(;;) {
1、按键中断
#include <hidef.h> #include "derivative.h"
#define LED
PORTA
#define LED_dir DDRA
#define KEY1 PTIJ_PTIJ0
#define KEY2 PTIJ_PTIJ1
#define KEY3 PTIJ_PTIJ2
//极性选择寄存器,选择下降沿; //对 PIFJ 的每一位写 1 来清除标志位; //中断使能寄存器;
/*************************************************************/
/*
按键中断函数
*/
/*************************************************************/
#define KEY4 PTIJ_PTIJ3
#define KEY1_dir DDRJ_DDRJ0
#define KEY2_dir DDRJ_DDRJ1
#define KEY3_dir DDRJ_DDRJ2
#define KEY4_dir DDRJ_DDRJ3
unsigned char data=0x01;
/*
初始化按键
*/
/*************************************************************/
void init_key(void)
{ KEY1_dir =0;
//设置为输入
KEY2_dir=0; KEY3_dir=0; KEY4_dir=0; PPSJ = 0x00; PIFJ = 0x0f; PIEJ = 0x0f; }
#include "derivative.h"
#define LEDCPU
PORTD_PD3
#define LEDCPU_dir DDRD_DDRD3
unsigned char single = 0;
/*************************************************************/
/*
初始化 LED 灯
*/
/*************************************************************/
void init_led(void)
{ LED_dir=0xff; LED=~data;
//设置为输出 //点亮 LED1
}
/*************************************************************/
/*************************************************************/
void delay(unsigned int n)
{
unsigned int i,j;
for(j=0;j<n;j++)
for(i=0;i<40000;i++);
}
/*************************************************************/