CC2541实现红外发送的方法
时间:10-02
整理:3721RD
点击:
CC2541实现红外发送的方法
用CC2541来实现红外发送,由于CC2541在任务中不能延时太久,所以用延时来实现红外信号不可行,要用硬件来实现。
红外发送一般基于载波38k,基带信号一般是根据无载波的时间来判断0和1,无论基带信号用什么编码,只要硬件部分能发载波和停止载波就可以。
硬件实现红外信号是基于定时器1和定时器3。定时器3产生38k载波,定时器1的时钟源接定时器3,然后共同输出调制波,当定时器每次比较中断时付值下一位的信号。
[cpp] view plain copy
#include "IR.h"
#include "hal_mcu.h"
void IR_init()
{
P1DIR|= BV(1);
P1SEL|= BV(1);
PERCFG |= 0x40;
IRCTL |= BV(0); //开启T1红外模式
T3CTL |= BV(1)| BV(6); //周期模式 重复0 -》T1CC0
T3CCTL0 |= BV(2); //channel 0 比较模式
T3CCTL1 |= BV(2)|BV(5); //changel 1 比较模式 比较置0
T3CC0 = 210; //38K
T3CC1 = 105;
//T3CTL |= BV(4);
T1CTL = 0x00;
T1CCTL0 |= 0x04;
T1CCTL1 = 0x34;//0x34;
T1CNTL = 0; // Reset timer to 0;
T1CC0L = 0x02;
T1CC0H = 0x02;
T1CC1L = 0x57;
T1CC1H = 0x01;
//T1CTL |= 0x02;
T1IE =1;
//EA=1;
}
uint8 irdat[33];
uint8 ir_i = 0;
void send_dat(void)
{
uint8 dat[4];
dat[0] = 0x00;
dat[1] = 0xff;
dat[2] = 0x09;
dat[3] = 0xf6;
send_irdat(dat);
}
void tran_irdat(uint8 *dat)
{
uint8 i,j,k;
for(i = 0; i < 4; i++)
{
k = dat;
for(j = 0; j < 8; j++)
{
if(k&0x01)
{
irdat[i*8+j] = 84;
}
else
{
irdat[i*8+j] = 46;
}
k = k >> 1;
}
}
irdat[32] = 84;
ir_i = 0;
// halIntState_t intState;
// HAL_ENTER_CRITICAL_SECTION( intState );
HAL_DISABLE_INTERRUPTS();
IR_init();
T1CNTH = 0;
T1CNTL = 0;
T3CNT = 0;
T1CC0L = 0x02;
T1CC0H = 0x02;
T1CC1L = 0x57;
T1CC1H = 0x01;
// T1IE =1;
// EA=1;
T1CTL |= 0x02;
T3CTL |= BV(4);
HAL_ENABLE_INTERRUPTS();
//HAL_EXIT_CRITICAL_SECTION( intState );
}
//定时器 T1 中断处理函数
#pragma vector = T1_VECTOR
__interrupt void Timer1_ISR(void)
{
//IRCON = 0x00;
HAL_DISABLE_INTERRUPTS();
if(ir_i == 33)
{
T1CTL = 0x00;
T3CTL &= ~BV(4);
HAL_ENABLE_INTERRUPTS();
return;
}
// if(T1STAT&0x01)
{
T1CC0L = irdat[ir_i];
T1CC0H = 0;
T1CC1L = 23;
T1CC1H = 0;
ir_i++;
}
T1STAT = 0;
HAL_ENABLE_INTERRUPTS();
}
uint8 IS_IR_OK(void)
{
if(ir_i == 33)
{
return 1;
}
else
return 0;
}
值得注意的是当开启POWER_SAVING时,当前没有任务时,晶振会给停止从而使时定器停止工作,发送不了信号。所以当发红外信号时,其中一个方法是不断的set_event从而使CC2541不休眠。