完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 michael_llh 于 2020-2-24 11:12 编辑 MSP430教程之四 上次和大家聊到了GPIO的使用,但是讲的不是很全面,要是全面涉及的话就是我们后面要讲的内容了,这里我们就不多加描述。在后期的讲解中也会慢慢涉及我们没有讲到的一些功能的。今天我们要涉及一个对于单片机来说非常重要的一个概念和功能。 什么是中断? 我们不以专业术语来描述这个东西,我们以一个比较好理解的方式来讲。首先大家要有一个理解就是我们单片机是按照程序一步一步的执行的,通过仿真的时候大家也可以看出来我们点击单步运行我们就可以看到光标向下移动一步,也就是单片机向下移动一步。就是单步运行的。就像我们人一样,你只能在一个时刻内做一件事情,没有办法说一边吃饭一边喝水吧(极短的时刻内你不行的吧),当你要做另外一件事的时候,你需要把手上这件事停下来去做另外一件事,对吧,这样子我们就产生了一个中断的概念,但我们在写作业的时候需要去把烧开的水关掉,就需要停止手头的事情去关掉开水。对于单片机来说也是这样的,我们看到我们之前写的程序中,都会有一个死循环,for(;;),这个是C语言的东西我们就不在过多描述了,在这个死循环里面做我们的动作,但是这是如果系统告诉我们需要去点亮一个灯,那单片机就需要停止死循环里面的动作,先去点灯,然后在跑回来继续执行死循环里面的代码。通过图示我们可以更加了解他的机制。 就如上图中描述的一样,当然我们也可以进行中断嵌套,也就是说在一个中断中间又进行中间又来一个优先级更高的中断,这是就会在中断当中又产生一个中断。这个我们在后头会继续再说,这里大家先知道一下他可以有这么个功能。 好了接下来我们进入中断的学习了,那么关于中断的知识我们该去哪里找呢? 还是那份文档,MSP430FR58xx, MSP430FR59xx, MSP430FR68xx, and MSP430FR69xx Family User's Guide.pdf。这份文档是十分重要的,我希望大家在写程序的时候需要打开它,查找到我们需要的那部分内容。 在第十章的10.2.6中有一个章节是Port Interrupts,这里就是讲到中断了。 插曲: 为什么我想写一个关于430的教程,前面也说到说他的资料较少,学的人感觉好像也不多,很少有人选择他作为入门的单片机学习,所以想打破这个局面。另外一个方面是他的很多资料是英文的,这个对大家是很有帮助的,在你以后进公司的时候可能面临的很多资料都不会是中文的,所以从一开始打破大家对中文的一种依赖性我觉得是很好的。虽然这样子明显难度就会大一些,我会尽量减少这个门槛的。 大家点击到这里的话就可以看到文档对中断的一个描述,我这里简单吧重点说一下,其他的大家就慢慢看一下,打开有道不懂的单词就查一下,不要觉得很烦,但是真的对你有很大的帮助。 对于430来讲,P1和P2口都是可以作为单片机的中断入口的,是由三个寄存器进行控制的。具体是PxIFG,PxIE,PxIES。有些器件可能会有些不同,具体要看他们的数据手册。 那么这三个寄存器分别是什么呢? PxIFG(Port x Interrupt Flag Register)端口x中断标志寄存器 PxIE(Port x Interrupt Enable Register)端口x中断使能寄存器 PxIES(Port x Interrupt Edge Select Register)端口x中断边沿选择寄存器 接下来我们看下怎么用它来写代码。 所限我们需要明白使用中断的一个具体的步骤是什么?(这里我们使用的是端口中断,下次我们还会谈到定时器中断) 1.配置端口,设置端口的方向,也就是设置PxDIR的方向,设置上拉下拉等 2.设置中断的触发模式,上升沿还是下降沿或者两者均可以产生中断 3.开启中断,就是设置PxIE 4.编写中断子函数 5.清除中断标志位,设置PxIFG 大概是这样的一个操作流程,但是也可能中间还会有些不同的地方。要根据具体的使用情景和方式。 这里我们要实现的是按键按下触发中断然后点亮led。这里我们使用FR5969板子上的按键S2和LED2。 第一步:还是和之前一样,需要关闭看门狗。关闭低功耗模式 WDTCTL = WDTPW + WDTHOLD; PM5CTL0 &= ~LOCKLPM5; 第二步:设置端口方向 P1DIR |= BIT0; //设置LED的方向 P1OUT &= ~BIT0;//设置LED的默认输出,为低电平不点亮 P1DIR &= ~BIT1;//这一步可以省略,但是我们最好都写,默认端口为输入 P1REN = BIT1;//设置按键的上拉电阻 第三步:配置中断 P1IES |= BIT1;//设置按键中断为下降沿触发 P1IE |= BIT1;//使能中断 最后我们还要使能总中断: _enable_interrupts(); 第四步: 我们要编写中断子函数: #pragma vector = PORT1_VECTOR __ interrupt void PORT1_ISR(void) { Unsigned int Key = 0; Key = P1IFG & (~P1DIR); __delay_cycles(10000); If((P1IN&Key) == 0) { Switch(Key){ //Case BIT0: P10_Onclick();break; Case BIT1: P11_Onclick();break; //Case BIT2: P12_Onclick();break; //Case BIT3: P13_Onclick();break; //Case BIT4: P14_Onclick();break; //Case BIT5: P15_Onclick();break; //Case BIT6: P16_Onclick();break; //Case BIT7: P17_Onclick();break; } } P1IFG = 0;//清除中断标志位 } void P11_Onclick() { P1OUT ^= BIT0;//翻转LED的电平 } 这样子我们就完成了整个的一个中断函数的的编写,也完成了我们预期想要达到的一个目的,按下按键点亮LED。 我们大概说一下代码的书写,其实大家发现,这次代码的书写没有只写在main函数中,我们分成了几个函数,分别称为主函数和子函数,那么程序开始都是从主函数中执行的。现在我们的工程还不大,所以在一个c文件我们就可以达到我们想要的功能,但是等你的代码很复杂的话,就需要进行模块化的搭建,需要一个框架来整理整个代码结构。下一讲我们会具体讲到如何应用该方法。 #pragma vector = PORT1_VECTOR 这个中断向量定义,是固定的写法,具体为什么这么写,我们来看看。 所先#pragma是一个预处理指令,和我们#define有点类似,具体的话我也不懂希望大家给一下解释。 vector = PORT1_VECTOR 这一句我的理解是指定中断向量表的入口地址,那么这些地址定义在哪里呢?还是一样的办法,右键找到定义。在msp430FR5969.h文件中找到。 |
|
相关推荐
|
|
interrupt前面一定要又两个下划线吗,为啥我有了之后报错说差一个分号,去掉下划线之后就不报错了,但烧到单片机里不能执行功能啊
|
|
|
|
|
|
对,是两个下划线,如果有错,可能那个地方有错,你检查一下。 |
|
|
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
3032个成员聚集在这个小组
加入小组2928 浏览 1 评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3600 浏览 2 评论
请问怎么把下面51单片机的代码改成msp430 g2 pocket的代码,还有改下时间变成30秒
2341 浏览 1 评论
4804 浏览 1 评论
2573 浏览 1 评论
1328浏览 3评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3601浏览 2评论
2928浏览 1评论
1510浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 18:03 , Processed in 1.311842 second(s), Total 56, Slave 47 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号