NEC 红外通信协议是一种广泛应用于遥控器设备的红外通信协议。它采用脉冲宽度调制(PWM)来编码数据,并使用38kHz的载波频率进行传输。协议的特点如下:
起始信号:9ms高电平+4.5ms低电平
引导码:560µs高电平+560µs低电平
逻辑0:560µs高电平+560µs低电平
逻辑1:560µs高电平+1.69ms低电平
结束码:560µs高电平(可选,通常为1ms)
每个数据包包含以下部分:
8位地址
8位地址反码
8位命令
8位命令反码
红外发射部分:连接红外发射二极管到单片机的GPIO引脚(比如P1.0)。
红外接收部分:连接红外接收模块到单片机的另一个GPIO引脚(比如P1.1)。
以下是MSP430G2553单片机进行NEC红外通信的收发实验的示例代码:
c展开代码#include <msp430.h>
#define IR_LED P1OUT_bit.P0
void delay_us(unsigned int us) {
    while (us--) {
        __delay_cycles(1); // 1us delay at 1MHz
    }
}
void send_nec_high(unsigned int time) {
    for (unsigned int i = 0; i < time; i++) {
        IR_LED = 1;
        delay_us(13); // High for 13us
        IR_LED = 0;
        delay_us(13); // Low for 13us
    }
}
void send_nec_low(unsigned int time) {
    for (unsigned int i = 0; i < time; i++) {
        IR_LED = 0;
        delay_us(26); // Low for 26us
    }
}
void send_nec_start() {
    send_nec_high(9000 / 26);
    send_nec_low(4500 / 26);
}
void send_nec_data(unsigned char data) {
    for (int i = 0; i < 8; i++) {
        if (data & 0x01) {
            send_nec_high(560 / 26);
            send_nec_low(1690 / 26);
        } else {
            send_nec_high(560 / 26);
            send_nec_low(560 / 26);
        }
        data >>= 1;
    }
}
void send_nec(unsigned char address, unsigned char command) {
    send_nec_start();
    send_nec_data(address);
    send_nec_data(~address);
    send_nec_data(command);
    send_nec_data(~command);
    send_nec_high(560 / 26);
}
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
    P1DIR |= BIT0;              // Set P1.0 as output for IR LED
    while (1) {
        send_nec(0x00, 0xFF);   // Send example NEC command
        __delay_cycles(1000000); // 1s delay
    }
}
c展开代码#include <msp430.h>
#define IR_RECEIVER P1IN_bit.P1
volatile unsigned char nec_data[4];
volatile unsigned char bit_count = 0;
volatile unsigned char byte_count = 0;
void init_timer() {
    TA0CCTL0 = CCIE; // CCR0 interrupt enabled
    TA0CCR0 = 26;    // 26us
    TA0CTL = TASSEL_2 + MC_1; // SMCLK, upmode
}
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer_A (void) {
    static unsigned int high_time = 0;
    static unsigned int low_time = 0;
    if (IR_RECEIVER) {
        high_time++;
        low_time = 0;
    } else {
        low_time++;
        high_time = 0;
    }
    if (low_time > 400) { // End of transmission
        byte_count = 0;
        bit_count = 0;
    } else if (high_time > 500) { // Start bit
        byte_count = 0;
        bit_count = 0;
    } else if (low_time > 200) { // Data bit
        if (high_time > 100) {
            nec_data[byte_count] |= (1 << bit_count);
        } else {
            nec_data[byte_count] &= ~(1 << bit_count);
        }
        bit_count++;
        if (bit_count == 8) {
            bit_count = 0;
            byte_count++;
        }
    }
}
int main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
    P1DIR &= ~BIT1;           // Set P1.1 as input for IR receiver
    P1REN |= BIT1;            // Enable pull-up resistor on P1.1
    P1OUT |= BIT1;            // Pull-up
    init_timer();
    __bis_SR_register(GIE); // Enable global interrupts
    while (1) {
        __no_operation(); // Placeholder for main loop
    }
}
红外发射部分:使用PWM方式生成38kHz的载波信号,按照NEC协议发送起始信号、数据位和结束信号。
红外接收部分:通过定时器中断来检测红外接收信号的高低电平持续时间,从而解码NEC协议的数据。
以上代码展示了如何在MSP430G2553单片机上实现NEC红外通信的收发功能。



本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!