Jump to content

timotet

Members
  • Content Count

    223
  • Joined

  • Last visited

  • Days Won

    1

Reputation Activity

  1. Like
    timotet reacted to username in MSP430 Reflow Oven   
    Hey all,

    Nate here, made a nice little reflow oven to help me in the construction of surface mount boards. Got a video explaining it all here:

    PCBs and Control Boards for sale here: viewtopic.php?f=22&t=2040
    No longer for sale, no time to pump any out.
     

    Project Video:





    Project Pics:







    Schematic:This is my old V1 schematic. Todo if you want a better board:
    -Use a MSP430G2553 MCU (more pins and flash)
    -Use a non EOL thermocouple driver IC: MAX31855KASA+
    -Add in a FT230XS for a USB interface
    -Add flyback protection to relay LSD if a mechanical relay is used.
     
    Full size at link:
    http://forum.43oh.com/uploads/monthly_12_2011/post-4818-135135531417.jpg
     



    Oven: Convection (30 usd)
    http://www.walmart.com/ip/Black-Decker-Toaster-Oven-Stainless-Steel/16913546
     
    Oven: IR (recommended that you use an IR oven of sorts)
    http://www.walmart.com/ip/George-Foreman-Infrared-Countertop-Oven-with-Rotisserie/19411514
     
     
    C# GUI for live plotting:

     

    Here is the BOM:

    Update: Schematic has most Part #s on it
     
    Thermal-couple: (Important that it is low thermal mass and rated for temp range)
    Digikey: 290-1911-ND
     
    Thermal-couple IC:
    MAX31855KASA+
    MAX31855KASA+T
     
    Relay: (this is a mechanical relay. I salvaged a SSR for my V2. I highly recommend you use an SSR for long life and quicker switching times)
    Digikey: T9AS1D22-5-ND (Relay)

    Misc Digikey Part # (Part Discription)
    MC78M05CDTGOS-ND (5V regulator Dpak)
    445-1590-1-ND ( CAP CER 1.0UF 25V Y5V 0805)
    754-1133-1-ND ( LED 2X1.2MM 630NM RD WTR CLR SMD)
    754-1127-1-ND (LED 2X1.2MM 570NM GN WTR CLR SMD)
    CP-102B-ND (CONN POWER JACK 2.5MM PCB CIRC)
    785-1112-1-ND (MOSFET N-CH 20V 25A TO-252 (Relay))
    IRLML6344TRPBFCT-ND ( MOSFET N-CH 30V 5A SOT23 (SSR Load))
    RMCF0805JT100KCT-ND ( RES 100K OHM 1/8W 5% 0805 SMD)
    RMCF0805JT47K0CT-ND ( RES 47K OHM 1/8W 5% 0805 SMD)
    RMCF0805FT499RCT-ND ( RES 499 OHM 1/8W 1% 0805 SMD)
    296-8247-5-ND (IC 8-BIT SHIFT REGISTER 14-SOIC)
    296-28430-1-ND (IC MCU 16BIT 20TSSOP)
    RMCF0805JT1K00CT-ND ( RES 1K OHM 1/8W 5% 0805 SMD)
    CT94EY104-ND (TRIMMER 100K OHM 0.5W TH)
    MCP1700T3302ETTCT-ND ( IC REG LDO 3.3V 250MA SOT23-3)

    + a 16x2 LCD display
    + some dip headers that are used for jumping and programing.
    + 5mm/.2in lead spacing terminal headers for relay and thermocouple input.
  2. Like
    timotet reacted to oPossum in Tiny printf() - C version   
    CCS requires labels in asm code to begin in the first column, so leading spaces will cause problems. This is typical for assembler code.
     
    Firefox may have problems with copy/paste from the forum. Chrome, Safari and IE seem to work as expected.
     
    To use the printf() with an LCD, just create a function named putc() that sends a single character to the LCD. If you find some sample code for LCD, there will probably a function that does this - just rename it.
     
    You will also need a puts() function. That can be this...
     

    void puts(char *s) { while(*s) putc(*s++); }
  3. Like
    timotet reacted to bluehash in Tiny printf() - C version   
    I made a new project. Copied the two code snippets from the first post into two different files. Also added serial.asm as a separate file.
  4. Like
    timotet reacted to oPossum in Tiny printf() - C version   
    You also need serial.asm from here
     
    It will all fit in a 2211/2231.
  5. Like
    timotet reacted to bluehash in Tiny printf() - C version   
    It will be in a separate file - serial.asm
    I totally forgot about putc()
     
    Working project attached.
    printf_1.zip
  6. Like
    timotet reacted to xpg in Eclipse plugin for mspdebug and msp430-gcc   
    Hi guys,

    I've finally hacked together a plugin for Eclipse that allows the msp430-gcc toolchain to be used from within Eclipse more easily.
    I must warn you that this is by no means finished, but I wanted to get it out there to get some opinions before I spend too much time on it.

    Features and Limitations:

    - Supports msp430-gcc macro and include directory discovery (though msp430-gcc must be in your PATH).
    - Extracts list of supportet MCUs from msp430-gcc, and allows target MCU to be easily selected and changed.
    - Use mspdebug to upload to target (only Launchpad is supported and the device is autodetected).
    - Only Linux and Windows are supported at this point.
    - Binary toolchains are provided for Linux and Windows, in order to ease installation.

    Changelog:
    1.0.5.1

    -Added Windows support.
    -Added dependency on "Target Management Terminal".
    -Add .cpp as C++ extension.
    -Support for FRAM board (by using a newer version of mspdebug).
    -Fix a bug: mspdebug fails to startup successfully for debugging session.
    -Group MCU List to make selection easier.
    -Remove usage of stdbuf.
    -Simplify tool selection by adding an "Activate"-button to the tool manager.
    -Add support for static libraries (project type).
    -Kill mspdebug when debugger is stopped.
    -"tilib" to the mspdebug driver selection.
     
    1.0.4.1
    -gcc, gdb, and mspdebug are no longer distributed as an eclipse plugin, but as a separate download package. This allows the tools to be installed in a user select location, rather than trying to install into the eclipse directory.
    -MSP430 C/C++ projects can now be created.
    -The protocol (SBW, JTAG) used by MSPDebug can now be selected.
     
    Installation:
    Add http://eclipse.xpg.dk as a software source in Eclipse, and install the Msp430Eclipse plugin.
    Currently, only Indigo is supported, but the plugin might work with Helios and Juno as well.

    If your system does not have up-to-date version of msp430-gcc, msp430-gdb, and mspdebug, you can download one of the following tool-packages:

    Linux 64-bit: msp430-toolchain-linux-amd64-3.0.tar.bz2
    Linux 32-bit: msp430-toolchain-linux-i386-2.1.tar.bz2
    Windows 32-bit: msp430-toolchain-win-x86-3.0.zip
    Mac OS X: msp430-toolchain-mac_os_x-x86_64-2.2.tar.bz2

    Extract the package in an appropriate location ($HOME, for instance), and go to Eclipse (with the MSP430Eclipse plugin installed), and from the menu select MSP430->Tool Manager. Click the "Add..."-button, and browse to the tool-package directory. Select the tool-chain and press the "Activate"-button in order to tell Eclipse to use it.

    You can verify that the right tool-package is used by going to the Eclipse preference and select "MSP430". Here you will be able to see and choose what tools are used from which package.

    For windows, you will need to install USB-drivers as described in the MSPDebug FAQ.

    Getting Started:
    In order to use the MSP430 features, you have to create a new C project and choose "Empty Project" from the "MSP430 Cross Target Application" group. It is possible to select the target MCU from the wizard, but this does currently not work.

    After having created the project, right click on it and select properties. In the "MSP430"-setting it is possible to select the target MCU. Remember to press "Apply" in order for the selection to take effect.

    After having added some source files and compiled the project, you can upload it to the MSP430 by choosing the MSP430-menu, and selecting the "Upload to target action"

    Using the Debugger
    In order to debug your program, go to the "Debug Configuration"-dialog, and create a new configuration in the "MPS430 Debug"-group (by right-clicking it). Having that new configurations elected, simply click "Debug".
     
    For people interested in hacking on the source code of msp430Eclipse, it is available at gitorious: https://gitorious.org/msp430eclipse
     

    Updated September 3rd: New version released (1.0.5.1), updated description
    Updated April 23rd 2013: Links to toolchains updated.
    Updated April 25th 2013: Added link to gitorious project.
  7. Like
    timotet reacted to fj604 in Interfacing the Launchpad with MAX6956 I2C LED driver   
    Here is a slightly modified version that implements a repeat start on I2C.
     
    It is explained here:
    http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/105688.aspx
     

    /* * Interfacing MSP430G2231 to MAX6956 I2C LED driver and I/O expander Pins MSP430G2231 MAX6956 1 DVCC ----------- 28 V+ 8 P1.6/SCL ----------- 26 SCL 9 P1.7/SDA ----------- 25 SDA 14 DVSS ----------- 2 GND ----------- GND 3 GND ----------- GND 4 AD0 ----------- GND 27 AD1 ----------- GND 1 ISET -/\/39K\/\- GND 12 P19 ----------- LED1 13 P20 ----------- LED2 14 P21 ----------- LED3 8 P15 ----/ ----- GND Upon startup, LED1-3 will light up for about 1.5 seconds, then LED2-3 will start glowing intermittently. While a button on P15 is pushed, LED1 will change brightness. */ #include #define PIN_CS BIT1 #define PIN_SCL BIT6 #define PIN_SDA BIT7 #define DELAY 40000 #define MAX6956_ADDR 0x80 #define ACK 0x00 #define NACK 0xFF void i2c_init(void) { BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P1REN |= PIN_SCL | PIN_SDA; // Enable pullup resistors for I2C termination P1OUT |= PIN_SCL | PIN_SDA; USICTL0 = USIPE7 | USIPE6 | USIMST | USISWRST; // SDA enable, SCL enable, Master mode, release USICTL1 = USII2C | USIIE ; // USICKPH; // CKPH = 1, I2C, Interrupt Enable; USICKCTL = USIDIV_7 | USISSEL_2 | USICKPL; // Clock / 128, SMCLK, SCL inactive is high USICTL0 &= ~USISWRST; // Release from reset } void timer_init(void) { TACTL = TASSEL_2 | MC_0; // SMCLK, stop timer TACCTL0 = CCIE; // Enable timer compare interrupt } void sleep(unsigned int count) { TACCR0 = count; // Load top value in compare register TACTL |= TACLR | MC_1; // Clear counter, start timer in up mode _low_power_mode_0(); // Sleep in LPM0 until interrupt TACTL &= ~MC_1; // Stop timer } void i2c_tx_start(void) { USISRL = 0; USICTL0 |= USIGE | USIOE; // Latch enable, SDA enable USICTL0 &= ~USIGE; // Latch disable } void i2c_tx_rpt_start(void) { USICTL0 |= USIOE; // SDA enable USISRL = 0xFF; // Set MSB of USISRL to high USICNT = 1; // Transmit 1 bit for a surplus clock cycle _low_power_mode_0(); // Sleep in LPM0 until interrupt i2c_tx_start(); } void i2c_tx_stop(void) { USICTL0 |= USIOE; // SDA enable USISRL = 0; USICNT = 1; // Transmit 1 bit _low_power_mode_0(); // Sleep in LPM0 until interrupt USISRL = 0xFF; USICTL0 |= USIGE; // Latch enable USICTL0 &= ~(USIGE | USIOE); // Latch disable, SDA disable } unsigned char i2c_tx_byte(unsigned char byte) { USICTL0 |= USIOE; USISRL = byte; USICNT = 8; _low_power_mode_0(); // Sleep in LPM0 until interrupt USICTL0 &= ~USIOE; // SDA disable USICNT = 1; // Receive ACK bit _low_power_mode_0(); // Sleep in LPM0 until interrupt return USISRL & BIT0; // Return ACK = first bit of USISRL } unsigned char i2c_rx_byte(void) { unsigned char v; USICTL0 &= ~USIOE; USICNT = 8; _low_power_mode_0(); // Sleep in LPM0 until interrupt v = USISRL; return v; } void i2c_tx_ack(unsigned char ack) { USICTL0 |= USIOE; USISRL = ack; // Send ACK/NACK bit USICNT = 1; _low_power_mode_0(); // Sleep in LPM0 until interrupt } void max6956_send(unsigned char addr, unsigned char data) { i2c_tx_start(); i2c_tx_byte(MAX6956_ADDR); i2c_tx_byte(addr); i2c_tx_byte(data); i2c_tx_stop(); } unsigned char max6956_recv(unsigned char addr) { unsigned char v; i2c_tx_start(); i2c_tx_byte(MAX6956_ADDR); i2c_tx_byte(addr); i2c_tx_rpt_start(); // Generate a repeat start i2c_tx_byte(MAX6956_ADDR | BIT0); v = i2c_rx_byte(); // Read and send NACK to stop transmission i2c_tx_ack(NACK); i2c_tx_stop(); return v; } void sense(void) { static unsigned char g=0; if (!(max6956_recv(0x2F) & BIT0)) // Send No-op command and check bit 0 = button pushed max6956_send(0x19, g++ << 4); // Increase brightness of LED on port 19 } void leds(unsigned char v) { max6956_send(0x1A, v | (0x0F-v) << 4); // control brightness of LEDs on ports 20-21 sense(); } void main(void) { signed char i=0; WDTCTL = WDTPW + WDTHOLD; // Disable WDT i2c_init(); timer_init(); _enable_interrupts(); max6956_send(0x0C, 0x00); // set ports 16-19 to LED max6956_send(0x0D, 0x00); // set ports 20-23 to LED max6956_send(0x0B, 0xFF); // set ports 12-15 to GPIO Input with pullup max6956_send(0x33, 0x01); // Port 19 on max6956_send(0x34, 0x01); // Port 20 on max6956_send(0x35, 0x01); // Port 21 on max6956_send(0x07, 0x01); // Display test on _delay_cycles(1500000); // ~ 1.5s pause max6956_send(0x07, 0x00); // Display test off max6956_send(0x04, BIT0 | BIT6); // Individual segment current control, normal operation for (; { for (i=0; i<0x10; i++) { leds(i); sleep(DELAY); } for (i=0x0F; i>=0; i--) { leds(i); sleep(DELAY); } } } #pragma vector=USI_VECTOR __interrupt void usi_interrupt(void) { USICTL1 &= ~USIIFG; // Clear interrupt flag _low_power_mode_off_on_exit(); // Return from LPM } #pragma vector=TIMERA0_VECTOR __interrupt void timer_A_interrupt(void) { _low_power_mode_off_on_exit(); // Return from LPM }
  8. Like
    timotet reacted to fj604 in Interfacing the Launchpad with MAX6956 I2C LED driver   
    As promised here: http://www.43oh.com/forum/viewtopic.php?f=10&t=1015
     
    MAX6956 is an I2C LED driver / port expander, here is a demo:
     

    /* * Interfacing MSP430G2231 to MAX6956 I2C LED driver and I/O expander Pins MSP430G2231 MAX6956 1 DVCC ----------- 28 V+ 8 P1.6/SCL ----------- 26 SCL 9 P1.7/SDA ----------- 25 SDA 14 DVSS ----------- 2 GND ----------- GND 3 GND ----------- GND 4 AD0 ----------- GND 27 AD1 ----------- GND 1 ISET -/\/39K\/\- GND 12 P19 ----------- LED1 13 P20 ----------- LED2 14 P21 ----------- LED3 8 P15 ----/ ----- GND Upon startup, LED1-3 will light up for about 1.5 seconds, then LED2-3 will start glowing intermittently. While a button on P15 is pushed, LED1 will change brightness. */ #include #define PIN_CS BIT1 #define PIN_SCL BIT6 #define PIN_SDA BIT7 #define DELAY 40000 #define MAX6956_ADDR 0x80 #define ACK 0x00 #define NACK 0xFF void i2c_init(void) { BCSCTL1 = CALBC1_1MHZ; // Set DCO DCOCTL = CALDCO_1MHZ; P1REN |= PIN_SCL | PIN_SDA; // Enable pullup resistors for I2C termination P1OUT |= PIN_SCL | PIN_SDA; USICTL0 = USIPE7 | USIPE6 | USIMST | USISWRST; // SDA enable, SCL enable, Master mode, release USICTL1 = USII2C | USIIE ; // USICKPH; // CKPH = 1, I2C, Interrupt Enable; USICKCTL = USIDIV_7 | USISSEL_2 | USICKPL; // Clock / 128, SMCLK, SCL inactive is high USICTL0 &= ~USISWRST; // Release from reset } void timer_init(void) { TACTL = TASSEL_2 | MC_0; // SMCLK, stop timer TACCTL0 = CCIE; // Enable timer compare interrupt } void sleep(unsigned int count) { TACCR0 = count; // Load top value in compare register TACTL |= TACLR | MC_1; // Clear counter, start timer in up mode _low_power_mode_0(); // Sleep in LPM0 until interrupt TACTL &= ~MC_1; // Stop timer } void i2c_tx_start(void) { USISRL = 0; USICTL0 |= USIGE | USIOE; // Latch enable, SDA enable USICTL0 &= ~USIGE; // Latch disable } void i2c_tx_stop(void) { USICTL0 |= USIOE; // SDA enable USISRL = 0; USICNT = 1; // Transmit 1 bit _low_power_mode_0(); // Sleep in LPM0 until interrupt USISRL = 0xFF; USICTL0 |= USIGE; // Latch enable USICTL0 &= ~(USIGE | USIOE); // Latch disable, SDA disable } unsigned char i2c_tx_byte(unsigned char byte) { USICTL0 |= USIOE; USISRL = byte; USICNT = 8; _low_power_mode_0(); // Sleep in LPM0 until interrupt USICTL0 &= ~USIOE; // SDA disable USICNT = 1; // Receive ACK bit _low_power_mode_0(); // Sleep in LPM0 until interrupt return USISRL & BIT0; // Return ACK = first bit of USISRL } unsigned char i2c_rx_byte(void) { unsigned char v; USICTL0 &= ~USIOE; USICNT = 8; _low_power_mode_0(); // Sleep in LPM0 until interrupt v = USISRL; return v; } void i2c_tx_ack(unsigned char ack) { USICTL0 |= USIOE; USISRL = ack; // Send ACK/NACK bit USICNT = 1; _low_power_mode_0(); // Sleep in LPM0 until interrupt } void max6956_send(unsigned char addr, unsigned char data) { i2c_tx_start(); i2c_tx_byte(MAX6956_ADDR); i2c_tx_byte(addr); i2c_tx_byte(data); i2c_tx_stop(); } unsigned char max6956_recv(unsigned char addr) { unsigned char v; i2c_tx_start(); i2c_tx_byte(MAX6956_ADDR); i2c_tx_byte(addr); i2c_tx_stop(); i2c_tx_start(); i2c_tx_byte(MAX6956_ADDR | BIT0); v = i2c_rx_byte(); // Read and send NACK to stop transmission i2c_tx_ack(NACK); i2c_tx_stop(); return v; } void sense(void) { static unsigned char g=0; if (!(max6956_recv(0x2F) & BIT0)) // Send No-op command and check bit 0 = button pushed max6956_send(0x19, g++ << 4); // Increase brightness of LED on port 19 } void leds(unsigned char v) { max6956_send(0x1A, v | (0x0F-v) << 4); // control brightness of LEDs on ports 20-21 sense(); } void main(void) { signed char i=0; WDTCTL = WDTPW + WDTHOLD; // Disable WDT i2c_init(); timer_init(); _enable_interrupts(); max6956_send(0x0C, 0x00); // set ports 16-19 to LED max6956_send(0x0D, 0x00); // set ports 20-23 to LED max6956_send(0x0B, 0xFF); // set ports 12-15 to GPIO Input with pullup max6956_send(0x33, 0x01); // Port 19 on max6956_send(0x34, 0x01); // Port 20 on max6956_send(0x35, 0x01); // Port 21 on max6956_send(0x07, 0x01); // Display test on _delay_cycles(1500000); // ~ 1.5s pause max6956_send(0x07, 0x00); // Display test off max6956_send(0x04, BIT0 | BIT6); // Individual segment current control, normal operation for (; { for (i=0; i<0x10; i++) { leds(i); sleep(DELAY); } for (i=0x0F; i>=0; i--) { leds(i); sleep(DELAY); } } } #pragma vector=USI_VECTOR __interrupt void usi_interrupt(void) { USICTL1 &= ~USIIFG; // Clear interrupt flag _low_power_mode_off_on_exit(); // Return from LPM } #pragma vector=TIMERA0_VECTOR __interrupt void timer_A_interrupt(void) { _low_power_mode_off_on_exit(); // Return from LPM }
  9. Like
    timotet reacted to PentiumPC in Bluetooth Booster Pack / Breakout board - HC05/HC06   
    Fix 1 up for testing.
     
    Since it is just a simple breakout board, it works pretty well.

  10. Like
    timotet reacted to oPossum in Graphics library for Nokia 5110 - preview   
    I got this working with the Nokia 5110 LCD.
     
    Added support for vertical frame buffers so more output devices can be supported. Currently works with NTSC, PAL, VGA, and Nokia 5110.
     
    Now has vector font in addition to bitmap font.
     
    Still have some work to do before code is ready to release.
     
    The 5110 is a passive matrix LCD, so the response time and contrast are not very good. Animation really reveals the weaknesses of this type of display. The response time of a pixel seems to be influenced by the state of adjacent pixels.
     


  11. Like
    timotet reacted to oPossum in CNC-milling: create 3 different frequencies with MSP430G2553   
    Here is some code that uses NCOs to generate three frequencies with 100 uHz (0.0001 Hz) resolution for a specified duration.
     
    There will be some jitter when 100000 / Frequency is not an integer. This may or may not be a problem. There are ways to reduce the jitter, but more hardware is required.
     
    Be very careful with the ISR code - it must be able to run in under 120 cycles.
     

    #include "msp430g2553.h" static long int timer = 0; // Duration of motion static long int pix = 0; // Phase increment static long int piy = 0; static long int piz = 0; static long int px = 0; // Position static long int py = 0; static long int pz = 0; static long int dx = 1; // Direction static long int dy = 1; static long int dz = 1; // Sample rate * (1 / resolution in Hz) static const long int pl = 1000000000; void set_fx(long int f) { pix = f - pl; } void set_fy(long int f) { piy = f - pl; } void set_fz(long int f) { piz = f - pl; } void main(void) { WDTCTL = WDTPW | WDTHOLD; // Disable watchdog DCOCTL = 0; BCSCTL1 = CALBC1_16MHZ; // Set DCO to 16 MHz DCOCTL = CALDCO_16MHZ; // P1DIR = 0x13; // I/O assignment P1REN = 0x00; // P1OUT = 0x02; // P1SEL = 0x10; // Enable SMCLK output P2DIR = 0x07; // P2REN = 0x00; // P2OUT = 0x00; // P2SEL = 0xC0; // TA0CTL = TASSEL_2 | MC_1; // Timer A config: SMCLK, count up TA0CCR0 = 160 - 1; // Setup Timer A CCR0 period for 100,000 Hz TA0CCTL0 |= CCIE; // Enable PWM interrupt _EINT(); // Enable interrupts set_fx(10000000); // 1000.0000 Hz set_fy(20000000); // 2000.0000 Hz set_fz(25000000); // 2500.0000 Hz timer = -1; // Run for a long time for(;; } #pragma vector = TIMER0_A0_VECTOR __interrupt void timer_a_isr(void) { static long int pax = 0; // Phase accumulator static long int pay = 0; static long int paz = 0; if(timer) { --timer; pax += pix; if(pax < 0) pax += pl; else { P2OUT |= 1; px += dx; P2OUT &= ~1; } pay += piy; if(pay < 0) pay += pl; else { P2OUT |= 2; py += dy; P2OUT &= ~2; } paz += piz; if(paz < 0) paz += pl; else { P2OUT |= 4; pz += dz; P2OUT &= ~4; } } }
  12. Like
    timotet reacted to roger430 in Simple temperature display project   
    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; }
  13. Like
    timotet got a reaction from tanh in Nokia 5110 display   
    I wrote some code for the nokia lcd using spi a couple of months ago and after seeing Robs post I thought I'd post mine as well.

    sorry about the video quality I lost my good camera in a drift boat accident






    here's the code:
      /* * 4/5/11 * talk to nokia 5011 LCD with spi */ #include #define PIN_SCLK BIT5 //display pin 7 / msp430 pin 7 //port p1.5 #define PIN_DNMOSI BIT6 //display pin 6 / msp430 pin 14 //port p1.6 these are used for USI SPI mode #define PIN_DC BIT4 //display pin 5 / msp430 pin 12 //port P2.4 #define PIN_RESET BIT3 //display pin 4 / msp430 pin 11 //port p2.3 #define PIN_SCE BIT1 //display pin 3 / msp430 pin 9 //port p2.1 #define PIN_VCC BIT0 //display pin 1 / msp430 pin 8 //port p2.0 #define LCD_X 84 //columns #define LCD_Y 48 //rows #define cmd 0 //for command data #define info 1 //for character data unsigned char * Flash_ptr = (unsigned char *) 0x1040; unsigned char * Flash_pOnes = (unsigned char *) 0x1042; unsigned char * Flash_pTens = (unsigned char *) 0x1044; unsigned char * Flash_pHunds = (unsigned char *) 0x1046; volatile char data = 0; //char for data to lcd volatile char pressCount = 0; //keep track of button presses volatile char number = 0; //char for data to lcd volatile char ones = 0; //used as placeholder for counting volatile char tens = 0; volatile char hunds = 0; const unsigned char table [][5] = { {0x00, 0x00, 0x00, 0x00, 0x00}// (space) ,{0x00, 0x00, 0x5F, 0x00, 0x00}// ! ,{0x00, 0x07, 0x00, 0x07, 0x00}// " ,{0x14, 0x7F, 0x14, 0x7F, 0x14}// # ,{0x24, 0x2A, 0x7F, 0x2A, 0x12}// $ ,{0x23, 0x13, 0x08, 0x64, 0x62}// % ,{0x36, 0x49, 0x55, 0x22, 0x50}// & ,{0x00, 0x05, 0x03, 0x00, 0x00}// ' ,{0x00, 0x1C, 0x22, 0x41, 0x00}// ( ,{0x00, 0x41, 0x22, 0x1C, 0x00}// ) ,{0x08, 0x2A, 0x1C, 0x2A, 0x08}// * ,{0x08, 0x08, 0x3E, 0x08, 0x08}// + ,{0x00, 0x50, 0x30, 0x00, 0x00}// , ,{0x08, 0x08, 0x08, 0x08, 0x08}// - ,{0x00, 0x60, 0x60, 0x00, 0x00}// . ,{0x20, 0x10, 0x08, 0x04, 0x02}// / ,{0x3E, 0x51, 0x49, 0x45, 0x3E}// 0 ,{0x00, 0x42, 0x7F, 0x40, 0x00}// 1 ,{0x42, 0x61, 0x51, 0x49, 0x46}// 2 ,{0x21, 0x41, 0x45, 0x4B, 0x31}// 3 ,{0x18, 0x14, 0x12, 0x7F, 0x10}// 4 ,{0x27, 0x45, 0x45, 0x45, 0x39}// 5 ,{0x3C, 0x4A, 0x49, 0x49, 0x30}// 6 ,{0x01, 0x71, 0x09, 0x05, 0x03}// 7 ,{0x36, 0x49, 0x49, 0x49, 0x36}// 8 ,{0x06, 0x49, 0x49, 0x29, 0x1E}// 9 ,{0x00, 0x36, 0x36, 0x00, 0x00}// : ,{0x00, 0x56, 0x36, 0x00, 0x00}// ; ,{0x00, 0x08, 0x14, 0x22, 0x41}// < ,{0x14, 0x14, 0x14, 0x14, 0x14}// = ,{0x41, 0x22, 0x14, 0x08, 0x00}// > ,{0x02, 0x01, 0x51, 0x09, 0x06}// ? ,{0x32, 0x49, 0x79, 0x41, 0x3E}// @ ,{0x7E, 0x11, 0x11, 0x11, 0x7E}// A ,{0x7F, 0x49, 0x49, 0x49, 0x36}// B ,{0x3E, 0x41, 0x41, 0x41, 0x22}// C ,{0x7F, 0x41, 0x41, 0x22, 0x1C}// D ,{0x7F, 0x49, 0x49, 0x49, 0x41}// E ,{0x7F, 0x09, 0x09, 0x01, 0x01}// F ,{0x3E, 0x41, 0x41, 0x51, 0x32}// G ,{0x7F, 0x08, 0x08, 0x08, 0x7F}// H ,{0x00, 0x41, 0x7F, 0x41, 0x00}// I ,{0x20, 0x40, 0x41, 0x3F, 0x01}// J ,{0x7F, 0x08, 0x14, 0x22, 0x41}// K ,{0x7F, 0x40, 0x40, 0x40, 0x40}// L ,{0x7F, 0x02, 0x04, 0x02, 0x7F}// M ,{0x7F, 0x04, 0x08, 0x10, 0x7F}// N ,{0x3E, 0x41, 0x41, 0x41, 0x3E}// O ,{0x7F, 0x09, 0x09, 0x09, 0x06}// P ,{0x3E, 0x41, 0x51, 0x21, 0x5E}// Q ,{0x7F, 0x09, 0x19, 0x29, 0x46}// R ,{0x46, 0x49, 0x49, 0x49, 0x31}// S ,{0x01, 0x01, 0x7F, 0x01, 0x01}// T ,{0x3F, 0x40, 0x40, 0x40, 0x3F}// U ,{0x1F, 0x20, 0x40, 0x20, 0x1F}// V ,{0x7F, 0x20, 0x18, 0x20, 0x7F}// W ,{0x63, 0x14, 0x08, 0x14, 0x63}// X ,{0x03, 0x04, 0x78, 0x04, 0x03}// Y ,{0x61, 0x51, 0x49, 0x45, 0x43}// Z ,{0x00, 0x00, 0x7F, 0x41, 0x41}// [ ,{0x02, 0x04, 0x08, 0x10, 0x20}// "\" ,{0x41, 0x41, 0x7F, 0x00, 0x00}// ] ,{0x04, 0x02, 0x01, 0x02, 0x04}// ^ ,{0x40, 0x40, 0x40, 0x40, 0x40}// _ ,{0x00, 0x01, 0x02, 0x04, 0x00}// ` ,{0x20, 0x54, 0x54, 0x54, 0x78}// a ,{0x7F, 0x48, 0x44, 0x44, 0x38}// b ,{0x38, 0x44, 0x44, 0x44, 0x20}// c ,{0x38, 0x44, 0x44, 0x48, 0x7F}// d ,{0x38, 0x54, 0x54, 0x54, 0x18}// e ,{0x08, 0x7E, 0x09, 0x01, 0x02}// f ,{0x08, 0x14, 0x54, 0x54, 0x3C}// g ,{0x7F, 0x08, 0x04, 0x04, 0x78}// h ,{0x00, 0x44, 0x7D, 0x40, 0x00}// i ,{0x20, 0x40, 0x44, 0x3D, 0x00}// j ,{0x00, 0x7F, 0x10, 0x28, 0x44}// k ,{0x00, 0x41, 0x7F, 0x40, 0x00}// l ,{0x7C, 0x04, 0x18, 0x04, 0x78}// m ,{0x7C, 0x08, 0x04, 0x04, 0x78}// n ,{0x38, 0x44, 0x44, 0x44, 0x38}// o ,{0x7C, 0x14, 0x14, 0x14, 0x08}// p ,{0x08, 0x14, 0x14, 0x18, 0x7C}// q ,{0x7C, 0x08, 0x04, 0x04, 0x08}// r ,{0x48, 0x54, 0x54, 0x54, 0x20}// s ,{0x04, 0x3F, 0x44, 0x40, 0x20}// t ,{0x3C, 0x40, 0x40, 0x20, 0x7C}// u ,{0x1C, 0x20, 0x40, 0x20, 0x1C}// v ,{0x3C, 0x40, 0x30, 0x40, 0x3C}// w ,{0x44, 0x28, 0x10, 0x28, 0x44}// x ,{0x0C, 0x50, 0x50, 0x50, 0x3C}// y ,{0x44, 0x64, 0x54, 0x4C, 0x44}// z ,{0x00, 0x08, 0x36, 0x41, 0x00}// { ,{0x00, 0x00, 0x7F, 0x00, 0x00}// | ,{0x00, 0x41, 0x36, 0x08, 0x00}// } ,{0x08, 0x08, 0x2A, 0x1C, 0x08}// -> ,{0x08, 0x1C, 0x2A, 0x08, 0x08} // <- }; const unsigned char nice [] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x60, 0x80, 0x00, 0x18, 0xE0, 0x80, 0x80, 0x80, 0x8E, 0x70, 0x00, 0x00, 0xE0, 0x1C, 0x00, 0x00, 0x00, 0x80, 0x60, 0x18, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x61, 0x12, 0x14, 0x08, 0x04, 0x02, 0x02, 0x41, 0x41, 0x81, 0x81, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x82, 0x82, 0x04, 0x0E, 0x11, 0x10, 0x60, 0x98, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xFE, 0x18, 0x60, 0x80, 0xFE, 0x02, 0x00, 0x00, 0x10, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x10, 0x10, 0x10, 0x20, 0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7C, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x42, 0x82, 0x84, 0x05, 0x09, 0x08, 0x02, 0x02, 0x11, 0x91, 0x89, 0x49, 0x44, 0x84, 0x82, 0x02, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x00, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x03, 0x04, 0x04, 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x19, 0x10, 0x26, 0x22, 0x10, 0x19, 0x06, 0x00, 0x00, 0x00, 0x00, 0x06, 0x19, 0x10, 0x22, 0x26, 0x10, 0x19, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0C, 0x30, 0x40, 0x40, 0x82, 0x06, 0x06, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x30, 0x0C, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; const unsigned char button [] = { 0x00, 0x00, 0x00, 0xC0, 0x30, 0x10, 0x08, 0x08, 0x10, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x48, 0x68, 0x64, 0x54, 0x54, 0x4C, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xE0, 0x03, 0x02, 0x04, 0x04, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x2C, 0x34, 0x54, 0x64, 0x44, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x21, 0x01, 0x3E, 0x20, 0x00, 0x1E, 0x25, 0x25, 0x25, 0x16, 0x00, 0x61, 0x47, 0x38, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xF8, 0x88, 0x88, 0x70, 0x00, 0x08, 0xF8, 0x10, 0x08, 0x18, 0x00, 0xF0, 0x28, 0x28, 0x28, 0xB0, 0x00, 0x90, 0x28, 0x28, 0x48, 0x98, 0x00, 0x90, 0x28, 0x28, 0x48, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x88, 0x08, 0xF0, 0x08, 0xF8, 0x00, 0x08, 0xF8, 0x00, 0x00, 0x08, 0xFF, 0x08, 0x88, 0x00, 0x00, 0x08, 0xFF, 0x08, 0x88, 0x00, 0x00, 0xF0, 0x08, 0x08, 0x08, 0xF0, 0x08, 0xF0, 0x08, 0x08, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x81, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x10, 0xF0, 0x00, 0x01, 0x00, 0x01, 0x80, 0x80, 0x80, 0x01, 0x01, 0x00, 0x81, 0x80, 0x00, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80, 0x01, 0x00, 0x80, 0x80, 0x80, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3F, 0x28, 0x08, 0x07, 0x00, 0x00, 0x10, 0x1F, 0x10, 0x00, 0x00, 0x0F, 0x12, 0x12, 0x12, 0x0B, 0x00, 0x0D, 0x12, 0x12, 0x0F, 0x10, 0x00, 0x19, 0x12, 0x12, 0x14, 0x09, 0x00, 0x0F, 0x12, 0x12, 0x12, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; ////////////////////////////function prototypes///////////////////////// void LcdWrite(char CMD,char data); void LcdInit(); void LcdClear(); void LcdString(char *characters); void LcdCharacter(const char character); void LcdNumber(); void gotoXY(char x, char y); void LcdBmp(const unsigned char my_array[]); void sendArray(const unsigned char digit[], char length); void delay(int ms); void loadFlash(); ////////////////////////////main/////////////////////////////////// void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL1 = CALBC1_1MHZ; // calibrate basic clock system control 1 to 1mhz DCOCTL = CALDCO_1MHZ; // calibrate DCO to 1mhz IE1 |= WDTIE; //enable watchdog timer interrupt P1SEL &= ~(BIT0 + BIT3); //enable port 1.0 and 1.3 P1IN &= ~BIT3; //input signal == low P1DIR |= BIT0; //set p1.0 red led to output P1DIR &= ~BIT3; // set p1.3 as an input P1OUT |= BIT0 + BIT3; // p1.0 high led is on //pullup for p1.3 P1REN |= BIT3; // Resistor Enable for p1.3 pull up P1IES |= BIT3; // Interrupt Edge Select - 0: trigger on rising edge, 1: trigger on falling edge P1IFG &= ~BIT3; //interrupt flag for p1.3 is off P1IE |= BIT3; // enable interrupt P2SEL &= ~(BIT1 + BIT4 + BIT3 + BIT0); //turns on port 2 P2DIR |= (BIT1 + BIT4 + BIT3 + BIT0); //set as outputs P2OUT &= ~(BIT4 + BIT3 + BIT1 + BIT0); //set pins low USICTL0 |= 0x6B; USICTL1 |= 0X91; //USICKCTL |= 0xE8; //divide by 128 USICKCTL |= 0xA8; // divide by 32 USICTL0 &= ~USISWRST; // Reset & release USI USICNT |= 8; // send 8 bits FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator //_bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt _BIS_SR(GIE); //enable interrupts LcdInit(); loadFlash(); //load counter values from before power down for(; { //infinite loop do{ LcdWrite(cmd , 0x0C); // LCD 0x0C for black on white //0x0d for inverse P1OUT |= BIT0; // turn on port 1.0 led gotoXY(0,0); LcdBmp(button); } while(0x08 & P1IN); } } //////////////////////ISR's////////////////////////////////// // USI interrupt service routine #pragma vector = USI_VECTOR __interrupt void USI_TXRX (void) { USICTL1 &= ~USIIFG; // Clear pending flag P2OUT |= PIN_SCE; //SCE pin high } #pragma vector=PORT1_VECTOR __interrupt void PORT1_ISR(void) { P1IFG &= ~BIT3; // clear interrupt flag WDTCTL = WDT_MDLY_32; //watchdog delay for debounce 32milli seconds// interval timer mode pressCount++; //increment button presses P1OUT &= ~BIT0; //turn off led LcdClear(); LcdWrite(cmd , 0x0D); // LCD 0x0C for black on white //0x0d for inverse gotoXY(0,0); LcdBmp(nice); delay(1000); LcdClear(); gotoXY(0,0); LcdString("************"); gotoXY(10,1); LcdString("now was'nt"); gotoXY(25,3); LcdString("that"); gotoXY(12,5); LcdString("exciting"); delay(700); LcdClear(); gotoXY(20,0); LcdString("Number"); gotoXY(10,2); LcdString("of button"); gotoXY(0,4); //locate cursor LcdString("press's"); ones = pressCount; if(ones > 9){ //write # of press's to lcd tens++; ones = 0; pressCount = 0; if(tens > 9){ hunds++; tens = 0; ones = 0; pressCount = 0; if(hunds > 9){ pressCount = 0; hunds = 0; tens = 0; ones = 0; } } } number = ones; //write the ones column gotoXY(67,5); LcdNumber(); number = tens; gotoXY(61,5); LcdNumber(); number = hunds; gotoXY(55,5); LcdNumber(); delay(1000); LcdClear(); //gotoXY(0,0); //LcdBmp(finger); //delay(500); FCTL1 = FWKEY + ERASE; // Set Erase bit FCTL3 = FWKEY; // Clear Lock bit *Flash_ptr = 0; // Dummy write to erase Flash segment // *Flash_pOnes = 0; // *Flash_pTens = 0; // *Flash_pHunds = 0; FCTL1 = FWKEY + WRT; // Set WRT bit for write operation *Flash_ptr = pressCount; // Write value to flash *Flash_pOnes = ones; *Flash_pTens = tens; *Flash_pHunds = hunds; FCTL1 = FWKEY; // Clear WRT bit FCTL3 = FWKEY + LOCK; // Set LOCK bit } #pragma vector=WDT_VECTOR __interrupt void WDT_ISR(void) //use watchdog for button debounce { IFG1 &= ~WDTIFG; // clear interrupt flag WDTCTL = WDTPW + WDTHOLD; // put WDT back in hold state // pressCount++; //increment button presses } //////////////////////////////functions////////////////////////// void gotoXY(char x, char y) { LcdWrite(cmd ,(0x40 | y & 0x07)); // Y row == 0100 0yyy LcdWrite(cmd ,(0x80 | x & 0x7F)); // X column == 1xxx xxxx } void LcdBmp(const unsigned char my_array[]) { unsigned short index = 0; for (index = 0; index < 504; index++) { LcdWrite(info,my_array[index]); } } void LcdCharacter(char character) { char index = 0; LcdWrite(info,0x00); for (index = 0; index < 5; index++) { LcdWrite(info,table[character - 0x20][index]); } LcdWrite(info,0x00); } void LcdString(char *characters) { while (*characters){ LcdCharacter(*characters++); } } void LcdNumber(){ switch(number){ case 0: sendArray(table[16],5); break; case 1: sendArray(table[17],5); break; case 2: sendArray(table[18],5); break; case 3: sendArray(table[19],5); break; case 4: sendArray(table[20],5); break; case 5: sendArray(table[21],5); break; case 6: sendArray(table[22],5); break; case 7: sendArray(table[23],5); break; case 8: sendArray(table[24],5); break; case 9: sendArray(table[25],5); break; default: pressCount = 0; //reset pressCount to 0 } } void LcdClear(void) { int i,j; LcdWrite(cmd, 0x80); LcdWrite(cmd, 0x40); for (i=0;i<6;i++) // number of rows for (j=0;j LcdWrite(info, 0x00); } void delay(int ms)// Delays by the specified Milliseconds { while (ms--){ __delay_cycles(1000); //set to 1000 for 1 Mhz } } void sendArray(const unsigned char digit[], char length) { char charIndex = 0; while(charIndex < length) { LcdWrite(info , digit[charIndex]); charIndex++; } } void LcdInit(void) { P2OUT |= PIN_VCC; //power to LCD P2OUT |= PIN_RESET; //set RESET high P2OUT &= ~PIN_RESET; //set RESET low delay(35); P2OUT |= PIN_RESET; //set RESET high P2OUT |= PIN_SCE; //SCE pin high LcdWrite(cmd , 0x21); // LCD Extended instruction set LcdWrite(cmd , 0xBF); // Set LCD Vop (Contrast). //0xE0 - BF may have to play with LcdWrite(cmd , 0x07); // Set Temp coefficent. //0x04 =t0 //0x05=t1 // 0x06=t2 // 0x07=t3 LcdWrite(cmd , 0x13); // LCD bias mode 1:100 0x10 //1:48 0x13 LcdWrite(cmd , 0x20); // LCD basic instruction set LcdWrite(cmd , 0x08); // lcd blank LcdWrite(cmd , 0x0C); // LCD 0x0C for black on white //0x0d for inverse } void LcdWrite(char CMD, char data) { if(CMD == cmd){ P2OUT &= ~PIN_DC; //set LCD to command mode } else{ P2OUT |= PIN_DC; //set lcd to data mode } P2OUT &= ~PIN_SCE; //SCE pin low USISRL |= data; // load shift register with data to send USICNT |= 8; // shift out 8 bits delay(1); } void loadFlash() { pressCount = *Flash_ptr; // load values from before power down if(*Flash_ptr == 0xFF){ pressCount = 0; } ones = *Flash_pOnes; if(*Flash_pOnes == 0xFF){ ones = 0; } tens = *Flash_pTens; if(*Flash_pTens == 0xFF){ tens = 0; } hunds = *Flash_pHunds; if(*Flash_pHunds == 0xFF){ hunds = 0; } } I found a couple of bitmap converters for displaying bitmaps on the lcds

    bitmap 2 LCD http://bitmap2lcd.com
    lcd assistant http://en.radzio.dxp.pl/bitmap_converter/

    The program stores the # of button press's in flash so when power is restored the count doesn't start over.
    Maybe this will help somebody. :thumbup:
    cheers
  14. Like
    timotet reacted to RobG in 4ch Volt Meter using Nokia 5110   
    This is just to show what can be done with 5110.
    FYI, inputs are floating, top bar is P1.3, which is pulled-up by default, values are raw, not calibrated.




    #include "msp430g2553.h" #include "PCD8544.h" #define LCD5110_SCLK_PIN BIT5 #define LCD5110_DN_PIN BIT7 #define LCD5110_SCE_PIN BIT4 #define LCD5110_DC_PIN BIT6 #define LCD5110_SELECT P1OUT &= ~LCD5110_SCE_PIN #define LCD5110_DESELECT P1OUT |= LCD5110_SCE_PIN #define LCD5110_SET_COMMAND P1OUT &= ~LCD5110_DC_PIN #define LCD5110_SET_DATA P1OUT |= LCD5110_DC_PIN #define LCD5110_COMMAND 0 #define LCD5110_DATA 1 void writeStringToLCD(const char *string); void writeCharToLCD(char c); void writeToLCD(unsigned char dataCommand, unsigned char data); void clearLCD(); void setAddr(unsigned char xAddr, unsigned char yAddr); void initLCD(); void binaryToUnpackedBCD(unsigned int n, unsigned char * digits); unsigned char bcd[4] = {0,0,0,0}; int adc[4] = {0,0,0,0}; unsigned char last[4] = {0,0,0,0}; static const char tick[64] = { 0x07, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x07, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x07, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x07, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x07, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x07, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x06, 0x04, 0x07, 0x04, 0x06, 0x04 }; void main(void) { WDTCTL = WDTPW + WDTHOLD; // disable WDT BCSCTL1 = CALBC1_1MHZ; // 1MHz clock DCOCTL = CALDCO_1MHZ; P1OUT |= LCD5110_SCE_PIN + LCD5110_DC_PIN; P1DIR |= LCD5110_SCE_PIN + LCD5110_DC_PIN; // setup USIB P1SEL |= LCD5110_SCLK_PIN + LCD5110_DN_PIN; P1SEL2 |= LCD5110_SCLK_PIN + LCD5110_DN_PIN; UCB0CTL0 |= UCCKPH + UCMSB + UCMST + UCSYNC; // 3-pin, 8-bit SPI master UCB0CTL1 |= UCSSEL_2; // SMCLK UCB0BR0 |= 0x01; // 1:1 UCB0BR1 = 0; UCB0CTL1 &= ~UCSWRST; // clear SW ADC10CTL1 = INCH_3 + CONSEQ_1; ADC10CTL0 = ADC10SHT_2 + MSC + ADC10ON + ADC10IE; ADC10DTC1 = 0x04; ADC10AE0 |= 0x0F; _delay_cycles(500000); initLCD(); clearLCD(); // LCD test writeStringToLCD("4ch Volt Meter"); setAddr(0,5); writeStringToLCD("by RobG @ 43oh"); char c = 0; // setup tickmarks char d = 0; while(d < 4) { d++; c = 0; setAddr(0,d); while(c < 64) { writeToLCD(LCD5110_DATA, tick[c]); c++; } } _bis_SR_register(GIE); while(1) { ADC10SA = (unsigned int)&adc[0]; ADC10CTL0 |= ENC + ADC10SC; _delay_cycles(100000); } } // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR(void) { ADC10CTL0 &= ~ENC; char c = 0; while(c < 4) { unsigned char curr = adc[c] >> 4; unsigned char prev = last[c]; unsigned char b = 0; unsigned char t = 0; binaryToUnpackedBCD(curr, bcd); if(curr < prev) { setAddr(curr, c + 1); b = prev - curr + 1; t = curr; while(b > 0) { writeToLCD(LCD5110_DATA, tick[t++]); b--; } } else if(curr > prev) { setAddr(prev, c + 1); b = curr - prev; t = prev; while(b > 0) { writeToLCD(LCD5110_DATA, 0x70 | tick[t++]); b--; } } setAddr(70 ,c + 1); writeCharToLCD(bcd[2] + 0x30); writeToLCD(LCD5110_DATA, 0x40); writeToLCD(LCD5110_DATA, 0x0); writeCharToLCD(bcd[3] + 0x30); last[c] = curr; c++; } } void writeStringToLCD(const char *string) { while(*string) { writeCharToLCD(*string++); } } void writeCharToLCD(char c) { unsigned char i; for(i = 0; i < 5; i++) { writeToLCD(LCD5110_DATA, font[c - 0x20][i]); } writeToLCD(LCD5110_DATA, 0); } void writeToLCD(unsigned char dataCommand, unsigned char data) { LCD5110_SELECT; if(dataCommand) { LCD5110_SET_DATA; } else { LCD5110_SET_COMMAND; } UCB0TXBUF = data; while(!(IFG2 & UCB0TXIFG)) ; LCD5110_DESELECT; } void clearLCD() { setAddr(0, 0); int c = 0; while(c < PCD8544_MAXBYTES) { writeToLCD(LCD5110_DATA, 0); c++; } setAddr(0, 0); } void setAddr(unsigned char xAddr, unsigned char yAddr) { writeToLCD(LCD5110_COMMAND, PCD8544_SETXADDR | xAddr); writeToLCD(LCD5110_COMMAND, PCD8544_SETYADDR | yAddr); } void initLCD() { writeToLCD(LCD5110_COMMAND, PCD8544_FUNCTIONSET | PCD8544_EXTENDEDINSTRUCTION); writeToLCD(LCD5110_COMMAND, PCD8544_SETVOP | 0x3F); writeToLCD(LCD5110_COMMAND, PCD8544_SETTEMP | 0x02); writeToLCD(LCD5110_COMMAND, PCD8544_SETBIAS | 0x03); writeToLCD(LCD5110_COMMAND, PCD8544_FUNCTIONSET); writeToLCD(LCD5110_COMMAND, PCD8544_DISPLAYCONTROL | PCD8544_DISPLAYNORMAL); } void binaryToUnpackedBCD(unsigned int n, unsigned char * digits) { __asm(" clr R14"); __asm(" rla R12"); __asm(" rla R12"); __asm(" rla R12"); __asm(" rla R12"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" rla R12"); __asm(" dadd R14, R14"); __asm(" mov.b R14, 3(R13)"); __asm(" swpb R14"); __asm(" mov.b R14, 1(R13)"); __asm(" rra R14"); __asm(" rra R14"); __asm(" rra R14"); __asm(" rra R14"); __asm(" mov.b R14, 0(R13)"); __asm(" swpb R14"); __asm(" mov.b R14, 2(R13)"); __asm(" and #0x0F0F, 0(R13)"); __asm(" and #0x0F0F, 2(R13)"); return; }
    #ifndef PCD8544_H_#define PCD8544_H_#define PCD8544_POWERDOWN 0x04#define PCD8544_ENTRYMODE 0x02#define PCD8544_EXTENDEDINSTRUCTION 0x01#define PCD8544_DISPLAYBLANK 0x0#define PCD8544_DISPLAYNORMAL 0x4#define PCD8544_DISPLAYALLON 0x1#define PCD8544_DISPLAYINVERTED 0x5// H = 0#define PCD8544_FUNCTIONSET 0x20#define PCD8544_DISPLAYCONTROL 0x08#define PCD8544_SETYADDR 0x40#define PCD8544_SETXADDR 0x80#define PCD8544_HPIXELS 84#define PCD8544_VBANKS 6#define PCD8544_MAXBYTES 504 // PCD8544_HPIXELS * PCD8544_VBANKS// H = 1#define PCD8544_SETTEMP 0x04#define PCD8544_SETBIAS 0x10#define PCD8544_SETVOP 0x80//transform#define NONE 0x00#define FLIP_H 0x01#define FLIP_V 0x02#define ROTATE 0x04 // 90 deg CW#define ROTATE_90_CW ROTATE#define ROTATE_90_CCW (FLIP_H | FLIP_V | ROTATE)#define ROTATE_180 (FLIP_H | FLIP_V)static const char font[][5] = { // basic font{0x00, 0x00, 0x00, 0x00, 0x00} // 20,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 ",{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 ',{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 ),{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c
  15. Like
    timotet reacted to DanAndDusty in Halloween Motion Triggered Sound and Light Thingamajig   
    Hi all,

    For Halloween this year I wanted to make a motion triggered device that screams at you and makes some UV lights flash/flicker.

    Here is a video of the device in action.



    My first thought was to use an SD Card but I couldn't get this to work (this was my first attempt with the hardware UART and I have a feeling I may be able to get a little further now.. so who knows)

    When the attempt with the SD Card failed I decided to use a 25AA1024 SPI 1Mbit EEPROM. As the EEPROM doesn't connect directly to a PC I needed a way to get the sound files onto the device. So I added a serial control menu that allows uploading via XMODEM. I chose XMODEM as the packet size is only 128 bytes, the protocol requirements are minimal and just about every comms program has the protocol built it. Because of the 128 bytes for the buffer and the serial requirements I used a G2553. For the serial comms I used an FT232 breakout circuit running at 460800 baud and she screams along happily. I have also tried it using the UART->USB of the launchpad at 9600 and it works there too, albeit much slower.

    Once the sound data is on the eeprom I store it as 8 bit unsigned raw samples. These I send out to a DAC. The only DAC I had to hand was a MAX5159. The only problem with this was there is an internal gain of 2x. So I had to divide Vcc by 2 to provide the DACs reference. Easy I thought.. Voltage Divider to the rescue.. However when I tried this I found that the voltage would jump about over quite a largish range. Further reading of the 5159 datasheet unearthed this little tidbit.. The reference input impedance ranges from 18k ohms (1558 hex) to several giga ohms.. Ouch... Thats gunna throw my little voltage divider off a little.. So I remember reading at some point that op-amps can be used to buffer inputs for just such situations. Ive not used an op-amp before but had a few LM324 quad op-amps to hand. Set one of the devices up as a voltage follower and bingo.. She worked.. I pass the output from the DAC through an AC Coupling Capacitor into a computer speaker amplifier. The quality isn't suitable for an audiophile but for this it works wonders.

    I also wanted some flashing lights.. (hey.. who doesn't like flashing lights).. I wanted these to flash roughly in time with the audio. So after a sound file has been uploaded the 430 runs a very simplistic peak counting routine. It finds the highest peak that occurs atleast 40 times in the sound file. It only checks the highest so the deepest trough won't trigger it, but Im happy with the results. When the sound is played back, each time this peak value is passed the lights are triggered. I used 10 UV LEDs driven via an NPN Transistor. The voltage drop of the transistor meant that they weren't as bright as I would like at 3.3V so I power them from 4 rechargeable AA batteries (4.8-5.0v ish) and use a 3.3V LDO for the rest of the circuit. The batteries Im using are 2900 mAh ones and during my testing they have been running the device for a week with no sign of giving out. So lasting all night shouldn't be a worry

    To trigger the sounds Im using an LDR as the lower resistor of a voltage divider. I compare this voltage to one from a potentiometer (for adjusting to different light levels) using another device in the LM324 quad op-amp. This triggers an interrupt on a pin on P2. For feedback on adjusting the pot I use another op-amp triggered from the same voltages to drive an LED. Adjust the pot until the LED comes on.. back off a little so it has just turned off and bingo.. Its primed and ready. There will be a light source the other side of the (narrow) garden that will be blocked by someone walking past it and this will trigger the playback of the sound/light combo.

    Because I don't want to have a PC down in the garden to setup I added a "playback" mode which is triggered if P2.4 is tied high at power on.

    Future changes that may (or may not.. depending on time free and success) include...
    Using an SD Card to store the sound samples. The EEPROM is 1MBit or 128KBytes. at 22KHz 8 bits this can store less than 6 seconds of sound.
    Compressing the sound files using something simple like uLaw or ADPCM. I have no experience with sound compression so lets see how this goes.
    Adding an audio amplifier circuit At the moment the audio is amplified using PC speakers with built in amplifier. If I can add this to the circuit it would be neater. I tried this using an LM386 but the quality was abysmal. Im still getting my head around analogue circuitry so Its not a total surprise

    When the POTM is announced I think I'll enter this as its not often I document my projects as detailed as I should. I tend to leap on to the next brain spasm. This time though, the code is neatish and well documented. Im even drawing up a schematic over the next couple of nights (never used eagle before so bear with me on this)

    Hope you enjoyed my little ramble, over the next few nights I should be posting the code and schematic. For now though I am off to bed.

    Enjoy,

    Dan
  16. Like
    timotet reacted to oPossum in Tiny printf() - C version   
    This is a tiny printf() function that can be used with the chips that come with the Launchpad. Code size is about 640 bytes with CCS.
     
    There are 7 format specifiers:
    %c - Character
    %s - String
    %i - signed Integer (16 bit)
    %u - Unsigned integer (16 bit)
    %l - signed Long (32 bit)
    %n - uNsigned loNg (32 bit)
    %x - heXadecimal (16 bit)
     
    Field width, floating point and other standard printf() features are not supported.
     
    printf() code

    #include "msp430g2231.h" #include "stdarg.h" void putc(unsigned); void puts(char *); static const unsigned long dv[] = { // 4294967296 // 32 bit unsigned max 1000000000, // +0 100000000, // +1 10000000, // +2 1000000, // +3 100000, // +4 // 65535 // 16 bit unsigned max 10000, // +5 1000, // +6 100, // +7 10, // +8 1, // +9 }; static void xtoa(unsigned long x, const unsigned long *dp) { char c; unsigned long d; if(x) { while(x < *dp) ++dp; do { d = *dp++; c = '0'; while(x >= d) ++c, x -= d; putc(c); } while(!(d & 1)); } else putc('0'); } static void puth(unsigned n) { static const char hex[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; putc(hex[n & 15]); } void printf(char *format, ...) { char c; int i; long n; va_list a; va_start(a, format); while(c = *format++) { if(c == '%') { switch(c = *format++) { case 's': // String puts(va_arg(a, char*)); break; case 'c': // Char putc(va_arg(a, char)); break; case 'i': // 16 bit Integer case 'u': // 16 bit Unsigned i = va_arg(a, int); if(c == 'i' && i < 0) i = -i, putc('-'); xtoa((unsigned)i, dv + 5); break; case 'l': // 32 bit Long case 'n': // 32 bit uNsigned loNg n = va_arg(a, long); if(c == 'l' && n < 0) n = -n, putc('-'); xtoa((unsigned long)n, dv); break; case 'x': // 16 bit heXadecimal i = va_arg(a, int); puth(i >> 12); puth(i >> 8); puth(i >> 4); puth(i); break; case 0: return; default: goto bad_fmt; } } else bad_fmt: putc(c); } va_end(a); }
     
    test code

    #include "msp430g2231.h" void serial_setup(unsigned out_mask, unsigned in_mask, unsigned duration); void printf(char *, ...); void main(void) { char *s; char c; int i; unsigned u; long int l; long unsigned n; unsigned x; // Disable watchdog WDTCTL = WDTPW + WDTHOLD; // Use 1 MHz DCO factory calibration DCOCTL = 0; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; // Setup the serial port // Serial out: P1.1 (BIT1) // Serial in: P1.2 (BIT2) // Bit rate: 9600 (CPU freq / bit rate) serial_setup(BIT1, BIT2, 1000000 / 9600); printf("%s", "\r\n*** printf() test ***\r\n"); s = "test"; c = 'X'; i = -12345; u = 12345; l = -1234567890; n = 1234567890; x = 0xABCD; printf("String %s\r\n", s); printf("Char %c\r\n", c); printf("Integer %i\r\n", i); printf("Unsigned %u\r\n", u); printf("Long %l\r\n", l); printf("uNsigned loNg %n\r\n", n); printf("heX %x\r\n", x); printf("multiple args %s %c %i %u %l %n %x\r\n", s, c, i, u, l, n, x); printf("\r\n*** Done ***\r\n"); for(;; }

  17. Like
    timotet reacted to HylianSavior in Free STM32F4 discovery kit in US/Canada   
    http://hackaday.com/2011/10/17/how-to-d ... k+a+Day%29
     
    This article may be of interest to some.
  18. Like
    timotet reacted to oPossum in Software async serial tx/rx without timer   
    Had some requests for this in IRC so here it is. This is an improved version of the serial tx previously posted and new serial rx code. Both tx and rx are blocking and interrupts should be disabled before calling.
     
    C code to show how to use the serial_setup(), putc(), puts(), and getc() functions.
    This will receive a character, increment it and echo it back. So if you type 'A', then 'B' will be echoed.

    // test.c #include "msp430g2211.h" // Functions in serial.asm (this really should be in a header file) void serial_setup(unsigned out_mask, unsigned in_mask, unsigned duration); void putc(unsigned); void puts(char *); unsigned getc(void); void main(void) { char c; // Disable watchdog WDTCTL = WDTPW + WDTHOLD; // Use 1 MHz DCO factory calibration DCOCTL = 0; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; // Setup the serial port // Serial out: P1.1 (BIT1) // Serial in: P1.2 (BIT2) // Bit rate: 9600 (CPU freq / bit rate) serial_setup(BIT1, BIT2, 1000000 / 9600); // Send a string puts("\r\nRunning...\r\n"); for(; { // Do forever c = getc(); // Get a char ++c; // Increment it putc(c); // Echo it back } }
     
    The serial tx/rx code. Just add this as a new source file in your CCS project and it will be callable from your C code.

    ; serial.asm .cdecls C, LIST, "msp430g2231.h" .bss in_bit_mask, 2 ; Serial in pin .bss out_bit_mask, 2 ; Serial out pin .bss bit_dur, 2 ; Bit duration in cycles .bss half_dur, 2 ; Half bit duration in cycles ; .text ; .def serial_setup ; void serial_setup(unsigned out_mask, unsigned in_mask, unsigned bit_duration); .def putc ; void putc(unsigned c); .def puts ; void puts(char *s); .def getc ; unsigned getc(void); ; ; serial_setup ; - Setup serial I/O bitmasks and bit duration (32 minimum) mov R12, &out_bit_mask ; Save serial output bitmask mov R13, &in_bit_mask ; Save serial input bitmask bis.b R12, &P1DIR ; Setup output pin bis.b R12, &P1OUT ; bic.b R13, &P1DIR ; Setup input pin or R13, R12 ; bic.b R12, &P1SEL ; Setup peripheral select mov R14, R12 ; sub #16, R14 ; Adjust count for loop overhead rla R14 ; Multiply by 2 because NOP is two bytes mov R14, &bit_dur ; Save bit duration sub #32, R12 ; Adjust count for loop overhead mov R12, &half_dur ; Save half bit duration ret ; Return ; ; - Send a single char putc ; Char to tx in R12 ; R12, R13, R14, R15 trashed mov &out_bit_mask, R15 ; Serial output bitmask mov &bit_dur, R14 ; Bit duration or #0x0300, R12 ; Stop bit(s) jmp bit_low ; Send start bit... ; tx_bit mov R14, R13 ; Get bit duration tx_delay nop ; 4 cycle loop sub #8, R13 ; jc tx_delay ; subc R13, PC ; 0 to 3 cycle delay nop ; 3 nop ; 2 nop ; 1 ; rra R12 ; Get bit to tx, test for zero jc bit_high ; If high... bit_low bic.b R15, &P1OUT ; Send zero bit jmp tx_bit ; Next bit... bit_high bis.b R15, &P1OUT ; Send one bit jnz tx_bit ; If tx data is not zero, then there are more bits to send... ; ret ; Return when all bits sent ; ; ; - Send a NULL terminated string puts ; Tx string using putc push R11 ; mov R12, R11 ; String pointer in R12, copy to R11 putsloop ; mov.b @R11+, R12 ; Get a byte, inc pointer tst.b R12 ; Test if end of string jz putsx ; Yes, exit... call #putc ; Call putc jmp putsloop ; putsx pop R11 ; ret ; ; getc ; - Get a char mov &bit_dur, R14 ; Bit duration mov &in_bit_mask, R13 ; Input bitmask mov #0x01FF, R12 ; 9 bits - 8 data + stop ; rx_start ; Wait for start bit mov.b &P1IN, R15 ; Get serial input and R13, R15 ; Mask and test bit jc rx_start ; Wait for low... ; mov &half_dur, R13 ; Wait for 1/2 bit time ; rx_delay nop ; Bit delay sub #8, R13 ; jc rx_delay ; subc R13, PC ; 0 to 3 cycle delay nop ; 3 nop ; 2 nop ; 1 ; mov.b &P1IN, R15 ; Get serial input and &in_bit_mask, R15 ; rrc R12 ; Shift in a bit ; mov R14, R13 ; Setup bit timer jc rx_delay ; Next bit... ; rla R12 ; Move stop bit to carry swpb R12 ; Move rx byte to lower byte, start bit in msb ret ; Return with rx char and start bit in R12, stop bit in carry ; .end ;
  19. Like
    timotet reacted to rockets4kids in Very Lucid MSP430 Documentation   
    I recently stumbled across some MSP430 documentation that does not seem to be linked from anywhere on their site. It appears to be rather old, but that is actually rather helpful as it documents just the core features of the MSP430 common to all chips and it is much more readable than the current Family Guides.
     
    "MSP430 Family Architecture Guide and Module Library"
     
    http://www.ti.com/sc/docs/products/micr ... /ag_01.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_02.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_03.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_04.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_05.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_06.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_07.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_08.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_09.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_10.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_11.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_12.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_13.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_14.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_15.pdf
    http://www.ti.com/sc/docs/products/micr ... /ag_16.pdf
    http://www.ti.com/sc/docs/products/micr ... d/ag_a.pdf
    http://www.ti.com/sc/docs/products/micr ... d/ag_b.pdf
    http://www.ti.com/sc/docs/products/micr ... d/ag_c.pdf
     
    "MSP430 Family" - a guide to assembly programming for the MSP430
     
    http://www.ti.com/sc/docs/products/micr ... d/as_1.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_2.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_3.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_4.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_5.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_6.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_7.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_8.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_9.pdf
    http://www.ti.com/sc/docs/products/micr ... /as_10.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_a.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_b.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_c.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_d.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_e.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_f.pdf
    http://www.ti.com/sc/docs/products/micr ... d/as_g.pdf
    http://www.ti.com/sc/docs/products/micr ... /as_in.pdf
    http://www.ti.com/sc/docs/products/micr ... /as_pr.pdf
     
    There are a few other files in this directory, but nothing particularly noteworthy.
  20. Like
    timotet reacted to zborgerd in Free STM32F4 discovery kit in US/Canada   
    I seem to be having some luck with Texane's stlink. It seems to support st-link v2 as well. https://github.com/texane/stlink
     
    There are a few requirements to build it (Ubuntu 11.10).
     

    sudo apt-get install libsgutils2-dev sudo apt-get install libusb-1.0-0-dev
     
    The St-link software can be installed as follows:
     

    git clone https://github.com/texane/stlink stlink.git
     
    The README and the tutorial.pdf detail how to build it. it's pretty simple if the above prerequisites are met. You will also need to copy the udev rules to /etc/udev/rules.d/ and restart the udev service, as detailed in the README.
     
    Afterward, a device node will be available at /dev/stm32l_stlink2 when the board is connected.
     
    You can connect to the device with:
     

    ./st-util port /dev/stm32l_stlink2
     
    GDB can connect with:
     

    target remote :4242
     
    At this point I've made some modifications to the LED example and it compiles just fine, but haven't yet loaded it. GDB seems to connect but gets a write failure. I suspect that it's address-related and I need to work on it a bit more.
  21. Like
    timotet reacted to rockets4kids in Free STM32F4 discovery kit in US/Canada   
    If this is your goal, then you definitely want to prefer the MSP430 over ARM. And if you don't already know C, then you might even be better just starting with assembly.
     
    I have been doing C on the MSP430 for about six months now, and while I have been wanting to do some ASM work, I have been put off by the complexity of the current MSP430 assembly manual. I just stumbled across a much older version which is far easier to read, as well as a much smaller and simpler assembler -- naken430asm (http://www.mikekohn.net/micro/naken430a ... embler.php)
     
    The MSP430 instruction set is *very* similar the the PDP-11 instruction set, often regarded as the quintessential CISC instruction set, and still used to teach assembly language programming in many college courses despite the fact that very few PDP-11s are still in use. (I have noticed that some colleges have shifted to the MSP430, likely due to it's similarity to the PDP-11.)
  22. Like
    timotet reacted to zborgerd in Free STM32F4 discovery kit in US/Canada   
    Here's a start. I'm using Ubuntu 11.10 (just released) and it appears that the Universe repository already has an ARM package available for GCC 4.6.
     

    sudo apt-get install gcc-arm-linux-gnueabi
     
    I had looked at GCC 4.6 a week or two ago and it looked like the core was supported. The cortex-m4 appears to be a valid target with -mcpu. I'll post more details as I progress (compiling a project and actually getting it to load).
  23. Like
    timotet reacted to zborgerd in Free STM32F4 discovery kit in US/Canada   
    I know that I am. And it sounds like rockets4kids is too.
     
    I use Linux, but as rocets4kits mentioned there are alternatives like stm32flash:
    http://stm32.spacevs.com/index.php?opti ... Itemid=103
     
    http://code.google.com/p/stm32flash/
     
    I am not sure that it supports STLINK V2 though. I'm debating just reprogramming mine with Versaloon or similar. It's just a matter of getting the time to do it though.
  24. Like
    timotet reacted to greeeg in Epaper desk calendar   
    Hi all,
     
    So basically instead of buying another one of those desk calendars that you tear of each day as it goes by I decided to make use of an epaper display from Sparkfun (that up until last week had been collecting dust) to create a digital daily calendar.
     
    The screen fits 20 16 segment digits on 2 lines. This gives enough room to display the current day of the week, and date. It is powered by a Li-ion cell from an old laptop battery, rated at 2.4Ah. (My estimates put the battery dying in about 200 years, as this draws ~20mAh for ~6 seconds every 24 hours )

     
    This was originally a launchpad project but I ported it to a F2013 board by changing one line, Shows how universal the code is
    The current hardware consists of a F2013 board that I got free from TI during one of their promo's. The board is soldered directly to the back of the epaper breakout board.

     
    The code is attached. The 2kb of flash available on the MSP430F2013 didn't give much wriggle room. currently the code compiles with about 64 bytes of flash free.
    Due to the sparkfun breakout board not breaking out the enable pin for the on board boost circuit I found to achieve reasonable low power consumption I had to connect the power Pins of the display to IO pins on the MSP430F2013

    main.c
  25. Like
    timotet got a reaction from roger430 in Using 3 wires to control parallel LCD display   
    So Ive managed to get RobG's code to work on the Wintek 1 x 24 Character LCD Display Module that I got awhile ago from
    Electronic Goldmine for $1.99.
     
    Here's the link: http://www.goldmine-elec-products.com/p ... ber=G15318
     
    There are only 2 cons so far:
    1 It takes 5v to power the display.
    2 It takes 4 wires instead of 3. ( you have to toggle the reset pin on the display.)
     
    logic seems to work fine at the 3.6v the msp430 puts out.
     


     
    here's the code:

    /* hex instructions for display setup 0x1C == LCD power control PW 0x14 == Display on/off DO 0x28 == Display Control sets lines ect. DC 0x4F == Contrast Set CN 0xE0 == DDRAM address set DA */ #include "msp430g2452.h" #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define clearDisplay() sendInstruction(0x01); _delay_cycles(2000) #define DATAPIN BIT6 #define CLOCKPIN BIT5 #define ENABLEPIN BIT4 #define RESETPIN BIT7 void send(char data, char registerSelect); void sendDataArray(char data[], char length); //void resetPin(unsigned int bit); void initDisplay(void); char charIndex = 0; char bitCounter = 0; const char message1[8] = {0x34,0x33,0x6F,0x68,0x2E,0x63,0x6F,0x6D}; char message2[11] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xA4}; const char message3[16] = {0x34,0x2D,0x70,0x69,0x6E,0x20,0x73,0x65,0x72,0x69,0x61,0x6C,0x20,0x4C,0x43,0x44}; char message4[12] = {0x54,0x68,0x61,0x6E,0x6B,0x73,0x20,0xAE,0x6F,0x62,0x47,0x21}; void main(void) { WDTCTL = WDTPW + WDTHOLD; _delay_cycles(100000); 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; // sets ENABLEPIN high initDisplay(); // initiate display while(1) { // send const message using sendDataArray clearDisplay(); sendDataArray((char *)message1, 8); _delay_cycles(3000000); // send message using sendDataArray clearDisplay(); sendDataArray(message2, 11); _delay_cycles(3000000); // send message one char at the time clearDisplay(); charIndex = 0; while(charIndex < 16) { sendData(message3[charIndex]); charIndex++; } _delay_cycles(3000000); // send message using sendDataArray clearDisplay(); sendDataArray(message4, 12); _delay_cycles(3000000); } } void sendDataArray(char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } 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 initDisplay(void) { P1OUT &= ~RESETPIN; // RESETPIN low _delay_cycles(10000); P1OUT |= RESETPIN; //RESETPIN high sendInstruction(0x1C); //PW sendInstruction(0x14); //DO 0x14 sendInstruction(0x28); //DC 0x28 sendInstruction(0x4F); //CN 0x4F sendInstruction(0xE0); //DA //sendInstruction(0x72); //SC //sendInstruction(0xC); //CR }
×
×
  • Create New...