Files
OldPeopleHome/zigbee/ZStack-CC2530-r200/Components/hal/target/CC2530EB/IR.c
LitterDryFish 0657e3a6a9 组网
2019-08-23 09:32:51 +08:00

223 lines
7.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/***********************************************************
** 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)