电赛MSP430知识小结

2024-05-10 16:58
文章标签 知识 小结 msp430 电赛

本文主要是介绍电赛MSP430知识小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(转)今年的电赛对TI公司生产的MSP430系列的单片机进行了初步的学习,第一次参加电赛,知识量不足,所以在此对资料进行了总结,旨在留存一下知识,以便在今后的学习中,可以有所回忆,减少时间的消耗,算是见见同志第一个菜鸟篇学习日志,菜鸟先飞,也希望能帮助初学MSP430单片机的同学,仅仅适合初学者,且只介绍我涉及到的方面,谢谢大家支持原创。

我使用的是Launchpad MSP430G2553开发板:有14个I/O口和10位A/D

一:编译软件

编译软件可以使用IAR和CCS两种,CCS体积较大,IAR针对性强,见见同志使用的是IAR for MSP430

相关的官方下载链接如下:

http://www.iar.com/en/Service-Center/Downloads/;下载过后使用注册机破解一下,注册机上百度搜索一个适合版本的,找一个就行;具体的IAR操作方法没办法附加在附件中,

给个IAR说明的下载链接:http://download.csdn.net/detail/tushuguan2/3986147 ,名字:《手把手教你使用TI MSP430 LaunchPad》

或者上新浪的下载链接http://ishare.iask.sina.com.cn/f/23840199.html?from=dl,要用Launchpad要设置一下IAR,看链接的说明就行,我就不一一介绍了。

TI公司生产的MSP430系列单片机与普通51单片机没有很大的不同,但是其内部含有大量的寄存器,功能比较细化,可能会造成混乱,与51对比学习,可以加快学习进度;

程序编写的格式:

#include<msp430g2553.h>

Void main()

{

WDTCTL=WDTPW+WDTHOLD;//关闭看门狗。

**(程序)

}

二:通用I/O方面

P口端口寄存器:

   (1)、PxDIR   输入/输出方向寄存器(0:输入模式    1:输出模式)

   (2)、PxIN    输入寄存器输入寄存器是只读寄存器,用户不能对其写入,只能通过读取该寄存器的内容知道I/O口的输入信号。

   (3)、PxOUT  输出寄存器寄存器内的内容不会受引脚方向改变的影响。

   (4)、PxIFG   中断标志寄存器(0:没有中断请求   1:有中断请求),该寄存器有8个标志位,对应相应的引脚是否有待处理的中断请求;这8个中断标志共用一个中断向量,中断标志不会自动复位,必须软件复位;外部中断事件的时间必须>=1.5倍的MCLK的时间,以保证中断请求被接受;

   (5)、PxIES   中断触发沿选择寄存器(0:上升沿中断       1:下降沿中断)

   (6)、PxSEL   功能选择寄存器(0:选择引脚为I/O端口 1:选择引脚为外围模块功能)

   (7)、PxREN     上拉/下拉电阻使能寄存器(0:禁止  1:使能)

 

基本操作:

(1)、所有P口都可作为通用IO口使用

(2)、所有P口都可进行字节操作和位操作

 

基本操作:

(1)、所有P口都可作为通用IO口使用

(2)、所有P口都可进行字节操作和位操作

   按字节操作:

 

传统51:

P1=0X01;

输入输出直接赋值

 

 



   例 :  P1DIR=0xff;    //将P1口作为输出口                

            PIOUT=0x20;  // P1口输出0x20

            P1DIR=0x00;    //将P1口作为输入口

            data=P1IN           //读取P1口外部输入值

    按位操作:

 

传统51:

sbit P1_0=P1^0;

输入输出直接赋值

 



    例:   P1DIR=BIT0;      //将P1.0作为输出口

 

           P1OUT|=BIT0;   //P1.0输出1

           P1OUT&=~BIT0;   //P1.0输出0

P1DIR&=~BIT0  //将P1.0口作为输入

           data=P1IN&BIT0 //读取P1.0口外部输入值

 

 

举例:闪烁LED。

LaunchPad 上面自带有2 个LED,一个接在P1.0 上,一个接在P1.6 上。

我们用2 个交替闪烁。

#include<msp430g2553.h>

void main();第一个字母小写

{

WDTCTL=WDTPW+WDTHOLD;

P1DIR|=BIT0+BIT6;//设置P1.0 和P1.6 为输出

P1OUT|=BIT0;//线让LED0 亮。

while(1)

{

unsigned int i=50000;

while(i--);

P1OUT^=0x41;//对P1.0 和P1.6 取反,所以LED0 和LED1 会交替闪烁。

}

}

 

MSP430不能和51一样直接按位操作,只能通过与、或、非等逻辑运算对寄存器进行操作。这里是最大的不同,用习惯了51,再用MSP430就会感觉特别的麻烦,只要习惯就行了,没什么好办法。

 

二:中断

中断的 一般设置:

 (1)、打开、关闭局部中断:

打开局部中断一般是给想关的特殊功能寄存器相关位置1

  以P1口外部中断为例:

  打开局部中断:

     P1IE|=BIT0;//打开P1.0外部中断 ,BIT0的值为0x01,即把P1IE的第一位置1

关闭局部中断一般是给想关的特殊功能寄存器相关位置0

同样以P1口外部中断为例:

关闭局部中断:

P1IE&=~BIT0;//关闭P1.0外部中断

(2)、打开、关闭全局中断:

        _EINT();//打开总中断,相当于51的EA=1;

           _DINT();//关闭总中断,相当于51的EA=0;

(3)、各中断向量Interrupt Vectors:

#define BASICTIMER_VECTOR   (0 * 2u) /* 0xFFE0 Basic Timer */

#define PORT2_VECTOR        (1 * 2u)  /* 0xFFE2 Port 2 */

#define USART1TX_VECTOR     (2 * 2u) /* 0xFFE4 USART 1 Transmit */

#define USART1RX_VECTOR     (3 * 2u) /* 0xFFE6 USART 1 Receive */

#define PORT1_VECTOR        (4 * 2u)  /* 0xFFE8 Port 1 */

#define TIMERA1_VECTOR      (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */

#define TIMERA0_VECTOR      (6 * 2u) /* 0xFFEC Timer A CC0 */

#define ADC12_VECTOR          (7 * 2u)  /* 0xFFEE ADC */

#define USART0TX_VECTOR     (8 * 2u) /* 0xFFF0 USART 0 Transmit */

#define USART0RX_VECTOR     (9 * 2u) /* 0xFFF2 USART 0 Receive */

#define WDT_VECTOR          (10 * 2u) /* 0xFFF4 Watchdog Timer */

#defineCOMPARATORA_VECTOR  (11 * 2u) /* 0xFFF6Comparator A */

#define TIMERB1_VECTOR      (12 * 2u) /* 0xFFF8 Timer B CC1-6, TB */

#define TIMERB0_VECTOR      (13 * 2u) /* 0xFFFA Timer B CC0 */

#define NMI_VECTOR          (14 * 2u) /* 0xFFFC Non-maskable */

#define RESET_VECTOR        (15 * 2u) /* 0xFFFE Reset [HighestPriority] */

(4)、中断的嵌套:

当同时有多个中断来的时候才有优先级的考虑(优先级顺序可查看向量表)

 

 

实现中断嵌套需要注意以下几点:

1)430默认的是关闭中断嵌套的,一定要中断嵌套的话,就必须在中断服务程序中打开总中断

  msp430的指令中,_DINT()和_EINT()分别指关和开总中断。

2)当进入中断服务程序时,只要不在中断服务程序中再次开中断,则总中断是关闭的,此时来中断不管是比当前中断的优先级高还是低都不执行;

3)若在中断服务程序A中开了总中断,则可以响应后来的中断B(不管B的优先级比A高还是低),B执行完再继续执行A。注意:进入中断服务程序B后总中断同样也会关闭,如 果B中断程序执行时需响应中断C,则此时也要开总中断,若不需响应中断,则不用开中断,B执行完后跳出中断程序进入A程序时,总中断会自动打开;

4)若在中断服务程序中开了总中断,后来的中断同时有多个,则会按优先级来执行,即中断优先级只有在多个中断同时到来时才起做用!中断服务不执行抢先原则。

5)对于单源中断,只要响应中断,系统硬件自动清中断标志位,对于TA/TB定时器的比较/捕获中断,只要访问TAIV/TBIV,标志位倍被自动清除;

    

  对于多源中断要手动清标志位,比如P1/P2口中断,要手工清除相应的标志,如果在这种中断用"EINT();"开中断,而在打开中断前没有清标志,就会 有相同的中断不断嵌入,而导致堆栈溢出引起复位,所以在这类中断中必须先清标志再打开中断开关.

 

举例:1:

中断应用程序举例(外部中断):

 void interrupt_initial()

{

 P1DIR&=~BIT7;      //P1.7为输入

 P1IE|=0x80;      //P1.7中断允许

 P1IES|=0x00;     //P1.7上升沿触发

 P1IFG=0;      //P1.7中断标志清除,对于多源中断必须先清中断标志再打开中断

 _EINT();       //总中断允许

}

#pragmavector=PORT1_VECTOR

__interruptvoid Port_1(void)

{

  P1IFG&=~BIT7;  //P1.7中断标志清除

/*在此写中断服务子程序*/

}

如果想写中断的嵌套,或者几个中断一起作用,我电赛就是写的按键中断、定时器中断:

举例2:(部分)

//------------------------按键初始化-----------------------------------------------------------------

 

 voidKey_init(void)

      {

          P1REN |= BIT3;        //打开上拉,电路板上没有上拉电阻,触发边沿是从高电平到低电平

          P1IES |= BIT3;       //选择触发边沿,从高电平到低电平

 

          P1IFG &= ~BIT3;      //清除P1.3的中断标志位(可以不清除,为了确保初始化之后为标志位不会触发中断)

          P1IE  |= BIT3;       //打开P1的中断

          

          P1REN |= BIT2;        //打开上拉,电路板上没有上拉电阻,触发边沿是从高电平到低电平

          P1IES |= BIT2;       //选择触发边沿,从高电平到低电平

 

          P1IFG &= ~BIT2;      //清除P1.2的中断标志位(可以不清除,为了确保初始化之后为标志位不会触发中断)

          P1IE  |= BIT2;       //打开P1的中断 

      }

 

 

//函数名称:main()

//功    能:主函数

//-----------------------------------------------------------------------------------------

void main(void)

{

//uchar i,j,t;

   Initial(); //初始化子程序

   Ht1621_Init(); //上电初始化LCD

   Key_init();  //调用IO中断初始化函数

   init_ADC10();

   TACTL=TASSEL1+MC1+TACLR;//定时器时钟源为SMCLK,up,不分频,清零

   CCTL0|=CCIE;//使能比较器中断

   CCR0=50000;// 计数器终值

   __enable_interrupt();//使能全局中断,C编译器中的内部函数

   _EINT();

      start_ADC10();     

          display_jiaodu();

       

   LPM1;            //进入低功耗模式1

}

 

void init_ADC10()

{

         //P1SEL|= 0xFF;

         ADC10AE0|= 0x70;//使用P1.0,1.1,1,2  AD转换

         ADC10CTL0= ADC10ON + MSC + SREF_0 + REFON;

         //开AD内核,选择电源为参考电压

         ADC10CTL1= ADC10SSEL_0 + CONSEQ_0; //采用单通道多次采用

       _EINT(); //使能中断

      

}

 

 

void start_ADC10()

{

        

         ADC10CTL0&= ~(ADC10SC + ENC);

         ADC10CTL1&= ~INCH_3;

         ADC10CTL1|= INCH_4;

         ADC10CTL0|= ADC10SC + ENC;

         while(ADC10CTL1 & ADC10BUSY != 0)

                   ;

         result[0]= ADC10MEM;

         ADC10CTL0&= ~(ADC10SC + ENC);

         ADC10CTL1&= ~INCH_4;

         ADC10CTL1|= INCH_5;

         ADC10CTL0|= ADC10SC + ENC;

         while(ADC10CTL1 & ADC10BUSY != 0)

                   ;

         result[1]= ADC10MEM;

         ADC10CTL0&= ~(ADC10SC + ENC);

         ADC10CTL1&= ~INCH_5;

         ADC10CTL1|= INCH_6;

         ADC10CTL0|= ADC10SC + ENC;

         while(ADC10CTL1 & ADC10BUSY != 0)

                   ;

         result[2]= ADC10MEM;

         ADC10CTL0&= ~(ADC10SC + ENC);

         ADC10CTL1&= ~INCH_6;

         ADC10CTL1|= INCH_7;

         ADC10CTL0|= ADC10SC + ENC;

         while(ADC10CTL1 & ADC10BUSY != 0)

                   ;

     if (result[0]<=483)

          {

              result[0]=483;

         }

       if (result[0]>=738)

         {

              result[0]=738;

         }

      if (result[1]<=530)

         {

              result[1]=530;

         }

       if (result[1]>=776)

         {

              result[1]=776;

         }

       if (result[2]>=698)

         {

              result[2]=698;

         }

       if (result[2]<=458)

         {

              result[2]=458;

         }

}

 

#pragma vector=TIMER0_A0_VECTOR

__interrupt void Timer(void)

{

 

   //PushKey=P1IFG&BIT3;

   if(flag==0)

    {

       i++;   

       if(i==100)//定时5s

       {

          i=0;

          start_ADC10();     

          display_jiaodu();

       }

       

    }

   

   

}

#pragma vector = PORT1_VECTOR                //中断向量声明

__interrupt void Key_interrput(void)

 

 if(P1IFG&(BIT2+BIT3))                //判断是不是P1.3这个IO口产生了中断

 {   

       if(P1IFG&BIT3)

       {

 

       start_ADC10();

 

       display_jiaodu();

       P1IFG&=~BIT3;                                           

       P1IFG &= ~BIT3;//清除中断标志位,这一步一定要有。

       }

       if(P1IFG&BIT2)

       {

 

       start_ADC10();

 

       display();

       P1IFG&=~BIT2;                                           

       P1IFG &= ~BIT2;//清除中断标志位,这一步一定要有。

       }

  }

 else

 {

  P1IFG = 0x00;

 }

}

 

提到中断,就不得不提到MSP430的五种低功耗模式:   LPM0、LPM1,LPM2,LMP3,LMP4

MSP430 具有一种运行模式及5 种可利用软件来选择的低功耗操作模式。一个中断事件能够将器件从任一低功耗模式唤醒、处理请求、并在接收到来自中断程序的返回信号时恢复至低功耗模式。

以下6 种操作模式可利用软件来配置:

1、激活模式(AM)

– 所有时钟处于激活状态

2、低功耗模式0 (LPM0)

– CPU 被禁用

– ACLK 和SMCLK 仍然有效,MCLK 被禁用

3、低功耗模式1 (LPM1)

– CPU 被禁用

– ACLK 和SMCLK 仍然有效,MCLK 被禁用

– 如果DCO 不是在激活模式下被使用,则DCO 的dc 生成器被禁用

3、低功耗模式2 (LPM2)

– CPU 被禁用

– MCLK 和SMCLK 被禁用

– DCO 的dc 生成器保持启用

– ACLK 保持激活

4、低功耗模式3 (LPM3)

– CPU 被禁用

– MCLK 和SMCLK 被禁用

– DCO 的dc 生成器保持启用

– ACLK 保持激活

5、低功耗模式4 (LPM4)

– CPU 被禁用

– ACLK 被禁用

– MCLK 和SMCLK 被禁用

– DCO 的dc 生成器保持启用

– 晶体振荡器被停止

有两篇博文写的特别好,我把链接发一下,强烈推荐大家看一下,比看我这个强多了:一个是对低功耗与中断的总结,一个是全面总结

1:http://blog.sina.com.cn/s/blog_6cd2030b01017x71.html(这个还有背景音乐)

2:http://blog.sina.com.cn/s/blog_76790d7d01012tir.html

  

三:10位AD

MSP430G2553可以8路采集AD后的电压信号,采集端口是P1.0~P1.7;

粘贴一下10位AD  8路采样模块化程序8路AD的结果存储在result[]数组里;然后根据自己的程序对result[]进行计算或者显示,这个程序是从坛友幻灵那里弄来的,留给读者自己研究吧:

 

voidinit_ADC10()

{

    P1SEL |= 0xFF;

    ADC10AE0 |= 0xF0;

    ADC10CTL0 = ADC10ON + MSC + SREF_0 + REFON;

    //开AD内核,选择电源为参考电压

    ADC10CTL1 = ADC10SSEL_0 + CONSEQ_0; //采用单通道多次采用

 

}

 

 

voidstart_ADC10()

{

    ADC10CTL1 |= INCH_0;

    ADC10CTL0 |= ADC10SC + ENC; // 开始转换  开转换允许

    while (ADC10CTL1 & ADC10BUSY != 0)

              ; //判断是否转换完毕

    result[0] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC); //关转换允许才能选择通道

    ADC10CTL1 &= ~INCH_0; //通道清0

    ADC10CTL1 |= INCH_1;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    result[1] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_1;

    ADC10CTL1 |= INCH_2;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    result[2] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_2;

    ADC10CTL1 |= INCH_3;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    /*result[3] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_3;

    ADC10CTL1 |= INCH_4;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    result[4] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_4;

    ADC10CTL1 |= INCH_5;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    result[5] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_5;

    ADC10CTL1 |= INCH_6;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    result[6] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_6;

    ADC10CTL1 |= INCH_7;

    ADC10CTL0 |= ADC10SC + ENC;

    while (ADC10CTL1 & ADC10BUSY != 0)

              ;

    result[7] = ADC10MEM;

    ADC10CTL0 &= ~(ADC10SC + ENC);

    ADC10CTL1 &= ~INCH_7;*/

 

}

这篇关于电赛MSP430知识小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/977028

相关文章

[职场] 公务员的利弊分析 #知识分享#经验分享#其他

公务员的利弊分析     公务员作为一种稳定的职业选择,一直备受人们的关注。然而,就像任何其他职业一样,公务员职位也有其利与弊。本文将对公务员的利弊进行分析,帮助读者更好地了解这一职业的特点。 利: 1. 稳定的职业:公务员职位通常具有较高的稳定性,一旦进入公务员队伍,往往可以享受到稳定的工作环境和薪资待遇。这对于那些追求稳定的人来说,是一个很大的优势。 2. 薪资福利优厚:公务员的薪资和

关于CPU的一点知识

首先说一下,CPU是干啥的: CPU所负责的就是解释和运行最终转换成机器语言的程序内容 我们需要知道的CPU结构:重点需要关注寄存器 运算器 简单说就是负责运算从内存读取到寄存器中的数据,可以看作一个数据加工厂,就是对寄存器中的数据做运算,这些运算包含基本的算术和逻辑运算。 算术逻辑单元(ALU) 这个是运算器中重要的一个组成,主要负责的就是对数据的处理,从而实现对数据的算术和

泛型和Integer小结

泛型在Java.util里面找:也可对其他你使用的函数进行查阅 如下:只要函数后面跟有尖括号<>,你都可以拿过来使用泛型     注意:用到集合时尽量使用泛型       int与Integer   integer这个不是关键字,是java的一个类。也就是int的包装类。int是基本数据类型,integer是引用类型,包含很多属性和方法,而int只是一个值,没有其他的任何

计算机组成入门知识

前言👀~ 数据库的知识点先暂且分享到这,接下来开始接触计算机组成以及计算机网络相关的知识点,这一章先介绍一些基础的计算机组成知识 一台计算机如何组成的? 存储器 CPU cpu的工作流程 主频 如何衡量CPU好坏呢? 指令 操作系统 操作系统功能 操作系统"内核"  如果各位对文章的内容感兴趣的话,请点点小赞,关注一手不迷路,如果内容有什么问题的话,欢迎各位

【Flink metric】Flink指标系统的系统性知识:以便我们实现特性化数据的指标监控与分析

文章目录 一. Registering metrics:向flink注册新自己的metrics1. 注册metrics2. Metric types:指标类型2.1. Counter2.2. Gauge2.3. Histogram(ing)4. Meter 二. Scope:指标作用域1. User Scope2. System Scope ing3. User Variables 三.

基础C语言知识串串香11☞宏定义与预处理、函数和函数库

​ 六、C语言宏定义与预处理、函数和函数库 6.1 编译工具链 源码.c ——> (预处理)——>预处理过的.i文件——>(编译)——>汇编文件.S——>(汇编)——>目标文件.o->(链接)——>elf可执行程序 预处理用预处理器,编译用编译器,汇编用汇编器,链接用链接器,这几个工具再加上其他一些额外的会用到的可用工具,合起来叫编译工具链(gcc就是一个编译工具链)。 gcc中各选项

什么是慢查询——Java全栈知识(26)

1、什么是慢查询 慢查询:也就是接口压测响应时间过长,页面加载时间过长的查询 原因可能如下: 1、聚合查询 2、多表查询 3、单表数据量过大 4、深度分页查询(limit) 如何定位慢查询? 1、Skywalking 我们可以通过 Skywalking 来看到是哪个请求的哪个查询的时间执行时间过长。 2、Mysql 自带的慢日志查询 慢查询日志记录了所有执行时间超过指定参数(long

JavaSE基础总结复习之面向对象の知识总结

目录 Java语言的基础特点 面向对象 类和对象 类 类的构造 一,发现类 二,发现类的共有属性(成员变量) 三,定义类的成员方法(行为,动词) 四,使用类创建对象 对象 什么是对象 如何创建对象 类和对象的关系 构造方法 特点 作用 对象与引用 值传递: 引用传递: 关键字 this关键字 static关键字 static--静态 static修饰

【java问答小知识19】一些Java基础的知识,用于想学习Java的小伙伴们建立一些简单的认知以及已经有经验的小伙伴的复习知识点

Java中的"java.util.concurrent.locks.StampedLock"的"tryConvertToReadLock()"方法如何工作? 回答:尝试将当前的写锁转换为读锁,并返回一个表示锁定状态的戳记。 Java中的"java.util.concurrent.locks.StampedLock"的"tryConvertToWriteLock()"方法有什么特点?

我的OS X系统使用小结

最近硬盘出现了故障,为了恢复确认问题,我的Windows电脑就一直运行坏道检测程序,暂时将工作迁移到我的MacBook Pro(后面简称为MBP)上进行。这里简单总结下自己是如何使用MBP进行做的。 原本计划是用我的小米游戏笔记本,但是不知为何,即便是非游戏模式,风扇偶尔也会狂转,产生很大的噪音。相反,MBP非常安静,就是有点烫手。 我的MBP是17年款,13寸屏幕,蝶式键盘。为了不烫手