找回密码
 立即注册
查看: 62|回复: 6

17-2 红外遥控电机调速,江协科技讲普中51单片机开发板STC89C52学习板 配套程序, A2标

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

231

主题

172

回帖

1081

积分

版主

积分
1081
发表于 2026-7-13 13:47:16 | 显示全部楼层 |阅读模式
17-2 红外遥控电机调速,江协科技讲普中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, 下载次数: 7

回复

使用道具 举报 送花

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

231

主题

172

回帖

1081

积分

版主

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

#include <REGX52.H>

/**
  * @brief  定时器0初始化
  * @param  无
  * @retval 无
  */
void Timer0_Init(void)
{
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0;                //设置定时初值
        TH0 = 0;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 0;                //定时器0不计时
}

/**
  * @brief  定时器0设置计数器值
  * @param  Value,要设置的计数器值,范围:0~65535
  * @retval 无
  */
void Timer0_SetCounter(unsigned int Value)
{
        TH0=Value/256;
        TL0=Value%256;
}

/**
  * @brief  定时器0获取计数器值
  * @param  无
  * @retval 计数器值,范围:0~65535
  */
unsigned int Timer0_GetCounter(void)
{
        return (TH0<<8)|TL0;
}

/**
  * @brief  定时器0启动停止控制
  * @param  Flag 启动停止标志,1为启动,0为停止
  * @retval 无
  */
void Timer0_Run(unsigned char Flag)
{
        TR0=Flag;
}


回复

使用道具 举报 送花

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

231

主题

172

回帖

1081

积分

版主

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

#include <REGX52.H>

/**
  * @brief  定时器1初始化,100us@12.000MHz
  * @param  无
  * @retval 无
  */
void Timer1_Init(void)
{
        TMOD &= 0x0F;                //设置定时器模式
        TMOD |= 0x10;                //设置定时器模式
        TL1 = 0x9C;                //设置定时初值
        TH1 = 0xFF;                //设置定时初值
        TF1 = 0;                //清除TF1标志
        TR1 = 1;                //定时器1开始计时
        ET1=1;
        EA=1;
        PT1=0;
}

/*定时器中断函数模板
void Timer1_Routine() interrupt 3
{
        static unsigned int T1Count;
        TL1 = 0x9C;                //设置定时初值
        TH1 = 0xFF;                //设置定时初值
        T1Count++;
        if(T1Count>=1000)
        {
                T1Count=0;
               
        }
}
*/


回复

使用道具 举报 送花

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

231

主题

172

回帖

1081

积分

版主

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

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

unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};

void Nixie(unsigned char Location,Number)
{
        switch(Location)
        {
                case 1:P2_4=1;P2_3=1;P2_2=1;break;
                case 2:P2_4=1;P2_3=1;P2_2=0;break;
                case 3:P2_4=1;P2_3=0;P2_2=1;break;
                case 4:P2_4=1;P2_3=0;P2_2=0;break;
                case 5:P2_4=0;P2_3=1;P2_2=1;break;
                case 6:P2_4=0;P2_3=1;P2_2=0;break;
                case 7:P2_4=0;P2_3=0;P2_2=1;break;
                case 8:P2_4=0;P2_3=0;P2_2=0;break;
        }
        P0=NixieTable[Number];
        Delay(1);
        P0=0x00;
}


回复

使用道具 举报 送花

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

231

主题

172

回帖

1081

积分

版主

积分
1081
发表于 2026-7-13 13:49:39 | 显示全部楼层
17-2 红外遥控电机调速,江协科技讲普中51单片机开发板STC89C52学习板 配套程序, A2标准版
Timer1.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:50:47 | 显示全部楼层
17-2 红外遥控电机调速,江协科技讲普中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:51:28 | 显示全部楼层
17-2 红外遥控电机调速,江协科技讲普中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>13500-500 && IR_Time<13500+500)
                {
                        IR_State=2;                        //置状态为2
                }
                //如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)
                else if(IR_Time>11250-500 && IR_Time<11250+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>1120-500 && IR_Time<1120+500)
                {
                        IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));        //数据对应位清0
                        IR_pData++;                        //数据位置指针自增
                }
                //如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)
                else if(IR_Time>2250-500 && IR_Time<2250+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.073325 second(s), 66 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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