Skip to content

Instantly share code, notes, and snippets.

@PhirePhly
Created April 26, 2011 23:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save PhirePhly/943392 to your computer and use it in GitHub Desktop.
Save PhirePhly/943392 to your computer and use it in GitHub Desktop.
MSP430 IR Serial Demo
// Simple IR Receiver
// Kenneth Finnegan, 2011
// kennethfinnegan.blogspot.com
//
// Pinout:
// P1.[0..7] - Common anode 7 segment display w/ decimal
// P2.5 - 38kHz IR receiver
#include <msp430g2252.h>
#define EN_DECIMAL_PT 0x7F
#define DIS_DECIMAL_PT 0xFF
#define BEAT_FREQ 512
#define BUTDEB_LEN (BEAT_FREQ / 4)
#define MAX_STATE 9
#define STATE_LEN 4
#define ERROR_STATE 0x0A
// xmit - flag to start 38kHz IR LED modulation
// xmitstate - state machine for serial protocol
// currstate - currently selected digit [0-9]
// decimalmask - mask to set or clear decimal point
// butdeb - Button debounce counters
volatile unsigned int currstate=ERROR_STATE, rcvrstate = 0, newstate = 0,
decimalmask = DIS_DECIMAL_PT, stateage = 0;
// Seven segment bit fields. Active low. {[0-9] E(rror)}
unsigned const char digits[] = { 0x82, 0xBB, 0xA4, 0xA1, 0x99,
0xC1, 0xC0, 0xAB, 0x80, 0x89, 0xC4 };
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
P1DIR = 0xFF; // Set P1 to output direction
P1OUT = 0xFF; // Set the LEDs off
P2DIR = 0xDF; // Set P2.5 to input for buttons
P2OUT = 0x00;
P2IES = 0x20; // Negative edge trigger
P2IFG = 0x00;
P2IE = 0x20; // Enable button interrupts
TACTL = TASSEL_1 | MC_1; // Set the timer A to ACLK, Up mode
TACCR0 = (0x8000 / BEAT_FREQ) - 1; // Reset timer at BEAT frequency
TACCTL0 = CCIE; // Clear the timer and enable timer interrupt
__enable_interrupt();
_BIS_SR(LPM1_bits + GIE);
}
// Timer A0 interrupt service routine
// Heartbeat interrupt
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{
stateage++;
// If we haven't seen an update in two cycles, something's wrong
if (stateage > 2 * BEAT_FREQ) {
currstate = ERROR_STATE;
}
decimalmask = DIS_DECIMAL_PT;
if (rcvrstate > 1) decimalmask = EN_DECIMAL_PT;
P1OUT = digits[currstate] & decimalmask;
}
// Timer A1 interrupt service routine
// Sampling pulse for IR data
#pragma vector=TIMER0_A1_VECTOR
__interrupt void Timer_A1 (void)
{
P2OUT ^= 0x01; // Debug tick
if (rcvrstate == 1) { // Test for START bit
if (P2IN & 0x20) { // No start bit
rcvrstate = 0;
P2IE |= 0x20;
TACCTL1 = 0;
}
} else if (rcvrstate == STATE_LEN + 2) { // Test for STOP bit
if (P2IN & 0x20) { // No stop bit
rcvrstate = 0;
P2IE |= 0x20;
TACCTL1 = 0;
}
} else if (rcvrstate == STATE_LEN + 3) { // Finish receive
rcvrstate = 0;
P2IE |= 0x20;
TACCTL1 = 0;
currstate = newstate;
stateage = 0;
} else { // State bit
newstate = (newstate << 1) | ((P2IN >> 5) & 0x01);
}
rcvrstate++;
TAIV &= ~(0x02); // CLEAR INTERRUPT
}
#pragma vector=PORT2_VECTOR
__interrupt void Port2 (void) {
// Start bit edge
if (P2IFG & 0x20) {
rcvrstate = 1; // Begin receive
newstate = 0;
// Set Timer0A1 to half a beat later
TACCR1 = (TAR + (0x8000 / 2 / BEAT_FREQ)) % (TACCR0 + 1);
TACCTL1 = CCIE;
// Turn off edge interrupt
P2IE &= ~0x20;
}
P2IFG = 0x00;
}
// Simple IR Transmitter
// Kenneth Finnegan, 2011
// kennethfinnegan.blogspot.com
//
// Pinout:
// P1.[0..7] - Common anode 7 segment display w/ decimal
// P2.0 - Increment state button
// P2.1 - Decrement state button
// P2.5 - IR LED OUTPUT
#include <msp430g2252.h>
#define EN_DECIMAL_PT 0x7F
#define DIS_DECIMAL_PT 0xFF
#define BEAT_FREQ 512
#define BUTDEB_LEN (BEAT_FREQ / 4)
#define MAX_STATE 9
#define STATE_LEN 4
// xmit - flag to start 38kHz IR LED modulation
// xmitstate - state machine for serial protocol
// currstate - currently selected digit [0-9]
// decimalmask - mask to set or clear decimal point
// butdeb - Button debounce counters
volatile int xmit=0, xmitstate=0, currstate=0, savestate=0,
decimalmask = DIS_DECIMAL_PT, butdeb[2] = {0,0};
// Seven segment bit fields. Active low. {[0-9] E(rror)}
unsigned const char digits[] = { 0x82, 0xBB, 0xA4, 0xA1, 0x99,
0xC1, 0xC0, 0xAB, 0x80, 0x89, 0xC4 };
void main(void) {
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL1 = CALBC1_1MHZ;
DCOCTL = CALDCO_1MHZ;
P1DIR = 0xFF; // Set P1 to output direction
P1OUT = 0xFF; // Set the LEDs off
P2DIR = 0xFC; // Set P2.0/1 to input for buttons
P2OUT = 0x20; // Set IR LED off
P2REN = 0x03; // Enable pulldown resistors
P2IES = 0x03; // Positive edge trigger
P2IFG = 0x00; // Clear pin change interrupt flags
P2IE = 0x03; // Enable button interrupts
TACTL = TASSEL_1 | MC_1; // Set the timer A to ACLK, Up mode
TACCR0 = (0x8000 / BEAT_FREQ) - 1; // Reset timer at BEAT frequency
TACCTL0 = CCIE; // Clear the timer and enable timer interrupt
__enable_interrupt();
while(1) {
while(xmit) {
// Delay some cycles to keep frequency at 38kHz
// This is much less than expected due to the
// lost time to the while loop's condition test
// and the bitwise math on P2OUT
// This value was found with an oscilloscope.
__delay_cycles(2);
P2OUT ^= BIT5;
}
// Turn off IR LED
P2OUT &= ~BIT5;
}
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0 (void)
{
xmitstate = (xmitstate + 1) % BEAT_FREQ;
// Set transmit flag for START BIT3 BIT2 BIT1 BIT0 STOP
if (xmitstate == 0 || xmitstate == (STATE_LEN + 1)) { // START & STOP bits
xmit = 1;
decimalmask = EN_DECIMAL_PT;
savestate = currstate; // Prevent state from changing during xmit
} else if (xmitstate < (STATE_LEN + 1)) { // 4 bits of state MSBF
xmit = !((savestate >> (STATE_LEN - xmitstate)) & 0x1);
} else {
xmit = 0;
decimalmask = DIS_DECIMAL_PT;
}
// Update display
P1OUT = digits[currstate] & decimalmask;
// Decrement debounce counters, but only to zero
butdeb[0]?butdeb[0]--:1;
butdeb[1]?butdeb[1]--:1;
}
#pragma vector=PORT2_VECTOR
__interrupt void Port2 (void) {
// Increment state
if ((P2IFG & 0x02) && !butdeb[1]) {
butdeb[1] = BUTDEB_LEN;
currstate = (currstate+1) % (MAX_STATE + 1);
}
// Decrement state
if ((P2IFG & 0x01) && !butdeb[0]) {
butdeb[0] = BUTDEB_LEN;
currstate = currstate ? (currstate - 1) : MAX_STATE;
}
P2IFG = 0x00;
}
Copy link

ghost commented Jan 30, 2013

hi,
i have a problem in your code:
TAIV &= ~(0x02); - Error[Pe137]: expression must be a modifiable lvalue.
can you help me?
i'm using IAR.
Thank you.

@SReddy2115
Copy link

Can i get circuit diagram for this
because i am not getting output

@umuteskin13
Copy link

Can i get circuit diagram for this because i am not getting output

can u get diagram???

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment