历史上的今天
返回首页

历史上的今天

今天是:2025年03月10日(星期一)

正在发生

2020年03月10日 | [MSP430] 2.中断和计时器

2020-03-10 来源:eefocus

在这一部分中我们将会初步了解到中断的概念及其作用, 我们会尝试使用计时器中断和 I/O 中断操作 LED 灯,让我们开始吧!


什么是中断?我们可以将它理解为一个约定的信号,来告知单片 机特定的事件发生了,引起程序从正常运行的主函数中断开,转而 执行中断处理程序,处理特定的事件。

中断是一个非常重要的概念,它可以让处理器免于执行冗余的轮 询操作等待特定的外部事件的发生。在 MSP430 的架构中,有许 多种类的中断:计时器中断,I/O 中断,ADC 中断等等。每一种中 断在使用前都要使能和配置,每一种中断又分别有中断处理程序 (Service Routine)。

下面就让我们尝试写一个小程序,实现使用计时器中断和 I/O 中 断操作 LED 灯。


#include "msp430g2553.h" void main(void)

{

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

按照惯例,首先包含 g2553 的头文件,关闭看门狗。每次写程序的时候你总会用到它们。

  CCTL0 = CCIE;  // CCR0 interrupt enabled

  TACTL = TASSEL_2 + MC_1 + ID_3;  // SMCLK/8, upmode

  TACCR0 = 10000;  // 12.5 Hz

这几行简单配置了计时器中断。


  CCTL0 = CCIE;  // CCR0 interrupt enabled

我们首先通过置 CCTL0(Timer_A capture/compare control 0)寄存器的 CCIE 位(Capture/compare interrupt enable)使能了计时器中断。

  TACTL = TASSEL_2 + MC_1 + ID_3;  // SMCLK/8, up mode

然后我们通过 TACTL(Timer_A control)寄存器配置了计时器的时钟。如果查阅一下 MSP430 的手册,你会看到之后几位分别表示什么含义:

TASSEL_2 选择了 SMCLK 时钟(由内部 DCO 支持,默认频 率大约为 1MHz);

MC_1 选择了上升模式(up mode),即计时器计数的时候由小 至大,计数上限由 TACCR0(Timer_A capture/compare 0)寄存器决定。

由此就有


  TACCR0 = 10000;  // 12.5 Hz

你一定猜到了配置的结果 12.5Hz 是怎么得来的了吧, 1M/8/10000=12.5Hz,这就是产生计时器中断的频率。

通过选择不同的时钟源,不同的时钟分频,不同的计数上限,你几乎可以配置出任何你想要的频率,需要注意的是,MSP430的寄存器都是16 位的,所以 TACCR0 的上限是 65535。

我们继续完善我们的程序。


  P1OUT &= 0x00;  // Shut down everything P1DIR &= 0x00;

  P1DIR |= BIT0 + BIT6;  // P1.0 and P1.6 pins output 

  P1REN |= BIT3; // Enable internal pull-up/down resistors

  P1OUT |= BIT3;  // Select pull-up mode for P1.3

这几行代码我们应该已经熟悉了。我们首先清空了 PORT1 的输 出寄存器和方向寄存器,然后配置板上两个 LED 所对应引脚为输出, 为按键对应的引脚配置上拉电阻。


  P1IE |= BIT3;  // P1.3 interrupt enabled

  P1IES |= BIT3;  // P1.3 Falling edge

  P1IFG &= ~BIT3;  // P1.3 IFG cleared

这几行代码中,我们首先使能了 P1.3 引脚的中断功能,然后我 们选择了下降沿触发中断(高电平到低电平触发),Launchpad 上的按键在不按下的时候连接着 VCC,而按下的时候连接的是 GND,因此我们选择下降沿触发。最后,我们要清除相应的中断标 志位。中断标志位通知单片机一个中断的产生,因此在每次中断处 理程序结束后,如果我们希望下次产生事件的时候依然有中断,我 们应当清除中断标志位。


  _EINT(); // Enable all interrupts

  while(1) // Loop forever, we work with interrupts! 

    {}

打开所有中断,轻松加愉快。接下来就是中断的事儿了。


// Timer A0 interrupt service routine

#pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A0 (void) {

  P1OUT ^= BIT0;  // Toggle P1.0

}

这是 TimerA 的中断处理程序。每当计数器溢出的时候,中断触 发,程序便会执行这段代码,翻转 P1.0 的输出,对应地,LED1 会 出现闪烁的效果。每次翻转之后,程序便会回到触发中断的地方, 在本例中,回到 While(1)。

// Port 1 interrupt service routine

#pragma vector=PORT1_VECTOR __interrupt void Port_1(void) {

  P1OUT ^= BIT6;  // Toggle P1.6

  P1IFG &= ~BIT3;  // P1.3 IFG cleared

}

这是PORT1的中断处理程序,每当我们按下P1.3对应的按键时,中断触发,程序便会执行这段代码,效果如同在前一节中演示的一样。


烧代码看效果吧!


以下是这一节的完整代码:


#include "msp430g2553.h" 

void main(void)

{

  WDTCTL = WDTPW + WDTHOLD;

  CCTL0 = CCIE;  // CCR0 interrupt enabled

  TACTL = TASSEL_2 + MC_1 + ID_3;  // SMCLK/8, upmode

  TACCR0 = 10000;  // 12.5 Hz

  P1OUT &= 0x00;  // Shut down everything

  P1DIR &= 0x00;

  P1DIR |= BIT0 + BIT6;  // P1.0 and P1.6 pins output

  P1REN |= BIT3;  // Enable internal pull-up/down resistors

  P1OUT |= BIT3;  // Select pull-up mode for P1.3

  P1IE |= BIT3;  // P1.3 interrupt enabled

  P1IES |= BIT3;  // P1.3 Falling edge

  P1IFG &= ~BIT3;  // P1.3 IFG cleared

  _EINT();  // Enable all interrupts

  while(1)  // Loop forever, we work with interrupts!

  {}

}

 

// Timer A0 interrupt service routine

#pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A0 (void) {

  P1OUT ^= BIT0;  // Toggle P1.0

}

 

// Port 1 interrupt service routine

#pragma vector=PORT1_VECTOR __interrupt void Port_1(void) {

  P1OUT ^= BIT6;  // Toggle P1.6

  P1IFG &= ~BIT3;  // P1.3 IFG cleared

}

推荐阅读

史海拾趣

Daniel Woodhead公司的发展小趣事

随着公司业务的不断拓展,Daniel Woodhead公司意识到人才是企业发展的核心。因此,公司加大了对研发团队的投入,引进了一批业界顶尖的技术人才。这些人才的加入不仅为公司带来了更多的创新思路,还提高了整体的技术水平。在团队的共同努力下,公司不断推出具有竞争力的新产品,进一步巩固了市场地位。

General Cable公司的发展小趣事
在红外遥控应用中,通信距离可能受到发射功率、接收灵敏度、环境光干扰等因素的影响。解决方法包括增加发射功率(在允许范围内)、使用更高灵敏度的接收头、优化发射和接收角度等。
General Instrument公司的发展小趣事
在某些情况下,突然断电可能引发安全隐患,如正在运行的设备突然停止可能导致事故。
埃派克森微电子(Apexone)公司的发展小趣事

作为一家具有社会责任感的企业,埃派克森微电子在发展过程中始终关注社会公益事业。在四川汶川地震发生后,公司积极发起救援捐赠活动,通过中国扶贫基金会为灾区捐款10万元,帮助受灾民众度过难关。这一行动体现了埃派克森的社会责任感和人文关怀精神,也为公司在社会中树立了良好的形象。

这五个故事展示了埃派克森微电子在电子行业中的发展历程和取得的成就。从创新起步到专利技术的突破与商用,再到业绩的连续增长和国际化步伐的加快,以及积极履行社会责任的公益行动,都充分展现了埃派克森微电子的实力和担当。未来,随着科技的不断进步和市场需求的不断变化,埃派克森微电子将继续保持创新精神,不断提升产品性能和市场竞争力,为电子行业的发展做出更大的贡献。

Embedded Planet公司的发展小趣事

作为一家负责任的企业,Embedded Planet公司一直将绿色环保理念融入产品设计和生产过程中。公司积极采用环保材料和技术,努力降低产品对环境的负面影响。同时,公司还倡导员工参与环保活动,共同为地球的可持续发展贡献力量。这些环保实践不仅提升了公司的社会形象,也为公司赢得了更多客户的信任和支持。

DAVE Embedded Systems公司的发展小趣事

DAVE Embedded Systems公司于1998年在意大利创立,其初衷是提供嵌入式系统解决方案。在成立初期,公司只有几名工程师和有限的资金,但他们凭借对技术的热爱和对市场的敏锐洞察力,成功设计并销售出了第一款基于微处理器和Linux平台的嵌入式系统模块(SOM)。这款产品因其高性价比和出色的性能,很快赢得了市场的认可,为公司的发展奠定了基础。

问答坊 | AI 解惑

TI芯片选型指南

相信很多工程师都在用TI的产品 本人在此分享一下官网公布的选型指南 希望对面临选型困惑的工程师有帮助 http://focus.ti.com.cn/cn/analog/docs/selectionguides.tsp…

查看全部问答>

【藏书阁】数字信号处理课件

第00章 数字信号处理 绪论 27页 0.5M PDF格式.pdf 第01章 离散时间信号与离散时间系统基础 71页 1.7M PDF格式 .pdf 第02章 Z变换及离散系统分析 43页 1.1M PDF格式.pdf 第03章 离散傅立叶变换 65页 1.4M PDF格式.pdf 第04章 附:关于图象压缩 4 ...…

查看全部问答>

如何在WM5.0上安装sqlite?

如题:如何在WM5.0上安装sqlite?    wce上又该怎么装?…

查看全部问答>

printk奇怪问题,请高手指点!

小弟我在调试网卡驱动的时候写了下面语句:             static   long   long   count   =   0;           stati ...…

查看全部问答>

电路板打样超级便宜

最近发现一个做电路板便宜的地方  www.sz-jlc.com/o   5*5cm以内50元 10*10以内100元 到现在为止最便宜的了 分享一下哈哈…

查看全部问答>

ST10技术资料

有关ST10的技术资料介绍,请参考:http://mcu.st.com/mcu/inchtml.php?fdir=pages&fnam=st10http://mcu.st.com/mcu/modules.php?name=mcu&file=familiesdocs&FAM=17ST10的中文手册书籍(类似ST7一样)不久也会面世了!!…

查看全部问答>

CC3000 wifi模块有木有

soso姐,帮我问一下TI办事处,CC3000什么时候搞一个活动哈,我看了TI 官网的宣传片了,我想要学习一下wifi的实时性能,我看他的DEMO 的是实时性还可以呀…

查看全部问答>

纽扣电池请教

关于纽扣电池,使用万用表测试其两端电阻,发现只有几欧姆的样子,这个是正常的吗?此外,想请教一下,如果我将纽扣电池串接在5V的电压源上放电,当串联电压降低后可以认为其电流都出自纽扣电池内吗?…

查看全部问答>