Jump to content
43oh

kenemon

Members
  • Content Count

    275
  • Joined

  • Last visited

  • Days Won

    2

Reputation Activity

  1. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    So here is my final (for now) encoder implementation, most reliable 2 pin so far.
    1. Increased capacitors to 1uF electrolytic (did try to debounce in software with WDT, but results were not so good.)
    2. Encoder A is P1.6, B is P1.7
    3. No other pins will use interrupts on P1
    4. Only one switch can interrupt at any time, this eliminates most of the problems with rocking and bouncing
    5. I really need to get something better than PEC11, about 90-120 deg of the turn produces horrible results.
     


     

    #include "msp430g2553.h" //required funct.asm #define APIN BIT6 #define BPIN BIT7 #define DPINT P1IE = 0; #define CLRPFG P1IFG = 0; #define LOWERNIBBLE BIT0 + BIT1 + BIT2 + BIT3 #define UPPERNIBBLE BIT4 + BIT5 + BIT6 + BIT7 #define ENABLEPIN BIT4 #define REGISTERSELECTPIN BIT5 #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define initDisplay() sendInstruction(0x3C); sendInstruction(0x0C); clearDisplay(); sendInstruction(0x06) #define clearDisplay() sendInstruction(0x01); _delay_cycles(2000) void binaryToASCIIScale(unsigned int n, unsigned char * digits, unsigned int scale); // asm prototype unsigned char d[5] = {0,0,0,0,0}; void sendDataArray(unsigned char data[], char length); void send(unsigned char data, unsigned char registerSelect); char charIndex = 0; char valueIndex = 0; int counter = 500; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = ENABLEPIN; P1DIR = ENABLEPIN + REGISTERSELECTPIN + LOWERNIBBLE; P2SEL &= ~(BIT6|BIT7); P2DIR = UPPERNIBBLE; P1IES = BPIN; CLRPFG; _delay_cycles(10000); // delay to allow display to settle down, might not be needed initDisplay(); _bis_SR_register(GIE); P1IE = BPIN; while(1) { sendInstruction(0x80); binaryToASCIIScale(counter>>1, d, 0); sendDataArray(d, 5); _bis_SR_register(LPM0_bits); } } void sendDataArray(unsigned char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(unsigned char data, unsigned char registerSelect) { P1OUT &= 0xF0; P1OUT |= data & 0x0F; P2OUT &= 0x0F; P2OUT |= data & 0xF0; registerSelect ? (P1OUT |= REGISTERSELECTPIN) : (P1OUT &= ~REGISTERSELECTPIN); P1OUT &= ~ENABLEPIN; P1OUT |= ENABLEPIN; } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { DPINT; // disable interrupts on port 1 if(P1IFG & APIN) { // interrupt came from switch A CLRPFG; // clear interrupt flags if((P1IES & APIN) ^ (P1IN & BPIN)) { // XOR IES of A with level of B to determine dir counter--; } else { counter++; } (P1IN & BPIN) ? (P1IES |= BPIN) : (P1IES &= ~BPIN); // set IES of B based on it's current level, safer than toggling P1IE = BPIN; // enable interrupts for switch B } else { // interrupt came from switch A CLRPFG; // clear interrupt flags if((P1IES & BPIN) ^ (P1IN & APIN)) { // XOR IES of B with level of A to determine dir counter++; } else { counter--; } (P1IN & APIN) ? (P1IES |= APIN) : (P1IES &= ~APIN); // set IES of A based on it's current level P1IE = APIN; // enable interrupts for switch A } _bic_SR_register_on_exit(LPM0_bits); }
  2. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    I guess it's the decision between simple software vs less pins used. You can sacrifice resolution and use only 2 pins instead of 4 for the encoder.
  3. Like
    kenemon reacted to Mac in Rotary Encoder and the LP   
    I wouldn't want to limit my creativity by thinking that way Rob (grin).
     
    Why can't you get full resolution with an encoder interrupt method using 2 pins instead of 4? I wonder if something like this might work? Couldn't you simply exclusive-or the P1IES 'A' or 'B' bit with the opposite 'B' or 'A' bit from P1IN to get "direction" and then toggle the P1IES interrupt edge select bit on your way out of the interrupt handler? Perhaps something like this (untested) example (both encoder pins on port 1)?
     

    #define old_A (P1IES & A_pin_mask) #define new_B (P1IN & B_pin_mask)
    #pragma vector = PORT1_VECTOR __interrupt void Port_1(void) { if(old_A ^ new_ // if direction = 1 counter--; // dec counter else // else counter++; // inc counter P1IES ^= P1IFG; // toggle edge select P1IFG = 0; // clr interrupt flag }

  4. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    You can be creative but you have to weight your options. If you end up with some spare pins because you used mux, I think simplifying your software should be considered.
     
     
    Looks like that should work, I will give it a try tonight. I wasn't crazy about switching IES, but I think our combined effort gave us some nice results.
    I wish I had better encoder though, those PEC11s are really awful, I get pretty nice results on one half of the turn, really bad on the other. On the other hand, if we can get crappy one to work, than all other will work too
  5. Like
    kenemon reacted to Mac in Rotary Encoder and the LP   
    What I was trying to say, as politely as possible, was that your statement was bull. It seemed that you were suggesting, and are continuing to suggest, that I can't write "simple" code for a solution that uses less pins, and I disagree with that. I take a lot of pride in writing clean, clever, simple, and elegant code. On the other hand, maybe I misunderstood. Were you perhaps trying to say that you can't write "simple" code for a solution that uses less pins?
     
    I'm sorry I don't have any way to test it but if it does work I think you'll agree it's pretty simple while using less pins without sacrificing resolution (grin).
     
    I agree. It seems like a very cheap mechanism.
  6. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    When talking about simple, I was talking about multiplexing, not just reducing pin count by 2.
     
    Anyway, I tried this...
     

    __interrupt void Port_1(void) { DINT; if((P1IES & A1PIN) ^ (P1IN & A2PIN)) { // A1PIN is A, A2PIN is B counter--; } else { counter++; } (P1IFG & A1PIN) ? (P1IES ^= A1PIN) : (P1IES ^= A2PIN); // toggle appropriate edge select CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); }
     
    ...and it works, but unreliably.
    Not sure if it's the encoder or the code, but the 4pin solution seems to be working a lot better.
     
    All I stated was that multiplexing requires more code because you have to juggle inputs and outputs.
    I can't comment on your code because honestly, I haven't seen any.
    It is a lot easier to improve and critique someone's work than to come up with it in the first place.
    Let's leave it at that.
  7. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    Here's the version that does not require serial board and uses 2553.
    The only other file you need from my previous posts is funct.asm.
    P1.0-P1.3 are connected to LCD's D0-D3
    P2.4-P2.7 to LCD's D4-D7
    P2.0 and P2.1 to encoder's A (with cap and pull-up resistor)
    P1.6 and P1.7 to encoder's B (with cap and pull-up resistor)
    P1.4 to LCD's enable
    P1.5 to LCD's RS
    LCD's R/W to GND
    LCD's GND, Vcc, Contrast, as required ( I tried with both, 3.3V and 5V, you can get 5V from LP's TP1.)
     

    #include "msp430g2553.h" //required funct.asm #define A1PIN BIT6 #define A2PIN BIT7 #define B1PIN BIT0 #define B2PIN BIT1 #define EINT P1IE |= A1PIN|A2PIN; P2IE |= B1PIN|B2PIN #define DINT P1IE &= ~(A1PIN|A2PIN); P2IE &= ~(B1PIN|B2PIN) #define CLRPFG P1IFG &= ~(A1PIN|A2PIN); P2IFG &= ~(B1PIN|B2PIN) #define LOWERNIBBLE BIT0 | BIT1 | BIT2 | BIT3 #define UPPERNIBBLE BIT4 | BIT5 | BIT6 | BIT7 #define ENABLEPIN BIT4 #define REGISTERSELECTPIN BIT5 #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define initDisplay() sendInstruction(0x3C); sendInstruction(0x0C); clearDisplay(); sendInstruction(0x06) #define clearDisplay() sendInstruction(0x01); _delay_cycles(2000) void binaryToASCIIScale(unsigned int n, unsigned char * digits, unsigned int scale); // asm prototype unsigned char d[5] = {0,0,0,0,0}; void sendDataArray(unsigned char data[], char length); void send(unsigned char data, unsigned char registerSelect); char charIndex = 0; char valueIndex = 0; int counter = 500; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = ENABLEPIN; P1DIR = ENABLEPIN | REGISTERSELECTPIN | LOWERNIBBLE; P2SEL &= ~(BIT6|BIT7); P2DIR = UPPERNIBBLE; P1IES &= ~A1PIN; P1IES |= A2PIN; P2IES &= ~B1PIN; P2IES |= B2PIN; CLRPFG; initDisplay(); _bis_SR_register(GIE); EINT; while(1) { sendInstruction(0x80); binaryToASCIIScale(counter>>1, d, 0); sendDataArray(d, 5); _bis_SR_register(LPM0_bits); } } void sendDataArray(unsigned char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(unsigned char data, unsigned char registerSelect) { P1OUT &= 0xF0; P1OUT |= data & 0x0F; P2OUT &= 0x0F; P2OUT |= data & 0xF0; registerSelect ? (P1OUT |= REGISTERSELECTPIN) : (P1OUT &= ~REGISTERSELECTPIN); P1OUT &= ~ENABLEPIN; P1OUT |= ENABLEPIN; } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { DINT; if((P1IFG & A1PIN) ^ (P2IN & B1PIN)) { counter--; } else { counter++; } CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); } // Port 2 interrupt service routine #pragma vector=PORT2_VECTOR __interrupt void Port_2(void) { DINT; if((P2IFG & B1PIN) ^ (P1IN & A1PIN)) { counter++; } else { counter--; } CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); }
     
    If you need 2 more pins and do not require full resolution, just change defines and reuse pins P1.1 and P2.7 (ISRs should be updated too but it's not necessary.)

    #define A1PIN BIT6 #define A2PIN BIT6 #define B1PIN BIT0 #define B2PIN BIT0
     
    If you need another 4 pins, you can drive LCD's 4bit mode and reclaim pins P1.0-P1.3 (several code changes are required.)
     
    Sidenote:
    This is actually a perfect example of why logical not arithmetic operators should be used for working with ports
    PxOUT |= BITA | BITB
    instead of
    PxOUT |= BITA + BITB
    I found many posts where statements were made that both yield same results and can be used interchangeably.
    This is true when all operands refer to a single unique bit (BIT0, BIT1, etc.)
    However, when operands refer to the same bit or more than one bits, using arithmetic operator will yield wrong results.
    For example:
    A1PIN and A2PIN are defined as bit 1
    P1OUT |= A1PIN | A2PIN, will correctly set bit 1
    P1OUT |= A1PIN + A2PIN, will incorrectly set bit 2
  8. Like
    kenemon reacted to Mac in Rotary Encoder and the LP   
    A variation of the previous design --> LCD interface and switch matrix on 6 pins. That's like getting the switch matrix for free (grin).
     
    Add two pins for a crystal and you're left with one pin for a "must have" piezo annunciator and one pin for a relay output. A potent single chip solution for that Clock/Calendar project, Alarm Clock project, or that Photo Timer / Appliance Timer project, etc...

  9. Like
    kenemon reacted to Mac in Rotary Encoder and the LP   
    One way you might reduce that 2 to 4 pin overhead for the encoder (ouch!) would be to mux' the encoder switches with the LCD data lines and poll the switches periodically in software.
     
    Regards...

  10. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    Serial board is used to save pins, you need 6 or 10 to control HD44780.
    LP has 10 available pins so after 2 or 4 used for the encoder, you have enough to control LCD in 4bit mode (6 pins.)
  11. Like
    kenemon reacted to nobody in Rotary Encoder and the LP   
    My code (above) do it.
     
    For this I also use RC debouncing. It's work perfectly.

    A----[ 4k7 ]---------> (internal pullup in MSP430) | | = 10nF | | --- B----[ 4k7 ]---------> (internal pullup in MSP430) | | = 10nF | | --- SW-------------------> (internal pullup in MSP430) | | = 100nF | | ---
  12. Like
    kenemon reacted to Mac in Rotary Encoder and the LP   
    With all four AB transition states between detent positions on that PEC11 encoder, you've come up with simplest and most elegant solution I've seen.
  13. Like
    kenemon reacted to Mac in Rotary Encoder and the LP   
    That method looks pretty good too. Another method uses quadrature direction = new A ^ old B = ~(new B ^ old A).
     
    I've used this method in the past. I would poll the encoder at some debounce interval and simply set "new press" switch flags (up, down, or left, right, etc.) based on quadrature direction.
     

    unsigned char newenc = 0; unsigned char oldenc = 0; unsigned char swflag = 0; #define old_A (oldenc & BIT7) #define new_B (newenc & BIT6)
    newenc = P1IN & 0xC0; // newenc = AB------ if(newenc != oldenc) // if changed { if(old_A ^ new_ // direction, 0 or 1 swflag |= sw1mask; // sw1 "new press" bit else // else swflag |= sw2mask; // sw2 "new press" bit oldenc = newenc; // update encoder latch }
    If I was using the PEC11 encoder with detents for a control, I would use an additional qualifier in my code to ignore all but the last transition into the detent position (new AB = 00 or 11, depending on code). It was kind of neat in that I could gently move the encoder back and forth between the detents and nothing would happen until I finally let the encoder fall into either detent position.
     
    Regards, Mike
  14. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    Here's my implementation.
    To cover all transitions, I am using pairs of pins with opposite edge detection.
    I am using external pullups and caps for denouncing since doing it in software would be very tricky and not reliable.
    My encoder is PEC11-4215K-S0024 and as Mike pointed it out, with detents it is hard to get single steps.
    After removing detent plate from my encoder, it works perfectly.
     

    #include "msp430g2231.h" #define A1PIN BIT1 #define A2PIN BIT2 #define B1PIN BIT6 #define B2PIN BIT7 #define EINT P1IE |= A1PIN|A2PIN; P2IE |= B1PIN|B2PIN #define DINT P1IE &= ~(A1PIN|A2PIN); P2IE &= ~(B1PIN|B2PIN) #define CLRPFG P1IFG &= ~(A1PIN|A2PIN); P2IFG &= ~(B1PIN|B2PIN) int counter = 0; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P2SEL &= ~(B1PIN|B2PIN); P2DIR = 0; P1DIR &= ~(A1PIN|A2PIN); P1IES &= ~A1PIN; P1IES |= A2PIN; P2IES &= ~B1PIN; P2IES |= B2PIN; CLRPFG; _bis_SR_register(GIE); EINT; while(1) { // do whatever _bis_SR_register(LPM0_bits); // sleep } } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { DINT; if((P1IFG & A1PIN) ^ (P2IN & B1PIN)) { counter--; } else { counter++; } CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); } // Port 2 interrupt service routine #pragma vector=PORT2_VECTOR __interrupt void Port_2(void) { DINT; if((P2IFG & B1PIN) ^ (P1IN & A1PIN)) { counter++; } else { counter--; } CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); }
     
     

    PEC11 +-------------------+ +-----+ | MSP430G2231 | | | | P2.6+-----+-----+---------+---------+ A | | | | | | | | | | | | +-+ | | | P2.7+-----+ |100n | | | | | | +---+ | |1K | | | | +---+ +-+ | | | | | | | | | | | GND | GND | | | | +---+ | +---+ C | | | | +---+ | | | | |100n | Vcc | | | | +---+ +-+ | | | | +---+ | | | | | P1.1+-----+ | | |1K | | | | | | +-+ | | | | | | | | | | P1.2+-----+-----+---------+---------+ B | | | | | +-------------------+ +-----+
     
     
    And here's the code which includes LCD display:
     

    #include "msp430g2231.h" #include "adc_lcd.h" #define A1PIN BIT1 #define A2PIN BIT2 #define B1PIN BIT6 #define B2PIN BIT7 #define EINT P1IE |= A1PIN|A2PIN; P2IE |= B1PIN|B2PIN #define DINT P1IE &= ~(A1PIN|A2PIN); P2IE &= ~(B1PIN|B2PIN) #define CLRPFG P1IFG &= ~(A1PIN|A2PIN); P2IFG &= ~(B1PIN|B2PIN) void binaryToASCIIScale(unsigned int n, unsigned char * digits, unsigned int scale); // asm prototype void sendChars(unsigned char chars[], unsigned char length); // asm prototype void send(unsigned char data, unsigned char registerSelect); // asm prototype unsigned char d[5] = {0,0,0,0,0}; void sendDataArray(unsigned char data[], char length); char charIndex = 0; char valueIndex = 0; int counter = 2000; void main(void) { WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT &= ~(CLOCKPIN + DATAPIN); P1OUT |= ENABLEPIN; P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN; P2SEL &= ~(B1PIN|B2PIN); P2DIR = 0; P1DIR &= ~(A1PIN|A2PIN); P1IES &= ~A1PIN; P1IES |= A2PIN; P2IES &= ~B1PIN; P2IES |= B2PIN; CLRPFG; initDisplay(); _bis_SR_register(GIE); EINT; while(1) { sendInstruction(0x80); binaryToASCIIScale(counter, d, 0); sendChars(d, 5); _bis_SR_register(LPM0_bits); // sleep } } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { DINT; if((P1IFG & A1PIN) ^ (P2IN & B1PIN)) { counter--; } else { counter++; } CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); } // Port 2 interrupt service routine #pragma vector=PORT2_VECTOR __interrupt void Port_2(void) { DINT; if((P2IFG & B1PIN) ^ (P1IN & A1PIN)) { counter++; } else { counter--; } CLRPFG; EINT; _bic_SR_register_on_exit(LPM0_bits); }
  15. Like
    kenemon reacted to RobG in Rotary Encoder and the LP   
    Here you can find header and asm files and the link to LCD post.
  16. Like
    kenemon reacted to nobody in Rotary Encoder and the LP   
    My version (based on msp430f2274 but portable to other series...)
    Advace:
    - It is controlled by rising and falling edge of signal.
    - Simplified by using the lookup table (look here).
     
    (it's only test code - not optimized yet...)
     
    I know - it is not necessary to test switch thru interrupts - but this is preparation to another extensions (measure time of pushing, recognize long and short click, ...)
     

    #include "io430.h" #include "font5x7.h" #include "stdio.h" #include "intrinsics.h" #include "putchar.c" #define ENC_A BIT6 // P2.6 encoder A #define ENC_B BIT7 // P2.7 encoder B #define ENC_SHIFT 6 // Encoder testing with (P2IN >> 6) #define ENC_SW BIT5 // P2.5 encoder switch volatile int Encoder_Value = 0; // Encoder value volatile unsigned char Encoder_SW = 0; // Encoder switch value push = 1, free = 0; int main( void ) { // int n, i; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset BCSCTL1 = CALBC1_8MHZ; // Set DCO to 8MHz DCOCTL = CALDCO_8MHZ; // (don't matter for this demo) // **Initialize system for encoder** P2SEL &= ~(ENC_A + ENC_B + ENC_SW); // Set back (XOUT/XIN) and Rosc to port function P2DIR &= ~(ENC_A + ENC_B + ENC_SW); // Input function P2REN |= ENC_A + ENC_B + ENC_SW; // Enable resistor P2OUT |= ENC_A + ENC_B + ENC_SW; // Pullup resistor P2IES |= ENC_A + ENC_B + ENC_SW; // Interrupt when 1 -> 0 (dynamically changed!!!!) P2IE |= ENC_A + ENC_B + ENC_SW; // Interrupt enable __enable_interrupt(); while(1) { if(Encoder_SW) Encoder_Value = 0; printf("Encoder=%d, \f", Encoder_Value); // I implemented my version of "putchar.c", // so I can use printf to an LCD display } } #pragma vector = PORT2_VECTOR __interrupt void Port2_Interrupt(void) { const signed char table[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; static unsigned char ab = 0; // the old value of the sensor ports // **switch test** if(P2IFG & ENC_SW) { P2IFG &= ~ENC_SW; if(P2IN & ENC_SW) // switch released { Encoder_SW = 0; P2IES |= ENC_SW; // Interrupt when 1 -> 0 } else // switch pushed { Encoder_SW = 1; P2IES &= ~ENC_SW; // Interrupt when 0 -> 1 } } // **encoder test** if(P2IFG & (ENC_A + ENC_) { P2IFG &= ~(ENC_A + ENC_; ab = ab << 2; // move the old data left two places ab |= ((P2IN >> ENC_SHIFT) & 0x03); // OR in the two new bits Encoder_Value += table[(ab & 0x0F)]; // get the change from the 16 entry table if(Encoder_Value > 32760) // Overflow? Encoder_Value = 32760; if(Encoder_Value < -32760) // Underflow? Encoder_Value = -32760; if(P2IN & ENC_A) // 1 P2IES |= ENC_A; // Interrupt when 1 -> 0 else // 0 P2IES &= ~ENC_A; // Interrupt when 0 -> 1 if(P2IN & ENC_ // 1 P2IES |= ENC_B; // Interrupt when 1 -> 0 else // 0 P2IES &= ~ENC_B; // Interrupt when 0 -> 1 } }
  17. Like
    kenemon reacted to zeke in Rotary Encoder and the LP   
    This is the code I used to test out the Bourns PEC11L-4220F-S0015 rotary encoder
     

    /* Rotary Encoder example Simple program to test a PEC11L-4220F-S0015 rotary encoder with pushbutton. Compiled using Code Composer Studio V4 Setup: +----------------+ LED -- | P1.0 P2.6 | -- NC LED -- | P1.1 P2.7 | -- Push Button LED -- | P1.2 | LED -- | P1.3 | LED -- | P1.4 P1.7 | -- Encoder B LED -- | P1.5 P1.6 | -- Encoder A +----------------+ Function: * Every time the encoder is pushed the LED on P1.0 will be toggled * The LED on P1.1 to P1.5 will move left/right according to the encoder * The script uses the internal pullup resistors */ #include #define CLI() _disable_interrupts() #define SEI() _enable_interrupts() #define dint() _disable_interrupts() #define eint() _enable_interrupts() unsigned char encoder_pos = BIT3; // Set starting pos to P1.3 unsigned char push_pos = 0; #pragma vector=PORT2_VECTOR __interrupt void p1_encoder_int(void) { dint(); if( P2IFG & 0x80 ) { push_pos ^= BIT0; P1OUT = BIT7 | BIT6 | encoder_pos | push_pos; // output P1 with push status and encoder pos } P2IFG = 0x00; eint(); } #pragma vector=PORT1_VECTOR __interrupt void p1_encoder_move(void) { dint(); if( P1IFG & 0x40 ) { if ( P1IN & BIT7 ) { // b is high -> counter clockwise if ( encoder_pos > BIT1 ) { // only move down if not already at bottom encoder_pos = encoder_pos >> 1; } } else { // b is low -> clockwise if ( encoder_pos < BIT5 ) { encoder_pos = encoder_pos << 1; } } P1OUT = BIT7 | BIT6 | encoder_pos | push_pos; // output P1 with push status and encoder pos } P1IFG = 0x00; eint(); } int main(void) { WDTCTL = WDTPW | WDTHOLD; // Setup port P1SEL = 0x00; // select io function for all ports (this is actually default for P1) P1REN = 0xC0; // select pullup resistors for pin 1.7 and 1.6 P1DIR = 0x3F; // iioo oooo P1OUT = 0xC8; // need to set P1.6 and P1.7 to high so PULLUP resistor will be selected P1IES = 0x00; // select low to high transition for interrupts on all port pins (this actually the default) P1IE = 0x40; // enable interrupt for P1.6 to reader status of encoder every time Encoder sigal A goes high P1IFG = 0x00; // clear interrupt register P2SEL = 0x00; // selection io function for all ports (default is actually XIN.XOUT for P2.7/2.6) P2REN = 0x80; // select pullup resistors for pin 2.7 P2DIR = 0x7F; // iooo oooo P2OUT = 0x80; // need to set P2.7 to high so PULLUP resistor will be selected P2IES = 0x00; // select low to high transition for interrupts on all port pins P2IE = 0x80; // enable interrupt P2.7 for push button P2IFG = 0x00; // clear interrupt register eint(); for (; { // loop forever } }
  18. Like
    kenemon reacted to bluehash in Rotary Encoder and the LP   
    You will have relative position by counting one of the pulses. Absolute positioning can be achieved by keeping the last counts in memory. The only error you will have is the size of the copper pads...
     
    Direction can be detected by looking at the two pulses and see which comes first - A or B.
  19. Like
    kenemon reacted to gordon in Standalone Nightmare   
    TEST and RST. Don't rely on pin numbers alone, for what if you'll use a smaller (or larger) chip?
     
    But yes, the general idea is the same with all SBW-programmable devices.
     
    Edit: for advice on schematic capture software, there's a whole thread. Add KiCad to that list; it seems to be popular in some circles.
  20. Like
    kenemon reacted to ike in LaunchPad HD44780 LCD USB PC interface   
    Your post looks too spamy for a new user.
    I can't post.
     
    The above restrictions only apply to new users. We are constantly tweaking the definition of a new user to stop spam while not annoying real people. These restrictions currently apply to users who:
    *Have less than 1 post - now I have 3 post.
    *Registered in the last 24 hours - I'm not registered in the last 24 hours.
    The restrictions are automatically removed once an account meets these criteria.
     
    And I'm not spam bot.
    Now I'm happy. I can post again
     
     
    I want to apologize for leaving project unfinished. And I want to tank bluehash for its support on this project.
     
    This LaunchPad HD44780 LCD USB PC interface is composed of 4 parts. Hardware, MSP430 firmware, LCDSmartie software and driver for software.
     
    Hardware. I've struggle to find software that is intuitive to use, to make schemes. So I'll use ASCII.
     

    LaunchPad LCD TP 1 Outputs 5V from USB - Pin 2 and Pin15 5V Vcc Vcc- nc P1.0 - Pin 4 RS P1.1 - PC UART interface P1.2 - PC UART interface P1.3 - Pin 6 Enable P1.4 - Pin 11 DB4 P1.5 - Pin 12 DB5 P1.6 - Pin 13 DB6 P1.7 - Pin 14 DB7 GND - Pin 5 R/W, Pin 1 and Pin 16 GND Pin 3 Resistor* 1800 ohm to GND
     
    In my LCD display there is 100 ohm resistor in series with white LED, so I can safety connect Pin 15 to
    5V VCC and Pin 14 to GND.
    *On Pin 3 should be potentiometer 100k ohm to GND, but the exact value needed for my display is 1800 ohm (It's value depends of supply voltage, ambient temperature and manufacture ot LCD).
     
    MSP430 firmware
    There is a lot of room for improvment here
    Use TI Code Composer Studio v4 Core Edition to compile.
     
     
    LCDSmartie software can be downloaded for free from here: http://lcdsmartie.sourceforge.net/
     
    Driver.
    There is a lot of room for improvment here also.
    Use M$ Microsoft Visual Studio 2005 to compile.
     
    Steps to make LaunchPad HD44780 LCD USB PC interface work.
    1. Assemble hardware. Use inferior MCU MSP430G2211 that comes with LaunchPad
    2. Compile msp430g2211.c with TI Code Composer Studio v4 - at this point you should see "Hello" on LCD display
    3. Download and unzip LCDSmartie.
    4. Compile LCDS_Plugin.cpp and LCDS_Plugin.H with Use M$ Microsoft Visual Studio 2005, save
    plugin.dll to \lcd_smartie_v5.4\displays\ directory.
    5. Connect LaunchPad with PC and go to: Computer Management->System Tools->Device Manager->
    Ports(COM & LPT)->MSP430 Aplication UART (COMx) and note COM port. It shoud be like COM5 or COM13.
    6. Setup LCDSmartie.
    Screens-> Display settings->Screen->LCD size 2x16
    Screens-> Display settings->Plugin->Display Plugin: plugin.dll
    Screens-> Display settings->Plugin->Startup Parameters: \\.\COM5
    or if your MSP430 Aplication UART is at COM13
    Screens-> Display settings->Plugin->Startup Parameters: \\.\COM13
    Screens->Screens settings
    On first line: http://www.43oh.com RSS
    On second line: $Rss(http://feeds.feedburner.com/Four-three-oh?format=xml,b)
     
    Here is new version of driver LCDS_Plugin.cpp, it now accept different COM port setings.
    One again sorry for my lack of coding experience. I do it in my spare time as a hoby. And I really hate to write long posts.
    This is open source project so feel free to improve it and make it beter.
    If you have questions don't hesitate to ask, I'm sure that bluehash will be happy ot answer it
     
     

    #include "msp430g2211.h" #include "stdint.h" //------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) //------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600) //------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character uint16_t CommandFlag; #define MAGIC 0x0f //------------------------------------------------------------------------------ //LCD //------------------------------------------------------------------------------ #define LCD_MODE_BIT 0x01 //BIT0 #define LCD_ENABLE_BIT 0x08 //BIT3 #define LCD_CMD_MASK 0x09 #define LCD_DATA_MASK 0xf0 #define LCD_PORT_OUT P1OUT #define LCD_PORT_DIR P1DIR int putchar( uint16_t in ) { LCD_PORT_OUT= ( in & 0xf0 ) | LCD_MODE_BIT; LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; // LCD_PORT_OUT= ( ( in << 4 ) & 0xf0 ) | LCD_MODE_BIT; LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; __no_operation(); //LCD_PORT_OUT= 0; __delay_cycles( 200 ); return (0); } void lcd_command( uint16_t cmd ) { LCD_PORT_OUT= ( cmd & 0xf0 ); LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; // LCD_PORT_OUT= ( ( cmd << 4 ) & 0xf0 ); LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; __no_operation(); //LCD_PORT_OUT= 0; __delay_cycles( 3000 ); } //------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; //P1OUT = 0x00; // Initialize all GPIO P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = 0xFF & ~UART_RXD; // Set all pins but RXD to output //P2OUT = 0x00; //P2SEL = 0x00; //P2DIR = 0xFF; //lcd //LCD_PORT_OUT= 0; LCD_PORT_DIR|= LCD_DATA_MASK | LCD_CMD_MASK; //don't assume VCC+ > 20ms away __delay_cycles(1000000); //first init LCD_PORT_OUT= 0x30; LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; //pause should be set by mclk div, > 4.1ms __delay_cycles( 15000 ); //second init LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; //pause should be set by mclk div, > 100us __delay_cycles( 500 ); //four bit mode LCD_PORT_OUT= 0x20; LCD_PORT_OUT|= LCD_ENABLE_BIT; __no_operation(); LCD_PORT_OUT&= ~LCD_ENABLE_BIT; __delay_cycles( 1000 ); //from here 'lcd_command can be used //operational mode 5x8 1/16 duty( two lines ) lcd_command( 0x28 ); __delay_cycles( 1000 ); //display off lcd_command( 0x08 ); __delay_cycles( 1000 ); //display on, no cursor, no blink... lcd_command( 0x0c ); __delay_cycles( 1000 ); //LCD_PORT_OUT= 0; putchar ('H'); putchar ('e'); putchar ('l'); putchar ('l'); putchar ('o'); __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("G2xx1 TimerA UART\r\n"); TimerA_UART_print("READY.\r\n"); //for (;;)TimerA_UART_print("12345678901234567890123456789012345678901234567890123456789012345678901234567890"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); if(rxBuffer!=MAGIC){ if(CommandFlag!=1){putchar(rxBuffer);} else{CommandFlag=0;lcd_command(rxBuffer);} } else{ CommandFlag=1;} // Update board outputs according to received byte // if (rxBuffer & 0x01) P1OUT |= 0x01; else P1OUT &= ~0x01; // P1.0 // if (rxBuffer & 0x02) P1OUT |= 0x08; else P1OUT &= ~0x08; // P1.3 // if (rxBuffer & 0x04) P1OUT |= 0x10; else P1OUT &= ~0x10; // P1.4 // if (rxBuffer & 0x08) P1OUT |= 0x20; else P1OUT &= ~0x20; // P1.5 // if (rxBuffer & 0x10) P1OUT |= 0x40; else P1OUT &= ~0x40; // P1.6 // if (rxBuffer & 0x20) P1OUT |= 0x80; else P1OUT &= ~0x80; // P1.7 // if (rxBuffer & 0x40) P2OUT |= 0x40; else P2OUT &= ~0x40; // P2.6 // if (rxBuffer & 0x80) P2OUT |= 0x80; else P2OUT &= ~0x80; // P2.7 // Echo received character //TimerA_UART_tx(rxBuffer); } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching case TAIV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) { // Capture mode = start bit edge TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) { // Get bit waiting in receive latch rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) { // All bits RXed? rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } //------------------------------------------------------------------------------

    #include #include "LCDS_Plugin.H" #define WIN32_LEAN_AND_MEAN #include "windows.h" #include "stdio.h" //#include "init.h" #define MAGIC 0xF //#define ComPort "\\\\.\\COM13" HANDLE hSerial; int error_handler(char* reason, char* file, int line){ printf("\n%s\nIn %s at line:%d\n",reason,file,line); return -1; } void init(void){} //int init_serial_port(void){ //hSerial = CreateFile(ComPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); // if (hSerial==INVALID_HANDLE_VALUE){ return error_handler("CreateFile INVALID_HANDLE_VALUE",__FILE__,__LINE__);} // //Comm settings // DCB serialInfo = {0}; // if (!GetCommState(hSerial,&serialInfo)){ return error_handler("GetCommState",__FILE__,__LINE__);} // serialInfo.DCBlength=sizeof(serialInfo); // serialInfo.BaudRate=CBR_9600; // //serialInfo.fBinary=TRUE; // serialInfo.Parity=NOPARITY; // //serialInfo.fOutxCtsFlow=FALSE; // //serialInfo.fOutxDsrFlow=FALSE; // //serialInfo.fDtrControl=DTR_CONTROL_DISABLE; // //serialInfo.fDsrSensitivity=FALSE; // //serialInfo.fOutX=FALSE; // //serialInfo.fInX=FALSE; // //serialInfo.fRtsControl=RTS_CONTROL_DISABLE; // //serialInfo.fAbortonerror=TRUE; // serialInfo.ByteSize=8; // serialInfo.StopBits=ONESTOPBIT; // SetCommState(hSerial, &serialInfo); // return 1; //} int sendLCD(char* ch){ DWORD byteSent = 0; while(byteSent != 1) //did we send every thing to the serial port? { //send to the serial port WriteFile(hSerial,ch,1,&byteSent,NULL); printf("."); } //Pause until break Sleep(5); return 1; } // +-----------------+ // ! DISPLAYDLL_Init ! // +-----------------+ //! Initializes the plugin. //! All initialization stuff goes there: opening and configuring IO ports, device detection and probing... //! Sets ok to 1 if initialization is successful, 0 otherwise. //! Returns an error message in case of failure, NULL otherwise. DLL_EXPORT(char *) DISPLAYDLL_Init(LCDS_BYTE size_x,LCDS_BYTE size_y,char *startup_parameters,LCDS_BOOL *ok) { init(); //if (init_serial_port()!=1){*ok=0; error_handler("init_serial_port error",__FILE__,__LINE__);} ; hSerial = CreateFile(startup_parameters, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_WRITE_THROUGH, 0); if (hSerial==INVALID_HANDLE_VALUE) { *ok=0;return NULL; } //Comm settings DCB serialInfo = {0}; if (!GetCommState(hSerial,&serialInfo)){ *ok=0;return NULL;} serialInfo.DCBlength=sizeof(serialInfo); serialInfo.BaudRate=CBR_9600; //serialInfo.fBinary=TRUE; serialInfo.Parity=NOPARITY; //serialInfo.fOutxCtsFlow=FALSE; //serialInfo.fOutxDsrFlow=FALSE; //serialInfo.fDtrControl=DTR_CONTROL_DISABLE; //serialInfo.fDsrSensitivity=FALSE; //serialInfo.fOutX=FALSE; //serialInfo.fInX=FALSE; //serialInfo.fRtsControl=RTS_CONTROL_DISABLE; //serialInfo.fAbortonerror=TRUE; serialInfo.ByteSize=8; serialInfo.StopBits=ONESTOPBIT; SetCommState(hSerial, &serialInfo); //ininLCD(); // char i; char ch; // while(true) // { // sendLCD(&i); // i++; //printf("LOOP"); // } //ch=15; //sendLCD(&ch); //ch=1; //sendLCD(&ch); ch=15; sendLCD(&ch); ch=(unsigned char)1; sendLCD(&ch); //i=0; //while(i<16) //{ // ch=0+i; // sendLCD(&ch); // i++; //} *ok=1; return NULL; } // +-----------------------+ // ! DISPLAYDLL_DriverName ! // +-----------------------+ //! Returns the driver name. //! The driver name is used by the driver selection GUI to identify the driver. //! It's good practice to return a proper name and version for the driver so that //! it can be clearly identified (or else we would have to rely on the plugin name //! which is subject to modifications). DLL_EXPORT(char *) DISPLAYDLL_DriverName(void) { static char plugin_name[]="my_plugin"; return plugin_name; } // +------------------+ // ! DISPLAYDLL_Usage ! // +------------------+ //! Returns plugin usage hints. //! The usage text describes the main plugin parameters and how they are assembled //! in the parameter string (syntax indications). DLL_EXPORT(char *) DISPLAYDLL_Usage(void) { static char plugin_usage[]="my_plugin usage"; return plugin_usage; } // +------------------------------+ // ! DISPLAYDLL_DefaultParameters ! // +------------------------------+ //! Returns the plugin default parameters. //! The default parameters string is used as parameter string after the driver //! has been initialized. DLL_EXPORT(char *) DISPLAYDLL_DefaultParameters(void) { static char plugin_default_parameters[]="default"; return plugin_default_parameters; } // +------------------------+ // ! DISPLAYDLL_SetPosition ! // +------------------------+ //! Moves the display cursor at a given position. DLL_EXPORT(void) DISPLAYDLL_SetPosition(LCDS_BYTE x,LCDS_BYTE y) { char ch; ch=15; sendLCD(&ch); if (y==1){ ch=(unsigned char)127;} else{ch=(unsigned char)191;} ch+=x; sendLCD(&ch); } // +------------------+ // ! DISPLAYDLL_Write ! // +------------------+ //! Writes the given string on the display. //! The string is displayed at the current cursor position (see DISPLAYDLL_SetPosition). //! It is assumed that the cursor position has been set so that the string can fit. DLL_EXPORT(void) DISPLAYDLL_Write(char *str) { unsigned int i=0; while (str[i]!=0){ sendLCD(&str[i]); i++; } } // +--------------------------+ // ! DISPLAYDLL_SetBrightness ! // +--------------------------+ DLL_EXPORT(void) DISPLAYDLL_SetBrightness(LCDS_BYTE brightness) { } // +-----------------------+ // ! DISPLAYDLL_CustomChar ! // +-----------------------+ DLL_EXPORT(void) DISPLAYDLL_CustomChar(LCDS_BYTE chr,LCDS_BYTE *data) { } // +----------------------------+ // ! DISPLAYDLL_CustomCharIndex ! // +----------------------------+ DLL_EXPORT(LCDS_BYTE) DISPLAYDLL_CustomCharIndex(LCDS_BYTE index) { --index; if (0==index) index=8; return index; } // +-----------------+ // ! DISPLAYDLL_Done ! // +-----------------+ DLL_EXPORT(void) DISPLAYDLL_Done(void) { } // +--------------------+ // ! DISPLAYDLL_ReadKey ! // +--------------------+ DLL_EXPORT(LCDS_WORD) DISPLAYDLL_ReadKey(void) { return 0; } // +-------------------------+ // ! DISPLAYDLL_SetBacklight ! // +-------------------------+ DLL_EXPORT(void) DISPLAYDLL_SetBacklight(LCDS_BOOL light_on) { } // +------------------------+ // ! DISPLAYDLL_SetContrast ! // +------------------------+ DLL_EXPORT(void) DISPLAYDLL_SetContrast(LCDS_BYTE contrast) { } // +------------------------+ // ! DISPLAYDLL_PowerResume ! // +------------------------+ DLL_EXPORT(void) DISPLAYDLL_PowerResume(void) { } // +-------------------+ // ! DISPLAYDLL_SetGPO ! // +-------------------+ DLL_EXPORT(void) DISPLAYDLL_SetGPO(LCDS_BYTE gpo,LCDS_BOOL gpo_on) { } // +-------------------+ // ! DISPLAYDLL_SetFan ! // +-------------------+ DLL_EXPORT(void) DISPLAYDLL_SetFan(LCDS_BYTE t1,LCDS_BYTE t2) { }

    #ifndef LCDS_PLUGIN_H #define LCDS_PLUGIN_H #ifndef DLL_EXPORT #define DLL_EXPORT(type) extern "C" __declspec(dllexport) type __stdcall #endif typedef unsigned char LCDS_BYTE; typedef unsigned short LCDS_WORD; typedef unsigned char LCDS_BOOL; #endif
    software.rar

  21. Like
    kenemon reacted to bluehash in LaunchPad HD44780 LCD USB PC interface   
    They Guy who made it provided it as proof of concept with no guarantee. He mentions it.
     
    Did you compile the VS2005 project? Once you build it, it will give you a plugin.dll file. Put that in your LCDSmartie /displays directory. See attachment(rename to .dll).
    In the LCDSmartie Screen tab, browse down to the plugin.dll
     
    This is correct according to the code in LCDS_Plugin.cpp
    plugin.zip
  22. Like
    kenemon reacted to zeke in Standalone Nightmare   
    Yeah, like BH says, it's a zero ohm resistor.
     
    When you're laying out a pcb and you're going to use surface mount parts, you might as well make the design as generic as possible. This will let you use that pcb for a new circuit later on down the road.
     
    Putting in a zero ohm resistor will allow you to disconnect the micro from the circuit and then you can solder in something new.
     
    Compare your circuit to the diagram.
    Do you have the reset line pulled up with a 47Kohm resistor?
    Do you have 3.3 volts connected to pin 1?
    Do you have ground connected to pin 16?
    Do you have your chip inserted with the correct orientation?
    Can you program your chip with the launchpad?
     
    If you are trying to program the target board with the launchpad then make sure that you remove the micro from the launchpad. If not then remove all the 0.100" jumpers from the launchpad's spy-bi-wire connector (J2) and then use the 0.050" connector (J4) and connect to your target.
     
    Simplify your setup and it will work for you.
  23. Like
    kenemon reacted to RobG in Standalone Nightmare   
    Did you enable internal pull up/down resistors on your inputs? Keep in mind that LP has some extra parts connected to pins that may affect your code.
  24. Like
    kenemon reacted to bluehash in Standalone Nightmare   
    It's not OR, it is 0R or zero resistance. Meaning a short - used instead of a jumper.
  25. Like
    kenemon reacted to zeke in Standalone Nightmare   
    This is what I do:
     
    Note: all the I/O's are unassigned in this diagram.
     

×
×
  • Create New...