223 lines
7.1 KiB
C
223 lines
7.1 KiB
C
/***********************************************************
|
||
** FileName: IR.c
|
||
** Introductions: Sunplusapp CC2530 ZigBee Node IR Romoter Signal Send Functions
|
||
** Last Modify time: 2013.05.21
|
||
** Modify: 修改红外编码发送,优化时序,添加注释
|
||
** Author: GuoZhenjiang <zhenjiang.guo@sunplusapp.com>
|
||
***********************************************************/
|
||
|
||
#include "IR.h"
|
||
#include "OSAL.h"
|
||
|
||
#if defined(HAL_IRENC) && (HAL_IRENC == TRUE)
|
||
|
||
// 定时器1中自增量,控制每一位编码的周期
|
||
volatile uint16 T1_80usCnt = 0;
|
||
|
||
// Timer1红外编码初始化
|
||
void IRSend_T1_Init(void);
|
||
// Timer3红外编码初始化
|
||
void IRSend_T3_Init(void);
|
||
// Timer1 & Timer3 中断处理函数声明
|
||
__near_func __interrupt void IRSend_T1IntHandle(void);
|
||
__near_func __interrupt void IRSend_T3IntHandle(void);
|
||
|
||
/***********************************************************
|
||
** 函数名称: GenIR
|
||
** 实现功能: 系统时钟设置
|
||
** 入口参数: IRData: 红外编码数据首地址
|
||
** Mode: 引导码分类:1 周期9ms 2:周期13.56ms
|
||
** CodeLen: 编码位数(bit,不是Byte)
|
||
** 返回结果: 0:发送失败 1:发送成功
|
||
***********************************************************/
|
||
int GenIR(uint8 *IRData , uint8 Mode , uint8 CodeLen )
|
||
{
|
||
uint16 GuideCodeLen=0;
|
||
static IRSendSta_t IRSendSta = IRSta_Guide;
|
||
static uint8 cntByte=0, cntbit=0, bitNum;
|
||
bitNum = CodeLen; //保存位数
|
||
|
||
if(Mode == 1)
|
||
GuideCodeLen = 56;//226; 引导码长度(4.5ms、4.5ms)
|
||
else if(Mode == 2)
|
||
GuideCodeLen = 114; //引导码长度(9ms、4.5ms)
|
||
|
||
IRSend_T1_Init();
|
||
IRSend_T3_Init();
|
||
IR_SEL_IOOUT;
|
||
CLR_IOB_BIT;
|
||
IRSendSta = IRSta_Guide;
|
||
T1_80usCnt = 0;
|
||
IR_SEL_T3PWM;
|
||
while(1)
|
||
{
|
||
// 查询红外编码发送状态
|
||
switch(IRSendSta)
|
||
{
|
||
// 引导码阶段
|
||
case IRSta_Guide:
|
||
// 引导码4.5ms或9ms载波阶段
|
||
if(T1_80usCnt <= GuideCodeLen)
|
||
{
|
||
IRSendSta = IRSta_Guide;
|
||
IR_SEL_T3PWM;
|
||
}
|
||
// 引导码4.5ms低电平阶段
|
||
else if((T1_80usCnt > GuideCodeLen) && (T1_80usCnt <= GuideCodeLen+56))
|
||
{
|
||
IRSendSta = IRSta_Guide;
|
||
IR_SEL_IOOUT;
|
||
CLR_IOB_BIT;
|
||
}
|
||
// 引导码发送完毕,准备发送数据位
|
||
else
|
||
{
|
||
IRSendSta = IRSta_T3PWM;
|
||
IR_SEL_T3PWM;
|
||
T1_80usCnt = 0;
|
||
}
|
||
break;
|
||
// 数据位中的位0、位1的0.56ms的38kHz载波阶段
|
||
case IRSta_T3PWM:
|
||
if(T1_80usCnt >= 7) // 7 * 80us = 560us
|
||
{
|
||
IR_SEL_IOOUT;
|
||
CLR_IOB_BIT;
|
||
IRSendSta = IRSta_Data0;
|
||
}
|
||
break;
|
||
// 数据位中的位0、位1的低电平持续阶段
|
||
case IRSta_Data0:
|
||
//发送数据0,低电平持续 0.565ms。
|
||
if(!(IRData[cntByte] & (0x80 >> (cntbit % 8))))
|
||
{
|
||
if(T1_80usCnt >= 14)
|
||
{
|
||
IR_SEL_T3PWM;
|
||
T1_80usCnt = 0;
|
||
cntbit++;
|
||
if(0 == (cntbit % 8))
|
||
cntByte++;
|
||
}
|
||
}
|
||
//发送数据1,低电平持续 1.685ms。
|
||
else if(IRData[cntByte] & (0x80 >> (cntbit % 8)))
|
||
{
|
||
if(T1_80usCnt >= 28)
|
||
{
|
||
IR_SEL_T3PWM;
|
||
T1_80usCnt = 0;
|
||
cntbit++;
|
||
if(0 == (cntbit % 8))
|
||
cntByte++;
|
||
}
|
||
}
|
||
// 发送完毕?
|
||
if(cntbit >= bitNum)
|
||
IRSendSta = IRSta_Stop;
|
||
// 继续发送?
|
||
else
|
||
IRSendSta = IRSta_T3PWM;
|
||
break;
|
||
// 红外编码数据部分发送完毕
|
||
case IRSta_Stop:
|
||
// 一组编码发送完毕 结束位是 0.56ms 的 38K 载波
|
||
while(T1_80usCnt < 7)
|
||
;
|
||
STOP_T1_T3; // stop T1 & T3
|
||
T1_80usCnt = 0;
|
||
IR_SEL_IOOUT;
|
||
CLR_IOB_BIT;
|
||
cntbit = 0;
|
||
cntByte = 0;
|
||
return 1;
|
||
break;
|
||
default:
|
||
return 0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
/***********************************************************
|
||
** 函数名称: IRSend_T1_Init
|
||
** 实现功能: 红外编码发送定时器1初始化
|
||
** 入口参数: None
|
||
** 返回结果: None
|
||
***********************************************************/
|
||
void IRSend_T1_Init(void)
|
||
{
|
||
T1CTL = 0x0E; // f = 32MHz / 128 = 250 000Hz, T = 4us;模模式,从0~T1CC0反复计数。
|
||
T1CCTL0 = 0x44; // Timer1通道0中断允许,比较匹配模式,比较比配时输出置位。
|
||
T1CC0L = 19; // 先写T1CC0L,再写T1CC0H,T1CNT=0时更新。 4us*20 = 80us;
|
||
T1CC0H = 0;
|
||
TIMIF |= BIT_1(6); // TIMIF.T1OVFIM Timer1溢出中断允许
|
||
IEN1 |= BIT_1(1); // IEN1.T1IE Timer1总中断允许
|
||
EA = 1; // 打开全局总中断
|
||
T1_80usCnt = 0; // 80us溢出中断自增量清零
|
||
}
|
||
|
||
/***********************************************************
|
||
** 函数名称: IRSend_T3_Init
|
||
** 实现功能: 红外编码发送定时器3初始化
|
||
** 入口参数: None
|
||
** 返回结果: None
|
||
***********************************************************/
|
||
void IRSend_T3_Init(void)
|
||
{
|
||
P1SEL |= BIT_1(3); // P1.3 us as T3 PWM Out Pin.
|
||
T3CTL = 0x02; // T3CTL.MODE[10] 模模式,从0~T3CC0反复计数
|
||
T3CTL |= BIT_1(5); // T3CTL.MODE[001] f = 32MHz / 2 = 16MHz;
|
||
T3CCTL0 |= BIT_1(2); // T3CCTL0.MODE 输出比较比配模式
|
||
T3CCTL0 |= BIT_1(4); // T3CCTL0.CMP[010] 比较匹配时,输出取反
|
||
|
||
T3CC0 = 208; // Timer3通道0输出比较匹配上限值,16MHz / 208 = 76923.076923Hz; 76923 / 2 =38k(比较匹配时取反).
|
||
T3CTL |= BIT_1(4); // T3CTL.START 启动Timer3
|
||
P2SEL |= BIT_1(5); // P2SEL.PRI2P1 当USART1和Timer3占用相同引脚,Timer3优先。
|
||
T3CCTL0 |= BIT_1(6); // T3CCTL0.IM Timer3通道0中断允许。
|
||
IEN1 |= BIT_1(3); // IEN1.T3IE Timer3总中断允许。
|
||
EA = 1; // 全局总中断允许。
|
||
}
|
||
|
||
/***********************************************************
|
||
** 函数名称: IRSendInit
|
||
** 实现功能: 红外编码发送初始化
|
||
** 入口参数: None
|
||
** 返回结果: None
|
||
***********************************************************/
|
||
void IRSendInit(void)
|
||
{
|
||
IR_SEL_IOOUT;
|
||
CLR_IOB_BIT;
|
||
}
|
||
|
||
/***********************************************************
|
||
** 函数名称: IRSend_T1IntHandle
|
||
** 实现功能: Timer1 红外编码发送中的中断处理函数
|
||
** 入口参数: None
|
||
** 返回结果: None
|
||
***********************************************************/
|
||
#pragma vector = T1_VECTOR
|
||
__interrupt void IRSend_T1IntHandle(void)
|
||
{
|
||
T1STAT &= BIT_0(5); // T1STAT.OVFIF 清除Timer1溢出中断标志
|
||
T1STAT &= BIT_0(1); // T1STAT.CH0IF 清除Timer1通道0中断标志
|
||
IRCON &= BIT_0(1); // IRCON.T1IF 清除Timer1总中断标志
|
||
T1_80usCnt++;
|
||
}
|
||
|
||
/***********************************************************
|
||
** 函数名称: IRSend_T3IntHandle
|
||
** 实现功能: Timer3 红外编码发送中的中断处理函数
|
||
** 入口参数: None
|
||
** 返回结果: None
|
||
***********************************************************/
|
||
#pragma vector = T3_VECTOR
|
||
__near_func __interrupt void IRSend_T3IntHandle(void)
|
||
{
|
||
TIMIF &= BIT_0(1); // TIMIF.T3CH0IF
|
||
}
|
||
|
||
|
||
#endif // defined(HAL_IRENC) && (HAL_IRENC == TRUE)
|