利用msp430g2553通过i2协议读取bmp180的测量的气压数据并通过串口在pc端显示出来,请给出具体程序及详细的注释 (程序适用于Code Composer Studio 12.3.0)
时间: 2023-06-19 07:03:22 浏览: 50
以下是一个简单的程序,用于读取BMP180的气压数据并通过UART发送到PC端。注释中会解释每个步骤的作用。
```
#include <msp430.h>
#include <stdio.h>
// 定义BMP180的I2C地址
#define BMP180_ADDR 0x77
// 定义BMP180的寄存器地址
#define BMP180_CTRL_REG 0xF4
#define BMP180_TEMP_REG 0x2E
#define BMP180_PRESSURE_REG 0x34
// 定义串口参数
#define BAUDRATE 9600
#define CLK_FREQ 1000000
// 初始化串口
void initUART() {
P1SEL |= BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD
P1SEL2 |= BIT1 + BIT2; // P1.1 = RXD, P1.2=TXD
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = CLK_FREQ / BAUDRATE;
UCA0BR1 = 0;
UCA0MCTL = UCBRS2 + UCBRS0; // Modulation UCBRSx = 5
UCA0CTL1 &= ~UCSWRST; // Initialize USCI state machine
}
// 向BMP180写入一个字节的数据
void writeByte(unsigned char addr, unsigned char data) {
// 发送START信号
UCB0CTL1 |= UCTR + UCTXSTT;
// 等待START信号发送完毕
while(!(IFG2 & UCB0TXIFG));
// 发送设备地址和寄存器地址
UCB0TXBUF = BMP180_ADDR << 1;
while(!(IFG2 & UCB0TXIFG));
UCB0TXBUF = addr;
while(!(IFG2 & UCB0TXIFG));
// 发送数据
UCB0TXBUF = data;
while(!(IFG2 & UCB0TXIFG));
// 发送STOP信号
UCB0CTL1 |= UCTXSTP;
while(UCB0CTL1 & UCTXSTP);
}
// 从BMP180读取一个字节的数据
unsigned char readByte(unsigned char addr) {
unsigned char data;
// 发送START信号
UCB0CTL1 |= UCTR + UCTXSTT;
// 等待START信号发送完毕
while(!(IFG2 & UCB0TXIFG));
// 发送设备地址和寄存器地址
UCB0TXBUF = BMP180_ADDR << 1;
while(!(IFG2 & UCB0TXIFG));
UCB0TXBUF = addr;
while(!(IFG2 & UCB0TXIFG));
// 发送RESTART信号
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
while(!(IFG2 & UCB0TXIFG));
// 发送设备地址,读取数据
UCB0TXBUF = (BMP180_ADDR << 1) | 0x01;
while(!(IFG2 & UCB0TXIFG));
// 接收数据
while(!(IFG2 & UCB0RXIFG));
data = UCB0RXBUF;
// 发送STOP信号
UCB0CTL1 |= UCTXSTP;
while(UCB0CTL1 & UCTXSTP);
return data;
}
// 从BMP180读取一个16位的数据
unsigned int readWord(unsigned char addr) {
unsigned int data;
// 发送START信号
UCB0CTL1 |= UCTR + UCTXSTT;
// 等待START信号发送完毕
while(!(IFG2 & UCB0TXIFG));
// 发送设备地址和寄存器地址
UCB0TXBUF = BMP180_ADDR << 1;
while(!(IFG2 & UCB0TXIFG));
UCB0TXBUF = addr;
while(!(IFG2 & UCB0TXIFG));
// 发送RESTART信号
UCB0CTL1 &= ~UCTR;
UCB0CTL1 |= UCTXSTT;
while(!(IFG2 & UCB0TXIFG));
// 发送设备地址,读取数据
UCB0TXBUF = (BMP180_ADDR << 1) | 0x01;
while(!(IFG2 & UCB0TXIFG));
// 接收数据
while(!(IFG2 & UCB0RXIFG));
data = UCB0RXBUF << 8;
while(!(IFG2 & UCB0RXIFG));
data |= UCB0RXBUF;
// 发送STOP信号
UCB0CTL1 |= UCTXSTP;
while(UCB0CTL1 & UCTXSTP);
return data;
}
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // 禁用看门狗
// 初始化I2C
P1SEL |= BIT6 + BIT7;
P1SEL2 |= BIT6 + BIT7;
UCB0CTL1 |= UCSWRST;
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;
UCB0CTL1 = UCSSEL_2 + UCSWRST;
UCB0BR0 = 10;
UCB0BR1 = 0;
UCB0CTL1 &= ~UCSWRST;
initUART(); // 初始化串口
// 读取BMP180的厂商ID,用于检测BMP180是否连接成功
unsigned int id = readByte(0xD0) << 8;
id |= readByte(0xD1);
if(id != 0x55) { // 厂商ID应为0x55
printf("BMP180 not found\r\n");
return;
}
// 读取BMP180的温度,并计算出实际温度值
writeByte(BMP180_CTRL_REG, BMP180_TEMP_REG);
__delay_cycles(5000); // 等待BMP180完成温度测量
unsigned int ut = readWord(0xF6);
long x1 = (ut - 0xAC6) * 160 / 32768;
long x2 = 160 * 7 * 2048 / 16000;
long b5 = x1 + x2;
long t = (b5 + 8) / 16;
// 读取BMP180的气压,并计算出实际气压值
writeByte(BMP180_CTRL_REG, BMP180_PRESSURE_REG + (3 << 6));
__delay_cycles(30000); // 等待BMP180完成气压测量
unsigned char msb = readByte(0xF6);
unsigned char lsb = readByte(0xF7);
unsigned char xlsb = readByte(0xF8);
long up = ((msb << 16) + (lsb << 8) + xlsb) >> (8 - 3);
long b6 = b5 - 4000;
x1 = (b6 * b6) >> 12;
x1 *= 16;
x2 = 160 * b6 / 2048;
long x3 = x1 + x2;
long b3 = (((long)readWord(0xB4)) * x3 + 2) >> 2;
x1 = 160 * b6 / 2048;
x2 = (b6 * b6) >> 11;
x2 *= 4;
x3 = (x2 >> 12) * 3755;
x2 = (x2 * b6) >> 12;
long b4 = readWord(0xB6);
long b7 = ((long)(up - b3)) * (50000 >> 3);
long p;
if(b7 < 0x80000000) {
p = (b7 * 2) / b4;
} else {
p = (b7 / b4) * 2;
}
x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16;
p += (x1 + x2 + 3791) >> 4;
printf("Temperature: %ld.%ld C\r\n", t / 10, t % 10);
printf("Pressure: %ld Pa\r\n", p);
}
```
注意:这个程序只是一个示例,实际应用中需要根据具体情况进行修改。例如,需要根据实际的CLK_FREQ和BAUDRATE值来计算正确的UBR值。另外,读取BMP180的气压数据需要进行一系列复杂的计算,可能需要使用浮点数和更高精度的整数计算。