找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 493|回复: 9
收起左侧

请教如何把89c52单片机红外解码程序移植到15W408中

[复制链接]
ID:891876 发表于 2023-12-16 11:49 | 显示全部楼层 |阅读模式
初次接触1T的stc15W408as单片机,不清楚哪些程序要改动?
请教如何把89c52单片机红外解码程序移植到15W408中运行?
#include <REGX52.H>
#include <intrins.h>
#define uchar unsigned char   
#define uint  unsigned int  

uchar code tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E,0xFF};

sbit        IR    = P3^2;        //红外接收端         

uchar        N[4];                                 //识别码,操作码存放
uchar  sj=0;

void XSQ(void);
void YS(uchar time);

/****************** 主函数 *******************/
void main(void)
{           
  IT0 = 1;
  EX0 = 1;
  EA  = 1;

  while(1)
  {
      XSQ();
  }
}

/**********************数码管显示函数************************/
void XSQ(void)
{
          
          P0=tab[X3];
           P2_6=0;
           YS(1);        //操作码
           P2_6=1;
         P0=tab[X4];
           P2_7=0;
           YS(1);
           P2_7=1;
}

/********************** 外部中断函数************************/
void exint0() interrupt 0
{          
   uint cnt;
   uchar i;

   EX0 = 0;
   cnt = 0;       
       
   while(!IR) cnt++;                               //记录引导码时间
   if(cnt < 1000){EX0=1;return;}                   //9ms的计数值(12MHz:1000< cnt <1500)
          
   cnt = 0;                         
   while(IR) if(cnt++ > 400){EX0=1;return;}        //防卡死,超时保护(12MHz: > 300)   
   if(cnt < 200){EX0=1;return;}                    //(12MHz不分频: <260)            

   for(i=0; i<32; i++)                             //读取32位位码
       {
         cnt = 0;                                                                                                                                               
         while(!IR);                       
         while(IR) if(cnt++ > 200){EX0=1;return;}  //超时保护(12MHz:>=200)
         N[i/8] >>= 1;
         if(cnt>60) N[i/8] |= 0x80;                //0和1的计数界线(12MHz:< 109)   
       }

         if(N[0] == ~N[1] && N[2] == ~N[3])            //校验识别码,操作码       
           {
                   X1 = N[0]/16;
                   X2 = N[0]%16;
                   X3 = N[2]/16;
                   X4 = N[2]%16;
           }
                EX0 = 1;                 
}

/***************************************************************
函数功能:按键消抖    延时程序
入口参数:1ms×time       (晶振=12MHz)
***************************************************************/
void YS(uchar time)
{
     uchar i,j;
         for(i=0; i<time; i++)
     for(j=0; j<247; j++)
        _nop_();
}




回复

使用道具 举报

ID:1045113 发表于 2023-12-16 17:14 | 显示全部楼层
这两个单片机的指令周期是不一样的,计算时间的部分需要修改下。别的地方应该不用怎么改
回复

使用道具 举报

ID:1045113 发表于 2023-12-16 17:15 | 显示全部楼层
这两个单片机的指令周期不一样 ,你把计算时间的部分修改下就好啦
回复

使用道具 举报

ID:161164 发表于 2023-12-16 23:24 | 显示全部楼层
这种在中断中死等的代码
还是不要学比较好
回复

使用道具 举报

ID:161164 发表于 2023-12-16 23:28 | 显示全部楼层
stc15W408as有定时器2
可以直接用我的例程
http://www.51hei.com/bbs/dpj-225989-1.html
回复

使用道具 举报

ID:891876 发表于 2023-12-17 11:21 | 显示全部楼层
lkc8210 发表于 2023-12-16 23:28
stc15W408as有定时器2
可以直接用我的例程
http://www.51hei.com/bbs/dpj-225989-1.html

学习了,谢谢!
回复

使用道具 举报

ID:584814 发表于 2023-12-18 09:30 | 显示全部楼层
这两个单片机的速度是不一样的,调适就好。
回复

使用道具 举报

ID:879348 发表于 2023-12-18 11:00 | 显示全部楼层
这程序你真的敢用吗,在中断写一大堆功能,还有while
回复

使用道具 举报

ID:485350 发表于 2023-12-18 11:56 | 显示全部楼层
#include "IR.h"

/*
红外5104
引导码 4.5ms      高电平
Logic '0' 1.48ms  高电平
Logic '1' 2.43ms  高电平
*/

#define IR_STATUS_LOCK             0X01   //红外锁定
#define IR_STATUS_RECEIVE_OK       0X02   //红外接收完成
#define IR_STATUS_KEY_UP           0X04   //红外释放
#define IR_STATUS_RECEIVE1_OK      0X08   //数据1接收完成
#define IR_STATUS_RECEIVE2_OK      0x10   //数据2接收完成
#define IR_STATUS_RECEIVE1_EN      0X20   //数据1接收允许
#define IR_STATUS_RECEIVE2_EN      0X40   //数据2接收允许

/************************************************变量声明********************************************/
idata u8 Ir_Status;             //红外状态
idata u8 Ir_Receive_Bit_Count;  //红外接收位计数
idata u8 Ir_H_Time;             //红外高电平计数
idata u8 Ir_L_Time;             //红外高电平计数
idata u16 Ir_Map;               //红外映射
idata u16 Ir_Receive_Data0;
idata u16 Ir_Receive_Data1;
idata u16 Ir_Receive_Data2;
idata u16 Ir_Receive_Data3;
/**********************************************变量声明结束******************************************/




/************************************************函数声明********************************************/
void IR_Receive();
void IR_Key_Handle();
/**********************************************函数声明结束******************************************/


/************************************************函数功能实现********************************************/
//功能:红外解码
//调用方式:125us中断
void IR_Receive()
{
        if(IR_RECEIVE_IO)
        {
        if(Ir_H_Time < 0xff)
        {
            Ir_H_Time++;
            if((Ir_Status & IR_STATUS_LOCK) && (Ir_H_Time > 80))
            {
                Ir_Status &= ~(IR_STATUS_LOCK | IR_STATUS_RECEIVE1_OK | IR_STATUS_RECEIVE2_OK);
                Ir_Status |= IR_STATUS_KEY_UP;
            }
        }
        
        if(Ir_L_Time)
        {
            if(Ir_L_Time >= 15)
            {
                Ir_L_Time = 0;
                return ;
            }
            
            //接收第一个16位数据
            if(Ir_Status & IR_STATUS_RECEIVE1_EN)
            {
                Ir_Receive_Data0 <<= 1;
                if(Ir_L_Time > 5)
                {
                    Ir_Receive_Data0 |= 0x01;
                }
                Ir_Receive_Bit_Count++;
                if(Ir_Receive_Bit_Count >= 12)
                {
                    Ir_Status &= ~IR_STATUS_RECEIVE1_EN;
                    Ir_Status |= IR_STATUS_RECEIVE1_OK;
                }
            }
            
            //接收第二个16位数据
            if(Ir_Status & IR_STATUS_RECEIVE2_EN)
            {
                Ir_Receive_Data1 <<= 1;
                if(Ir_L_Time > 5)
                {
                    Ir_Receive_Data1 |= 0x01;
                }
                Ir_Receive_Bit_Count++;
                if(Ir_Receive_Bit_Count >= 12)
                {
                    Ir_Status &= ~IR_STATUS_RECEIVE2_EN;
                    if(Ir_Receive_Data0 == Ir_Receive_Data1)
                    {
                        Ir_Receive_Data2 = Ir_Receive_Data0;
                        Ir_Receive_Data3 = Ir_Receive_Data1;
                        Ir_Status |= IR_STATUS_LOCK | IR_STATUS_RECEIVE_OK | IR_STATUS_RECEIVE2_OK;
                        Ir_Map = 0;//快速响应
                    }
                    else
                    {
                        //接收错误重接收
                        Ir_Status &= ~(IR_STATUS_LOCK | IR_STATUS_RECEIVE1_OK | IR_STATUS_RECEIVE2_OK);
                    }
                }
            }
        }
        Ir_L_Time = 0;
        }
        else
        {
        Ir_L_Time++;
        if(Ir_H_Time > 12)//12 * 125 = 1500us
        {
            if((Ir_Status & IR_STATUS_RECEIVE1_OK) == 0)
            {
                Ir_Receive_Data0 = 0;
                Ir_Status |= IR_STATUS_RECEIVE1_EN;
            }
            else if((Ir_Status & IR_STATUS_RECEIVE2_OK) == 0)  
            {
                Ir_Receive_Data1 = 0;
                Ir_Status |= IR_STATUS_RECEIVE2_EN;
            }
            Ir_Receive_Bit_Count = 0;
        }
        Ir_H_Time = 0;
        }
}



//功能:红外按键码的功能处理
//调用方式:建议Main中10毫秒处理一次
void IR_Key_Handle()
{
    //红外按键单次处理
    if(Ir_Status & IR_STATUS_RECEIVE_OK)
    {
        Ir_Status &= ~IR_STATUS_RECEIVE_OK;                  //清除IR接收成功标志
        
        if(Ir_Receive_Data2 != Ir_Receive_Data3)
        {
            //两次接收数据不相同不执行按键处理
            return ;
        }
        
        //红外按键映射到触摸按键处理上
        switch(Ir_Receive_Data2)
        {
            case 0X0D81://开关
                Ir_Map |= KEY_POWER;
                break;
            case 0X0D90://挡位
                Ir_Map |= KEY_LEVEL;
                break;
            case 0X0D84://温度
                Ir_Map |= KEY_TEMP;
                break;
            case 0X0D88://定时
                Ir_Map |= KEY_TIMING;
                break;
            case 0X0D82://童锁
                Ir_Map |= KEY_IR_CHIP;
                break;
            default:
                Ir_Status &= ~(IR_STATUS_LOCK | IR_STATUS_RECEIVE1_OK | IR_STATUS_RECEIVE2_OK);
                break;
        }
    }
   
    //红外按键释放
    if(Ir_Status & IR_STATUS_KEY_UP)
    {
        Ir_Status &= ~IR_STATUS_KEY_UP;
        Ir_Map = 0;
    }
}

/**********************************************函数功能实现结束******************************************/
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表