11889|27

255

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

eZ430-RF2500试用心得(三)—字斟句酌读例程 呕心沥血写心得 [复制链接]

       从拿到开发板到现在已经过去十来天了,经过一堆杂事、数番折腾和各种挫折,经历了肉体的劳苦奔波和精神的打击折磨,终于解决了前一阶段的大部

分问题,可以开始正是实验和学习开发板了!现在我的心情是十分的冲动,今夜阳光明媚,今夜鸟语花香···
       首先我要代表我姥爷及我个人感谢论坛里关注我的帖子或者提出了友好建议的热心坛友们,尤其是管理员soso姐的热忱相助!正式开始学习后,肯定还

会有更多的问题要请教大家,还望各位能继续关注,不吝赐教!
       之前也发过两篇帖子,但都是表达拿到板子后的喜悦心情,并未涉及技术和知识,略有滥竽充数之嫌,还望诸位谅解!现在,解决了驱动问题后,板子

可以正常运行程序了,后面的心得体会帖子都会是本人的学习经过和体验,而且会写的尽量详细、易懂。但本人也先坦白,自己真正接触单片机也才月把时间,连

C语言都没看完,是一个标准的菜鸟(而且是一个入门过程十分坎坷、处处碰壁、祸不单行、好事多磨的菜鸟),学习的过程可能会因为比较吃力,以及课程、考

试等原因而有些慢,甚至错漏百出,还望大家多多包涵并给予指教。但我觉得,也许自己作为新手,一切从头学起,这个过程正好可以为同是对此感兴趣的入门

者提供一个借鉴和参考(但愿不要是误导···)。我也会尽量详细、全面的写出自己的思考和体会,以便和大家交流讨论。
       虽然可以实验了,心情很激动,但是却有些迷茫,不知道从何学起。在论坛里看了一些上期和本期试用者们发表的心得体会,发现自己基础实在太薄弱

,根本写不出那样有见解的分析和扩展研究。想来想去,只好从光盘里附带的Sensor Monitor例程入手,仔仔细细的把这个历程研究透了再说。这样虽然有些操

之过急,但也不失为一种快刀斩乱麻的办法吗,况且,后面的事情还很多,也不允许我按部就班、步步为营的进行实验了。
      主意既定,在下就闲话少说,先上几张例程的实际效果图片:

 

 

 

 

 


       下面就是我花了两天时间对例程源代码demo_AP.c的主程序main的解读,和大家分享一下。本来打算一次性详细解释的,但开始没多久就发现此非一日

之寒也,因此只能先解释这一部分,更详细的解释必须要另开篇幅了。里面也提出了一些疑问,希望各位阅读后能帮忙解释一下,多谢!
       在经过几段代码的分析后,我发现首先应该弄懂它的数据格式定义,因为这是整个代码的基础,不搞清楚的话对各种常量、变量、参数的理解都会有障

碍。数据格式的定义在BSP_MSP430_DEFS_H文件中(抱歉,应该是bsp_msp430_def.h文件,为省去切换输入法打字的麻烦,就直接从头文件里复制了,下面都是

这么做的,呵呵):

typedef   signed char     __bsp_int8_t__;
typedef   signed short    __bsp_int16_t__;
typedef   signed long     __bsp_int32_t__;

typedef   unsigned char   __bsp_uint8_t__;
typedef   unsigned short  __bsp_uint16_t__;
typedef   unsigned long   __bsp_uint32_t__;
其它的格式定义头文件也很重要,解读的过程中需要经常查阅,但这里先只列出这些最基本的,以后要用到其它定义的话会再说明。

#include "bsp.h"
#include "mrfi.h"
#include "bsp_leds.h"
#include "bsp_buttons.h"
#include "nwk_types.h"
#include "nwk_api.h"
#include "nwk_frame.h"
#include "nwk.h"

#include "msp430x22x4.h"
#include "vlo_rand.h"

//这些是主函数中调用的头文件,下面的解读经常需要在这些文件里翻来找去,当然,其实这些文件还要涉及到其他的头文件,就更麻烦了···
//以下是本文件中的宏定义和函数声明,等遇到了再解释
#define MESSAGE_LENGTH 3
void TXString( char* string, int length );
void MCU_Init(void);
void transmitData(int addr, signed char rssi,  char msg[MESSAGE_LENGTH] );
void transmitDataString(char addr[4],char rssi[3], char msg[MESSAGE_LENGTH]);
void createRandomAddress();

//终端输出信息
const char splash[] = {"\r\n--------------------------------------------------\r\n     ****\r\n     ****           eZ430-RF2500\r\n   

 ******o****    Temperature Sensor Network\r\n********_///_****   Copyright 2007\r\n ******/_//_/*****  Texas Instruments

Incorporated\r\n  ** ***(__/*****   All rights reserved.\r\n      *********     Version 1.02\r\n       *****\r\n        ***\r\n------

--------------------------------------------\r\n"};

__no_init volatile int tempOffset @ 0x10F4; // 请高手指点,这一句什么意思?我知道是后面用语文读数据转换计算的偏差值,但为什么要设置成@  0x10F4这个数值呢?  

__no_init volatile char Flash_Addr[4] @ 0x10F0; // 为什么可以随机设置Flash地址?

// 为连接数量的最大可能值保留空间
static linkID_t sLID[NUM_CONNECTIONS];
static uint8_t  sNumCurrentPeers;

// 回调处理函数
static uint8_t sCB(linkID_t);

// 主工作循环信息
static uint8_t sPeerFrameSem;
static uint8_t sJoinSem;
static uint8_t sSelfMeasureSem;

// 温度数据模式默认设置,默认为华氏温度数值
char verboseMode = 1;
char degCMode = 0;

[ 本帖最后由 wwh19910609 于 2011-5-31 11:54 编辑 ]

最新回复

学习了,顶!  详情 回复 发表于 2012-11-20 23:01
 
点赞 关注(1)

回复
举报

255

帖子

0

TA的资源

纯净的硅(中级)

沙发
 

void main (void)
{
  addr_t lAddr;
  /*addr_t的格式定义在NWK_TYPES_H文件中:
 
  typedef struct
{
  uint8_t  addr[NET_ADDR_SIZE]; 
} addr_t;           NET_ADDR_SIZE定义在NWK_TYPES_H文件中:#define NET_ADDR_SIZE      MRFI_ADDR_SIZE   // 地址字节长度,定义在mrfi.h文件

中:#define MRFI_ADDR_SIZE         __mrfi_ADDR_SIZE__
                                                                                                      // __mrfi_ADDR_SIZE__定义在

MRFI_CC2500_DEFS_H文件中:#define __mrfi_ADDR_SIZE__          4
  总结起来就是NET_ADDR_SIZE=4,即addr[]数组有4个参数,32位
  */     
  bspIState_t intState;
  /*大家别小看了这一句,我跳转了几个文件才搞明白:
  1,bsp.h文件中:typedef __bsp_ISTATE_T__  bspIState_t;
  2,BSP_MSP430_DEFS_H文件中:#define __bsp_ISTATE_T__    istate_t;
  3,__INTRINSICS_H文件中:typedef unsigned short istate_t;
  原来就是个无符号短整型数据!干嘛这么费劲?*/

  WDTCTL = WDTPW + WDTHOLD;                 // 关WDT,经典句子了
  {
 
    volatile int i;
    for(i = 0; i < 0xFFFF; i++){}
  }
  if( CALBC1_8MHZ == 0xFF )                 // #define CALBC1_8MHZ_     (0x10FDu)  CALBC1_8MHZ_参数是用来设置振荡器频率的
                                                                //READ_ONLY DEFC( CALBC1_8MHZ  , CALBC1_8MHZ_)
                                                                //这句话是用来防止程序在不正确的工作频率下运行
  {
    volatile int i;
    P1DIR |= 0x03;   //P1DIR:P1方向寄存器,设置P1.0、P1.1为输出方向以分别控制LED1和LED2                   
    BSP_TURN_ON_LED1();
    BSP_TURN_OFF_LED2();
    /*这两个函数分别用于点亮LED1、熄灭LED2,看似简单,却使用了四个文件里的宏定义:
    1,BSP_LEDS_H文件中:#define BSP_TURN_ON_LED1()    __bsp_LED1_TURN_ON__();
    2,BSP_GENERIC_LEDS_H文件中:#define __bsp_LED1_TURN_ON__()    __bsp_LED_TURN_ON__ ( __bsp_LED1_BIT__, __bsp_LED1_PORT__,

__bsp_LED1_DDR__, __bsp_LED1_IS_ACTIVE_LOW )
                                 #define __bsp_LED_TURN_ON__(bit,port,ddr,low)  \
                                       st( if (low) { port &= ~BV(bit); } else { port |= BV(bit); } )
    3,BSP_LED_DEFS_H文件中:#define __bsp_LED1_BIT__            0
                            #define __bsp_LED1_PORT__           P1OUT
                            #define __bsp_LED1_DDR__            P1DIR
                            #define __bsp_LED1_IS_ACTIVE_LOW    0
                            这四个宏定义对应于上面__bsp_LED_TURN_ON__(bit,port,ddr,low)的四个参数
    4,BSP_MACROS_H文件中: #ifndef BV
                           #define BV(n)      (1 << (n))
                           #endif
                          
                           #define st(x)      do { x } while (__LINE__ == -1)//这种判断条件能在大多数编译器上避免warning
   
    这是BSP_TURN_ON_LED1()点亮LED1的过程,BSP_TURN_OFF_LED2()熄灭LED2的过程与此类似,就不重述了
    */
    while(1)
    {
      for(i = 0; i < 0x5FFF; i++){}
      BSP_TOGGLE_LED2();
      BSP_TOGGLE_LED1();
      /*这两个函数与上两个也类似,调用的文件及其宏定义都很相像,但第三个文件中的宏定义不同:
      #define __bsp_LED_TOGGLE__(bit,port,ddr,low)     st( port ^= BV(bit); )
      这个定义就用于转换LED的状态
      */
    }
  }
   
  BSP_Init();
  /*开发板和驱动初始化函数,定义如下:
  void BSP_Init(void)
{
  BSP_INIT_BOARD();
  BSP_INIT_DRIVERS();

#ifdef BSP_ASSERTS_ARE_ON   //好像是用来控制显示开关的
 
  {
    uint16_t test = 0x00AA;
    BSP_ASSERT(!(*((uint8_t *)&test)) == !BSP_LITTLE_ENDIAN);
  (*参数BSP_LITTLE_ENDIAN的定义在bsp.h和BSP_MSP430_DEFS_H中:
      #define BSP_LITTLE_ENDIAN   __bsp_LITTLE_ENDIAN__
      #define __bsp_LITTLE_ENDIAN__   1)
  }
#endif
}*/
 
  if( Flash_Addr[0] == 0xFF &&
      Flash_Addr[1] == 0xFF &&
      Flash_Addr[2] == 0xFF &&
      Flash_Addr[3] == 0xFF )
  {
    createRandomAddress();                  // 该函数用于在初始启动时随机设置设备地址,下面有分析

  }
  lAddr.addr[0]=Flash_Addr[0];
  lAddr.addr[1]=Flash_Addr[1];
  lAddr.addr[2]=Flash_Addr[2];
  lAddr.addr[3]=Flash_Addr[3];
  SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
  /*没能在工程文件里找到该函数的原型,应该是被封装在库文件里了。但从参数来看,应该是用来设置上一步生成的地址位本机地址,以便通信识别的
  IOCTL_OBJ_ADDR、IOCTL_ACT_SET两个参数定义在NWK_TYPES_H文件中
  enum ioctlObject  {             //enum用于定义枚举类型变量
  IOCTL_OBJ_FREQ,
  IOCTL_OBJ_CRYPTKEY,
  IOCTL_OBJ_RAW_IO,
  IOCTL_OBJ_RADIO,
  IOCTL_OBJ_AP_JOIN,
  IOCTL_OBJ_ADDR
  };

  enum ioctlAction  {
  IOCTL_ACT_SET,
  IOCTL_ACT_GET,
  IOCTL_ACT_READ,
  IOCTL_ACT_WRITE,
  IOCTL_ACT_RADIO_SLEEP,
  IOCTL_ACT_RADIO_AWAKE,
  IOCTL_ACT_RADIO_SIGINFO,
  IOCTL_ACT_ON,
  IOCTL_ACT_OFF
  };
  至于定义中每个参数的具体含义,我还没有找到相关资料,找到后再和大家分享吧,这里先将就着理解好了*/
  MCU_Init();   //MSP430初始化,具体过程后面再详述
  //发送splash screen和组网信息,splash信息见本文件102行
  TXString( (char*)splash, sizeof splash);
  TXString( "\r\nInitializing Network....", 26 );

  SMPL_Init(sCB);       //这个函数也没找到,但明显是个初始化的函数,而且初始化结果因sCB函数的值而异
                                  //sCB函数根据参数lib的值有两种结果:1,sPeerFrameSem=1,即收到的为节点数据帧信号;
                                  //2,sJoinSem=1,即收到的为请求加入网络信号
  // 发送网络初始化完成信息
  TXString( "Done\r\n", 6);

  // 主工作循环
  while (1)
  {
    /*等待接收到的信号被设置.*/
   
    if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))   //要同时满足加入信号存在且序号不超过允许的连接总数
    {
      SMPL_LinkListen(&sLID[sNumCurrentPeers]);          //监听任务函数,参数都很易懂,就不解释了
      sNumCurrentPeers++;
      BSP_ENTER_CRITICAL_SECTION(intState);
      if (sJoinSem)
      {
        sJoinSem--;
      }
      BSP_EXIT_CRITICAL_SECTION(intState);
    }
    /*BSP_MSP430_DEFS_H文件中:
      #define BSP_ENTER_CRITICAL_SECTION(x)   st( x = __bsp_GET_ISTATE__()(获取中断状态); __bsp_DISABLE_INTERRUPTS__(关闭中断); )
      #define BSP_EXIT_CRITICAL_SECTION(x)    __bsp_RESTORE_ISTATE__(x)(重新设置中断状态)*/
    
  

 
 

回复

255

帖子

0

TA的资源

纯净的硅(中级)

板凳
 

 if(sSelfMeasureSem)  // 如果是数据信号
    {
      char msg [6];
      char addr[] = {"HUB0"};
      char rssi[] = {"000"};       //接收的信号强度指示
      int degC, volt;
      volatile long temp;
      int results[2];
     
      ADC10CTL1 = INCH_10 + ADC10DIV_4;     //#define INCH_10         (10*0x1000u)(选择频道,这里选择的10频道为片内温度传感器的输出);
                                                                          //#define ADC10DIV_4          (4*0x20u) (分频因数,这里定为5分频)
                                                                          //以上定义转换控制寄存器1为温度传感5分频
      ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE + ADC10SR;     //#define SREF_1(电源电压参考位)     (1*0x2000u)  /*

                                                                                                                                                           VR+ = VREF+ and VR- = AVSS */
                                                         //#define ADC10SHT_3(采样保持定时器分频因数)         
(3*0x800u)   /*选为64倍ADC10CLKs,下面的ADC10SHT_2为16倍分频*/
                                                         //#define REFON(参考电压控制位)  (0x020)     /* 1为内
部参考电压发生器打开,0为关闭 */       
                                                         //#define ADC10ON(转换开启控制)  (0x010)     /* 开启
ADC10*/   
                                                         //#define ADC10IE(中断允许控制)  (0x008)     /* ADC10
终端使能*/       
                                                         //#define ADC10SR(采样速率选择)  (0x400)     /*  0:200ksps / 1:50ksps */          
                                                                              
      for( degC = 240; degC > 0; degC-- );    // 延时以便设置参数
      ADC10CTL0 |= ENC + ADC10SC;         //#define ENC   (0x002)     /* ADC10转换使能 */
                                                                   //#define ADC10SC   (0x001)     /* ADC10开始转换 */
                                                                   // 这一句采样并开始转换
      __bis_SR_register(CPUOFF + GIE);      // 函数定义没找到,但明显,这一句使得在LPM0模式下开总中断允许
      results[0] = ADC10MEM;                      //#define ADC10MEM_           (0x01B4u)    /* ADC10温度数据存储器地址*/
                                                                  // DEFW(   ADC10MEM          , ADC10MEM_)
                                                                  //这一句读取转换存储器,里面是温度数据
      ADC10CTL0 &= ~ENC;                       //关闭转换器
   
      ADC10CTL1 = INCH_11;                  // 选择11输入频道,AVcc/2
      ADC10CTL0 = SREF_1 + ADC10SHT_2 + REFON + ADC10ON + ADC10IE + REF2_5V;     //参考电压2.5V
     
     
     
     
     
     
      for( degC = 240; degC > 0; degC-- );     // 延时以便设置参数
      ADC10CTL0 |= ENC + ADC10SC;           // 采样并开始转换
      __bis_SR_register(CPUOFF + GIE);      // 开总中断
      results[1] = ADC10MEM;                        // 再次读取转换存储器,这次是电压数据
      ADC10CTL0 &= ~ENC;                          //关闭转换器
      ADC10CTL0 &= ~(REFON + ADC10ON);      // 关闭A/D以节电,不同于上面的关闭转换器命令
     
      // 温度数据转换公式:oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
      // 温度数据都是以10倍的整数形式传送的,如32.1改成321
     
      temp = results[0];
      degC = (((temp - 673) * 4230) / 1024);
      if( tempOffset != 0xFFFF )
      {
        degC += tempOffset;
      }                                  //到这里温度值储存在了degC中
     
      temp = results[1];
      volt = (temp*25)/512;               //电压值储存在了volt中
     
      msg[0] = degC&0xFF;                //加载温度值的低8位
      msg[1] = (degC>>8)&0xFF;        //加载温度值的高8位
      msg[2] = volt;                             //加载电压值
      transmitDataString(addr, rssi, msg );    //传送温度和电压数据到串口
      BSP_TOGGLE_LED1();                       //传送后转换LED1的状态
      sSelfMeasureSem = 0;                         //清除数据信号,为其它信号预留位置
    }
   
   
    // 下面的这段程序用于处理接收到但未来得及处理的信号,里面的几个函数基本都在上面介绍过了
    if (sPeerFrameSem)
    {
      uint8_t     msg[MAX_APP_PAYLOAD], len, i;

      // 处理所有正在等待的信号
      for (i=0; i<sNumCurrentPeers; ++i)
      {
        if (SMPL_Receive(sLID, msg, &len) == SMPL_SUCCESS)  //如果接收到信号
        {
          ioctlRadioSiginfo_t sigInfo;
          sigInfo.lid = sLID;
          SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SIGINFO, (void *)&sigInfo);
          transmitData( i, (signed char)sigInfo.sigInfo[0], (char*)msg );
          BSP_TOGGLE_LED2();
          BSP_ENTER_CRITICAL_SECTION(intState);
          sPeerFrameSem--;
          BSP_EXIT_CRITICAL_SECTION(intState);
        }
      }
    }
  }
}

 

 

       好了,终于把AP的main函数解读完了,多我来说实属不易啊!我在解读时打开了IAR、翻译词典、WORD、PDF、搜狗浏览器、图片查看器等等应用程序,可以说是使尽了浑身解数。这两天也是啥都没干,就坐在电脑前解读这些英文句子和数学符号。现在终于迈出了一小步,迈得虽然艰难,但还是蛮有收获的,相信后面的解读会顺利得多!
       再次郑重声明:由于缺乏知识基础和实践经验,解读过程中难免有许多不足和错误之处,希望读者多多包涵并给予指导,在下十分感谢!也希望同为初学者的坛友能发表对此帖的看法,以便我在后面的帖子里加以改善!
                                                                                                                                                                                                                (To be continued···)

[ 本帖最后由 wwh19910609 于 2011-5-29 22:20 编辑 ]
 
 
 

回复

255

帖子

0

TA的资源

纯净的硅(中级)

4
 
版主啊,虽然这个心得体会可能没多少技术含量和参考价值,但就连这个帖子的编辑也花了在下不少时间,还遇到了帖子过长,不得不删掉已经编辑好的部分,重新回复再编辑的悲剧!所以呢,呵呵,如果此帖反映良好的话,希望您能给我加个精哈···

[ 本帖最后由 wwh19910609 于 2011-5-30 07:34 编辑 ]
 
 
 

回复

452

帖子

0

TA的资源

五彩晶圆(初级)

5
 
帮你顶一下,我看了下,楼主的分析还是很周到,对于一个接触单片机不久的人来说,呵呵,不简单。
 
个人签名人生苦短,何必为声名所累,放开自己心态,去追求自己想要的梦想去吧!http://pytech-inc.taobao.com/
 
 

回复

255

帖子

0

TA的资源

纯净的硅(中级)

6
 
终于有人帮顶了···
十分感谢梦之旅版主!另外,用红色标出的字体是解读过程中遇到的问题,也希望版主能帮忙解答啊
 
 
 

回复

255

帖子

0

TA的资源

纯净的硅(中级)

7
 
唉,枉我辛辛苦苦写了这篇心得,原来不仅高手没兴趣看,连初学者都不来光顾··· 看来还是技术不行啊

[ 本帖最后由 wwh19910609 于 2011-5-31 11:42 编辑 ]
 
 
 

回复

2万

帖子

71

TA的资源

管理员

8
 

回复 7楼 wwh19910609 的帖子

相当细心的分享 很不错
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

9
 

__no_init volatile int tempOffset @ 0x10F4;

 

这个就是把那个tempOffset变量定义到指定的地址0x10f4这个地方呀,记得类型要匹配,int型的对应偶地址,char型对应奇地址。

 

__no_init就是无需初始化,复位后变量保持不变

 

还有flash中使用@指定这个地址的时候不能用__no_init的,具体的不和你多说了,有点复杂

 

一般msp430对于大数组的初始化也会采用__no_init的,应为这样就没有初始化变量的时间了,大家都懂的430上电看门狗是开启的,所以这样可以防止那个片子一直在复位。

 

用法很多,需要好好体会,比如那个flash产生随机数的,ti的例子还是很有可读性的。

 
 
 

回复

452

帖子

0

TA的资源

五彩晶圆(初级)

10
 

回复 9楼 lyzhangxiang 的帖子

呵呵,功力果然厉害,真不愧为在利尔达实习过的 ,对于430我也是第一次用,所以有些地方也不清楚,我想问下__no_init volatile int tempOffset @ 0x10F4;



这个就是把那个tempOffset变量定义到指定的地址0x10f4这个地方呀,记得类型要匹配,int型的对应偶地址,char型对应奇地址。



__no_init就是无需初始化,复位后变量保持不变

__no_init volatile char Flash_Addr[4] @ 0x10F0; // 为什么可以随机设置Flash地址?

这里用的char,但好像也是偶数地址吧
 
个人签名人生苦短,何必为声名所累,放开自己心态,去追求自己想要的梦想去吧!http://pytech-inc.taobao.com/
 
 

回复

25

帖子

0

TA的资源

一粒金砂(中级)

11
 
我也想问问关于这些地址设置的问题,这样直接设置地址是为了什么目的呢?保存在flash里了?我看了一些关于操作flash的例程,还有调整时钟什么的,很复杂的啊?求帮助
 
 
 

回复

2144

帖子

3

TA的资源

五彩晶圆(中级)

12
 

回复 10楼 梦之旅 的帖子

__no_init volatile char Flash_Addr[4] @ 0x10F0

这个只是告诉起始地址的,可以用仿真器看一下定位在哪个地址那里,我觉得应该是往后推一个。没用仿真器看,只是表达个人看法。
 
 
 

回复

255

帖子

0

TA的资源

纯净的硅(中级)

13
 

回复 9楼 lyzhangxiang 的帖子

多谢您的解答!这个知识我还从来没遇到过,看了您的解释,实在是获益匪浅呐!

后面可能还会有许多这样没有实际经验而无法理解的问题,希望您能继续关注我的解读心得~

[ 本帖最后由 wwh19910609 于 2011-6-1 08:31 编辑 ]
 
 
 

回复

25

帖子

0

TA的资源

一粒金砂(中级)

14
 
有一个关于温度的问题很奇怪啊。 注释里面说的:
      // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278
      // the temperature is transmitted as an integer where 32.1 = 321
      // hence 4230 instead of 423

代码里面写的

degC = (((temp - 673) * 4230) / 1024);

为什么不是:
degC = temp*4230/1024 - 2780;

虽然 2780可以约等于673*4230/1024 可这样的转换一下对运算或编译有什么好处吗? 少用一个字节? 不是很理解 请大侠指点。十分感谢
 
 
 

回复

255

帖子

0

TA的资源

纯净的硅(中级)

15
 
楼上的兄弟想得还真仔细,我还没考虑到这个细节。同样求教于高人!
 
 
 

回复

25

帖子

0

TA的资源

一粒金砂(中级)

16
 
还是关于0x10F4的问题, 这个东西是不是跟TLV有关啊?我看了半天code,发现代码里似乎没有对tempOffset进行过写入操作,只用它做了一个判断条件,然后就加到degC里面去了,可是根据表格里面,似乎0x10F4地址永远是0xFFFF啊,难道我搞混了吗?求指教。

Capture1.JPG (69.14 KB, 下载次数: 2)

Capture1.JPG
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

17
 

xie

学习过了  很有帮助 谢谢
 
 
 

回复

49

帖子

0

TA的资源

一粒金砂(中级)

18
 

回复 15楼 wwh19910609 的帖子

楼主帮忙看看我的问题:程序是没有错误的,用串口助手来显示uart的输出时,总是没有数据输出,苦恼好多天了
//******************************************************************************
//   MSP430F22x4 Demo - USCI_A0, Ultra-Low Pwr UART 9600 String, 32kHz ACLK
//
//   Description: This program demonstrates a full-duplex 9600-baud UART using
//   USCI_A0 and a 32kHz crystal.  The program will wait in LPM3, and will
//   respond to a received 'u' character using 8N1 protocol. The response will
//   be the string 'Hello World'.
//   ACLK = BRCLK = LFXT1 = 32768Hz, MCLK = SMCLK = DCO ~1.2MHz
//   Baud rate divider with 32768Hz XTAL @9600 = 32768Hz/9600 = 3.41
//   //* An external watch crystal is required on XIN XOUT for ACLK *//
//
//                MSP430F22x4
//             -----------------
//         /|\|              XIN|-
//          | |                 | 32kHz
//          --|RST          XOUT|-
//            |                 |
//            |     P3.4/UCA0TXD|------------>
//            |                 | 9600 - 8N1
//            |     P3.5/UCA0RXD|<------------
//
//   A. Dannenberg
//   Texas Instruments Inc.
//   October 2006
//   Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.41A
//******************************************************************************
#include  "msp430x22x4.h"

const char string1[] = { "Hello World\r\n" };
unsigned int i;

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P1DIR = 0xFF;                             // All P1.x outputs
  P1OUT = 0;                                // All P1.x reset
  P2DIR = 0xFF;                             // All P2.x outputs
  P2OUT = 0;                                // All P2.x reset
  P3SEL = 0x30;                             // P3.4,5 = USCI_A0 TXD/RXD
  P3DIR = 0xFF;                             // All P3.x outputs
  P3OUT = 0;                                // All P3.x reset
  P4DIR = 0xFF;                             // All P4.x outputs
  P4OUT = 0;                                // All P4.x reset
  UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
  UCA0BR0 = 0x03;                           // 32kHz/9600 = 3.41
  UCA0BR1 = 0x00;                           //
  UCA0MCTL = UCBRS1 + UCBRS0;               // Modulation UCBRSx = 3
  UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  __bis_SR_register(LPM3_bits + GIE);       // Enter LPM3 w/ int until Byte RXed
}

#pragma vector=USCIAB0TX_VECTOR
__interrupt void USCI0TX_ISR(void)
{
  UCA0TXBUF = string1[i++];                 // TX next character

  if (i == sizeof string1 - 1)              // TX over?
    IE2 &= ~UCA0TXIE;                       // Disable USCI_A0 TX interrupt
}

#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
  if (UCA0RXBUF == 'u')                     // 'u' received?
  {
    i = 0;
    IE2 |= UCA0TXIE;                        // Enable USCI_A0 TX interrupt
    UCA0TXBUF = string1[i++];
  }
}
 
 
 

回复

49

帖子

0

TA的资源

一粒金砂(中级)

19
 

回复 楼主 wwh19910609 的帖子

还有我感觉,大家最好是可以留个邮箱或者QQ之类的联系方式,有问题的话可以及时讨论,相互解决 我先留一个QQ:363782100
 
 
 

回复

20

帖子

0

TA的资源

一粒金砂(中级)

20
 

谢谢

初学者  顶
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表