消えゆく世界と流れる未来に最後の灯を since 2006/4/3
#include <msp430.h>
volatile unsigned char RXData[0x10]; // RX Data array
volatile unsigned char TXData[10]; // TX Data array
volatile unsigned char RXByteCnt=0; // RX number
volatile signed char TXByteCnt=9; // TX Counter
volatile unsigned char read=0;
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
P1SEL0 |= BIT2 | BIT3; // I2C pins
P1OUT &= ~(BIT0 | BIT1); // Communication Indicator
P1DIR |= BIT0 | BIT1;
P2IE |= BIT0;
P2IES &= ~BIT0;
PM5CTL0 &= ~LOCKLPM5;
P2IFG &= ~BIT0;
// Configure USCI_B0 for I2C mode
UCB0CTLW0 |= UCSWRST; // put eUSCI_B in reset state
UCB0CTLW0 |= UCMODE_3 | UCMST; // I2C master mode, SMCLK
UCB0CTLW1 |= UCASTP_2; // Automatic stop generated
UCB0BRW = 0x8; // baudrate = SMCLK(1MHz) / 16
UCB0I2CSA = 0x40; // Slave address = 0x40 = 1000000b (ADDR=GND or open)
UCB0CTLW0 &= ~UCSWRST; // clear reset register
UCB0IE |= UCTXIE0 | UCNACKIE; // transmit and NACK interrupt enable
TXData[9] = 0x07; // Address
TXData[8] = BIT7; // 0x07: Interruption Setting = DRDY_ENABLE
TXData[7] = 0; // 0x08: Temperature Offset Adjustment = none
TXData[6] = 0; // 0x09: Humidity Offset Adjustment = none
TXData[5] = 0; // 0x0a: Temperature Threshold LOW = none
TXData[4] = 0xff; // 0x0b: Temperature Threshold HIGH = none
TXData[3] = 0; // 0x0c: Humidity Threshold LOW = none
TXData[2] = 0xff; // 0x0d: Humidity Threshold HIGH = none
TXData[1] = BIT1 | BIT2 | BIT4 | BIT6; // 0x0e: DRDY/INT = Active High, DRDY Enable, 1Hz Auto measurement
TXData[0] = BIT0; // 0x0f: Measurement start
__delay_cycles(200);
while (UCB0CTLW0 & UCTXSTP);
UCB0CTLW0 |= UCTR | UCTXSTT; // transmit START condition
__bis_SR_register(LPM0_bits | GIE);
}
#pragma vector = USCI_B0_VECTOR
__interrupt void USCIB0_ISR(void) {
switch (__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG)) {
// NACK
case USCI_I2C_UCNACKIFG:
UCB0CTL1 |= UCTXSTT; //resend start if NACK
break;
// TX Interruption
case USCI_I2C_UCTXIFG0:
if (TXByteCnt+1) { // Write multiple bytes until TXByteCnt=0
P1OUT |= BIT0;
UCB0TXBUF = TXData[TXByteCnt];
TXByteCnt--;
} else {
if (read) { // Read data
UCB0IE |= UCRXIE | UCBCNTIE;
UCB0IE &= ~UCTXIE0;
UCB0CTLW0 &= ~UCTR;
__delay_cycles(20);
while (UCB0CTLW0 & UCTXSTP);
UCB0CTLW0 |= UCTXSTT;
} else { // Write data finishes
while (UCB0CTLW0 & UCTXSTP);
UCB0CTLW0 |= UCTXSTP; // transmit STOP condition
}
P1OUT &= ~BIT0;
}
UCB0IFG &= ~UCTXIFG;
break;
// RX Interruption
case USCI_I2C_UCRXIFG0:
RXData[RXByteCnt] = UCB0RXBUF;
RXByteCnt++;
break;
// RX Counter reached
case USCI_I2C_UCBCNTIFG:
P1OUT &= ~BIT1;
break;
default:
break;
}
}
#pragma vector=PORT2_VECTOR
__interrupt void Port2_ISR(void) {
P1OUT |= BIT1;
P2IFG &= ~BIT0;
RXByteCnt = 0;
TXByteCnt = 0;
UCB0TBCNT = 0x04; // Counter for multiple-byte read
read = 1;
TXData[0] = 0x00; // address
UCB0IE |= UCTXIE0;
__delay_cycles(20);
while (UCB0CTLW0 & UCTXSTP);
UCB0CTLW0 |= UCTR | UCTXSTT; // transmit START condition
}