急问!!用MSP430G2553控制DS1631数字温度传感器

2019-03-24 12:47发布

本人完全是新手!!用G2553控制DS1631数字温度传感器(I2C协议的)显示温度。 用IAR 编辑后没有错误,没有警告。
想在示波器中显示信号,看程序做的对不对。但是总是显示不出来。自己也没调试出程序问题出在哪里。希望前辈能指点一下,给些提示和帮助。
我实在是没办法了!!!求弄过的前辈帮帮忙!!!谢谢!!!

#include <msp430g2553.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

#ifndef READ
#define READ 1
#endif
#ifndef WRITE
#define WRITE 0
#endif

#define SDA BIT7  // Data line
#define SCL BIT6  // Clock line
#define TOUT BIT1 // Thermostat Output

#define DS1631_START                         0x51
#define DS1631_STOP                         0x22
#define DS1631_RESET                         0x54
#define DS1631_READ_TEMP                 0xAA
#define DS1631_CONFIG                         0xAC
#define DS1631_CONFIG_1SHOT                0x01
#define DS1631_CONFIG_POL                0x02
#define DS1631_CONFIG_R0                0x04
#define DS1631_CONFIG_R1                0x08
#define DS1631_CONFIG_NVB                0x10
#define DS1631_CONFIG_TLF                0x20
#define DS1631_CONFIG_THF                  0x40
#define DS1631_CONFIG_DONE                0x80
#define DS1631_CONFIG_9BIT                0x00
#define DS1631_CONFIG_10BIT                0x04
#define DS1631_CONFIG_11BIT                0x08
#define DS1631_CONFIG_12BIT                0x0C
#define DS1631_TH                        0xA1
#define DS1631_TL                        0xA2



float temp_c;
float temp_f;
unsigned char MSB;
unsigned char LSB;

void I2CBitDly(void);
void SDA_high(void);
void SDA_low(void);
void SCL_high(void);
void SCL_low(void);


void I2CSCLHigh(void);
void I2CSendAddr(unsigned char Address, unsigned char rd);
void I2CSendByte(unsigned char bt);
unsigned char I2CGetByte(unsigned char lastone);
void I2CSendStart(void);
void I2CSendStop(void);
void GetTemp(unsigned char Address);


void main(void)
{
   WDTCTL = WDTPW + WDTHOLD;  // Stop WDT

   DCOCTL = CALDCO_12MHZ;   
   BCSCTL1 = CALBC1_12MHZ;

  TACTL |= TACLR; /* TAR may be cleared by setting the TACLR bit. Setting TACLR also clears the clock divider and count direction for up/down mode.*/
  TACTL |= TASSEL_2 + MC_1;  /* Timer A clock source select: 2 – SMCLK; Timer A mode control: 1 - Up to CCR0 */
  TACCTL0 = CCIE;  // CCR0 interrupt enabled
  CCR0 = 4096;

  //Init_USCI--I2C
  P1DIR |= BIT1;
  P1SEL &= ~BIT1; // ?
  P1SEL |= SCL + SDA;                     // Assign I2C pins to USCI_B0
  P1SEL2|= SCL + SDA;                     // Assign I2C pins to USCI_B0
  UCB0CTL1 |= UCSWRST;                      // Enable SW reset
  UCB0CTL0 = UCMST+UCMODE_3+UCSYNC;         // I2C Master, synchronous mode
  UCB0CTL1 = UCSSEL_2+UCSWRST;              // Use SMCLK, keep SW reset
  UCB0BR0 = 12;                             // fSCL = SMCLK/12 = ~100kHz
  UCB0BR1 = 0;
  UCB0CTL1 &= ~UCSWRST;                     // Clear SW reset, resume operation

  while(1)
  {
  GetTemp(0x90);
  }  


}// End Main Program     


void I2CBitDly(void)  // wait 4.7uS, or thereabouts =5
  {
  unsigned int time_end = 10;
  unsigned int index;
  for (index = 0; index < time_end; index++);
  return;
  }


  void SDA_high(void)  // SDA = 1
  {
    P1DIR |= SDA;
    P1OUT |= SDA;
    I2CBitDly();
  }
  void SDA_low(void)   // SDA = 0
  {
    P1DIR |= SDA;
    P1OUT &= ~SDA;
    I2CBitDly();
  }
  void SCL_high(void)   // SCL = 1
  {
    P1DIR |= SCL;
    P1OUT |= SCL;
    I2CBitDly();
    I2CBitDly();
  }
  void SCL_low(void)    // SCL= 0
  {
    P1DIR |= SCL;
    P1OUT &= ~SCL;  
    I2CBitDly();
  }


void GetTemp(unsigned char Address)
{
  I2CSendAddr(Address, WRITE);  // control byte
  I2CSendByte(0x51);  // command byte access Config reg.  start convert
  I2CSendStop();  // send stop
  I2CBitDly();  // wait
  I2CSendAddr(Address, WRITE);  // control byte
  I2CSendByte(0xAA);  // command byte read temp
  I2CSendAddr(Address, READ);  // restart control byte and device address, now slave enabled to write data to master
  MSB = I2CGetByte(0);  // read upper temp byte
  LSB = I2CGetByte(1);  // read lower temp byte
  I2CSendStop();
  // calculate Temp
  if(MSB >= 0x80)  // if sign bit is set, then temp is negative
  {
    temp_c = (float)((MSB << 8 + LSB) - 65536) * 0.0625;
  }
  else
  {
    temp_c = (float)(MSB << 8 + LSB) * 0.0625;
    temp_f = (temp_c * 9/5) + 32;
  }
}

void I2CSCLHigh(void)  // set SCL high, and wait for it to go high
{
  SCL_high();
  I2CBitDly();
  I2CBitDly();
}

void I2CSendAddr(unsigned char addr, unsigned char rd)
{
  I2CSendStart();
  I2CSendByte(addr + rd);  // send address byte
}

void I2CSendByte(unsigned char bt)  // Transfer from the Microcontroller a data or command byte to the ds1631
{
  register unsigned char i;
  for(i=0; i<8; i++)
  {
    if(bt & 0x80)   // check if MSB is 1 or 0: 1: SDA = 1;  0: SDA = 0
    {
      SDA_high();
    }
    else
    {
      SDA_low();
    }
    I2CSCLHigh();
    I2CBitDly();
    SCL_low();
    bt = bt << 1;
  }
  SDA_high();  
  I2CSCLHigh();
  I2CBitDly();// check for ACK
  if((P1OUT |= SDA))  // if SDA = 1, NACK
    SCL_low();
    SDA_high();  // end transmission
    SCL_high();
}

unsigned char I2CGetByte(unsigned char lastone)  // lastone == 1 for last byte; 0 for any other byte
{
  register unsigned char i, res;
  res = 0;
  for(i=0; i<8; i++)  // each bit at a time, MSB first
  {
    I2CSCLHigh();
    I2CBitDly();
    res *= 2;  // shift current bit pattern once to the left
    if((P1OUT |= SDA))
      res++;  // if bit read in is a 1, then set LSB to a 1, see above for shifting
    SCL_low();
  }
  if(lastone == 1)  // send ACK according to "lastone"
  {
    SDA_high();
  }
  else
  {
    SDA_low();
  }
  I2CSCLHigh();
  I2CBitDly();
  SCL_low();
  SDA_high();
  SCL_high();
  return(res);
}

void I2CSendStart(void)
  {
    SCL_high();
    SDA_high();
    SDA_low();
    SCL_low();
  }

void I2CSendStop(void)
  {
    SDA_low();
    SCL_low();
    SCL_high();
    SDA_high();
  } 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
wudayongnb
1楼-- · 2019-03-24 21:36
 精彩回答 2  元偷偷看……
cqr
2楼-- · 2019-03-25 03:02
< :TI_MSP430_内容页_SA7 --> 程序看着有点儿乱,前面看上去好像要用芯片自带的IIC模块啊!

先别慌乱,如果是自己模拟IIC协议:
首先是起始位要做好,这都比较简单,就是两个端口高低电平的配合问题;
其次要正确发送从设备地址,并且在后面加一位读写位;
最重要的是要找到ack信号!如果前面你都配置都对了,正确的发送了从设备的地址,那么应该能有从设备发回来的确认信号,只要找到了确认信号,其他的就可以慢慢调试了。

另外,建议以上几步,每步都用示波器监测,得到了你想要的结果,再看后面的程序是否输出正确的波形,等等……
否则会有些盲目。

[ 本帖最后由 cqr 于 2013-3-20 11:09 编辑 ]
veraymy
3楼-- · 2019-03-25 07:30
嗯, 谢谢你的提醒。我去学习一下。
veraymy
4楼-- · 2019-03-25 11:52
 精彩回答 2  元偷偷看……
veraymy
5楼-- · 2019-03-25 17:43
我现在用芯片自带的IIC模块,但是在示波器显示时,CLK信号很密集而SDA信号很疏松,请问这是什么原因呢?
veraymy
6楼-- · 2019-03-25 22:59
我现在用芯片自带的IIC模块,但是在示波器显示时,CLK信号很密集而SDA信号很疏松,请问这是什么原因呢?

一周热门 更多>

相关问题

    相关文章