Jump to content
43oh

Cannot get lcd to work


Recommended Posts

Greetings,

 

Thank you all for the support.

 

I am trying to get some text displayed on an LCD but I cannot get it to work. I found some code and got rid of everything but the basics but for some reason I cannot get it to work. There is a timer interrupt within the code I'm not 100% sure what it does but i believe it triggers the reloading of the text to the LCD could someone clarify this for me?

 

Here is the code:

/*
 * UART TX demonstration program for MSP430G2231, using
 * SparkFun Serial LCD module.
 *
 * Hook up the RX line on the SparkFun Serial LCD backpack to
 * P1.1 (TXD) on the LaunchPad board, power everything appropriately,
 * and you're all set to go.
 *
 * Matthew R. Wilson <mwilson@mattwilson.org>
 * http://mattwilson.org/msp430/
 * August 16, 2010
 *
 * The code to deal with serial data transmission in the following
 * functions is copied and modified from the sample program that ships
 * with the TI MSP430 LaunchPad:
 *   ConfigureTimerUart()
 *   Transmit()
 *   Timer_A()
 *
 * Release for demonstration and education purposes only, I make no
 * promises that this code will even work properly, let alone do anything
 * useful.
 */

#include "msp430g2553.h"

// Pins on the MSP430 we're using
#define     TXD                   BIT1     // TXD on P1.1



//   Conditions for 9600 Baud SW UART, SMCLK = 1MHz
#define     Bitime                13       // 1,000,000 / 8 / 9600 = ~13

// variables for serial communication
unsigned char BitCnt;
unsigned int  TXByte;



// function prototypes
void TXString(char *string);
void ConfigureTimerUart(void);
void Transmit();
void brag(void);


void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  // Set clock to 1MHz, and SMCLK to 125kHz
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL = CALDCO_1MHZ;
  BCSCTL2 &= ~(DIVS_3);         //SMCLK is DCO/8

  // Set up the timer to simulate a UART
  ConfigureTimerUart();


  // wait for LCD display to initialize
  __delay_cycles(1000000);

  __enable_interrupt();



  brag();

  // Display the current button count, then go into LPM4. The button
  // interrupt handler will turn the CPU back on which will bring us back
  // to the beginning of the while() loop.
  while(1)
  {
    brag();
    __bis_SR_register(LPM4_bits);
  }
}


void brag(void)
{
  // Clear LCD
  TXByte = 0xFE; Transmit();
  TXByte = 0x01; Transmit();

  TXString("You pressed the button ");
\
  TXString("foo");
  TXString(" times");

}

// Transmit a string via serial UART by looping through it and transmitting
// each character one at a time.
void TXString(char *string)
{
  while(*string != 0)
  {
    TXByte = *string; Transmit();
    string++;
  }
}

// Set up timer for simulated UART. Copied from MSP430 LaunchPad sample code.
void ConfigureTimerUart(void)
{
  TACCTL0 = OUT;                             // TXD Idle as Mark
  TACTL = TASSEL_2 + MC_2 + ID_3;            // SMCLK/8, continuous mode
  P1SEL |= TXD;                              //
  P1DIR |= TXD;                              //
}

// Function Transmits Character from TXByte
// Copied from MSP430 LaunchPad sample code
void Transmit()
{
  BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
  while (TACCR0 != TAR)                       // Prevent async capture
    TACCR0 = TAR;                             // Current state of TA counter
  TACCR0 += Bitime;                     // Some time till first bit
  TXByte |= 0x100;                        // Add mark stop bit to TXByte
  TXByte = TXByte << 1;                 // Add space start bit
  TACCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
  while ( TACCTL0 & CCIE );                   // Wait for TX completion
}

// Timer A0 interrupt service routine
// Copied from MSP430 LaunchPad sample code
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
  TACCR0 += Bitime;                           // Add Offset to CCR0
  if (TACCTL0 & CCIS0)                        // TX on CCI0B?
  {
    if ( BitCnt == 0)
      TACCTL0 &= ~ CCIE;                     // All bits TXed, disable interrupt
    else
    {
      TACCTL0 |=  OUTMOD2;                    // TX Space
      if (TXByte & 0x01)
      TACCTL0 &= ~ OUTMOD2;                   // TX Mark
      TXByte = TXByte >> 1;
      BitCnt --;
    }
  }
}

Thanks once again for your patience :)

Link to post
Share on other sites

It looks like your smclk is 1Mhz/8, and then your timer setup also /8, so it's really /64. But your bittime is based on 1Mhz/8/9600. Can you point us to the source of your code example so that we can take a closer look?

 

May be try and not do one of the /8.

 

For debugging, you may want to 1st connect your uart via the Launchpad (Tx/Rx or P1.1/P1.2) setup and use a terminal program like putty or minicom to observe the transmit. At least you will be able to see garbage. A LCD module will show you nothing if your timing is off.

Link to post
Share on other sites

I am using Code Composer and the TI Launchpad dev board. The LCD is one sold through Spark fun https://www.sparkfun.com/products/9394  hooked up to a MSP430G2553. 

 

Here is the code I started with:

/*
 * UART TX demonstration program for MSP430G2231, using
 * SparkFun Serial LCD module.
 *
 * Hook up the RX line on the SparkFun Serial LCD backpack to
 * P1.1 (TXD) on the LaunchPad board, power everything appropriately,
 * and you're all set to go.
 *
 * Matthew R. Wilson <mwilson@mattwilson.org>
 * http://mattwilson.org/msp430/
 * August 16, 2010
 *
 * The code to deal with serial data transmission in the following
 * functions is copied and modified from the sample program that ships
 * with the TI MSP430 LaunchPad:
 *   ConfigureTimerUart()
 *   Transmit()
 *   Timer_A()
 *
 * Release for demonstration and education purposes only, I make no
 * promises that this code will even work properly, let alone do anything
 * useful.
 */

#include "msp430g2231.h"

// Pins on the MSP430 we're using
#define     TXD                   BIT1     // TXD on P1.1
#define     BUTTON                BIT3     // Button on P1.3

//   Conditions for 9600 Baud SW UART, SMCLK = 1MHz
#define     Bitime                13       // 1,000,000 / 8 / 9600 = ~13

// variables for serial communication
unsigned char BitCnt;
unsigned int  TXByte;

// How many times have we pushed the button?
unsigned int  buttonPresses = 0;

// function prototypes
void TXString(char *string);
void ConfigureTimerUart(void);
void Transmit();
void brag(void);
void itoa(unsigned int val, char *str, unsigned int limit);

void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  // Set clock to 1MHz, and SMCLK to 125kHz
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL = CALDCO_1MHZ;
  BCSCTL2 &= ~(DIVS_3);         //SMCLK is DCO/8

  // Set up the timer to simulate a UART
  ConfigureTimerUart();

  // Set up button (P1.3)
  P1DIR &= ~BUTTON;
  P1OUT |= BUTTON;
  P1REN |= BUTTON;
  P1IES |= BUTTON;
  P1IFG &= ~BUTTON;
  P1IE |= BUTTON;

  // Turn on the LED
  P1DIR |= (BIT0|BIT6);
  P1OUT |= BIT0;
  P1OUT &= ~BIT6;

  // wait for LCD display to initialize
  __delay_cycles(1000000);

  __enable_interrupt();

  // Set brightness full
  //TXByte = 0x7c; Transmit();
  //TXByte = 157; Transmit();

  brag();

  // Display the current button count, then go into LPM4. The button
  // interrupt handler will turn the CPU back on which will bring us back
  // to the beginning of the while() loop.
  while(1)
  {
    brag();
    __bis_SR_register(LPM4_bits + GIE);
  }
}

// base-10 itoa for positive numbers. Populates str with a null-terminated string.
// limit lets you overflow back to 1 when you hit the limit+1, 2*limit+1, ...
// make sure *str is an array that can hold the number of digits in your limit + 1.
void itoa(unsigned int val, char *str, unsigned int limit)
{
  int temploc = 0;
  int digit = 0;
  int strloc = 0;
  char tempstr[5]; //16-bit number can be at most 5 ASCII digits;

  if(val>limit)
    val %= limit;

  do
  {
    digit = val % 10;
    tempstr[temploc++] = digit + '0';
    val /= 10;
  } while (val > 0);

  // reverse the digits back into the output string
  while(temploc>0)
    str[strloc++] = tempstr[--temploc];

  str[strloc]=0;
}

// Output the number of button presses to LCD
void brag(void)
{
  // Clear LCD
  TXByte = 0xFE; Transmit();
  TXByte = 0x01; Transmit();

  TXString("You pressed the button ");
  char times[4];
  itoa(buttonPresses, times, 999);
  TXString(times);
  if(buttonPresses!=1)
    TXString(" times");
  else
    TXString(" time");
}

// Transmit a string via serial UART by looping through it and transmitting
// each character one at a time.
void TXString(char *string)
{
  while(*string != 0)
  {
    TXByte = *string; Transmit();
    string++;
  }
}

// Set up timer for simulated UART. Copied from MSP430 LaunchPad sample code.
void ConfigureTimerUart(void)
{
  TACCTL0 = OUT;                             // TXD Idle as Mark
  TACTL = TASSEL_2 + MC_2 + ID_3;            // SMCLK/8, continuous mode
  P1SEL |= TXD;                              //
  P1DIR |= TXD;                              //
}

// Function Transmits Character from TXByte
// Copied from MSP430 LaunchPad sample code
void Transmit()
{
  BitCnt = 0xA;                             // Load Bit counter, 8data + ST/SP
  while (TACCR0 != TAR)                       // Prevent async capture
    TACCR0 = TAR;                             // Current state of TA counter
  TACCR0 += Bitime;                     // Some time till first bit
  TXByte |= 0x100;                        // Add mark stop bit to TXByte
  TXByte = TXByte << 1;                 // Add space start bit
  TACCTL0 =  CCIS0 + OUTMOD0 + CCIE;          // TXD = mark = idle
  while ( TACCTL0 & CCIE );                   // Wait for TX completion
}

// Timer A0 interrupt service routine
// Copied from MSP430 LaunchPad sample code
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  TACCR0 += Bitime;                           // Add Offset to CCR0
  if (TACCTL0 & CCIS0)                        // TX on CCI0B?
  {
    if ( BitCnt == 0)
      TACCTL0 &= ~ CCIE;                     // All bits TXed, disable interrupt
    else
    {
      TACCTL0 |=  OUTMOD2;                    // TX Space
      if (TXByte & 0x01)
      TACCTL0 &= ~ OUTMOD2;                   // TX Mark
      TXByte = TXByte >> 1;
      BitCnt --;
    }
  }
}

// Update the button press count, and toggle LEDs, when the button is pressed
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
  buttonPresses++;
  P1OUT ^= BIT0;
  P1OUT ^= BIT6;
  P1IFG = 0; // clear interrupt
  __bic_SR_register_on_exit(LPM4_EXIT);
}
Link to post
Share on other sites

That appears to be a standard 16x2 LCD on the board which may work at 3.3v but needs the full 5v for the contrast. I had a similar problem trying to run an LCD (thought without the PIC controller) like that with a LaunchPad. It could be that your code is working fine but you don't see anything on the screen because at 3.6v there is no contrast. I would take @@RobG's advice and try it with 5v supply first.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...