/*******************************************************************************
* 标 题: PIC-ST2学习板演示程序--红外
* 文 件 名: IR
* 建立日期: 2010.5.10
* 修改日期: 2010.5.10
* 版 本: V1.0
* 作 者: simomli
********************************************************************************
* 接法描述:短接1、2
* 功能描述: 接收遥控器红外,并显示红外键码
********************************************************************************
*【版权】Copyright(C) 2010-2020 All Rights Reserved
*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!
*******************************************************************************/
//#include <pic1687x.h>
#include <htc.h>
#include <math.h>
#include <PIC.h>
#define uint8 unsigned char
#define uint16 unsigned int
__CONFIG(WDTDIS & LVPDIS & HS & PWRTDIS & BORDIS);//设置配置位
//WDTDIS:disable watchdog timer
//LVPDIS:low voltage programming disabled
//HS:high speed crystal/resonator
//PWRTDIS:disable power up timer
//BORDIS:disable brown out reset
/***************************定义全局变量***************************************/
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
const uint8 disp[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};//共阳数码管段码表
volatile uint8 IR_code[4];
volatile bit error_flag = 0;
/***************************函数声明*******************************************/
void CCP1_Init(void); //捕获初始化
void Delay140us(uint8 delay); //延时0.14ms
void DelayUS(uint8 delay); //延时微妙
void Display(uint8 chosebit,uint8 data);//显示
/******************************************************************************
* 函 数 名: Delay140us(uint8 delay)
* 函数功能: 延时0.14ms
* 入口参数: delay
* 返 回: 无
*******************************************************************************/
void Delay140us(uint8 delay)
{
uint8 k;
for(;delay>0;delay--)
for(k=0;k<115;k++);
}
/******************************************************************************
* 函 数 名: DelayUS(uint8 delay)
* 函数功能: 微妙延时
* 入口参数: delay 微秒数
* 返 回: 无
*******************************************************************************/
void DelayUS(uint8 delay)
{
while(--delay);
}
/******************************************************************************
* 函 数 名: CCP1_Init(void
* 函数功能: 捕获初始化
* 入口参数: delay 微秒数
* 返 回: 无
*******************************************************************************/
void CCP1_Init(void)
{
CCP1CON = 0x04; //每个下降沿捕获
T1CON = 0x08;
TRISC2 = 1;
CCP1IF = 0; //清中断标志位
PEIE = 1;
CCP1IE = 1; //使能CCP1中断
}
/******************************************************************************
* 函 数 名: Display(uint8 chosebit,uint8 data)
* 函数功能: 单个数码管显示
* 入口参数: chosebit选择字位,data字型
* 返 回: 无
*******************************************************************************/
void Display(uint8 chosebit,uint8 data)
{
ADCON1 = 0x8E; //设置PORTA0为模拟输入,其他为IO口
TRISA &= 0xC1;
TRISD = 0x00; //数据线配置为输出
PORTA = 0xFF;
PORTA &= ~(0x02 << chosebit);
PORTD = data; //送字型
DelayUS(20); //延时
PORTD = 0xFF; //关显示
}
/******************************************************************************
* 函 数 名: mian()
* 函数功能: 接收红外,解码并显示键码,解码不成功的,显示8.8.
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void main()
{
CCP1_Init(); //捕获功能初始化
TMR1ON = 1; //开定时器1
GIE = 1; //开总中断
while(1)
{
if(error_flag == 0) //解码成功
{
Display(0,disp[IR_code[2]/16]);
Display(1,disp[IR_code[2]%16]);
}
else //解码有错
{
Display(0,0x00);
Display(1,0x00);
}
}
}
/******************************************************************************
* 函 数 名: interrupt Capture(void)
* 函数功能: 中断函数
* 入口参数: 无
* 返 回: 无
*******************************************************************************/
void interrupt Capture(void)
{
uint8 i,j,N = 0;
if(CCP1IF == 1) //发生捕获
{
CCP1IF = 0; //清中断标志位
CCP1IE = 0;
TMR1ON = 0;
Delay140us(15); //延时15*0.14ms 消除抖动
if(RC2 == 1)
{
CCP1IE = 1;
TMR1ON = 1;
CCP1IF = 0;
N =0;
return;
// asm("retfie");
}
while(RC2 == 0) //确认IR信号出现
{
Delay140us(1); //9ms引导时间
}
while(RC2 == 1) //4.5ms结果吗
{
Delay140us(1);
}
for(i=0;i<4;i++) //四组解码数据
{
for(j=0;j<8;j++)
{
while(RC2 == 0); //等待高电平
{
Delay140us(1);
}
while(RC2 == 1) //计算高电平时间
{
Delay140us(1);
N++;
if(N>=30) //超时,则解码不成功,推出
{
CCP1IE = 1; //使能CCP1中断
TMR1ON = 1;
CCP1IF = 0;
N =0;
return;
// asm("retfie");
}
}
IR_code[i] = IR_code[i]>>1;
if(N >= 8)
{
IR_code[i] |= 0x80;
}
N =0;
}
}
//数据码与反码不正确
if(((IR_code[2]^0xFF) != IR_code[3]))
{
CCP1IE = 1; //使能CCP1中断
TMR1ON = 1;
CCP1IF = 0;
error_flag = 1;
N =0;
return;
}
else
{
error_flag = 0;
}
while(RC2 == 0);
CCP1IE = 1;
TMR1ON = 1;
CCP1IF = 0;
}
}