#include "msp430g2231.h"
#define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0)
#define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A)
#define DHT11 0x10 // DHT11 on P1.4
#define UART_TBIT_DIV_2 (1000000 / (9600 * 2))
#define UART_TBIT (1000000 / 9600)
unsigned
int
txData;
// UART internal variable for TX
unsigned
char
rxBuffer;
// Received UART character
char
message1[] =
"Temp = 00.0 C "
;
char
message2[] =
"RH = 00.0 % "
;
void
TimerA_UART_init(
void
);
void
TimerA_UART_tx(unsigned
char
byte);
void
TimerA_UART_print(
char
*string);
void
main(
void
)
{
int
i;
long
x;
long
tickCount;
unsigned
char
bits[5];
char
temp;
char
rh;
unsigned
char
sum = 0;
int
cnt = 7;
int
idx = 0;
int
loopCnt = 10000;
WDTCTL = WDTPW + WDTHOLD;
// Stop watchdog timer
DCOCTL = 0x00;
// Set DCOCLK to 1MHz
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
P1OUT = 0x00;
// Initialise all GPIO
P1SEL = UART_TXD + UART_RXD;
// Timer function for TXD/RXD pins
P1DIR = 0xFF & ~UART_RXD;
// Set all pins but RXD to output
__enable_interrupt();
TimerA_UART_init();
// Start Timer_A UART
TimerA_UART_tx(0x7C);
TimerA_UART_tx(0x04);
for
(;;)
{
idx = 0;
for
(x = 0; x < 5; x++) bits[x] = 0;
while
(TACCTL0 & CCIE);
// Ensure last char got TX'd
__disable_interrupt();
P1DIR |= DHT11;
P1OUT &= ~DHT11;
for
(x = 0; x < 1800; x++);
P1OUT |= DHT11;
_nop();_nop();_nop();
P1DIR &= ~DHT11;
while
((P1IN & DHT11) == 0)
if
(loopCnt-- == 0)
break
;
loopCnt = 10000;
while
((P1IN & DHT11) == DHT11)
if
(loopCnt-- == 0)
break
;
//read DHT11 output
for
(i = 0; i < 40; i++)
{
loopCnt = 10000;
while
((P1IN & DHT11) == 0)
if
(loopCnt-- == 0)
break
;
tickCount = 0;
loopCnt = 100;
while
((P1IN & DHT11) == DHT11)
{
tickCount++;
if
(loopCnt-- == 0)
break
;
}
if
(tickCount > 1) bits[idx] |= (1 << cnt);
if
(cnt == 0)
{
cnt = 7;
idx++;
}
else
cnt--;
}
temp = bits[2];
rh = bits[0];
sum = ( bits[0] + bits[2]) & 0xFF;
if
((sum == bits[4]) && (temp < 100) && (rh < 100))
{
message1[7] = temp/10 + 48;
message1[8] = temp%10 + 48;
message2[7] = rh/10 + 48;
message2[8] = rh%10 + 48;
message1[11] = 223;
// Degree symbol
__enable_interrupt();
TimerA_UART_tx(0xFE);
TimerA_UART_tx(0x01);
//clear display
TimerA_UART_print(message1);
TimerA_UART_print(message2);
}
}
}
void
TimerA_UART_init(
void
)
{
TACCTL0 = OUT;
// Set TXD Idle as Mark = '1'
TACCTL1 = SCS + CM1 + CAP + CCIE;
// Sync, Neg Edge, Capture, Int
TACTL = TASSEL_2 + MC_2;
// SMCLK, start in continuous mode
}
void
TimerA_UART_tx(unsigned
char
byte)
{
while
(TACCTL0 & CCIE);
// Ensure last char got TX'd
TACCR0 = TAR;
// Current state of TA counter
TACCR0 += UART_TBIT;
// One bit time till first bit
TACCTL0 = OUTMOD0 + CCIE;
// Set TXD on EQU0, Int
txData = byte;
// Load global variable
txData |= 0x100;
// Add mark stop bit to TXData
txData <<= 1;
// Add space start bit
}
void
TimerA_UART_print(
char
*string)
{
while
(*string)
{
TimerA_UART_tx(*string++);
}
}
#pragma vector = TIMERA0_VECTOR
__interrupt
void
Timer_A0_ISR(
void
)
{
static
unsigned
char
txBitCnt = 10;
TACCR0 += UART_TBIT;
// Add Offset to CCRx
if
(txBitCnt == 0)
{
// All bits TXed?
TACCTL0 &= ~CCIE;
// All bits TXed, disable interrupt
txBitCnt = 10;
// Re-load bit counter
}
else
{
if
(txData & 0x01)
{
TACCTL0 &= ~OUTMOD2;
// TX Mark '1'
}
else
{
TACCTL0 |= OUTMOD2;
// TX Space '0'
}
txData >>= 1;
txBitCnt--;
}
}
#pragma vector = TIMERA1_VECTOR
__interrupt
void
Timer_A1_ISR(
void
)
{
static
unsigned
char
rxBitCnt = 8;
static
unsigned
char
rxData = 0;
switch
(__even_in_range(TAIV, TAIV_TAIFG)) {
// Use calculated branching
case
TAIV_TACCR1:
// TACCR1 CCIFG - UART RX
TACCR1 += UART_TBIT;
// Add Offset to CCRx
if
(TACCTL1 & CAP)
{
// Capture mode = start bit edge
TACCTL1 &= ~CAP;
// Switch capture to compare mode
TACCR1 += UART_TBIT_DIV_2;
// Point CCRx to middle of D0
}
else
{
rxData >>= 1;
if
(TACCTL1 & SCCI)
{
// Get bit waiting in receive latch
rxData |= 0x80;
}
rxBitCnt--;
if
(rxBitCnt == 0)
{
// All bits RXed?
rxBuffer = rxData;
// Store in global variable
rxBitCnt = 8;
// Re-load bit counter
TACCTL1 |= CAP;
// Switch compare to capture mode
__bic_SR_register_on_exit(LPM0_bits);
// Clear LPM0 bits from 0(SR)
}
}
break
;
}
}
// AUTOMATIC COFFEE DRYING SYSTEM
// Joel Corporan, Kenneth Aviles, Christian Montes
// Spring 2015
#include "msp430f5529.h"
#define UART_TXD 0x08 // TXD on P1.1 (Timer0_A.OUT0)
#define UART_RXD 0x10 // RXD on P1.2 (Timer0_A.CCI1A)
#define DHT11 0x02 // DHT11 on P1.4
#define UART_TBIT_DIV_2 (1000000 / (9600 * 2))
#define UART_TBIT (1000000 / 9600)
unsigned int txData; // UART internal variable for TX
unsigned char rxBuffer; // Received UART character
char message1[] = "Temp = 00.0 C ";
char message2[] = "RH = 00.0 % ";
void TimerA_UART_init(void);
void TimerA_UART_tx(unsigned char byte);
void TimerA_UART_print(char *string);
void main(void)
{
int i;
long x;
long tickCount;
unsigned char bits[5];
char temp;
char rh;
unsigned char sum = 0;
int cnt = 7;
int idx = 0;
int loopCnt = 80;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P5SEL |= BIT4+BIT5; // Port select XT1
UCSCTL6 &= ~(XT1OFF); // XT1 On
UCSCTL6 |= XCAP_3; // Internal load cap
// Loop until XT1 fault flag is cleared
do
{
UCSCTL7 &= ~XT1LFOFFG; // Clear XT1 fault flags
}while (UCSCTL7&XT1LFOFFG); // Test XT1 fault flag
// Initialize DCO to 2.45MHz
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_3; // Set RSELx for DCO = 4.9 MHz
UCSCTL2 = FLLD_1 + 29; // Set DCO Multiplier for 2.45MHz
// (N + 1) * FLLRef = Fdco
// (74 + 1) * 32768 = 2.45MHz
// Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0); // Enable the FLL control loop
// Worst-case settling time for the DCO when the DCO range bits have been
// changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx
// UG for optimization.
// 32 x 32 x 2.45 MHz / 32,768 Hz = 76563 = MCLK cycles for DCO to settle
__delay_cycles(31250);
// Loop until XT1,XT2 & DCO fault flag is cleared
do
{
UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
P1OUT = 0x00; // Initialise all GPIO
P8OUT = 0x00; // Initialise all GPIO
P1SEL = BIT2 + BIT3; // Timer function for TXD/RXD pins
P1DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output
P8DIR = 0xFF;
__enable_interrupt();
TimerA_UART_init(); // Start Timer_A UART
TimerA_UART_tx(0x7C);
TimerA_UART_tx(0x04);
for (;;)
{
idx = 0;
for(x = 0; x < 5; x++) bits[x] = 0;
while (TA0CCTL0 & CCIE); // Ensure last char got TX'd
__disable_interrupt();
P8DIR |= DHT11;
P8OUT &= ~DHT11;
__delay_cycles(1000);//
P8OUT |= DHT11;
__delay_cycles(30);//
P8DIR &= ~DHT11;
loopCnt = 80;
while((P8IN & DHT11) == 0){
if(loopCnt-- == 0) break;
}
loopCnt = 80;
while((P8IN & DHT11) == DHT11){
if(loopCnt-- == 0) break;
}
int data[40];
//read DHT11 output
for (i = 0; i < 40; i++)
{
loopCnt = 10000;
while((P8IN & DHT11) == 0){
__delay_cycles(2);
if(loopCnt-- == 0) break;
tickCount = 0;
}
loopCnt = 100;
while((P8IN & DHT11) == DHT11)
{
__delay_cycles(6);
tickCount++;
if(loopCnt-- == 0) break;
}
data[i] = tickCount;
if(loopCnt < 99) bits[idx] |= (1 << cnt);
if (cnt == 0)
{
cnt = 7;
idx++;
}
else cnt--;
}
sum = ( bits[0] + bits[1] + bits[2] + bits[3]);// & 0xFF;
if((sum == bits[4]))
{
float t, h;
h = bits[0] << 8 | bits[1];
h /= 10.0;
t = (float)(bits[2] & 0x7F)* 256 + (float)bits[3];
t = (float)t / 10.0;
if ((bits[2] & 0x80) != 0) t *= -1;
int hum = (int)h;
float humDec = h - hum;
message2[7] = hum;
message2[8] = humDec;
//message1[7] = h%10;
//message1[8] = temp%10 + 48;
//message2[7] = t;
//message2[8] = rh%10 + 48;
//message1[11] = 223; // Degree symbol
__enable_interrupt();
TimerA_UART_tx(0xFE);
TimerA_UART_tx(0x01); //clear display
TimerA_UART_print(message1);
TimerA_UART_print(message2);
//printf("Humidity = %.2f %% Temperature = %.2f *C \n", h, t );
//printf(message1);
//printf("\n");
//printf(message2);
}
int k = data[0];
__delay_cycles(1000000);//
}
}
void TimerA_UART_init(void)
{
TA0CCTL0 = OUT; // Set TXD Idle as Mark = '1'
TA0CCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int
TA0CTL = TASSEL_2 + MC_2 + TAIE; // SMCLK, start in continuous mode
}
void TimerA_UART_tx(unsigned char byte)
{
while (TA0CCTL0 & CCIE); // Ensure last char got TX'd
TA0CCR0 = TA0R; // Current state of TA counter
TA0CCR0 += UART_TBIT; // One bit time till first bit
TA0CCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int
txData = byte; // Load global variable
txData |= 0x100; // Add mark stop bit to TXData
txData <<= 1; // Add space start bit
}
void TimerA_UART_print(char *string)
{
while (*string)
{
TimerA_UART_tx(*string++);
}
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
{
static unsigned char txBitCnt = 10;
TA0CCR0 += UART_TBIT; // Add Offset to CCRx
if (txBitCnt == 0)
{ // All bits TXed?
TA0CCTL0 &= ~CCIE; // All bits TXed, disable interrupt
txBitCnt = 10; // Re-load bit counter
}
else
{
if (txData & 0x01)
{
TA0CCTL0 &= ~OUTMOD2; // TX Mark '1'
}
else
{
TA0CCTL0 |= OUTMOD2; // TX Space '0'
}
txData >>= 1;
txBitCnt--;
}
}
#pragma vector = TIMER0_A1_VECTOR
__interrupt void Timer0_A1_ISR(void)
{
static unsigned char rxBitCnt = 8;
static unsigned char rxData = 0;
switch (__even_in_range(TA0IV, TA0IV_TAIFG)) { // Use calculated branching
case TA0IV_TACCR1: // TACCR1 CCIFG - UART RX
TA0CCR1 += UART_TBIT; // Add Offset to CCRx
if (TA0CCTL1 & CAP)
{ // Capture mode = start bit edge
TA0CCTL1 &= ~CAP; // Switch capture to compare mode
TA0CCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0
}
else
{
rxData >>= 1;
if (TA0CCTL1 & SCCI)
{ // Get bit waiting in receive latch
rxData |= 0x80;
}
rxBitCnt--;
if (rxBitCnt == 0)
{ // All bits RXed?
rxBuffer = rxData; // Store in global variable
rxBitCnt = 8; // Re-load bit counter
TA0CCTL1 |= CAP; // Switch compare to capture mode
__bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR)
}
}
break;
}
}