MSP430 LaunchPad学习第一记

lyzhangxiang   2010-11-8 22:17 楼主

  前天收到了SOSO姐的板子,打开来一看板子质量很不错啊,就是不像淘宝上买的那种有光盘资。只有一张介绍的卡片,看着卡片我心情好是激动想玩玩不了。上坛子里来看看,原来有——LaunchPad.pdf的资料。讲解的很详细,虽然是E文的,不过阅读起来还不算是吃力,Ti的东西没话说。对着着篇文章好好看看,先是下载CCS(当然你可以考虑下载IAR的,不过先前没接触过CCS所幸这里也是毫无顾忌的选择了他,体会一下新东西嘛,正好430也是第一次玩虽然常常在各种网站上都能见到他的身影)

       想玩430一直是我的一个梦想,用这个词好像有点夸张了,不过的确在淘宝上看到的多是F系列的片子,加上仿真器价格真是不菲,作为学生的我难以接受。或许这就是一直没能玩上的缘故吧。这次坛子里的活动第一让我玩到了430,也让我明白了原来430G系列价格也很便宜甚至比51PIC还便宜。16位的东西且不管片上资源的多少,就冲着16位也要去玩下。记得申请这个板子好几天才收到了SOSO姐的回复(应该是我申请的方式不对,不知道为何发不到申请专栏),那时候我正做着从合肥开往芜湖的火车上(去利尔达面试也拿到了Offer,不知道利尔达怎么样,请知道详情的朋友说下吧),告知了SOSO姐我的地址,哈哈没过几天板子就来了。当天晚上就下载了很多关于这个板子的资料,多是坛子里面那位热心网友上传的。

       首先就是阅读了那个LaunchPadpdf,然后下载CCS安装完毕,其次看了一下G2211G2231的数据手册。大概有个了解之后开始玩了,打开CCS新建工程,关于CCS的操作可以下载那个视频看一下啦,基本对付了。哦忘了说了还有那个很不错的触摸板子,也有一篇很好的pdf——LaunchPad实验板触摸感应子卡使用指南。原理图以及代码示例里面都有讲解的。

    详细的操作我也不说了直接进入主题了,第一次嘛还是跑通Demo的好,毕竟我是第一次搞430,也不知道代码需要怎样去写。这里我采用的Temperature_Sense_Demo这个例子,相关代码可以在那个LaunchPad中提供的网址中下载。
 
其实我一直很困惑一个东西,说一下大家帮帮我啊,菜鸟问题:
 
#define     LED0                       BIT0
#define     LED1                       BIT6
#define     LED_DIR                 P1DIR
#define     LED_OUT                P1OUT
就是关于这个P1DIR和P1OUT当然还有P1IN等等,这些是在哪里定义的呢,我找了那个msp430x20x2.h中直接用这个不需要定义的吗?
 
后来我上网查了一下,搜索内容如下:
#define P1IN_               0x0020  /* P1 输入寄存器 */
const sfrb P1IN           = P1IN_;
#define P1OUT_              0x0021  /* P1 输出寄存器 */
sfrb    P1OUT             = P1OUT_;
#define P1DIR_              0x0022  /* P1 方向选择寄存器 */
sfrb    P1DIR             = P1DIR_;
#define P1IFG_              0x0023  /* P1 中断标志寄存器*/
sfrb    P1IFG             = P1IFG_;
#define P1IES_              0x0024  /* P1 中断边沿选择寄存器*/
sfrb    P1IES             = P1IES_;
#define P1IE_               0x0025  /* P1 中断使能寄存器 */
sfrb    P1IE              = P1IE_;
#define P1SEL_              0x0026  /* P1 功能选择寄存器*/
sfrb    P1SEL             = P1SEL_;
 
这个怎么就没找到呢,那为何P1DIR、P1OUT可以直接来用,是不是CCS和他通过某个文件约定的呢,菜鸟不懂请教了,其次在G2231的手册中有如下截图:

1.jpg
 
正好可以对上,也就是寄存器的地址吧,怎么说在头文件里面需要定义一下啊 。
还有一个叫LaunchPad_Temp_GUI的东西好像是一种类似java的语言写的吧,不是很清楚界面还不错。可惜我没能通信成功。截个图上来大家看看:


2.jpg  
等下上传源码,不要急啊 。没有成功我很失落啊 ,用串口调试助手看看数据呵呵有了:

3.jpg
 
这里的波特率需要设置为2400,不然会出错的哟。
还有这个代码设置了通过一个按钮切换APP的模式,呵呵还是很不错的一个应用Demo啊,详细的代码这里暂时就不分析了等我下次分析啊。

4.jpg

5.jpg

 

没来得急测试的界面,呵呵,等我完善啊,毕竟板子拿到手才两天。资源基本熟悉了,就等着开发了,主要还是以uart、Timer、ADC做一些开发了。

之前不知道这个G系列的诗歌入门级的片子,哈哈刚好适合我。

[ 本帖最后由 lyzhangxiang 于 2010-11-8 22:32 编辑 ]

回复评论 (37)

2推荐 lyzhangxiang 

MSP430 LaunchPad学习第一记

/******************************************************************************
* 1. 第一个按钮按下后,设备过渡到应用模式
* 2. 应用模式:
* a、连续采样ADC的温度传感器通道,对比较结果初始值
* b、将PWM根据测量ADC偏移:红色发光二极管的正偏移,绿LED为负偏移
* c、发送到PC的UART通过TimerA的温度值
* d、键按一下“ - >使用当前的温度校准
* e、通过UART发送字符'',通知电脑
******************************************************************************/
  
#include  "msp430x20x2.h"

#define     LED0                  BIT0
#define     LED1                  BIT6
#define     LED_DIR               P1DIR
#define     LED_OUT               P1OUT



#define     BUTTON                BIT3
#define     BUTTON_OUT            P1OUT
#define     BUTTON_DIR            P1DIR
#define     BUTTON_IN             P1IN
#define     BUTTON_IE             P1IE
#define     BUTTON_IES            P1IES
#define     BUTTON_IFG            P1IFG
#define     BUTTON_REN            P1REN

#define     TXD                   BIT1                      // TXD on P1.1
#define     RXD                   BIT2                      // RXD on P1.2

#define     APP_STANDBY_MODE      0   //APP待机模式
#define     APP_APPLICATION_MODE  1   //APP应用模式

#define     TIMER_PWM_MODE        0   
#define     TIMER_UART_MODE       1
#define     TIMER_PWM_PERIOD      2000   //周期
#define     TIMER_PWM_OFFSET      20

#define     TEMP_SAME             0
#define     TEMP_HOT              1
#define     TEMP_COLD             2

#define     TEMP_THRESHOLD        5     //阀值

//   Conditions for 9600/4=2400 Baud SW UART, SMCLK = 1MHz
#define     Bitime_5              0x05*4                      // ~ 0.5 bit length + small 调整
#define     Bitime                13*4//0x0D   

#define     UART_UPDATE_INTERVAL  1000  //Uart更新区间


unsigned char BitCnt;


unsigned char applicationMode = APP_STANDBY_MODE;
unsigned char timerMode = TIMER_PWM_MODE;

unsigned char tempMode;
unsigned char calibrateUpdate = 0;       //校准更新
unsigned char tempPolarity = TEMP_SAME;  //temp 极性
unsigned int TXByte;
                              
/* 使用8值的移动平均滤波器采样ADC值*/  
long tempMeasured[8];  //测量值
unsigned char tempMeasuredPosition=0; //测量位置
long tempAverage;      //平均值

long tempCalibrated, tempDifference;


  
void InitializeLeds(void);
void InitializeButton(void);
void PreApplicationMode(void);                     // 闪烁LED, 等待按键按下
void ConfigureAdcTempSensor(void);
void ConfigureTimerPwm(void);
void ConfigureTimerUart(void);  
void Transmit(void);
void InitializeClocks(void);

void main(void)
{
  unsigned int uartUpdateTimer = UART_UPDATE_INTERVAL;  //Uart更新空间
  unsigned char i;
  WDTCTL = WDTPW + WDTHOLD;                 // 停止 WDT
  
  InitializeClocks();
  InitializeButton();
  InitializeLeds();
  PreApplicationMode();                     // 闪烁LED, 等待按键按下
  
  /* 应用模式开始 */
  applicationMode = APP_APPLICATION_MODE;
  ConfigureAdcTempSensor();                //配置ADC温度传感器
  ConfigureTimerPwm();                     //配置定时器PWM
   
  __enable_interrupt();                     //使能中断
  
  
  /* 主函数应用循环 */
  while(1)
  {   
    ADC10CTL0 |= ENC + ADC10SC;             // 采样和转换开始
    __bis_SR_register(CPUOFF + GIE);        // LPM0中断使能
   
   
    /* 移动平均滤波器的8个值进行采样的ADC中有所稳定 */
    tempMeasured[tempMeasuredPosition++] = ADC10MEM;
    if (tempMeasuredPosition == 8)
      tempMeasuredPosition = 0;
    tempAverage = 0;
    for (i = 0; i < 8; i++)
      tempAverage += tempMeasured;
      tempAverage >>= 3;                      // 除以8获得平均值,此处采用右移3位实现除以8
   
    if ((--uartUpdateTimer == 0) || calibrateUpdate )
    {
      ConfigureTimerUart();
      if (calibrateUpdate)
      {
        TXByte = 248;                       // 一个具有高值的字符, 超过温度范围
        Transmit();
        calibrateUpdate = 0;
      }   
      TXByte = (unsigned char)( ((tempAverage - 630) * 761) / 1024 );      
      Transmit();
      uartUpdateTimer = UART_UPDATE_INTERVAL;
      ConfigureTimerPwm();
    }
   
   
    tempDifference = tempAverage - tempCalibrated;
    if (tempDifference < -TEMP_THRESHOLD)
    {
      tempDifference = -tempDifference;
      tempPolarity = TEMP_COLD;
      LED_OUT &= ~ LED1;
    }
    else
    if (tempDifference > TEMP_THRESHOLD)
    {
      tempPolarity = TEMP_HOT;
      LED_OUT &= ~ LED0;
    }
    else
    {
      tempPolarity = TEMP_SAME;
      TACCTL0 &= ~CCIE;
      TACCTL1 &= ~CCIE;
      LED_OUT &= ~(LED0 + LED1);        
    }
   
    if (tempPolarity != TEMP_SAME)   
    {      
      tempDifference <<= 3;
      tempDifference += TIMER_PWM_OFFSET;      
      TACCR1 = ( (tempDifference) < (TIMER_PWM_PERIOD-1) ? (tempDifference) : (TIMER_PWM_PERIOD-1) );
      TACCTL0 |= CCIE;
      TACCTL1 |= CCIE;      
    }   
  }  
}

void PreApplicationMode(void)
{   
  LED_DIR |= LED0 + LED1;
  LED_OUT |= LED0;                          // LED的切换效果
  LED_OUT &= ~LED1;
   
  BCSCTL1 |= DIVA_1;                        // ACLK/2
  BCSCTL3 |= LFXT1S_2;                      // ACLK = VLO
  
  TACCR0 = 1200;                          
  TACTL = TASSEL_1 | MC_1;                  // TACLK = SMCLK, Up mode.  
  TACCTL1 = CCIE + OUTMOD_3;                // TACCTL1 Capture Compare
  TACCR1 = 600;  
  __bis_SR_register(LPM3_bits + GIE);       // LPM0使能中断
}

void ConfigureAdcTempSensor(void)
{
  unsigned char i;
  /* 配置ADC温度传感器通道 */
  ADC10CTL1 = INCH_10 + ADC10DIV_3;         // Temp Sensor ADC10CLK/4
  ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE;
  __delay_cycles(1000);                     // 等待选择ADC参考
  ADC10CTL0 |= ENC + ADC10SC;               // 采样和转换开始
  __bis_SR_register(CPUOFF + GIE);          // LPM0使能中断
  tempCalibrated = ADC10MEM;
  for (i=0; i < 8; i++)
    tempMeasured = tempCalibrated;
  tempAverage = tempCalibrated;  
}


void ConfigureTimerPwm(void)
{
  timerMode = TIMER_PWM_MODE;
  
  TACCR0 = TIMER_PWM_PERIOD;                  
  TACTL = TASSEL_2 | MC_1;                  // TACLK = SMCLK, 截至模式.
  TACCTL0 = CCIE;
  TACCTL1 = CCIE + OUTMOD_3;                // TACCTL1捕获比较
  TACCR1 = 1;
}

void ConfigureTimerUart(void)
{
  timerMode = TIMER_UART_MODE;               // 配置 TimerA0 UART TX
                           
  CCTL0 = OUT;                               // TXD Idle as Mark
  TACTL = TASSEL_2 + MC_2 + ID_3;            // SMCLK/8, 连续模式
  P1SEL |= TXD + RXD;                        //
  P1DIR |= TXD;                              //  
}

void Transmit()
{
  BitCnt = 0xA;                             // 装载位计数器, 8data + ST/SP
  while (CCR0 != TAR)                       // 防止异步捕获
    CCR0 = TAR;                             // 当前TA计数器的状态
  CCR0 += Bitime;                           // 一些时间直到第一位
  TXByte |= 0x100;                          // 新增标记停止位TXByte
  TXByte = TXByte << 1;                     // 加空间的起始位
  CCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
  while ( CCTL0 & CCIE );                   // 等待TX完成
}



// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  if (timerMode == TIMER_UART_MODE)
  {
    CCR0 += Bitime;                            // 新增偏移量CCR0  
    if (CCTL0 & CCIS0)                         // TX on CCI0B?
    {
      if ( BitCnt == 0)
        CCTL0 &= ~ CCIE;                      // All bits TXed, 失能中断
      else
      {
        CCTL0 |=  OUTMOD2;                    // TX Space
        if (TXByte & 0x01)
        CCTL0 &= ~ OUTMOD2;                   // TX Mark
        TXByte = TXByte >> 1;
        BitCnt --;
      }
    }
  }
  else
  {
    if (tempPolarity == TEMP_HOT)
      LED_OUT |= LED1;   
    if (tempPolarity == TEMP_COLD)      
      LED_OUT |= LED0;
    TACCTL0 &= ~CCIFG;              
  }
}

#pragma vector=TIMERA1_VECTOR
__interrupt void ta1_isr(void)
{
  TACCTL1 &= ~CCIFG;
  if (applicationMode == APP_APPLICATION_MODE)
    LED_OUT &= ~(LED0 + LED1);
  else
    LED_OUT ^= (LED0 + LED1);
   
}

void InitializeClocks(void)
{

  BCSCTL1 = CALBC1_1MHZ;                        // 设定范围
  DCOCTL = CALDCO_1MHZ;
  BCSCTL2 &= ~(DIVS_3);                         // SMCLK = DCO / 8 = 1MHz  
}

void InitializeButton(void)                     // 配置按钮
{
  BUTTON_DIR &= ~BUTTON;
  BUTTON_OUT |= BUTTON;
  BUTTON_REN |= BUTTON;
  BUTTON_IES |= BUTTON;
  BUTTON_IFG &= ~BUTTON;
  BUTTON_IE |= BUTTON;
}


void InitializeLeds(void)
{
  LED_DIR |= LED0 + LED1;                          
  LED_OUT &= ~(LED0 + LED1);  
}

/* *************************************************************
*按钮按下口中断
* 1、在待机模式:进入和退出应用模式
* 2、在应用模式:重新调整温度传感器
* *********************************************************** */
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{   
  BUTTON_IFG = 0;  
  BUTTON_IE &= ~BUTTON;            /* 去抖 */
  WDTCTL = WDT_ADLY_250;
  IFG1 &= ~WDTIFG;                 /* 清除中断标志 */
  IE1 |= WDTIE;  
   
  if (applicationMode == APP_APPLICATION_MODE)
  {
    tempCalibrated = tempAverage;
    calibrateUpdate  = 1;
  }
  else
  {
    applicationMode = APP_APPLICATION_MODE; // 从待机状态切换到应用模式
    __bic_SR_register_on_exit(LPM3_bits);        
  }   
}

#pragma vector=WDT_VECTOR
__interrupt void WDT_ISR(void)
{
    IE1 &= ~WDTIE;                   /* 失能中断 */
    IFG1 &= ~WDTIFG;                 /* 清除中断标志 */
    WDTCTL = WDTPW + WDTHOLD;        /* 使 WDT 返回至保持状态 */
    BUTTON_IE |= BUTTON;             /* 去抖完成 */
}

// ADC10中断服务程序
#pragma vector=ADC10_VECTOR
__interrupt void ADC10_ISR (void)
{
  __bic_SR_register_on_exit(CPUOFF);        // 返回到Active模式
}
点赞  2010-11-8 22:25
好贴子顶一个
工程 = 数学+物理+经济
点赞  2010-11-8 23:58
很好的帖子,在官网下载半天没有下载下来
点赞  2010-11-11 15:25

回复 4楼 hahaliuhehe 的帖子

呵呵 谢谢支持
点赞  2010-11-11 22:44
顶一下LZ
点赞  2010-11-14 16:36
Temperature_Sense_Demo的zip文件楼主有没有,在提供的网站下不了。
点赞  2010-11-19 16:20

回复 7楼 qinzheng0507 的帖子

有的 上传啦 你看下附件
点赞  2010-11-21 13:05
我也有这个疑问,特别是这句:

SFR_8BIT(IE1);   


这个IE1在哪里定义的呢?
https://bbs.eeworld.com.cn/thread-471646-1-1.html 欢迎加入我的团队
点赞  2010-11-21 21:49

回复 9楼 youki12345 的帖子

同感 很多这样的 希望高人给予解惑
点赞  2010-11-22 23:25
我任务,430试用里面那可以申请精华了
点赞  2010-11-23 00:07
顶一下 谢谢LZ
点赞  2011-1-11 17:30
要顶一下
点赞  2011-10-7 00:49
指点问题哈
long tempMeasured[8]; //测量值
这是定义语句,是数组,但后面用的时候不是数组,不知道楼主在编译的时候报错了么
点赞  2011-10-7 10:07
顶一下,这个温度测试的程序太长了,好混啊,主要是发送数据那儿不清楚,怎么去配置,谁会的说一下吧,谢谢了
点赞  2011-10-7 14:56
好文章,做的很用心。
labview做的上位机也挺好
点赞  2011-10-7 15:52

回复 楼主 lyzhangxiang 的帖子

不错···
点赞  2011-10-16 15:35

引用: 原帖由 lyzhangxiang 于 2010-11-8 22:25 发表


void InitializeClocks(void)

{

BCSCTL1 = CALBC1_1MHZ; // 设定范围
DCOCTL = CALDCO_1MHZ;
BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 8 = 1MHz

}


怎么理解?DCO是多少?

点赞  2011-10-18 23:11

回复 18楼 wangfuchong 的帖子

DCO为1M

BCSCTL2 &= ~(DIVS_3); // SMCLK = DCO / 8 = 1MHz

这句注解问题。
点赞  2011-10-19 13:36

回复 楼主 lyzhangxiang 的帖子

大侠在合肥读书吗?我在合工大读本科
点赞  2011-10-19 18:35
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复