用MSP430(F149)做紅外接收比發送更為簡單,我采用的紅外傳感器是HS0038B,這個原件在接收到38K紅外時輸出低電平,否則輸出高電平,因此,我們就可以從這點開始編寫程序了,由於HS0038B的電路圖很多,我這裡就不貼出來了,下面是具體的代碼:
[cpp]
#include <msp430x14x.h>
#include "delay.h"
static unsigned short addr = 0x00;
static unsigned char ir_rx_buf[256];
static unsigned char ir_rx_w_offset = 0;
static unsigned char ir_rx_r_offset = 0;
void ir_tx_open(){
P2DIR |= BIT2 | BIT3;//P2.2, P2.3輸出
P2SEL |= BIT3; //P2.2:IO P2.3:TA0
P2SEL &= ~BIT2; //
P2OUT &= ~(BIT2 | BIT3);
//38K->P2.3
CCR0 = (int)(26.3*8 + 0.5);
CCTL1 = OUTMOD_6;
CCR1 = (int)(13.15*8 + 0.5);
TACTL = TASSEL_2 + MC_1;
}
void ir_set_addr(unsigned char addr){
addr = (unsigned char)(0xff&addr);
}
static void ir_start(){
P2OUT |= BIT2;
delay_us(9000);
P2OUT &= ~BIT2;
delay_us(4500);
}
static void ir_next(){
P2OUT |= BIT2;
delay_us(9000);
P2OUT &= ~BIT2;
delay_us(2250);
}
static void ir_send_byte(unsigned char c){
unsigned char i;
for(i = 0; i != 8; ++i){
P2OUT |= BIT2;
delay_us(560);
P2OUT &= ~BIT2;
if(c&0x01){
delay_us(1685);
}
else{
delay_us(565);
}
c >>= 1;
}
}
static void ir_end(){
P2OUT |= BIT2;
delay_us(300);
P2OUT &= ~BIT2;
}
void ir_put_char(unsigned char c){
ir_start();
ir_send_byte(addr);
ir_send_byte(~addr);
ir_send_byte(c);
ir_send_byte(~c);
ir_end();
}
void ir_put_string(char* str){
if(*str != '\0')
ir_start();
else
return;
while(1){
ir_send_byte(addr);
ir_send_byte(~addr);
ir_send_byte(*str);
ir_send_byte(~(*str));
++str;
if(*str != '\0'){
ir_next();
}
else{
ir_end();
}
}
}
void ir_put_array(unsigned char* array, unsigned int length){
unsigned int i;
ir_start();
for(i = 0; i != length; ++i){
ir_send_byte(addr);
ir_send_byte(~addr);
ir_send_byte(array[i]);
ir_send_byte(array[i]);
if(i < length-1){
ir_next();
}
else{
ir_end();
}
}
}
void ir_tx_close(){
P2SEL &- ~BIT3;
P2DIR |= BIT3;
P2OUT &= ~BIT3;
TACTL = TACLR;
}
void ir_rx_open(){
P2SEL &= ~BIT0; //I/O
P2DIR &= ~BIT0; //Input
P2IES |= BIT0; //High->Low
P2IE |= BIT0; //Enable interrupt
}
void ir_rx_close(){
P2IE &= ~BIT0; //Disable interrupt
}
unsigned char ir_get(){
while(ir_rx_r_offset == ir_rx_w_offset);
return ir_rx_buf[ir_rx_r_offset++];
}
#pragma vector=PORT2_VECTOR
__interrupt void port2_handler(){
static unsigned char ir_code[4];
unsigned char i, j;
unsigned short time;
if(P2IFG&BIT0){
P2IE &= ~BIT0;
P2IFG &= ~BIT0;
_EINT();
time_start(9500);
while(!time_out() && !(P2IN&BIT0));
time = time_end();
if(!time_out() && time > 8500){
time_start(5000);
while(!time_out() && (P2IN&BIT0));
time = time_end();
if(!time_out() && time > 4000){
for(i = 0; i != 4; ++i){
for(j = 0; j != 8; ++j){
while(!(P2IN&BIT0));//等待高電平
time_start(2000); //計時高電平
while(!time_out() && (P2IN&BIT0));
time = time_end();
ir_code[i] >>= 1;
if(!time_out() && time > 1500){
//uart_put(0x03);
ir_code[i] |= 0x80;
}
else{
//uart_put(0x04);
ir_code[i] &= 0x7f;
}
}
}
if(ir_code[0] == addr && (0xff == ir_code[0] + ir_code[1])){
if(0xff == ir_code[2] + ir_code[3]){
ir_rx_buf[ir_rx_w_offset++] = ir_code[2];
}
}
}
}
P2IE |= BIT0;;
}
}
#include <msp430x14x.h>
#include "delay.h"
static unsigned short addr = 0x00;
static unsigned char ir_rx_buf[256];
static unsigned char ir_rx_w_offset = 0;
static unsigned char ir_rx_r_offset = 0;
void ir_tx_open(){
P2DIR |= BIT2 | BIT3;//P2.2, P2.3輸出
P2SEL |= BIT3; //P2.2:IO P2.3:TA0
P2SEL &= ~BIT2; //
P2OUT &= ~(BIT2 | BIT3);
//38K->P2.3
CCR0 = (int)(26.3*8 + 0.5);
CCTL1 = OUTMOD_6;
CCR1 = (int)(13.15*8 + 0.5);
TACTL = TASSEL_2 + MC_1;
}
void ir_set_addr(unsigned char addr){
addr = (unsigned char)(0xff&addr);
}
static void ir_start(){
P2OUT |= BIT2;
delay_us(9000);
P2OUT &= ~BIT2;
delay_us(4500);
}
static void ir_next(){
P2OUT |= BIT2;
delay_us(9000);
P2OUT &= ~BIT2;
delay_us(2250);
}
static void ir_send_byte(unsigned char c){
unsigned char i;
for(i = 0; i != 8; ++i){
P2OUT |= BIT2;
delay_us(560);
P2OUT &= ~BIT2;
if(c&0x01){
delay_us(1685);
}
else{
delay_us(565);
}
c >>= 1;
}
}
static void ir_end(){
P2OUT |= BIT2;
delay_us(300);
P2OUT &= ~BIT2;
}
void ir_put_char(unsigned char c){
ir_start();
ir_send_byte(addr);
ir_send_byte(~addr);
ir_send_byte(c);
ir_send_byte(~c);
ir_end();
}
void ir_put_string(char* str){
if(*str != '\0')
ir_start();
else
return;
while(1){
ir_send_byte(addr);
ir_send_byte(~addr);
ir_send_byte(*str);
ir_send_byte(~(*str));
++str;
if(*str != '\0'){
ir_next();
}
else{
ir_end();
}
}
}
void ir_put_array(unsigned char* array, unsigned int length){
unsigned int i;
ir_start();
for(i = 0; i != length; ++i){
ir_send_byte(addr);
ir_send_byte(~addr);
ir_send_byte(array[i]);
ir_send_byte(array[i]);
if(i < length-1){
ir_next();
}
else{
ir_end();
}
}
}
void ir_tx_close(){
P2SEL &- ~BIT3;
P2DIR |= BIT3;
P2OUT &= ~BIT3;
TACTL = TACLR;
}
void ir_rx_open(){
P2SEL &= ~BIT0; //I/O
P2DIR &= ~BIT0; //Input
P2IES |= BIT0; //High->Low
P2IE |= BIT0; //Enable interrupt
}
void ir_rx_close(){
P2IE &= ~BIT0; //Disable interrupt
}
unsigned char ir_get(){
while(ir_rx_r_offset == ir_rx_w_offset);
return ir_rx_buf[ir_rx_r_offset++];
}
#pragma vector=PORT2_VECTOR
__interrupt void port2_handler(){
static unsigned char ir_code[4];
unsigned char i, j;
unsigned short time;
if(P2IFG&BIT0){
P2IE &= ~BIT0;
P2IFG &= ~BIT0;
_EINT();
time_start(9500);
while(!time_out() && !(P2IN&BIT0));
time = time_end();
if(!time_out() && time > 8500){
time_start(5000);
while(!time_out() && (P2IN&BIT0));
time = time_end();
if(!time_out() && time > 4000){
for(i = 0; i != 4; ++i){
for(j = 0; j != 8; ++j){
while(!(P2IN&BIT0));//等待高電平
time_start(2000); //計時高電平
while(!time_out() && (P2IN&BIT0));
time = time_end();
ir_code[i] >>= 1;
if(!time_out() && time > 1500){
//uart_put(0x03);
ir_code[i] |= 0x80;
}
else{
//uart_put(0x04);
ir_code[i] &= 0x7f;
}
}
}
if(ir_code[0] == addr && (0xff == ir_code[0] + ir_code[1])){
if(0xff == ir_code[2] + ir_code[3]){
ir_rx_buf[ir_rx_w_offset++] = ir_code[2];
}
}
}
}
P2IE |= BIT0;;
}
}包含整理後的紅外發送和接收,放在這裡做個記錄,有什麼疑問歡迎留言討論。