Jump to content

roger430

Members
  • Content Count

    21
  • Joined

  • Last visited

  1. I recently purchased some watch crystals from China. I ordered 10 they sent me 60. Anyway, they have the following specifications: Load Capacitance: 12.5pf Equivalent Resistance: 35K Frequency Tolerance: 20 ppm Operating Temp Range: -20C to +70C I breadboarded up a test circuit using a MSP430G2553 and could not get the oscillator to start. I used two AA batteries for power, an excellent 3.3v mains power supply and a cheap charger type power supply with a 3.3v regulator (LM1117T) to no avail. To get the oscillator to start, I had to place a 10M resistor in parallel with the crystal. It then worked with the AA batteries and the 3.3v mains power supply. It did not startup with the El Cheapo charger until I added a 100mfd 25v capacitor across the charger output. The circuit now runs with all three power supplies and is dead on accurate and stable (32768HZ) according to my Frequency meter.
  2. :thumbup: Thanks guys, looks like it may not be worth the effort to get this thing to work with so many other displays available. I may get one just to mess with it a bit - the price is right!
  3. Does anyone have information on this LCD module? The price is right, however, I can't seem to find any information on it. http://www.goldmine-elec-products.com/p ... ber=g18246 Thanks in advance.
  4. Tweaked code to display 100's digit and to alternately display the temperature in Fahrenheit and Celsius.
  5. Here is my submission for this POTM: PCF8566 & MSP430G The project interfaces the Launchpad to a PCF8566 that controls a raw (no logic) LCD panel. The LCD panel that I used most likely cannot be purchased easily as I salvaged it from a scrapped digital blood pressure device. However, I believe the code should be adaptable to most any raw LCD display. The code as written will display the temperature alternately between Fahrenheit and Celsius and a small character in the upper right hand corner of the display will change from F to C accordingly.
  6. Thanks for the invitation to submit this to POTM, however, I don't feel that this experiment would qualify as a candidate for POTM. I believe this project is too specific in nature as it contains an LCD display that most likely cannot be purchased anywhere. It was salvaged from a scrapped digital blood pressure device. The code could possibly be used with other raw LCD displays - don't know for sure. Thanks, Roger
  7. I managed to cobble together a workable temperature display of the internal MSP430 temperature sensor. I used the small character in the upper right hand corner of the display as a degree symbol (actually the character 0). I used a table lookup for the characters 0 - 9. Right now it only displays the temp in two digits. I need to display 3 digits here in Texas - temps last summer were mostly in the 100's. Here's a picture followed by the code if anyone is interested (the schematic has been updated above): //****************************************************************************** // This project is a simple display of the internal temperature sensor // of the MSP430G2231 utilizing a raw (no logic) LCD panel and a PCF8566 // display driver. The MSP430 communicates with the PCF8566 using 2 wires // via I2C. Temperatures up to 199F will be displayed, however, no provision // has been made for negative temperatures. (Rarely gets that cold if at all // in this part of Texas.) I2c code came directly from the example code TI // has provided. // Roger430 - December, 2011 // // MSP430G2x21/G2x31 Demo - I2C Master Transmitter / Receiver, multiple bytes // // Description: I2C Master communicates with I2C Slave using // the USI. Master data should increment from 0x55 with each transmitted byte // and Master determines the number of bytes received, set by // the Number_of_Bytes value. LED off for address or data Ack; // LED on for address or data NAck. // ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz // // // ***THIS IS THE MASTER CODE*** // // Slave Master // PCF8566 MSP430G2x31 // ----------------- ----------------- // | | /|\| XIN|- // | Address: | | | | // | 0x7C | --|RST XOUT|- // | 0111 1100 | | | // | | | | // | | | P1.0|-> LED // | Pin 2 SDA |<-------|P1.6/SDA | // | Pin 1 SCL |<-------|P1.7/SCL | // // Note: internal pull-ups are used in this example for SDA & SCL // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 // //****************************************************************************** #include void Master_Transmit(void); void Setup_USI_Master_TX(void); // Initialize data: static char MST_DataInit[10] = {0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x00}; // LCD segment array: static const char Digits[10] = {0xBE, 0x06, 0x7C, 0x5E, 0xC6, 0xDA, 0xFA, 0x0E, 0xFE, 0xCE}; // Transmit array: static char MST_DataT[7] = {0xC8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}; int number_of_bytes = 0; int digit1 = 0; int digit2 = 0; long temp; long IntDegF; long IntDegC; char *MST_Data; char SLV_Addr = 0x7C; int I2C_State = 0; int Bytecount = 0; int Transmit = 0; // State variable int FCflag = 1; //Fahrenheit/Celsius flag void Data_TX (void); void GetDigits(int); void main(void) { volatile unsigned int i; // Use volatile to prevent removal WDTCTL = WDTPW + WDTHOLD; // Stop watchdog if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) { while(1); // If calibration constants erased // do not load, trap CPU!! } ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; __enable_interrupt(); // Enable interrupts. TACCR0 = 30; // Delay to allow Ref to settle TACCTL0 |= CCIE; // Compare-mode interrupt. TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode. LPM0; // Wait for delay. TACCTL0 &= ~CCIE; // Disable timer Interrupt __disable_interrupt(); BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P1OUT = 0xC0; // P1.6 & P1.7 Pullups, others to 0 P1REN |= 0xC0; // P1.6 & P1.7 Pullups P1DIR = 0xFF; // Unused pins as outputs P2OUT = 0; P2DIR = 0xFF; _delay_cycles(100000); MST_Data = MST_DataInit; // Load initialize data number_of_bytes = 10; Master_Transmit(); // Initialize PCF8566 while(1) { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled __disable_interrupt(); temp = ADC10MEM; // IntDegF = ((temp - 630) * 761) / 1024; // Calculate Fahrenheit IntDegF = ((temp - 623) * 761) / 1024; // Calculate Fahrenheit //IntDegC = ((temp - 673) * 423) / 1024; // Calculate Celsius IntDegC = ((temp - 666) * 423) / 1024; // Calculate Celsius if (FCflag == 1) { GetDigits(IntDegF); MST_DataT[6] = 0xE8; // set small character to "F" FCflag = 0; // celsius on the next go-around } else { GetDigits(IntDegC); MST_DataT[6] = 0xB8; // set small character to "C" FCflag = 1; // fahrenheit on the next go-around } MST_DataT[3] = Digits[digit1]; // put 10's digit in array MST_DataT[4] = Digits[digit2]; // put units digit in array MST_Data = MST_DataT; // get data to xmit number_of_bytes = 7; Master_Transmit(); // transmit data to PCF8566 __enable_interrupt(); } } /****************************************************** // USI interrupt service routine // Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14 // Data Recieve : state 0 -> 2 -> 4 -> 6 -> 8 -> 14 ******************************************************/ #pragma vector = USI_VECTOR __interrupt void USI_TXRX (void) { switch(__even_in_range(I2C_State,14)) { case 0: // Generate Start Condition & send address to slave P1OUT |= 0x01; // LED on: sequence start Bytecount = 0; USISRL = 0x00; // Generate Start Condition... USICTL0 |= USIGE+USIOE; USICTL0 &= ~USIGE; if (Transmit == 1){ USISRL = 0x7C; // Address is 0x48 << 1 bit + 0 (rw) } if (Transmit == 0){ USISRL = 0x91; // 0x91 Address is 0x48 << 1 bit // + 1 for Read } USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address I2C_State = 2; // next state: rcv address (N)Ack break; case 2: // Receive Address Ack/Nack bit USICTL0 &= ~USIOE; // SDA = input USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit I2C_State = 4; // Go to next state: check (N)Ack break; case 4: // Process Address Ack/Nack & handle data TX USICTL0 |= USIOE; // SDA = output if (USISRL & 0x01) // If Nack received... { // Send stop... USISRL = 0x00; USICNT |= 0x01; // Bit counter=1, SCL high, SDA low I2C_State = 14; // Go to next state: generate Stop P1OUT |= 0x01; // Turn on LED: error } else { // Ack received, TX data to slave... USISRL = MST_Data[bytecount]; // Load data byte USICNT |= 0x08; // Bit counter = 8, start TX I2C_State = 10; // next state: receive data (N)Ack //Bytecount++; P1OUT &= ~0x01; // Turn off LED break; } case 10: // Receive Data Ack/Nack bit USICTL0 &= ~USIOE; // SDA = input USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit I2C_State = 12; // Go to next state: check (N)Ack break; case 12: // Process Data Ack/Nack & send Stop USICTL0 |= USIOE; if (Bytecount == number_of_bytes){// If last byte USISRL = 0x00; I2C_State = 14; // Go to next state: generate Stop P1OUT |= 0x01; USICNT |= 0x01; } // set count=1 to trigger next state else{ P1OUT &= ~0x01; // Turn off LED Data_TX(); // TX byte } break; case 14:// Generate Stop Condition USISRL = 0x0FF; // USISRL = 1 to release SDA USICTL0 |= USIGE; // Transparent latch enabled USICTL0 &= ~(USIGE+USIOE); // Latch/SDA output disabled I2C_State = 0; // Reset state machine for next xmt LPM0_EXIT; // Exit active for next transfer break; } USICTL1 &= ~USIIFG; // Clear pending flag } void Data_TX (void){ USISRL = MST_Data[bytecount]; // Load data byte USICNT |= 0x08; // Bit counter = 8, start TX I2C_State = 10; // next state: receive data (N)Ack Bytecount++; } void Setup_USI_Master_TX (void) { _DINT(); Bytecount = 0; Transmit = 1; USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt USICKCTL = USIDIV_7+USISSEL_2+USICKPL; // USI clk: SCL = SMCLK/128 USICNT |= USIIFGCC; // Disable automatic clear control USICTL0 &= ~USISWRST; // Enable USI USICTL1 &= ~USIIFG; // Clear pending flag _EINT(); } void Master_Transmit(void){ Setup_USI_Master_TX(); USICTL1 |= USIIFG; // Set flag and start communication LPM0; // CPU off, await USI interrupt __delay_cycles(2000000); // Delay between comm cycles } // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) } #pragma vector=TIMERA0_VECTOR __interrupt void ta0_isr(void) { TACTL = 0; LPM0_EXIT; // Exit LPM0 on return } void GetDigits(tempVal) { if (tempVal >= 100 ) { tempVal -= 100; MST_DataT[2] = 0x06; // set 100's digit to "1" (no provision for > 199) } else { MST_DataT[2] = 0x00; // or not } digit1 = tempVal/10; // separate 10's digit digit2 = tempVal%10; // separate units digit } ** Added code to alternately display the temperature in Fahrenheit and Celsius. The symbol in the upper right hand corner will change from F to C accordingly. ** Added display of 100's digit - Dec. 2011
  8. Thanks for the ideas! :clap: :clap: I came across this offer from "The Electronic Goldmine": http://www.goldmine-elec-products.com/prodinfo.asp?number=G17892 3 LCD displays for $0.99! I wonder what treasure could be hidden in those! Now that I have a way of checking them out, I may just get a bunch!
  9. Well here it is in all its glory! If only I could find a use for it. . . The toughest part was trying to figure out the configuration of the Raw LCD display. This one happened to have 4 back planes and used only 2 pins for each character for a total of 20 pins. It has a few graphics and a low battery indicator. It also has a small 7 segment character in the upper right hand corner as seen in the photo. The PCF8566 plays nicely with the MSP420G2231 and works very well with 3.3v. and here is the code: //****************************************************************************** // MSP430G2x21/G2x31 Demo - I2C Master Transmitter / Reciever, multiple bytes // // Description: I2C Master communicates with I2C Slave using // the USI. Master data should increment from 0x55 with each transmitted byte // and Master determines the number of bytes recieved, set by // the Number_of_Bytes value. LED off for address or data Ack; // LED on for address or data NAck. // ACLK = n/a, MCLK = SMCLK = Calibrated 1MHz // // // ***THIS IS THE MASTER CODE*** // // Slave Master // (msp430g2x21_usi_15.c) // MSP430G2x21/G2x31 MSP430G2x21/G2x31 // ----------------- ----------------- // /|\| XIN|- /|\| XIN|- // | | | | | | // --|RST XOUT|- --|RST XOUT|- // | | | | // LED <-|P1.0 | | | // | | | P1.0|-> LED // | SDA/P1.7|------->|P1.6/SDA | // | SCL/P1.6|<-------|P1.7/SCL | // // Note: internal pull-ups are used in this example for SDA & SCL // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include #define number_of_bytes 10 // How many bytes? void Master_Transmit(void); //void Master_Recieve(void); void Setup_USI_Master_TX(void); //void Setup_USI_Master_RX(void); // First two bytes are PCF8566 commands static char MST_Data[10] = {0xC8, 0x00, 0xBE, 0x06, 0x7C, 0x5E, 0xC6, 0xDA, 0xBE, 0x00}; //character segment map char SLV_Addr = 0x7C; int I2C_State = 0; int Bytecount = 0; int Transmit = 0; // State variable void Data_TX (void); void main(void) { volatile unsigned int i; // Use volatile to prevent removal WDTCTL = WDTPW + WDTHOLD; // Stop watchdog if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) { while(1); // If calibration constants erased // do not load, trap CPU!! } BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P1OUT = 0xC0; // P1.6 & P1.7 Pullups, others to 0 P1REN |= 0xC0; // P1.6 & P1.7 Pullups P1DIR = 0xFF; // Unused pins as outputs P2OUT = 0; P2DIR = 0xFF; while(1) { Master_Transmit(); //_NOP(); // Used for IAR } } /****************************************************** // USI interrupt service routine // Data Transmit : state 0 -> 2 -> 4 -> 10 -> 12 -> 14 ******************************************************/ #pragma vector = USI_VECTOR __interrupt void USI_TXRX (void) { switch(__even_in_range(I2C_State,14)) { case 0: // Generate Start Condition & send address to slave P1OUT |= 0x01; // LED on: sequence start Bytecount = 0; USISRL = 0x00; // Generate Start Condition... USICTL0 |= USIGE+USIOE; USICTL0 &= ~USIGE; if (Transmit == 1){ USISRL = 0x7C; // Address is 0x48 << 1 bit + 0 (rw) } if (Transmit == 0){ USISRL = 0x91; // 0x91 Address is 0x48 << 1 bit // + 1 for Read } USICNT = (USICNT & 0xE0) + 0x08; // Bit counter = 8, TX Address I2C_State = 2; // next state: rcv address (N)Ack break; case 2: // Receive Address Ack/Nack bit USICTL0 &= ~USIOE; // SDA = input USICNT |= 0x01; // Bit counter=1, receive (N)Ack bit I2C_State = 4; // Go to next state: check (N)Ack break; case 4: // Process Address Ack/Nack & handle data TX USICTL0 |= USIOE; // SDA = output if (USISRL & 0x01) // If Nack received... { // Send stop... USISRL = 0x00; USICNT |= 0x01; // Bit counter=1, SCL high, SDA low I2C_State = 14; // Go to next state: generate Stop P1OUT |= 0x01; // Turn on LED: error } else { // Ack received, TX data to slave... USISRL = MST_Data[bytecount]; // Load data byte USICNT |= 0x08; // Bit counter = 8, start TX I2C_State = 10; // next state: receive data (N)Ack //Bytecount++; P1OUT &= ~0x01; // Turn off LED break; } case 10: // Receive Data Ack/Nack bit USICTL0 &= ~USIOE; // SDA = input USICNT |= 0x01; // Bit counter = 1, receive (N)Ack bit I2C_State = 12; // Go to next state: check (N)Ack break; case 12: // Process Data Ack/Nack & send Stop USICTL0 |= USIOE; if (Bytecount == number_of_bytes){// If last byte USISRL = 0x00; I2C_State = 14; // Go to next state: generate Stop P1OUT |= 0x01; USICNT |= 0x01; } // set count=1 to trigger next state else{ P1OUT &= ~0x01; // Turn off LED Data_TX(); // TX byte } break; case 14:// Generate Stop Condition USISRL = 0x0FF; // USISRL = 1 to release SDA USICTL0 |= USIGE; // Transparent latch enabled USICTL0 &= ~(USIGE+USIOE); // Latch/SDA output disabled I2C_State = 0; // Reset state machine for next xmt LPM0_EXIT; // Exit active for next transfer break; } USICTL1 &= ~USIIFG; // Clear pending flag } void Data_TX (void){ USISRL = MST_Data[bytecount]; // Load data byte USICNT |= 0x08; // Bit counter = 8, start TX I2C_State = 10; // next state: receive data (N)Ack Bytecount++; } void Setup_USI_Master_TX (void) { _DINT(); Bytecount = 0; Transmit = 1; USICTL0 = USIPE6+USIPE7+USIMST+USISWRST; // Port & USI mode setup USICTL1 = USII2C+USIIE; // Enable I2C mode & USI interrupt USICKCTL = USIDIV_7+USISSEL_2+USICKPL; // USI clk: SCL = SMCLK/128 USICNT |= USIIFGCC; // Disable automatic clear control USICTL0 &= ~USISWRST; // Enable USI USICTL1 &= ~USIIFG; // Clear pending flag _EINT(); } void Master_Transmit(void){ Setup_USI_Master_TX(); USICTL1 |= USIIFG; // Set flag and start communication LPM0; // CPU off, await USI interrupt __delay_cycles(10000); // Delay between comm cycles }
  10. Sure, it's just an experiment with a raw LCD display that I salvaged from a digital device. I did this to get familiar with I2C and the PFC8566 was pretty cheap. I'll get a picture and clean up my code a bit and post it here shortly. Thanks for asking! Roger
  11. :oops: :oops: My bad! Turns out my Raw LCD display segment map was totally different than what I expected. I got the 4 backplane pins right but the segment pins were way off. Everything is working just fine now. I modified the I2c code in TI's example code "msp430g2x21_usi_12.c" to communicate with the PCF8566.
  12. Does anyone on this board have any experience in using the PCF8566 to drive glass LCD displays? It uses I2C for communications with a Master. I'm getting acknowledgments back from the PCF8566 after selecting its address and also from sending a command to it, however, subsequent data bytes display incorrectly. Any help would be greatly appreciated. Thanks, Roger430
  13. Thanks timotet! I couldn't get this display to work until I saw your post in RobG's "Using 3 wires to control parallel LCD display." The key was using RESET P1.7 on pin 3 of the display. After that it "lit up."
  14. gwdeveloper - Not sure, I obtained mine from Ebay for $4.29 including shipping. I haven't seen this power supply for sale anywhere else.
  15. I know, I know, not another temperature project . This one is a little different in that it is very simple and uses readily available and inexpensive components. A $1.99 display from Electronic Goldmine: http://www.goldmine-elec-products.com/p ... ber=G15318 or even cheaper at $1.85 from All Electronics: http://www.allelectronics.com/make-a-st ... LCD/1.html a $4.29 breadboard power supply that provides both 5.0vdc and 3.3vdc using and ordinary 9 - 12 vdc wall wart: http://www.ebay.com/itm/Perfect-High-Qu ... 3f0f10117f and a 74HC595N 8 bit shift register at a quantity of 5 for as low as $1.85 including shipping from Ebay. I started this project to learn more about ADC and the '595 8 bit shift register. Along the way I learned about integer to ascii conversion (necessary for displaying the temperature value). It was also just plain fun working with the LCD display. ' alt='>'> The schematic: ' alt='>'> Here's the code: //****************************************************************************** // A simple temperature display project utilizing a $1.99 surplus LCD display module, // a 74HC595N serial/parallel chip, TI Launchpad with an MSP430G2231 installed and a $4.29 // power supply from Ebay that provides 5vdc and 3.3vdc from a wall wart. // Code to obtain the temperature came directly from TI's example files, itoa function from // Google group comp.lang.c and display routines from RobG's "Using 3 wires to control // parallel LCD display with timotet's adaptation for the Wintek 1x24 char LCD display. // //R.G. Rioux - October, 2011 // // MSP430G2x31 Demo - ADC10, Sample A10 Temp and Convert to oC and oF // Description: A single sample is made on A10 with reference to internal // 1.5V Vref. Software sets ADC10SC to start sample and conversion - ADC10SC // automatically cleared at EOC. ADC10 internal oscillator/4 times sample // (64x) and conversion. In Mainloop MSP430 waits in LPM0 to save power until // ADC10 conversion complete, ADC10_ISR will force exit from any LPMx in // Mainloop on reti. Temperaure in oC stored in IntDegC, oF in IntDegF. // Uncalibrated temperature measured from device to device will vary with // slope and offset - please see datasheet. // ACLK = n/a, MCLK = SMCLK = default DCO ~1.2MHz, ADC10CLK = ADC10OSC/4 // // D. Dang // Texas Instruments Inc. // October 2010 // // MSP430G2x31 // ----------------- // /|\| XIN|- // | | | // --|RST XOUT|- // | | // |A10 | // ENABLE<--|P1.4 P1.6|-->DATA // CLOCK<--|P1.5 | _____ // | P1.7|-->RESET (for Wintek 1x24 Char Display) // // Built with CCS Version 4.2.4.00033 // R.G. Rioux October 2011 //****************************************************************************** #include "msp430g2231.h" #include #include //------------------------------------------------------------------------------ // Display related definitions //------------------------------------------------------------------------------ #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define initDisplay() sendInstruction(0x1C); sendInstruction(0x14); sendInstruction(0x28); sendInstruction(0x4F); sendInstruction(0xE0) #define clearDisplay() sendInstruction(0x01); sendInstruction(0xE3); _delay_cycles(2000) #define DATAPIN BIT6 // P1.6 #define CLOCKPIN BIT5 // P1.5 #define ENABLEPIN BIT4 // P1.4 #define RESETPIN BIT7 // P1.7 //------------------------------------------------------------------------------ // Display related functions and variables //------------------------------------------------------------------------------ void send(char data, char registerSelect); void sendStr(char data[], int length); void reset(void); char charIndex = 0; char bitCounter = 0; //------------------------------------------------------------------------------ // Global variables in program //------------------------------------------------------------------------------ char buffer[4]; long temp; long IntDegF; long IntDegC; //------------------------------------------------------------------------------ // itoa functions //------------------------------------------------------------------------------ static char *i2a(unsigned i, char *a, unsigned r); char *itoa(int i, char *a, int r); // main void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT _delay_cycles(100000); // Wait for display to settle DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN + RESETPIN; // sets ENABLEPIN,CLOCKPIN,DATAPIN and RESETPIN to outputs P1OUT &= ~(CLOCKPIN + DATAPIN + RESETPIN); // sets CLOCKPIN,RESETPIN and DATAPIN low P1OUT |= ENABLEPIN; ADC10CTL1 = INCH_10 + ADC10DIV_3; // Temp Sensor ADC10CLK/4 ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON + ADC10IE; __enable_interrupt(); // Enable interrupts. TACCR0 = 30; // Delay to allow Ref to settle TACCTL0 |= CCIE; // Compare-mode interrupt. TACTL = TASSEL_2 | MC_1; // TACLK = SMCLK, Up mode. LPM0; // Wait for delay. TACCTL0 &= ~CCIE; // Disable timer Interrupt __disable_interrupt(); reset(); // reset Wintek 1x24 LCD display initDisplay(); // initialize display sendStr("Temperature:", 12); while(1) { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468 temp = ADC10MEM; IntDegF = ((temp - 630) * 761) / 1024; // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278 temp = ADC10MEM; IntDegC = ((temp - 673) * 423) / 1024; sendInstruction(0xF2); // position cursor itoa (IntDegF, buffer, 10); // convert to ascii chars sendStr(buffer, strlen(buffer)); send(0xB0, 1); sendStr("F", 1); sendInstruction(0xF7); // position cursor itoa(IntDegC, buffer, 10); sendStr(buffer, strlen(buffer)); send(0xB0, 1); sendStr("C", 1); } } // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) } #pragma vector=TIMERA0_VECTOR __interrupt void ta0_isr(void) { TACTL = 0; LPM0_EXIT; // Exit LPM0 on return } void send(char data, char registerSelect) { bitCounter = 0; while(bitCounter < 8) { (data & BIT7) ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); data <<= 1; P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } registerSelect ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); P1OUT &= ~ENABLEPIN; _delay_cycles(3000); P1OUT |= ENABLEPIN; _delay_cycles(10000); P1OUT &= ~ENABLEPIN; } void sendStr(char string[], int size) { int charIndex = 0; while(charIndex < size) { sendData(string[charIndex]); charIndex++; } } void reset() { P1OUT &= ~RESETPIN; // RESETPIN low _delay_cycles(10000); P1OUT |= RESETPIN; } /* ** The following two functions together make up an itoa() ** implementation. Function i2a() is a 'private' function ** called by the public itoa() function. ** ** itoa() takes three arguments: ** 1) the integer to be converted, ** 2) a pointer to a character conversion buffer, ** 3) the radix for the conversion ** which can range between 2 and 36 inclusive ** range errors on the radix default it to base10 ** Code from Google group comp.lang.c */ static char *i2a(unsigned i, char *a, unsigned r) { if (i/r > 0) a = i2a(i/r,a,r); *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; return a+1; } char *itoa(int i, char *a, int r) { if ((r < 2) || (r > 36)) r = 10; if (i < 0) { *a = '-'; *i2a(-(unsigned)i,a+1,r) = 0; } else *i2a(i,a,r) = 0; return a; }
×
×
  • Create New...