飞思卡尔xs128单片机的简单定时中断

合集下载

飞思卡尔单片机中断

飞思卡尔单片机中断

在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

飞思卡尔单片机中断

飞思卡尔单片机中断

中断嵌套与中断返回
中断嵌套处理
在中断处理过程中,如果再次触发其他中断,需要进行嵌套处理,确保每个中断都能得到及时响应。
中断返回
中断处理完成后,需要返回被中断的程序,继续执行后续操作。在返回过程中,需要注意恢复被中断 程序的现场状态。
04
中断应用实例
定时器中断
定时器中断概述
定时器中断的配置
定时器中断是由单片机内部的定时器产生 的中断,用于在设定的时间间隔内执行特 定的任务。
中断使能与中断屏蔽
中断使能
通过设置中断使能位,可以启用或禁用某个中断源的中断处理功能。
中断屏蔽
通过设置中断屏蔽位,可以禁止某些不希望处理的中断源产生中断。
03
中断处理程序
中断处理程序的编写
初始化中断向量表
根据需要,在程序中初始化中断向量表,以确定不同 中断源对应的处理函数。
编写中断处理函数
根据中断源的不同,编写相应的中断处理函数,实现 中断响应和处理。
硬件结构
01
02
03
中断控制器
中断控制器是单片机中断 系统的核心部件,负责管 理中断的响应、优先级和 向量。
中断源
中断源是指能够触发中断 的信号源,如定时器溢出 、串行通信接收到数据等 。
中断优先级和向量
中断优先级决定了中断的 优先级,而向量则是指中 断处理程序的入口地址。
中断源
定时器溢出
当定时器计数达到最大值时,会触发一个中断,用于定时器 溢出处理。
THANKS。
解决方法
解决中断丢失问题需要从以下几个方面入手:首先,检查中断优先级设置,确保优先级 正确且没有重叠;其次,优化ISR的编写,避免在ISR中执行耗时的操作,确保ISR简洁 高效;最后,如果问题依然存在,可以尝试在外部硬件上加装抗干扰措施,如滤波电容

XS128单片机实验中断扫描控制循环速度

XS128单片机实验中断扫描控制循环速度

XS128单片机实验:中断扫描控制循环速度PORTA端口与1个8位拨码开关连接,PORTB端口与8只LED连接,IRQ引脚与一个按键链接,按键按下为低电平。

要求中断源触发,8位拨码开关控制8只LED灯的循环点亮速度。

///////////////////////////////////////////////// ///////////////////////////////////////////////// ///////////////////////////////////////////////// 有一个现象一直困扰着我,当中断按键按下时,程序会整个中断,BDM下载器仿真环境停止;这个原因已经找到了,因为,E0口是非屏蔽中断,E1口是可屏蔽中断,所以要接E1口。

///////////////////////////////////////////////// ///////////////////////////////////////////////// ///////////////////////////////////////////////// /#include ;/* common defines and macros */#include "derivative.h"/* derivative-specific definitions */#include "WQ.h"uchar IRQ_flag;/************************************************ *****************//功能:中断触发后实现流水灯的速度控制//This is the fourth program of mine//we use the interrupt to control the led************************************************* ****************//**********************IRQ 中断服务子程序***********************/#pragma CODE_SEG __NEAR_SEG NON_BANKEDvoid interrupt 6 IRQ_INT (void){IRQ_flag =1;}#pragma CODE_SEG DEFAULTvoid main(void) {uchar loop_index,loop_time;DDRA = 0X00;//A口做输入口;DDRB = 0XFF;//B口做输出口;loop_time = PORTA;loop_index=0;IRQ_flag=0;EnableInterrupts; //允许可屏蔽中断while(1){if(IRQ_flag) {IRQ_flag=0;loop_time=PORTA;}switch(loop_index){case 0:PORTB = 0xFE; break; case 1:PORTB = 0xFD; break;case 2:PORTB = 0xFB; break;case 3:PORTB = 0xF7; break; case 4:PORTB = 0xEF; break; case 5:PORTB = 0xDF; break; case 6:PORTB = 0xBF; break; case 7:PORTB = 0x7F; break;}loop_index++;if(loop_index==8) {loop_index =0;}delay_1(loop_time);}}。

飞思卡尔16位单片机9S12XS128使用(一些初始化)

飞思卡尔16位单片机9S12XS128使用(一些初始化)

飞思卡尔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口上去。

飞思卡尔MC9S12XS128(定时器)ECT寄存器详解

飞思卡尔MC9S12XS128(定时器)ECT寄存器详解

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端口上。

飞思卡尔2014mc9s12xs128学习及智能车制作笔记

飞思卡尔2014mc9s12xs128学习及智能车制作笔记

S128学习笔记(一)GPIO 模块S128 IO操作主要有三个寄存器数据寄存器(PORTX)数据方向寄存器(DDRX) 上拉上拉电阻控制寄存器PUCR)一. GPIO概述通用I/O:GPIO(General Purpose I/O),是I/O的最基本形式,它是一组输入或输出引脚,有时也称为并行I/O(parallel I/O)。

作为普通输入引脚,MCU内部程序可以读取该引脚,知道该引脚是“1”(高电平)或“0”(低电平),即开关量输入。

作为普通输出引脚,MCU内部程序由该引脚输出“1”(高电平)或“0”(低电平),即开关量输出。

大多数通用I/O引脚可以通过编程来设定工作方式为输入或输出,称之为双向通用I/O。

2. I/O口的使用方法MC9S12DG128 MCU有10个普通I/O口,分别是A口、B口、E口、H口、J口、K口、M 口、P口、S口、T口。

这些引脚中的大部分具有双重功能,其中A、B、E、K口只用做GPIO 功能,这里仅讨论它们编程方法。

使用这些I/O口主要设置如下寄存器:1)数据方向寄存器(Data Direction Register x,DDRx)DDRx的第7~0位分别记为DDRx7~DDRx0,这些位分别控制着x口引脚PORTx7~PORTx0是输入还是输出,若DDRxn=0,则引脚PORTAxn为输入,若DDRxn=1,则引脚PORTxn为输出。

复位时DDRx为$00。

(注:x代表A、B、E、K口中的某一个,n表示某一位)2)数据寄存器(Port x I/O Register,PORTx)PORTx的第7~0位分别记为PORTx7~PORTx0。

若A口的某一引脚PORTxn被定义。

成输出,程序使x口I/O寄存器PORTx的相应位PORTxn=0,则引脚PORTxn输出“低电平”;程序使PORTxn=1,则引脚PORTxn输出“高电平”。

若x口的某一引脚PORTxn被定义成输入,程序通过读取x口I/O寄存器PORTx,获得输入情况,0表示输入为“低电平”,1表示输入为“高电平”。

XS128智能车程序流程

XS128智能车程序流程

XS128智能车整体程序流程图
初始化过程电机启动前2s内完成工作
初始化完成工作
1、初始化锁相环倍频72MHz;
2、设定5个中断优先级分别是SCI0(串口接收中断)、PIT0(速度采集中断)、
TIM0(图像采集行[HREF]中断)、TIM1(图像采集场[VSYNC]中断)、PIT2(启动定时中断);
3、完成舵机初始化设初值为中间值并启动;
4、完成电机初始化设初值为0不启动(在启动定时中断服务程序中启动);
5、完成串口初始化、不启动接收中断
6、完成速度采集初始化、不启动中断
7、完成图像采集初始化、启动场中断,进入场中断服务程序后启动行中断
8、完成参数读入初始化、在PORTA端口读入;
9、完成启动定时初始化、启动定时中断;
10、开启中断使能。

启动定时中断服务程序中完成工作
1)根据电机启动前摄像头适应场地采集的图像计算出的图像二值化阈值并设定
阈值;并根据路径识别给出电机目标值
2)关闭启动定时中断;
3)启动速度采集控制中断;
4)启动串口接收中断;
5)启动电机。

系统初始化部分列表
小车启动后程序运行流程
1.进入图像场中断
2.。

xs128单片机的简单定时中断

xs128单片机的简单定时中断

基于飞思卡尔xs128单片机的简单定时中断(PIT)2009-10-08 21:47:40刚开始接触这款单片机,由于看的书基本上都是以dg128为原型来讲解的,故很多东西都是按照dg128的情况来移植到xs128上的,导致出了很多错误。

像定时器模块这部分,查了很多资料,最后发现xs128没有dg128所具有的MDC模数计数器模块,相对应的是定时模块PIT,然后在网上疯狂的找了很多资料,总结下来,自己花了一晚上弄了个最最简单的定时中断程序,实现1秒钟LED灯的闪烁。

PIT说明:S12PIT24B4CV1是一个模数递减计数器。

首先给计数寄存器设定一个初值,每经过一个总线周期,计数器进行一次减一操作,当计数器自减溢出时,触发中断。

因为总线周期是已知的,即可以通过计数器自减实现定时。

在XS128PIT模块中,需要用到得是如下几个寄存器。

1)、PIT Contorl and force Lad Micro Timer Register(PITCFLMT)该寄存器用于PIT模块的使能设置和工作方式设置。

通常设置该寄存器中的PITE为即可,即PITCFLMT_PITE=1,使PIT使能。

2)、PIT Channel Enable Register(PITCE)该寄存器用于对PIT模块中的4个通道使能进行设置。

如果使用某个通道时,对对应位进行置一即可,即PITCE_PCEx=1,其中x代表通道序号,为0~3。

3)、PIT Micro Timer Load Register 0 to 1 (PITMTLD0-1)该寄存器用于设置PIT模块中的8位计数器初值,以实现24位的计数。

设定值为0到255范围。

4)、PIT Load Register 0 to 3(PITLD0-3)该寄存器用于设置PIT模块中的16位计数器初值,和8位计数器配合而成24位计数器。

设定值范围0-65535。

5)、PIT Multiplex Register(PITMUX)该寄存器对定时器通道的8位时基进行选择。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#pragma CODE_SEG __NEAR_SEG NON_BANKED void interrupt { PulseCnt++; TFLG1=0X01; PORTB=~PulseCnt; } #pragma CODE_SEG DEFAULT //在 PORTB 显示脉冲数 IC0_ISR(void)
基于飞思卡尔 xs128 单片机的简单定时中断(PIT)
刚开始接触这款单片机,由于看的书基本上都是以 dg128 为原型来讲解的,故 很多东西都是按照 dg128 的情况来移植到 xs128 上的,导致出了很多错误。像 定时器模块这部分,查了很多资料,最后发现 xs128 没有 dg128 所具有的 MDC 模数计数器模块,相对应的是定时模块 PIT,然后在网上疯狂的找了很多资料, 总结下来,自己花了一晚上弄了个最最简单的定时中断程序,实现 1 秒钟 LED 灯的闪烁。 PIT 说明: S12PIT24B4CV1 是一个模数递减计数器。首先给计数寄存器设定一个初值, 每经过一个总线周期,计数器进行一次减一操作,当计数器自减溢出时,触发中 断。因为总线周期是已知的,即可以通过计数器自减实现定时。 在 XS128PIT 模块中,需要用到得是如下几个寄存器。 1)、PIT Contorl and force Lad Micro Timer Register(PITCFLMT) 该寄存器用于 PIT 模块的使能设置和工作方式设置。通常设置该寄存器中的 PITE 为即可,即 PITCFLMT_PITE=1,使 PIT 使能。 2)、PIT Channel Enable Register(PITCE) 该寄存器用于对 PIT 模块中的 4 个通道使能进行设置。 如果使用某个通道时, 对对应位进行置一即可,即 PITCE_PCEx=1,其中 x 代表通道序号,为 0~3。 3)、PIT Micro Timer Load Register 0 to 1 (PITMTLD0-1) 该寄存器用于设置 PIT 模块中的 8 位计数器初值, 以实现 24 位的计数。 设定 值为 0 到 255 范围。 4)、PIT Load Register 0 to 3(PITLD0-3) 该寄存器用于设置 PIT 模块中的 16 位计数器初值,和 8 位计数器配合而成 24 位计数器。设定值范围 0-65535。 5)、PIT Multiplex Register(PITMUX) 该寄存器对定时器通道的 8 位时基进行选择。因为 8 位计数器只有两个,所 以在将 8 位计数器和 16 位计数器连接时,可以选择不同的 8 位时基。 当设置为 0 时,对应通道选择时基 0;置一时,对应通道选择时基 1。 如 PITMUX_PMUX0=1 为通道 0 选择时基 1。 6)、PIT Interrupt Enable Register(PITINTE) 该寄存器为中断使能寄存器,为不同的 PIT 通道中断使能。设定为 0 时,相 应通道中断禁止。置一时,相应通道使能。 如 PITINTE_PINTE0=1 时, PIT 通道 0 定时中断使能, 当计数器递减溢出时, 申请中断。 7)、PIT Time-Out Flag Register(PITTF) 该寄存器为溢出标志位,当某一通道的 8 位计数器和 16 位计数器递减到 0 时,该位置一。给改位写 1 则清除该标志位。 可以通过查询该位来判断定时是否完成。
S12 系列的定时器模块是在标准定时器模块(Standard Timer Module,TIM)的 基础上增加了一些功能,称为增强型定时器模块(Enhanced Capture Timer Module,ECT).
ECT 功能:1)高速 I/O 口 2)一个 16 位自由运行计数器 3)八个 16 位输入捕捉(IC)/输出比较(OC) 通道 4)一个 16 位脉冲累加器 5)Байду номын сангаас个 16 位模数递减计数器(MDC)
void PIT_init(void)//定时中断初始化函数 5MS 定时中断设置 { PITCFLMT_PITE=0; //定时中断通道 0 关 PITCE_PCE0=1;//定时器通道 0 使能 PITMTLD0=160-1;//8 位定时器初值设定,160 分频,在 32MHzBusClock 下, 为 0.2MHz。即 5us PITLD0=PITTIME-1;//16 位定时器初值设定。PITTIME*0.005MS PITINTE_PINTE0=1;//定时器中断通道 0 中断使能 PITCFLMT_PITE=1;//定时器通道 0 使能 } void main(void) { /* put your own code here */ setbusclock(); PORTB_init(); PIT_init(); EnableInterrupts; for(;;) { _FEED_COP(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */ }
代码如下: #include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #define PITTIME 1000//设定为 5ms 定时 uchar count=0; void setbusclock(void) //32MHz 外部时钟 16MHz { CLKSEL=0X00; // disengage PLL to system PLLCTL_PLLON=1; // turn on PLL
#pragma CODE_SEG __NEAR_SEG NON_BANKED //指示该程序在不分页区 void interrupt 66 PIT0(void) { count++; if(count==200) { PORTB=~PORTB;//输出取反 count=0; } PITTF_PTF0=1;//清中断标志位 }
程序中要注意的问题:
1、头文件 derivative.h 中包含为: #include <MC9S12XS128.h> #pragma LINK_INFO DERIVATIVE "MC9S12XS128" 这是 Codewarrior5.0 版本中的默认设置。 2、 设置 PLL 时钟时 SYNR 和 REFDV 须按照给的程序当中来设置,若按照程序 注释中来设置的话时钟将出现很大误差,原因我不知道,我是不断测试得到的。 3、具体的寄存器要根据给定的对应的头文件,不同的 IDE 版本中 xs128 的头文 件可能不同,应根据实际情况来写。
我想说说做智能车中应该能用到的功能 1、 输入捕捉: 4 个缓冲通道 IC0-IC3(引脚 PT0-PT3) , 4 个非缓冲通道 IC4-IC7 (引脚 PT4-PT7) 区别:缓冲和非缓冲都有一个捕捉寄存器,而 缓冲通道还有一个保持寄存器。
例程:利用 IC 对通道 0 的脉冲信号进行计数,并在 PORTB 端口显示脉冲 数 #include <hidef.h> #include <MC9S12XS128.h> #pragma LINK_INFO DERIVATIVE "mc9s12xs128" unsigned char PulseCnt; void main(void) { DDRB=0XFF; PORTB=0XFF; asm sei; TIOS=0X00; TSCR1=0X80; //设置 PORTB 为输出 //PORTB 端口的初始值 //关闭所有中断 //设置 ECT 通道 0 为 IC 工作方式 //定时器使能,正常工作
SYNR =0x40 | 0x03; REFDV=0x80 | 0x01; //SYNR =1; //PLLCLK=2*fOSC*(SYNR + 1)/(REFDV + 1) //REFDV=1;
POSTDIV=0x00; // 4:0, fPLL= fVCO/(2xPOSTDIV) // If POSTDIV = $00 then fPLL is identical to fVCO (divide by one). _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; } void PORTB_init(void)//IO 口初始化,B 口为输出 { DDRB=0xFF; PORTB=0x00; }
TSCR2=0X01; TCTL4=0X02; TIE=0X01; TFLG1=0X01; DLYCT=0X01; PulseCnt=0X00; asm cli; for(;;){} }
//禁止定时器溢出中断,预分频系数为 2 //捕捉下降沿 //允许 ECT 通道 0 中断 //清中断标志 //延迟 //计脉冲数变量初始值
相关文档
最新文档