Jump to content

pkonzak

Members
  • Content Count

    8
  • Joined

  • Last visited


Reputation Activity

  1. Like
    pkonzak got a reaction from pine in $4.30 LCD Booster - Sold Out   
    Finally opened my LCD and found a dollar. Thanks SA. Now I need to finally get around to building my controller. Thanks for the great job and the cheap price.
  2. Like
    pkonzak reacted to RobG in Nokia 7110 Library   
    Here's my version of Nokia 7110 library.
    Just text for now, but graphics will be included later on.
    Enjoy!
     


     
    main.cfont_5x7.h
    sed1565.c
    sed1565.h
  3. Like
    pkonzak reacted to SugarAddict in $4.30 LCD Booster - Sold Out   
    And a little later... they are all done. Please post if you find something inside one hahaha I'll have these nicely packaged up tomorrow and in the mail to bluehash Friday!! Man, I feel like I accomplished something Hope you all enjoy!!!!!!!!!!!! :mrgreen: 8-)
  4. Like
    pkonzak reacted to RobG in $4.30 LCD Booster - Sold Out   
    Well, here's the v1 of my code.
  5. Like
    pkonzak reacted to SugarAddict in $4.30 LCD Booster - Sold Out   
    Got the ship notice on the 100 boards today. First 8 (remainder of the 10 final proto order) assembled and done.
     

  6. Like
    pkonzak reacted to oPossum in Frequency Counter using Launchpad & Nokia 5110 LCD   
    This is a simple frequency counter with a range of 1 Hz to 16 MHz. It uses the 32 kHz watch crystal so the accuracy is good enough for many applications. Gate time is automatically set to 250 ms or 1 second.
     
    There is no signal conditioning (front end), so it is limited to 3V logic levels signals only! It is intended to be used with digital circuits like another MSP430 or 74HCxx circuits. It is not a substitute for a proper commercial frequency counter.
     
    How a frequency counter works: Fundamentals of Electronic Counters by Agilent
     
    Wiring

     


     
     
    main.c

    #include "msp430g2553.h" #include "lcd.h" static const unsigned long dv[] = { // Base 10 digit weights 10000000, // 8 digit maximum count 1000000, // 100000, // 10000, // 1000, // 100, // 10, // 1, // 0 // }; static void print_freq(unsigned long n) { const unsigned long *dp = dv; unsigned x = 0; unsigned c; unsigned long d; while(n < *dp) { // Skip leading zeros if(*dp == 100000 || *dp == 100) x += 2; // Space between 3 digit groups ++dp; // lcd_pd10(10, x, 2); // Print space x += 10; // } // if(n) { // Non-zero do { // d = *dp++; // Get digit value c = 0; // while(n >= d) ++c, n -= d; // Divide if(d == 100000 || d == 100) x += 2; // Space between 3 digit groups lcd_pd10(c, x, 2); // Print digit x += 10; // } while(!(d & 1)); // Until all digits done } else // lcd_pd10(0, x - 10, 2); // Print zero } static unsigned clock_input = 0; void set_input(void) { const unsigned char z = 0; lcd_pos(0, 4); lcd_send(&z, 84, lcd_data_repeat); switch(clock_input) { default: clock_input = 0; case 0: TACTL = TASSEL_2; lcd_print("Internal 16MHz", 0, 4); break; case 1: TACTL = TASSEL_0; lcd_print("Clock In P1.0", 3, 4); break; #if 0 case 2: // This should always show 32768 TACTL = TASSEL_1; // Something is very wrong if it doesn't lcd_print("Internal 32kHz", 0, 4); break; #endif } } void set_gate(unsigned long f) { if(WDTCTL & WDTIS0) { // 250 ms gate currently in use if(f < 800000) { // Switch to 1 s gate if frequncy is below 800 kHz lcd_print("1 Second Gate", 3, 5); WDTCTL = WDTPW | WDTTMSEL | WDTSSEL; } } else { // 1 s gate currently in use if(f > 900000) { // Switch to 250 ms gate if frequency above 900 kHz lcd_print(" 250 ms Gate ", 3, 5); WDTCTL = WDTPW | WDTTMSEL | WDTSSEL | WDTIS0; } } } void main(void) { unsigned long freq = 12345678L; // Measured frequency // WDTCTL = WDTPW | WDTHOLD; // Disable watchdog reset // DCOCTL = 0; // Run at 16 MHz BCSCTL1 = CALBC1_16MHZ; // DCOCTL = CALDCO_16MHZ; // //BCSCTL3 = XCAP_1; // 6 pF (default) BCSCTL3 = XCAP_2; // 10 pF //BCSCTL3 = XCAP_3; // 12.5 pF // lcd_init(); // Initialize LCD // P1SEL |= BIT0; // Use P1.0 as TimerA input P1SEL2 &= ~BIT0; // P1DIR &= ~BIT0; // P1OUT &= ~BIT0; // Enable pull down resistor to reduce stray counts P1REN |= BIT0; // // WDTCTL = WDTPW | WDTTMSEL | WDTCNTCL | WDTSSEL | WDTIS0; // Use WDT as interval timer // Default to 250 ms gate so that initial call to set_gate() // will switch to 1 s gate and update the LCD // lcd_clear(0); // Clear LCD lcd_print("Frequency", 16, 0); // What it is lcd_print("Counter", 22, 1); // print_freq(freq); // 8 digit frequency set_input(); // Set input and show on LCD set_gate(0); // Set gate time and show on LCD // for(; { // for-ever freq = 0; // Clear frequency TACTL |= TACLR; // Clear TimerA // IFG1 &= ~WDTIFG; // Wait for WDT period to begin while(!(IFG1 & WDTIFG)); // // TACTL |= MC_2; // Start counting - TimerA continuous mode // IFG1 &= ~WDTIFG; // while(!(IFG1 & WDTIFG)) { // While WDT period.. if(TACTL & TAIFG) { // Check for TimerA overflow freq += 0x10000L; // Add 1 to msw of frequency TACTL &= ~TAIFG; // Clear overflow flag } // } // // TACTL &= ~MC_2; // Stop counting - TimerA stop mode if(TACTL & TAIFG) freq += 0x10000L; // Handle TimerA overflow that may have occured between // last check of overflow and stopping TimerA freq |= TAR; // Merge TimerA count with overflow if(WDTCTL & WDTIS0) freq <<= 2; // Multiply by 4 if using 250 ms gate print_freq(freq); // Show on LCD // set_gate(freq); // Adjust gate time if necessary // if(!(P1IN & BIT3)) { // Check if pushbutton down ++clock_input; // Switch clock input set_input(); // } // } // } lcd.h
    typedef enum { lcd_command = 0, // Array of one or more commands lcd_data = 1, // Array of one or more bytes of data lcd_data_repeat = 2 // One byte of data repeated } lcd_cmd_type; void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type); void lcd_home(void); void lcd_pos(unsigned char x, unsigned char y); void lcd_clear(unsigned char x); void lcd_init(void); void lcd_print(char *s, unsigned x, unsigned y); void lcd_pd10(unsigned n, unsigned x, unsigned y); lcd.c
    #include "msp430g2553.h" #include "lcd.h" //static const unsigned TXD = BIT1; static const unsigned RXD = BIT2; static const unsigned SWITCH = BIT3; static const unsigned LCD_CLK = BIT5; static const unsigned LCD_BACKLIGHT = BIT6; static const unsigned LCD_DATA = BIT7; static const unsigned LCD_DC = BIT0; // PORT2 static const unsigned LCD_CE = BIT1; // PORT2 void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type) { register unsigned mask; P2OUT &= ~LCD_CE; do { mask = 0x0080; do { if(*cmd & mask) { P1OUT &= ~LCD_CLK; P1OUT |= LCD_DATA; } else { P1OUT &= ~(LCD_CLK | LCD_DATA); } P1OUT |= LCD_CLK; mask >>= 1; } while(!(mask & 1)); if(!type) P2OUT &= ~LCD_DC; if(*cmd & mask) { P1OUT &= ~LCD_CLK; P1OUT |= LCD_DATA; } else { P1OUT &= ~(LCD_CLK | LCD_DATA); } P1OUT |= LCD_CLK; P2OUT |= LCD_DC; if(!(type & 2)) ++cmd; } while(--len); P2OUT |= LCD_CE; } static const unsigned char home[] = { 0x40, 0x80 }; void lcd_home(void) { lcd_send(home, sizeof(home), lcd_command); } void lcd_pos(unsigned char x, unsigned char y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 | y; lcd_send(c, sizeof(c), lcd_command); } void lcd_clear(unsigned char x) { lcd_home(); lcd_send(&x, 504, lcd_data_repeat); lcd_home(); } void lcd_init(void) { static const unsigned char init[] = { 0x20 + 0x01, // Function set - extended instructions enabled //0x80 + 64, // Set vop (contrast) 0 - 127 0x80 + 66, // This is better for fast LCD update 0x04 + 0x02, // Temperature control 0x10 + 0x03, // Set bias system 0x20 + 0x00, // Function set - chip active, horizontal addressing, basic instructions 0x08 + 0x04 // Display control - normal mode }; P1REN = RXD | SWITCH; P1DIR = LCD_CLK | LCD_BACKLIGHT | LCD_DATA; P1OUT = LCD_CLK | RXD | SWITCH | LCD_BACKLIGHT; P2REN = 0; P2DIR = LCD_DC | LCD_CE; P2OUT = LCD_CE; __delay_cycles(20000); P2OUT |= LCD_DC; __delay_cycles(20000); lcd_send(init, sizeof(init), lcd_command); } static const unsigned char font6x8[96][5] = { 0x00, 0x00, 0x00, 0x00, 0x00, // 20 32 <space> 0x00, 0x00, 0x5F, 0x00, 0x00, // 21 33 ! 0x00, 0x07, 0x00, 0x07, 0x00, // 22 34 " 0x14, 0x7F, 0x14, 0x7F, 0x14, // 23 35 # 0x24, 0x2A, 0x7F, 0x2A, 0x12, // 24 36 $ 0x23, 0x13, 0x08, 0x64, 0x62, // 25 37 % 0x36, 0x49, 0x56, 0x20, 0x50, // 26 38 & 0x00, 0x08, 0x07, 0x03, 0x00, // 27 39 ' 0x00, 0x1C, 0x22, 0x41, 0x00, // 28 40 ( 0x00, 0x41, 0x22, 0x1C, 0x00, // 29 41 ) 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // 2A 42 * 0x08, 0x08, 0x3E, 0x08, 0x08, // 2B 43 + 0x00, 0x40, 0x38, 0x18, 0x00, // 2C 44 , 0x08, 0x08, 0x08, 0x08, 0x08, // 2D 45 - 0x00, 0x00, 0x60, 0x60, 0x00, // 2E 46 . 0x20, 0x10, 0x08, 0x04, 0x02, // 2F 47 / 0x3E, 0x51, 0x49, 0x45, 0x3E, // 30 48 0 0x00, 0x42, 0x7F, 0x40, 0x00, // 31 49 1 0x42, 0x61, 0x51, 0x49, 0x46, // 32 50 2 0x21, 0x41, 0x49, 0x4D, 0x33, // 33 51 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 34 52 4 0x27, 0x45, 0x45, 0x45, 0x39, // 35 53 5 0x3C, 0x4A, 0x49, 0x49, 0x30, // 36 54 6 0x41, 0x21, 0x11, 0x09, 0x07, // 37 55 7 0x36, 0x49, 0x49, 0x49, 0x36, // 38 56 8 0x06, 0x49, 0x49, 0x29, 0x1E, // 39 57 9 0x00, 0x00, 0x14, 0x00, 0x00, // 3A 58 : 0x00, 0x00, 0x40, 0x34, 0x00, // 3B 59 ; 0x00, 0x08, 0x14, 0x22, 0x41, // 3C 60 < 0x14, 0x14, 0x14, 0x14, 0x14, // 3D 61 = 0x00, 0x41, 0x22, 0x14, 0x08, // 3E 62 > 0x02, 0x01, 0x51, 0x09, 0x06, // 3F 63 ? 0x3E, 0x41, 0x5D, 0x59, 0x4E, // 40 64 @ 0x7C, 0x12, 0x11, 0x12, 0x7C, // 41 65 A 0x7F, 0x49, 0x49, 0x49, 0x36, // 42 66 B 0x3E, 0x41, 0x41, 0x41, 0x22, // 43 67 C 0x7F, 0x41, 0x41, 0x41, 0x3E, // 44 68 D 0x7F, 0x49, 0x49, 0x49, 0x41, // 45 69 E 0x7F, 0x09, 0x09, 0x09, 0x01, // 46 70 F 0x3E, 0x41, 0x49, 0x49, 0x7A, // 47 71 G 0x7F, 0x08, 0x08, 0x08, 0x7F, // 48 72 H 0x00, 0x41, 0x7F, 0x41, 0x00, // 49 73 I 0x20, 0x40, 0x41, 0x3F, 0x01, // 4A 74 J 0x7F, 0x08, 0x14, 0x22, 0x41, // 4B 75 K 0x7F, 0x40, 0x40, 0x40, 0x40, // 4C 76 L 0x7F, 0x02, 0x1C, 0x02, 0x7F, // 4D 77 M 0x7F, 0x04, 0x08, 0x10, 0x7F, // 4E 78 N 0x3E, 0x41, 0x41, 0x41, 0x3E, // 4F 79 O 0x7F, 0x09, 0x09, 0x09, 0x06, // 50 80 P 0x3E, 0x41, 0x51, 0x21, 0x5E, // 51 81 Q 0x7F, 0x09, 0x19, 0x29, 0x46, // 52 82 R 0x26, 0x49, 0x49, 0x49, 0x32, // 53 83 S 0x01, 0x01, 0x7F, 0x01, 0x01, // 54 84 T 0x3F, 0x40, 0x40, 0x40, 0x3F, // 55 85 U 0x1F, 0x20, 0x40, 0x20, 0x1F, // 56 86 V 0x3F, 0x40, 0x38, 0x40, 0x3F, // 57 87 W 0x63, 0x14, 0x08, 0x14, 0x63, // 58 88 X 0x03, 0x04, 0x78, 0x04, 0x03, // 59 89 Y 0x61, 0x51, 0x49, 0x45, 0x43, // 5A 90 Z 0x00, 0x7F, 0x41, 0x41, 0x41, // 5B 91 [ 0x02, 0x04, 0x08, 0x10, 0x20, // 5C 92 '\' 0x00, 0x41, 0x41, 0x41, 0x7F, // 5D 93 ] 0x04, 0x02, 0x01, 0x02, 0x04, // 5E 94 ^ 0x80, 0x80, 0x80, 0x80, 0x80, // 5F 95 _ 0x00, 0x03, 0x07, 0x08, 0x00, // 60 96 ' 0x20, 0x54, 0x54, 0x54, 0x78, // 61 97 a 0x7F, 0x28, 0x44, 0x44, 0x38, // 62 98 b 0x38, 0x44, 0x44, 0x44, 0x28, // 63 99 c 0x38, 0x44, 0x44, 0x28, 0x7F, // 64 100 d 0x38, 0x54, 0x54, 0x54, 0x18, // 65 101 e 0x00, 0x08, 0x7E, 0x09, 0x02, // 66 102 f 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // 67 103 g 0x7F, 0x08, 0x04, 0x04, 0x78, // 68 104 h 0x00, 0x44, 0x7D, 0x40, 0x00, // 69 105 i 0x00, 0x20, 0x40, 0x40, 0x3D, // 6A 106 j 0x00, 0x7F, 0x10, 0x28, 0x44, // 6B 107 k 0x00, 0x41, 0x7F, 0x40, 0x00, // 6C 108 l 0x7C, 0x04, 0x78, 0x04, 0x78, // 6D 109 m 0x7C, 0x08, 0x04, 0x04, 0x78, // 6E 110 n 0x38, 0x44, 0x44, 0x44, 0x38, // 6F 111 o 0xFC, 0x18, 0x24, 0x24, 0x18, // 70 112 p 0x18, 0x24, 0x24, 0x18, 0xFC, // 71 113 q 0x7C, 0x08, 0x04, 0x04, 0x08, // 72 114 r 0x48, 0x54, 0x54, 0x54, 0x24, // 73 115 s 0x04, 0x04, 0x3F, 0x44, 0x24, // 74 116 t 0x3C, 0x40, 0x40, 0x20, 0x7C, // 75 117 u 0x1C, 0x20, 0x40, 0x20, 0x1C, // 76 118 v 0x3C, 0x40, 0x30, 0x40, 0x3C, // 77 119 w 0x44, 0x28, 0x10, 0x28, 0x44, // 78 120 x 0x4C, 0x90, 0x90, 0x90, 0x7C, // 79 121 y 0x44, 0x64, 0x54, 0x4C, 0x44, // 7A 122 z 0x00, 0x08, 0x36, 0x41, 0x00, // 7B 123 { 0x00, 0x00, 0x77, 0x00, 0x00, // 7C 124 | 0x00, 0x41, 0x36, 0x08, 0x00, // 7D 125 } 0x02, 0x01, 0x02, 0x04, 0x02, // 7E 126 ~ 0x00, 0x06, 0x09, 0x09, 0x06, // 7F 127 degrees }; void lcd_print(char *s, unsigned x, unsigned y) { lcd_pos(x, y); while(*s) { lcd_send(&font6x8[*s - 32][0], 5, lcd_data); lcd_send(&font6x8[0][0], 1, lcd_data); ++s; } } static const unsigned char num10x16[11][9 * 2] = { // Numbers for 10x16 cell 0xF0,0xF8,0x0C,0x04,0x04,0x04,0x0C,0xF8,0xF0, // 0 0x0F,0x1F,0x30,0x20,0x20,0x20,0x30,0x1F,0x0F, 0x00,0x00,0x10,0x10,0xFC,0xFC,0x00,0x00,0x00, // 1 0x00,0x00,0x20,0x20,0x3F,0x3F,0x20,0x20,0x00, 0x18,0x1C,0x04,0x04,0x04,0x04,0x8C,0xF8,0x70, // 2 0x20,0x30,0x38,0x2C,0x26,0x23,0x21,0x20,0x20, 0x18,0x1C,0x04,0x84,0x84,0x84,0xCC,0x78,0x30, // 3 0x18,0x38,0x20,0x20,0x20,0x20,0x31,0x1F,0x0E, 0x00,0x80,0x40,0x20,0x10,0x08,0xFC,0xFC,0x00, // 4 0x03,0x02,0x02,0x02,0x02,0x02,0x3F,0x3F,0x02, 0x00,0x7C,0x7C,0x44,0x44,0x44,0xC4,0x84,0x04, // 5 0x18,0x38,0x20,0x20,0x20,0x20,0x30,0x1F,0x0F, 0xE0,0xF0,0x58,0x4C,0x44,0x44,0xC4,0x84,0x00, // 6 0x0F,0x1F,0x30,0x20,0x20,0x20,0x30,0x1F,0x0F, 0x04,0x04,0x04,0x04,0x04,0xC4,0xF4,0x3C,0x0C, // 7 0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00, 0x30,0x78,0xCC,0x84,0x84,0x84,0xCC,0x78,0x30, // 8 0x0E,0x1F,0x31,0x20,0x20,0x20,0x31,0x1F,0x0E, 0xF0,0xF8,0x0C,0x04,0x04,0x04,0x0C,0xF8,0xF0, // 9 0x00,0x21,0x23,0x22,0x22,0x32,0x1A,0x0F,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <space> 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; void lcd_pd10(unsigned n, unsigned x, unsigned y) // Print 10x16 digit { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 + y; lcd_send(c, 2, lcd_command); lcd_send(num10x16[n], 9, lcd_data); c[1] = 0x41 + y; lcd_send(c, 2, lcd_command); lcd_send(num10x16[n] + 9, 9, lcd_data); }
  7. Like
    pkonzak reacted to oPossum in Nokia 5110 C++ Template Class   
    This is a C++ template for the Nokia 5100 that uses software SPI. Inspired by Rickta59's GPIO template
     
    Using C++ templates allow the compiler to make decisions at compile time that would normally occur (repeatedly) at execution time. This results in smaller and faster code. They also are type safe and compatible with source level debugging (unlike macros).
     
    Software SPI is used to make the code very portable to the entire MSP430 family and allow flexible pin assignment. Four wiring schemes are supported.
     

     
    This is the syntax for creating an instance of the template.

    Nokia5110< \ // Template name P1OUT, // Output port for clock and data BIT0, // Clock pin bitmask BIT1, // Data pin bitmask P1OUT, // Output port for DC (data/command), use PNONE if DC line is not used BIT2, // DC pin bitmask (or clock stretch cycles if DC line is not used) P1OUT, // Output port for CE (chip enable), use PNONE if CE line is not used BIT3, // CE pin bitmask 10000> \ // Reset cycle count lcd; // Object name
    The class template

    namespace nokia5110 { unsigned char PNONE; typedef enum { lcd_command = 0, // Array of one or more commands lcd_data = 1, // Array of one or more bytes of data lcd_data_repeat = 2 // One byte of data repeated } lcd_cmd_type; template struct Nokia5110 { void write(const unsigned char *cmd, unsigned len, const lcd_cmd_type type = lcd_data); void reset(void); void init(void); void vert(void); void home(void); void pos(unsigned char x, unsigned char y); void clear(unsigned char x = 0); void bitmap(const unsigned char *bmp, signed char x, signed char y, unsigned char w, unsigned char h); inline void bitmap(const unsigned char *bmp, signed char x, signed char y) { bitmap(bmp + 2, x, y, bmp[0], bmp[1]); }; void print(char c); inline void print(unsigned char x, unsigned char y, char c) { pos(x, y); print(c); }; void print(char *s); inline void print(unsigned char x, unsigned char y, char *s) { pos(x, y); print(s); }; void printv(unsigned char x, unsigned char y, char *s); }; template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::write(const unsigned char *cmd, unsigned len, const lcd_cmd_type type) { register unsigned mask; if(&_EP != &PNONE) _EP &= ~_CE; do { mask = 0x0080; do { if(*cmd & mask) { _SP |= _DATA; _SP &= ~_CLK; } else { _SP &= ~(_CLK | _DATA); } _SP |= _CLK; mask >>= 1; } while(!(mask & 1)); if(&_CP == &PNONE) { __delay_cycles(_DC); } else { if(!type) _CP &= ~_DC; } if(*cmd & mask) { _SP |= _DATA; _SP &= ~_CLK; } else { _SP &= ~(_CLK | _DATA); } _SP |= _CLK; if(&_CP != &PNONE) _CP |= _DC; if(!(type & 2)) ++cmd; } while(--len); if(&_EP != &PNONE) _EP |= _CE; } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::reset(void) { // --- Set initial state of CLK, DC and CE as needed // * = output used for reset if(&_CP == &PNONE) { if(&_EP != &PNONE) { // CLK*, DATA, CE _EP |= _CE; } // else // CLK*, DATA } else { if(&_EP != &PNONE) { // CLK, DATA, DC*, CE if(&_SP == &_EP) { _SP |= (_CLK | _CE); } else { _SP |= _CLK; _EP |= _CE; } } // else // CLK, DATA, DC* } // --- Reset pulse on CLK or DC as needed if(&_CP == &PNONE) { // No DC port, use CLK to reset _SP &= ~_CLK; __delay_cycles(_RST); _SP |= _CLK; } else { // Use DC to reset _CP &= ~_DC; __delay_cycles(_RST); _CP |= _DC; } __delay_cycles(_RST); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::init(void) { static const unsigned char init[] = { 0x20 | 0x01, // Function set - extended instructions enabled //0x80 | 64, // Set vop (contrast) 0 - 127 0x80 | 70, // Higher contrast improves animation 0x04 | 2, // Temperature control 0x10 | 3, // Set bias system 0x20 | 0x00, // Function set - chip active, horizontal addressing, basic instructions 0x08 | 0x04 // Display control - normal mode }; write(init, sizeof(init), lcd_command); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::vert(void) { static const unsigned char v[] = { 0x20 | 0x02, // Function set - chip active, vertical addressing, basic instructions }; write(v, sizeof(v), lcd_command); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::home(void) { static const unsigned char home[] = { 0x40, 0x80 }; write(home, sizeof(home), lcd_command); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::pos(unsigned char x, unsigned char y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 | y; write(c, sizeof(c), lcd_command); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::clear(unsigned char x) { home(); write(&x, 504, lcd_data_repeat); home(); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::bitmap(const unsigned char *bmp, signed char x, signed char y, unsigned char w, unsigned char h) { unsigned char c[2]; unsigned char ww; if(x < 0) { ww = w + x; bmp -= x; x = 0; } else if(x + w >= 84) { ww = (84 - x); } else { ww = w; } c[0] = 0x80 | x; c[1] = 0x40 | y; while(h--) { write(c, sizeof(c), lcd_command); ++c[1]; write(bmp, ww); bmp += w; } } static const unsigned char font[96][5] = { 0x00, 0x00, 0x00, 0x00, 0x00, // 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, 0x56, 0x20, 0x50, // & 0x00, 0x08, 0x07, 0x03, 0x00, // ' 0x00, 0x1C, 0x22, 0x41, 0x00, // ( 0x00, 0x41, 0x22, 0x1C, 0x00, // ) 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // * 0x08, 0x08, 0x3E, 0x08, 0x08, // + 0x00, 0x40, 0x38, 0x18, 0x00, // , 0x08, 0x08, 0x08, 0x08, 0x08, // - 0x00, 0x00, 0x60, 0x60, 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, 0x49, 0x4D, 0x33, // 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 0x27, 0x45, 0x45, 0x45, 0x39, // 5 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 0x41, 0x21, 0x11, 0x09, 0x07, // 7 0x36, 0x49, 0x49, 0x49, 0x36, // 8 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 0x00, 0x00, 0x14, 0x00, 0x00, // : 0x00, 0x00, 0x40, 0x34, 0x00, // ; 0x00, 0x08, 0x14, 0x22, 0x41, // < 0x14, 0x14, 0x14, 0x14, 0x14, // = 0x00, 0x41, 0x22, 0x14, 0x08, // > 0x02, 0x01, 0x51, 0x09, 0x06, // ? 0x3E, 0x41, 0x5D, 0x59, 0x4E, // @ 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 0x7F, 0x49, 0x49, 0x49, 0x36, // B 0x3E, 0x41, 0x41, 0x41, 0x22, // C 0x7F, 0x41, 0x41, 0x41, 0x3E, // D 0x7F, 0x49, 0x49, 0x49, 0x41, // E 0x7F, 0x09, 0x09, 0x09, 0x01, // F 0x3E, 0x41, 0x49, 0x49, 0x7A, // 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, 0x1C, 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 0x26, 0x49, 0x49, 0x49, 0x32, // S 0x01, 0x01, 0x7F, 0x01, 0x01, // T 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 0x3F, 0x40, 0x38, 0x40, 0x3F, // W 0x63, 0x14, 0x08, 0x14, 0x63, // X 0x03, 0x04, 0x78, 0x04, 0x03, // Y 0x61, 0x51, 0x49, 0x45, 0x43, // Z 0x00, 0x7F, 0x41, 0x41, 0x41, // [ 0x02, 0x04, 0x08, 0x10, 0x20, // '\' 0x00, 0x41, 0x41, 0x41, 0x7F, // ] 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 0x80, 0x80, 0x80, 0x80, 0x80, // _ 0x00, 0x03, 0x07, 0x08, 0x00, // ' 0x20, 0x54, 0x54, 0x54, 0x78, // a 0x7F, 0x28, 0x44, 0x44, 0x38, // b 0x38, 0x44, 0x44, 0x44, 0x28, // c 0x38, 0x44, 0x44, 0x28, 0x7F, // d 0x38, 0x54, 0x54, 0x54, 0x18, // e 0x00, 0x08, 0x7E, 0x09, 0x02, // f 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g 0x7F, 0x08, 0x04, 0x04, 0x78, // h 0x00, 0x44, 0x7D, 0x40, 0x00, // i 0x00, 0x20, 0x40, 0x40, 0x3D, // j 0x00, 0x7F, 0x10, 0x28, 0x44, // k 0x00, 0x41, 0x7F, 0x40, 0x00, // l 0x7C, 0x04, 0x78, 0x04, 0x78, // m 0x7C, 0x08, 0x04, 0x04, 0x78, // n 0x38, 0x44, 0x44, 0x44, 0x38, // o 0xFC, 0x18, 0x24, 0x24, 0x18, // p 0x18, 0x24, 0x24, 0x18, 0xFC, // q 0x7C, 0x08, 0x04, 0x04, 0x08, // r 0x48, 0x54, 0x54, 0x54, 0x24, // s 0x04, 0x04, 0x3F, 0x44, 0x24, // 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 0x4C, 0x90, 0x90, 0x90, 0x7C, // y 0x44, 0x64, 0x54, 0x4C, 0x44, // z 0x00, 0x08, 0x36, 0x41, 0x00, // { 0x00, 0x00, 0x77, 0x00, 0x00, // | 0x00, 0x41, 0x36, 0x08, 0x00, // } 0x02, 0x01, 0x02, 0x04, 0x02, // ~ 0x00, 0x06, 0x09, 0x09, 0x06, // degrees }; template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::print(char c) { write(&font[c - 32][0], 5); write(&font[0][0], 1); } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::print(char *s) { while(*s) { write(&font[*s - 32][0], 5); write(&font[0][0], 1); ++s; } } template void Nokia5110<_SP, _CLK, _DATA, _CP, _DC, _EP, _CE, _RST>::printv(unsigned char x, unsigned char y, char *s) { while(*s) { pos(x, y); ++y; write(&font[*s - 32][0], 5); write(&font[0][0], 1); ++s; } } } // namespace
     
    Test code

    #include "msp430g2553.h" #include "nokia5110tl.h" using namespace nokia5110; static const unsigned char ti[] = { 48, 48 / 8, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00,0x00,0xF0, 0xF0,0xF0,0xF0,0xF0,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,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFC,0xFC,0x3C,0x80,0xFC,0xFD, 0xFD,0xFD,0x3D,0x81,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFC,0x00,0x00,0x00,0x00, 0x00,0x1C,0x7C,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xF7,0xF0,0xF0,0x00,0xF0,0xFF,0xFF,0xFF, 0xFF,0x0F,0xF0,0xF0,0xF0,0xF0,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xF8,0xF0,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x3F,0x7F,0xFF, 0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,0x3F,0x7F,0xFF,0xFF, 0xFF,0xFF,0xFF,0x1F,0x00,0x1E,0x1F,0x1F,0x1F,0x1F, 0x01,0x1E,0x1F,0xDF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x7F,0x7F,0x3F,0x3F,0x3F,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03, 0x0F,0x3F,0xFF,0xFE,0xFE,0xFE,0xFC,0xFC,0xFC,0xFC, 0xFC,0xFC,0xFC,0x7F,0x1F,0x07,0x03,0x03,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,0x01,0x07,0x0F,0x0F,0x1F,0x1F,0x3F, 0x3F,0x3F,0x3F,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static const unsigned char g0[] = { 40, 40 / 8, 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x20,0x10,0x20, 0x20,0x40,0x80,0x80,0x00,0x00,0xE0,0x1E,0x02,0x02, 0x0C,0x30,0xC0,0x80,0x40,0x20,0x20,0x10,0x08,0x08, 0xD0,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x43,0x6C,0x10, 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E, 0x11,0x10,0x10,0x08,0x08,0x08,0x88,0xB0,0x40,0x00, 0x00,0x03,0x02,0x04,0x84,0x88,0x48,0x70,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x1E,0x12,0x21,0x21,0x20,0x40,0xC0,0x00, 0x00,0x02,0x0D,0x11,0x10,0x10,0x10,0x08,0x08,0x88, 0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x00,0x00, 0x08,0x36,0xC2,0x02,0x02,0x02,0x02,0x02,0x03,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0B, 0x10,0x10,0x08,0x04,0x04,0x02,0x01,0x03,0x0C,0x30, 0xC0,0x40,0x78,0x07,0x00,0x00,0x01,0x01,0x02,0x04, 0x04,0x08,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00 }; static const unsigned char g1[] = { 40, 40 / 8, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30, 0xC8,0x08,0x04,0x08,0x30,0x40,0x80,0x80,0xC0,0x38, 0x06,0x02,0x02,0x1E,0xE0,0x00,0x00,0x80,0x80,0x40, 0x40,0x20,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x30,0x4C,0x84,0x84,0x04,0x08,0x08,0x08, 0x09,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00, 0x20,0x58,0x44,0x43,0x40,0x80,0x80,0x80,0x80,0x00, 0x00,0xE0,0x20,0x10,0x10,0x10,0x09,0x0E,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x70,0x90,0x08,0x08,0x08,0x04,0x07,0x00, 0x00,0x01,0x01,0x01,0x01,0x02,0xC2,0x22,0x1A,0x04, 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x90, 0x10,0x10,0x10,0x20,0x21,0x21,0x32,0x0C,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x04,0x02, 0x02,0x01,0x01,0x00,0x00,0x07,0x78,0x40,0x40,0x60, 0x1C,0x03,0x01,0x01,0x02,0x0C,0x10,0x20,0x10,0x13, 0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; static const unsigned char g2[] = { 40, 40 / 8, 0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0xFC,0x04,0x02,0x02,0x0C,0x30,0xC0, 0x80,0x80,0x60,0x18,0x06,0x02,0xC4,0x3C,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x03,0x04,0x19,0xA1,0x42,0x02, 0x04,0x04,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x02,0x04,0x04, 0x02,0x82,0x42,0x21,0x11,0x0A,0x04,0x00,0x00,0x00, 0x00,0x1C,0x14,0x22,0x22,0x22,0x41,0x41,0x80,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x01,0x82,0x82,0x44,0x44,0x44,0x28,0x38,0x00, 0x00,0x00,0x00,0x20,0x50,0x88,0x84,0x42,0x41,0x40, 0x20,0x20,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x20,0x20, 0x40,0x42,0x85,0x98,0x20,0xC0,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x3C,0x23,0x40,0x60,0x18,0x06,0x01,0x01, 0x03,0x0C,0x30,0x40,0x40,0x20,0x3F,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00 }; static const unsigned RXD = BIT2; static const unsigned SWITCH = BIT3; static const unsigned LCD_DC = BIT0; static const unsigned LCD_CE = BIT4; static const unsigned LCD_CLK = BIT5; static const unsigned LCD_BACKLIGHT = BIT6; static const unsigned LCD_DATA = BIT7; int main(void) { WDTCTL = WDTPW | WDTHOLD; P1REN = RXD | SWITCH; P1DIR = LCD_DC | LCD_CE | LCD_CLK | LCD_BACKLIGHT | LCD_DATA; P1OUT = LCD_CLK | LCD_DC | RXD | SWITCH | LCD_CE | LCD_BACKLIGHT; Nokia5110 lcd; lcd.reset(); lcd.init(); lcd.clear(); for(int x = -47; x < 14; ++x) { lcd.bitmap(ti, x, 0); __delay_cycles(20000); } lcd.printv(0, 0, "MSP430"); lcd.printv(70, 0, "Nokia"); lcd.printv(78, 2, "5110"); __delay_cycles(2000000); lcd.clear(); for(int x = 14; x < 84; ++x) { lcd.bitmap(ti, x, 0); __delay_cycles(20000); } lcd.home(); char c; for(c = 33; c <= 116; ++c) { lcd.print(c); } __delay_cycles(2000000); lcd.clear(); lcd.print(0, 5, "Template Class"); for(; { for(signed char x = -39; x < 84; ) { lcd.bitmap(g0, x++, 0); __delay_cycles(100000); lcd.bitmap(g1, x++, 0); __delay_cycles(100000); lcd.bitmap(g2, x++, 0); __delay_cycles(100000); } } return 0; }
     


  8. Like
    pkonzak reacted to zeke in Best information for those new to the MSP430?   
    So, now you got a job doing hardware design and you want to use the MSP430 in your design.
     
    But you've discovered that your boss has insisted on using this "wicked cool awesome" and ancient 5V sensor because they have a bazillion in stock.
     
    "What's the problem with that?" you ask.
     
    The problem is this: the MSP430 is a 3.6V device and it doesn't have 5V tolerant I/O's. This means that you'll probably hurt the part if you put 5V into an input. Go ahead and google it. You'll find our very own OCY schooling someone on this topic back in 2008. I'll let you find the article. OCY is shy. And he's probably gonna rip me open for giving away his secret identity.
     
    So, what's the answer? SLAA148 is the answer.
     
    It will take you through the various input and output scenarios that you may face trying to interface to higher voltage systems - not just 5V.
     
    Using this information, you should be able to measure the status of a 12V power supply with the A/D inputs or figure out how to drive a 12V relay.
     
    Have a read. It's useful info.
  9. Like
    pkonzak reacted to zeke in Best information for those new to the MSP430?   
    If you are new to the MSP430 then you're probably drowning in information right now.

    It's true that there are a zillion configurations to make before the 430 will do what you want it do do.

    So I'm betting that you are asking yourself "Where do I start?"

    I humbly suggest the following TI application notes and books that will get you going in the right direction:

    1. slaa294: MSP430 Software Coding Techniques

    This application report covers software techniques and topics of interest to all MSP430
    programmers. The first part of the document discusses the MSP430 standard
    interrupt-based code flow model, recommended for the vast majority of applications.
    The next part discusses a handful of techniques that should be considered by any
    developer that sets out to develop an MSP430 application. Using these methods can
    greatly reduce debug time and/or provide additional robustness in the field. They
    include initialization procedures, validation of supply rails before performing
    voltage-sensitive operations, and use of special functions. Code examples are
    provided.

    2. : MSP430 32-kHz Crystal Oscillators

    Selection of the right crystal, correct load circuit, and proper board layout are important
    for a stable crystal oscillator. This application report summarizes crystal oscillator
    function and explains the parameters to select the correct crystal for MSP430
    ultralow-power operation. In addition, hints and examples for correct board layout are
    given. The document also contains detailed information on the possible oscillator tests
    to ensure stable oscillator operation in mass production.

    3. MSP430 Microcontroller Basics by John H. Davies

    The best thing I can say about this book at this time is that it describes well how to make use of the clocking system of the MSP430. This book should be in your personal library or at least on your wishlist.

    Once you digest the information above then you will be in good shape for success in working with the msp430.

    Have something to add?
    Then post up your valuable sources of knowledge.
  10. Like
    pkonzak reacted to RobG in Nokia 5110 display   
    Updated original post with new code.
    Added simple graphic stuff, 8 x 8 pixel graphics can be displayed, rotated, and flipped.
    Rotating is not very efficient, maybe there is another way of doing it. Alternatively, two images can be stored, normal and rotated 90, all other combinations can be achieved with flips.
     

  11. Like
    pkonzak reacted to DanAndDusty in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
×
×
  • Create New...