Tool/software: Code Composer Studio
I’ve designed six Allegro A3214LUA-T magnetic proximity switches into a custom single board computer. Currently have two identical PCBs running. I’m using these switches to generate interrupts to a TI MSP430F5638 MCU’s port 3.
Switch 1 through 4 are working fine on both PCB’s; switch 5 and 6 are not. Their Vout pins seem to be tied low to ground. I’ve tried resoldering pin3 on both S5 and S6, measured resistance on the circuit pull-up resistor and they are good, 49.9k. Was not using any internal pull-up resistors on P3 because they are hardwired in the circuit, so tried enabling them for just bits 4 and 5 for the two non-working switches – no effect.
Also put a scope probe on Vout for either S5 or S6, powered PCB down and back up and I see a quick blip to high, then immediately goes low to ground. Switch schematic and interrupt vector table shown below, Vouts go directly to P3.0 to P3.5. Don't understand why these two switches are doing this.
Code and ISR below
#include <msp430.h> // Switch-01 // develop ISR for 6 magnetic switches on P3 // see P3 pin table in doc file & schematic // don't unplug the MSP-FET, may be contributing to the LCD hang ups Use P3IV to determine which button was pushed Clear P3IFG in total, can't specify .0 to .7 P3 generates maskable interrupts, needs individual bit enable + GIE */ #include <DC2-msp430f5638-01.h> #include <LCD-Addresses-00.h> #include <LCD-NHD-4.3-480272EF-ASXN-03.h> void setup_430_ports(void); // declare global P3 ISR flags, replaces bitfields unsigned char s1_flag = 0; unsigned char s2_flag = 0; unsigned char s3_flag = 0; unsigned char s4_flag = 0; unsigned char s5_flag = 0; unsigned char s6_flag = 0; // declare global P3 ISR counters unsigned char s1_count = 0; unsigned char s2_count = 0; unsigned char s3_count = 0; unsigned char s4_count = 0; unsigned char s5_count = 0; unsigned char s6_count = 0; // access global color settings extern unsigned int white[3]; extern unsigned int violet[3]; extern unsigned int magenta[3]; extern unsigned int blue[3]; extern unsigned int green[3]; extern unsigned int yellow[3]; extern unsigned int orange[3]; extern unsigned int red[3]; extern unsigned int black[3]; /** * main.c */ int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer // not used here, want to see all P3 settings below //setup_430_ports(); // msb 7654 3210 lsb // 0000 0011 = 0x03 // 1111 1100 = 0xFC // setup P3, move into port function above when done P3DIR = 0b00000011; // 6 inputs, 2 outputs for TA2.1 and TA2.2 P3SEL = 0b00000011; // 6 normal IO, 2 special function for TA2 P3REN = 0x00; // not using internal pull-up/down resistors, hard wired on PCB // try using internal pull-ups on bits P3.4 & 5 for the two switches not working // did not fix the problem //P3REN = 0b00110000; // pull up/down resistors, not needed pull-up in circuit already //P3OUT = 0b00110000; // for input, 1 = pull-up resistor P3IES = 0b11111100; // set interrupt edge select for each pin: 1 is high to low transition - check A3214 DS P3IE = 0b11111100; // set IE for 6 switch pins // enable General Interrupt Enable (GIE) in status register SR // must use intrinsic function, can't access directly from C, can also set LPM here too // use this form in ISR's //_BIS_SR(LPM4_bits + GIE); //_BIS_SR(GIE); // or // use this form in regular code _enable_interrupts(); // this only applies to GIE // _disable_interrupts(); // disable GIE // put something on the LCD LCD_init_3(); LCD_black(); // endless loop while(1) { LCD_button_test_screen(); // puts 6 switch labels, ISR flags, and counts on the LCD P3IFG = 0b00000011; // clear interrupt flags for all 6 switch pins } } // define ISR for all 6 P3 switches // 1 ISR per IO port, must decode for each individual pin interrupt vector #pragma vector = PORT3_VECTOR __interrupt void PBswitchesISR(void) { // clear all switch ISR flags // normally these would get cleared individually in each main module started from its ISR vector // also clear specific P3IFG bit there too s1_flag = s2_flag = s3_flag = s4_flag = s5_flag = s6_flag = 0; // which button was pushed? // need 1 test per switch / pin // if(P3IV == 2) // DC2switch.s1 = 1; // which button was pushed? // need 1 case per switch / pin // s1_flag to s6_flag are global interrupt flags, set in ISR, process in main code // LED on/off want to be instantaneous, process in ISR // both of these switch operands work, second should allow faster executing code, even only, up to 16 max only //switch(P3IV) switch(_even_in_range(P3IV, 16)) { // PB switch 6 case 2: { // set global switch flag, processed in main code // gets cleared in main code after task complete s6_flag = 1; // update s6_count to determine #of counts per switch off/on/off cycle, from tests = 1 s6_count++; // toggle button color on LCD LCD_put_string_4_cc(BUTROW, BUT6COL, "BUT6", white, black); // clear P3IFG for this switch only, rest unchanged P3IFG &= (~BIT0); break; } // PB switch 5 case 4: { s5_flag = 1; s5_count++; LCD_put_string_4_cc(BUTROW, BUT5COL, "BUT5", white, black); P3IFG &= (~BIT1); break; } // PB switch 4 case 6: { s4_flag = 1; s4_count++; LCD_put_string_4_cc(BUTROW, BUT4COL, "BUT4", white, black); P3IFG &= (~BIT2); break; } // PB switch 3 case 8: { s3_flag = 1; s3_count++; LCD_put_string_4_cc(BUTROW, BUT3COL, "BUT3", white, black); P3IFG &= (~BIT3); break; } // PB switch 2 case 10: { s2_flag = 1; s2_count++; LCD_put_string_4_cc(BUTROW, BUT2COL, "BUT2", white, black); P3IFG &= (~BIT4); break; } // PB switch 1 case 12: { s1_flag = 1; s1_count++; LCD_put_string_4_cc(BUTROW, BUT1COL, "BUT1", white, black); P3IFG &= (~BIT5); break; } } }