找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2626|回复: 2
收起左侧

单片机+ULN2003+红外模块而成的pwm遥控变速风扇的源代码

[复制链接]
ID:779880 发表于 2020-6-21 17:33 | 显示全部楼层 |阅读模式
//本人刚自学11天的单片机,写成一个程序,发出来旨在交流和学习;
//按照自己的理解加以注释,算是复习一遍;如有需要者,可以作为参考;

#include<reg52.h>

typedef unsigned int u16;          
typedef unsigned char u8;

sbit moto=P1^0;   //电机控制端口
sbit IRIN=P3^2;   //红外接收端口

u8 IrValue[6];
u8 Time;
u8 flag=100;
u8 num=0;
u8 pwm=0;

void delay(u8 i)   //延时函数
{ while(i--);

}


void IrInit()    //外部中断0的初始化
{
        IT0=1;
        EX0=1;
        EA=1;       

        IRIN=1;
}

void IrInit2()     //定时器0的初始化
{TMOD = 0x01;
TH0 = 0x0FF;
    TL0 = 0x9C;
EA = 1;
ET0 = 1;
TR0=1;}


void key()    //检测红外用户码来确定风速档位
{if(IrValue[2]==0x45)      //0x45 0x46 0x47 是我的红外遥控的三个用户码,可自调
        {
          pwm=30;      //pwm调速,分为三档
   }
       

if(IrValue[2]==0x46)
        {
          pwm=60;
   }
       
        if(IrValue[2]==0x47)
        {
          pwm=90;
   }




        }

void main()
{moto=0;   //电机关闭
IrInit2();
IrInit();
while(1)
{      key();
         if(num==flag) num=0;
         if(num<pwm) moto=1;
         else moto=0;

}

}

void T0_time() interrupt 1     //定时器0服务程序
{  TH0 = 0x0FF;
    TL0 = 0x9C;
    num++;

}

void ReadIr() interrupt 0    //外部中断0服务程序
{
        u8 j,k;
        u16 err;
        Time=0;                                         
        delay(700);         
        if(IRIN==0)    //检测是否接收到红外信号       
        {         
               
                err=1000;                               
                while((IRIN==0)&&(err>0))        //等待起始码的前9ms低电平过去                
                {                       
                        delay(1);
                        err--;
                }
                if(IRIN==1)        //开始收到高电平       
                {
                        err=500;    //等待起始码的4.5ms高电平过去
                        while((IRIN==1)&&(err>0))               
                        {
                                delay(1);
                                err--;
                        }
                        for(k=0;k<4;k++)        //开始接收四组数据       
                        {                               
                                for(j=0;j<8;j++)        //每组数据有八位
                                {

                                        err=60;               
                                        while((IRIN==0)&&(err>0))    //等待每一位的前0.56ms低电平过去(位0和位1的区别在于高电平的时间)
                                        {
                                                delay(1);
                                                err--;
                                        }
                                        err=500;
                                        while((IRIN==1)&&(err>0))        //开始计时高电平时间
                                        {
                                                delay(10);       
                                                Time++;
                                                err--;
                                                if(Time>30)      //若time大于30,说明接受数据错误,强制返回
                                                {
                                                        return;
                                                }
                                        }
                                        IrValue[k]>>=1;        //数据移位
                                        if(Time>=8)               //大概以0.8ms为界区别位0和位1               
                                        {
                                                IrValue[k]|=0x80;  //1000 0000
                                        }
                                        Time=0;                //Time置0               
                                }
                        }
                }
                if(IrValue[2]!=~IrValue[3])   //检验,若不相等则强制返回
                {
                        return;
                }
        }                       
}

回复

使用道具 举报

ID:328014 发表于 2020-6-22 15:39 | 显示全部楼层
能分享或者介绍一下原理图吗?
回复

使用道具 举报

ID:779880 发表于 2020-6-22 21:35 | 显示全部楼层
51hei团团 发表于 2020-6-22 15:39
能分享或者介绍一下原理图吗?

其实没什么原理啊 ,就是红外接收头接P3.2,然后根据接收到的用户码确定pwm的值(30,60,90)来调速。调速是用的定时器0,红外接收用的外部中断0  uln2003嘛 就一个接vcc,一个接P1.0,按照周期(这个pwm波的周期要调好,不能太大也不能太小),就转动了
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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