红外遥控电机调速+普中51单片机+江科大自化协

发布者:JoyfulMelody最新更新时间:2024-08-05 来源: cnblogs关键字:红外遥控  电机调速 手机看文章 扫描二维码
随时随地手机看文章

1 实验现象

   基于STC89C52单片机设计一个红外遥控直流电机调速系统。一上电,数码管上显示0,此时直流电机不转动。当按下红外遥控器上的“1”键时,数码管显示1,直流电机开始转动。电机转速分为4个挡位,每升高一个挡位,数码管都会显示对应的挡位数字同时提高电机的转速。

2 实验原理

  该系统整体采用红外遥控器控制,红外接收模块接收到遥控器键码信号后,向单片机送入中断信号并由单片机译码,单片机开始进行相应挡位的数据处理和挡位的改变。通过模拟PWM模块产生不同的PWM矩形波来控制直流电机调速,最后显示挡位到数码管上。

3 系统设计

 

4 硬件设计(略)

5 软件设计

5.1 主函数


#include

#include 'Nixie.h'

#include 'motor.h'

#include 'InfraredRemote.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(Command==IR_4) {Speed=4;}

                

            if(Speed==0) {motor_setspeed(0);}    //速度输出

            if(Speed==1) {motor_setspeed(25);}

            if(Speed==2) {motor_setspeed(50);}

            if(Speed==3) {motor_setspeed(75);}

            if(Speed==4) {motor_setspeed(100);}

        }

        Nixie(1,Speed);

    }

}


5.2 红外遥控函数


#include

#include 'timer0.h'

#include 'exint0.h'


unsigned int     IR_time;        //记录相邻两个下降沿的时间

unsigned char     IR_state;        //状态机设计

unsigned char     IR_data[4];        //用来接收数据32位,4个字节

unsigned char    IR_pdata;        //用来记录接收第几位数据,0-31


unsigned char     IR_dataflag;    //数据接收完毕标识信号

unsigned char     IR_repeatflag;    //重复发送标识信号

unsigned char     IR_address;        //接收地址

unsigned char     IR_command;        //接收命令


/**

  * @brief  红外遥控初始化

  * @param  无

  * @retval 无

  */

void IR_init(void)

{

    exint0_init();        //外部中断INT0

    timer0_init();        //定时器T0

}


/**

  * @brief  红外遥控获取收到数据帧标志位

  * @param  无

  * @retval 是否收到数据帧,1为收到,0为未收到

  */

unsigned char IR_getdataflag(void)

{

    if(IR_dataflag)

    {

        IR_dataflag=0;

        return 1;

    }

    else

        return 0;

}


/**

  * @brief  红外遥控获取收到连发帧标志位

  * @param  无

  * @retval 是否收到连发帧,1为收到,0为未收到

  */

unsigned char IR_getrepeatflag(void)

{

    if(IR_repeatflag)

    {

        IR_repeatflag=0;

        return 1;

    }

    else

        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);            //启动定时器T0

        IR_state=1;

    }

    else if(IR_state==1)    //状态1,等待Start信号或Repeat信号

    {

        IR_time=timer0_GetCounter(); //获取上一次中断到此次中断的时间

        timer0_SetCounter(0);        //设置计数器起始值,从0开始计数

        //如果计时为9ms+4.5ms=13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)

        if(IR_time>12442-500 && IR_time<12442+500)    //起始信号(11.0592MHz)

        {

            IR_state=2;        //状态2,接收数据

        }

        //如果计时为9ms+2.25ms=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);        //关闭定时器T0

            IR_state=0;            //置状态为0

        }

        else  IR_state=1;        //接收错误,状态保持

    }

    else if(IR_state==2)        //接收数据状态

    {

        IR_time=timer0_GetCounter();     //获取上一次中断到此次中断的时间

        timer0_SetCounter(0);            //设置计数器起始值,从0开始计数

        //如果计时为560+560=1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)

        if(IR_time>1032-500 && IR_time<1032+500)        //数据0

        {

            IR_data[IR_pdata/8] &= ~(0x01<<(IR_pdata%8));    //数据对应位清0

            IR_pdata++;        //数据位置指针自增

        }

        //如果计时为560+1690=2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)

        else if(IR_time>2074-500 && IR_time<2074+500)    //数据1

        {

            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)    //接收完所有数据

    {

        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);            //关闭定时器T0

        IR_state=0;                //空闲状态

    }        

}


#ifndef _InfraredRemote_h_

#define _InfraredRemote_h_


#define IR_POWER        0x45

#define IR_MODE            0x46

#define IR_MUTE            0x47


#define IR_START_STOP    0x44

#define IR_PREVIOUS        0x40

#define IR_NEXT            0x43


#define IR_EQ            0x07

#define IR_VOL_MINUS    0x15

#define IR_VOL_ADD        0x09


#define IR_0            0x16

#define IR_RPT            0x19

#define IR_USD            0x0D


#define IR_1            0x0C

#define IR_2            0x18

#define IR_3            0x5E


#define IR_4            0x08

#define IR_5            0x1C

#define IR_6            0x5A


#define IR_7            0x42

#define IR_8            0x52

#define IR_9            0x4A


void IR_init(void);

unsigned char IR_getdataflag(void);

unsigned char IR_getrepeatflag(void);

unsigned char IR_getaddress(void);

unsigned char IR_getcommand(void);

    

#endif


5.3 定时器T0


#include


/**

  * @brief  定时器0初始化,1毫秒@11.0592MHz

  * @param  无

  * @retval 无

  */

void timer0_init(void)        //1毫秒@11.0592MHz

{

    TMOD &= 0xF0;    //设置定时器模式,1111_0000,&,高四位保留,低四位清零

    TMOD |= 0x01;    //设置定时器模式,0000_0001,|,高四位保留,设置模式为T0

    TL0 = 0;        //设置定时初始值

    TH0 = 0;        //设置定时初始值

    TF0 = 0;        //清除TF0标志

    TR0 = 0;        //定时器0暂时不计时

}


void timer0_SetCounter(unsigned int value)

{

    TH0=value/256;

    TL0=value%256;

}


unsigned int timer0_GetCounter(void)

{

    return (TH0<<8)|TL0;

}


void timer0_Run(unsigned char Flag)

{

    TR0=Flag;

}


#ifndef _timer0_h_

#define _timer0_h_


void timer0_init(void);

void timer0_SetCounter(unsigned int value);

[1] [2]
关键字:红外遥控  电机调速 引用地址:红外遥控电机调速+普中51单片机+江科大自化协

上一篇:IO扩展(74HC595)_单片机_普中
下一篇:红外遥控接收模块+普中51单片机+江科大自化协

推荐阅读最新更新时间:2026-03-22 12:54

AT24C02数据存储+51单片机+科大
1 系统原理图 2 现象 当按键Key1被按下时,LCD1602显示的数值加1,每按下一次,自增1;当按键Key2被按下时,LCD1602显示的数值自减1;当按键Key3被按下时,单片机将LCD1602显示的数值保存在AT24C02中,掉电不丢失;当按键Key4被按下时,单片机从AT24C02中读取数据,并显示在LCD1602。 3 参考程序 (1)主函数 #include REGX52.H #include delayms.h #include key.h #include lcd1602.h #include at24c02.h unsigned char KeyNum; unsigned in
[单片机]
AT24C02数据存储+<font color='red'>普</font><font color='red'>中</font><font color='red'>51单片机</font>+<font color='red'>江</font><font color='red'>科大</font><font color='red'>自</font><font color='red'>化</font><font color='red'>协</font>
电机调速器能增大功率吗?
电机调速器是一种用于控制电机转速的装置,其主要作用是通过改变电机的输入电压、频率或电流来调整电机的转速。电机调速器的运行原理是通过改变电机的电压或电流,达到控制电机输出功率的目的。 然而,电机调速器并不能直接增大电机的功率。电机的功率主要由电压和电流决定,通常情况下,电压和电流的乘积即为电机的功率。而电机调速器只是改变电机的输入电压、频率或电流,从而控制电机的转速,而非直接增加电机的功率。 电机调速器的工作原理是通过改变电机的输入电压或电流,改变电机的输出转矩,从而控制电机的转速。在低负载情况下,电机调速器可以通过降低电机的电压或电流,减少电机的输出转矩,从而降低电机的功率输出。在高负载情况下,电机调速器可以通过增加电机的电压或电
[嵌入式]
微型直流电机调速器上动磁和励磁有什么区别?
微型直流电机调速器的动磁和励磁是两个重要的概念,它们在直流电机的工作原理中发挥着不同的作用。在下面的文章中,我将详细介绍动磁和励磁的概念、功能以及它们在微型直流电机调速器中的应用。 一、动磁的概念和功能 动磁是指通过对电枢线圈施加直流电流,使电枢产生磁场,进而与定子产生磁场相互作用,从而产生力矩,推动转子旋转。动磁的主要作用是产生驱动力矩,即将电能转化为机械能,使电机正常运转。 在微型直流电机中,动磁是通过一个电枢来实现的。电枢是由一组绕在铁芯上的线圈构成的,当通过线圈的电流改变时,将会改变电枢的磁场强度,从而改变转子受到的力矩大小,实现电机的调速。 动磁的控制是通过控制器对电枢电流进行调节来实现的。通过改变控制器的输出电压或电流
[嵌入式]
PWM直流电机调速器为何无法调速?
PWM直流电机调速器无法调速的原因有以下几方面: 1.主回路击穿; 2.无反馈或反馈系统坏; 3.调节器坏; 4.不能无级变速,可以固定速度不能调节。 常见原因大概包括这些,但是因现场会有多种因素影响,所以具体线路具体分析,才能有最为准确的判断。
[嵌入式]
对国产直流/力矩电机调速控制器反思
什么是设计?曾听到有人说起中国设计多为运用,也曾思考过这个问题。 我刚开始工作时就用的KBA机箱做力矩电机控制器,一转眼已快40年了,仍然还是老样子,连运用都没改变,有的厂家连当初的线路,技术控制方式都没变。那么是我们的产品好吗?还是止步不前? 从最初的单极晶体管到集成电路再到数字电路,更新的智能,远程,无线控制,是谁走在最前沿,我们是否该停下来反思一下自己,路该怎么走?投入资金从那来?谁也改变不了现实,只能是改变对待现实的态度。 沐天的直流电机调速器的多用途及各功能,一般情况下很少会用到,大多数为简单的调速而已。其实我们除了简单调速还有些其他功能,比如: a)系统可用于电压反馈,也可用于测速反馈,测速反馈电压DC55
[嵌入式]
有刷电机调速器是调节的电压还是电流?
对于有刷电机调速器调节的是电压还是电流这个问题来说,一般电流调速器都是调压或调频。也有磁阻调速。电极的电流是客观负载所存在的。负载大输出电流大。 但有很多实验及特种场合需要调电流的一般都采用内部假性负载来达到具体需求。
[嵌入式]
对国产的直流电机调速控制器和力矩电机调速控制器的反思
什么是设计?为什么外国人说中国人没有设计,有的只是运用而已,这句话虽然极端,但确也反映了现实的真实存在。 如我刚开始工作时就用的KBA机箱做力矩 电机控制 器,一转眼已快40年了,仍然还是老样子,连运用都没改变,有的厂家连当初的线路,技术控制方式都没变。那么是我们的 产品 好吗?还是止步不前? KTS-50A~80A全数字面板式力矩电机控制器 从最初的单极 晶体管 到 集成电路 再到 数字电路 ,更新的 智能 ,远程,无线控制,是谁走在最前沿,我们是否该停下来反思一下自己,路该怎么走?投入资金从那来?谁在剥削我们?谁也改变不了现实,只能是改变对待现实的态度。 ZKS-4KW的多种用途与各种功能的使用,一般情况
[嵌入式]
对国产的直流<font color='red'>电机调速</font>控制器和力矩<font color='red'>电机调速</font>控制器的反思
怎样控制变频器实现电机调速?变频器的频率源给定有几种方式呢?
今天我们来讲解变频器的一个重要概念:频率源,同样的有的品牌会叫给定通道等等,其实说的都是一码事。之前只要给变频器一个运行命令,变频器其实就已经在运行了,但是如果不给其频率,如果此时变频器给定频率为0,就算变频器已经运行了,但是由于变频器输出频率为0电机是不会转的,因此我们一般情况下,命令源和频率源都是要同时给定的,命令源负责启动、频率源负责控制转速,这样才能用变频器控制电机进行调速。 变频器接线 那么变频器的频率源给定有几种方式呢?那可是比较多了,以某国产变频器为例,其频率给定源足足有10种,分别如下: 0:数字给定1(面板正倒三角给定) 1:数字给定2(UP/DOWN 端子调整) 2:数字给定 3(通讯设定) 3:AI
[嵌入式]
怎样控制变频器实现<font color='red'>电机调速</font>?变频器的频率源给定有几种方式呢?
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved