找回密码
 立即注册
查看: 84|回复: 2

17-2 红外遥控电机调速(11.0592MHz晶振),江协科技讲普中51单片机开发板STC89C52学习

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:80
  • 最近打卡:2026-07-23 09:36:34
已绑定手机

231

主题

172

回帖

1081

积分

版主

积分
1081
发表于 2026-7-13 13:52:22 | 显示全部楼层 |阅读模式
17-2 红外遥控电机调速(11.0592MHz晶振),江协科技讲普中51单片机开发板STC89C52学习板 配套程序, A2标准版
主程序main.C代码如下:


#include <REGX52.H>
#include "Delay.h"
#include "Key.h"
#include "Nixie.h"
#include "Motor.h"
#include "IR.h"

unsigned char Command,Speed;

void main()
{
        Motor_Init();
        IR_Init();
        while(1)
        {
                if(IR_GetDataFlag())        //如果收到数据帧
                {
                        Command=IR_GetCommand();                //获取遥控器命令码
                       
                        if(Command==IR_0){Speed=0;}                //根据遥控器命令码设置速度
                        if(Command==IR_1){Speed=1;}
                        if(Command==IR_2){Speed=2;}
                        if(Command==IR_3){Speed=3;}
                       
                        if(Speed==0){Motor_SetSpeed(0);}        //速度输出
                        if(Speed==1){Motor_SetSpeed(50);}
                        if(Speed==2){Motor_SetSpeed(75);}
                        if(Speed==3){Motor_SetSpeed(100);}
                }
                Nixie(1,Speed);                                                //数码管显示速度
        }
}


17-2 红外遥控电机调速(11.0592MHz晶振).zip

65.41 KB, 下载次数: 11

回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:80
  • 最近打卡:2026-07-23 09:36:34
已绑定手机

231

主题

172

回帖

1081

积分

版主

积分
1081
发表于 2026-7-13 13:53:06 | 显示全部楼层
17-2 红外遥控电机调速(11.0592MHz晶振),江协科技讲普中51单片机开发板STC89C52学习板 配套程序, A2标准版
Motor.C代码如下:

#include <REGX52.H>
#include "Timer1.h"

//引脚定义
sbit Motor=P1^0;

unsigned char Counter,Compare;

/**
  * @brief  电机初始化
  * @param  无
  * @retval 无
  */
void Motor_Init(void)
{
        Timer1_Init();
}

/**
  * @brief  电机设置速度
  * @param  Speed 要设置的速度,范围0~100
  * @retval 无
  */
void Motor_SetSpeed(unsigned char Speed)
{
        Compare=Speed;
}

//定时器1中断函数
void Timer1_Routine() interrupt 3
{
        TL1 = 0x9C;                //设置定时初值
        TH1 = 0xFF;                //设置定时初值
        Counter++;
        Counter%=100;        //计数值变化范围限制在0~99
        if(Counter<Compare)        //计数值小于比较值
        {
                Motor=1;                //输出1
        }
        else                                //计数值大于比较值
        {
                Motor=0;                //输出0
        }
}


回复

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:80
  • 最近打卡:2026-07-23 09:36:34
已绑定手机

231

主题

172

回帖

1081

积分

版主

积分
1081
发表于 2026-7-13 13:53:55 | 显示全部楼层
17-2 红外遥控电机调速(11.0592MHz晶振),江协科技讲普中51单片机开发板STC89C52学习板 配套程序, A2标准版
IR.C代码如下:

#include <REGX52.H>
#include "Timer0.h"
#include "Int0.h"

unsigned int IR_Time;
unsigned char IR_State;

unsigned char IR_Data[4];
unsigned char IR_pData;

unsigned char IR_DataFlag;
unsigned char IR_RepeatFlag;
unsigned char IR_Address;
unsigned char IR_Command;

/**
  * @brief  红外遥控初始化
  * @param  无
  * @retval 无
  */
void IR_Init(void)
{
        Timer0_Init();
        Int0_Init();
}

/**
  * @brief  红外遥控获取收到数据帧标志位
  * @param  无
  * @retval 是否收到数据帧,1为收到,0为未收到
  */
unsigned char IR_GetDataFlag(void)
{
        if(IR_DataFlag)
        {
                IR_DataFlag=0;
                return 1;
        }
        return 0;
}

/**
  * @brief  红外遥控获取收到连发帧标志位
  * @param  无
  * @retval 是否收到连发帧,1为收到,0为未收到
  */
unsigned char IR_GetRepeatFlag(void)
{
        if(IR_RepeatFlag)
        {
                IR_RepeatFlag=0;
                return 1;
        }
        return 0;
}

/**
  * @brief  红外遥控获取收到的地址数据
  * @param  无
  * @retval 收到的地址数据
  */
unsigned char IR_GetAddress(void)
{
        return IR_Address;
}

/**
  * @brief  红外遥控获取收到的命令数据
  * @param  无
  * @retval 收到的命令数据
  */
unsigned char IR_GetCommand(void)
{
        return IR_Command;
}

//外部中断0中断函数,下降沿触发执行
void Int0_Routine(void) interrupt 0
{
        if(IR_State==0)                                //状态0,空闲状态
        {
                Timer0_SetCounter(0);        //定时计数器清0
                Timer0_Run(1);                        //定时器启动
                IR_State=1;                                //置状态为1
        }
        else if(IR_State==1)                //状态1,等待Start信号或Repeat信号
        {
                IR_Time=Timer0_GetCounter();        //获取上一次中断到此次中断的时间
                Timer0_SetCounter(0);        //定时计数器清0
                //如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)
                if(IR_Time>12442-500 && IR_Time<12442+500)
                {
                        IR_State=2;                        //置状态为2
                }
                //如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)
                else if(IR_Time>10368-500 && IR_Time<10368+500)
                {
                        IR_RepeatFlag=1;        //置收到连发帧标志位为1
                        Timer0_Run(0);                //定时器停止
                        IR_State=0;                        //置状态为0
                }
                else                                        //接收出错
                {
                        IR_State=1;                        //置状态为1
                }
        }
        else if(IR_State==2)                //状态2,接收数据
        {
                IR_Time=Timer0_GetCounter();        //获取上一次中断到此次中断的时间
                Timer0_SetCounter(0);        //定时计数器清0
                //如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)
                if(IR_Time>1032-500 && IR_Time<1032+500)
                {
                        IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));        //数据对应位清0
                        IR_pData++;                        //数据位置指针自增
                }
                //如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)
                else if(IR_Time>2074-500 && IR_Time<2074+500)
                {
                        IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));        //数据对应位置1
                        IR_pData++;                        //数据位置指针自增
                }
                else                                        //接收出错
                {
                        IR_pData=0;                        //数据位置指针清0
                        IR_State=1;                        //置状态为1
                }
                if(IR_pData>=32)                //如果接收到了32位数据
                {
                        IR_pData=0;                        //数据位置指针清0
                        if((IR_Data[0]==~IR_Data[1]) && (IR_Data[2]==~IR_Data[3]))        //数据验证
                        {
                                IR_Address=IR_Data[0];        //转存数据
                                IR_Command=IR_Data[2];
                                IR_DataFlag=1;        //置收到连发帧标志位为1
                        }
                        Timer0_Run(0);                //定时器停止
                        IR_State=0;                        //置状态为0
                }
        }
}


回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-7-24 05:52 , Processed in 0.079692 second(s), 52 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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