标题: 单片机红外线测距源码 [打印本页]

作者: 梁廷明    时间: 2018-3-8 10:16
标题: 单片机红外线测距源码
#include "config.h"
/***********************
infrared.c文件程序源代码
*************************/
#include <reg51.h>
sbit IR_INPUT = P1^0;  //红外接收引脚

bit irflag = 0;  //红外接收标志,收到一帧正确数据后置1
unsigned char ircode[4];  //红外代码接收缓冲区


void InitInfrared(void)  //红外功能的初始化函数
{
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x10;  //配置T1为模式1
    TR1 = 0;       //停止T1计数
    ET1 = 0;       //禁止T1中断
    IT1 = 1;       //设置INT1为负边沿触发
    EX1 = 1;       //使能INT1中断
}
unsigned int GetHighTime(void)  //获取高电平时间
{
    TH1 = 0;  //清零T1计数初值
    TL1 = 0;
    TR1 = 1;  //启动T1计数
    while (IR_INPUT)  //红外输入引脚为1时循环检测等待,变为0时则结束本循环
    {
        if (TH1 >= 0x40)
        {           //当T1计数值大于0x4000,即高电平持续时间超过约18ms时,
            break;  //强制退出循环,是为了避免信号异常时,程序假死在这里。
        }
    }
    TR1 = 0;  //停止T1计数

    return (TH1*256 + TL1);  //返回T1的计数值
}


unsigned int GetLowTime(void)  //获取低电平时间
{
    TH1 = 0;  //清零T1计数初值
    TL1 = 0;
    TR1 = 1;  //启动T1计数
    while (!IR_INPUT)  //红外输入引脚为0时循环检测等待,变为1时则结束本循环
    {
        if (TH1 >= 0x40)
        {           //当T1计数值大于0x4000,即低电平持续时间超过约18ms时,
            break;  //强制退出循环,是为了避免信号异常时,程序假死在这里。
        }
    }
    TR1 = 0;  //停止T1计数
    return (TH1*256 + TL1);  //返回T1的计数值
}

void EXINT1_ISR() interrupt 2  //INT1中断服务函数,执行红外接收及解码
{
    unsigned char i, j;
    unsigned char byt;
    unsigned int time;
    //接收并判定引导码的9ms低电平
    time = GetLowTime();
    if ((time<7833) || (time>8755))  //时间判定范围为8.5~9.5ms,
    {                                //超过此范围则说明为误码,直接退出
        IE1 = 0;   //退出前清零INT1中断标志
        return;
    }
    //接收并判定引导码的4.5ms高电平
    time = GetHighTime();
    if ((time<3686) || (time>4608))  //时间判定范围为4.0~5.0ms,
    {                                //超过此范围则说明为误码,直接退出
        IE1 = 0;
        return;
    }
    //接收并判定后续的4字节数据
    for (i=0; i<4; i++)  //循环接收4个字节
    {
        for (j=0; j<8; j++)  //循环接收判定每字节的8个bit
        {
            //接收判定每bit的560us低电平
            time = GetLowTime();
            if ((time<313) || (time>718))  //时间判定范围为340~780us,
            {                              //超过此范围则说明为误码,直接退出
                IE1 = 0;
                return;
            }
            //接收每bit高电平时间,判定该bit的值
            time = GetHighTime();
            if ((time>313) && (time<718))  //时间判定范围为340~780us,
            {                              //在此范围内说明该bit值为0
                byt >>= 1;   //因低位在先,所以数据左移,高位为0
            }
            else if ((time>1345) && (time<1751))  //时间判定范围为1460~1900us,
            {                                     //在此范围内说明该bit值为1
                byt >>= 1;   //因低位在先,所以数据左移,
                byt |= 0x80; //高位置1
            }
            else  //不在上述范围内则说明为误码,直接退出
            {
                IE1 = 0;
                return;
            }
        }
        ircode[ i] = byt;  //接收完一个字节后保存到缓冲区
    }
    irflag = 1;  //接收完毕后设置标志
    IE1 = 0;    //退出前清零INT1中断标志
}



作者: admin    时间: 2018-3-8 20:07
楼主能分享下config.h头文件与电路图吗?




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1