MCU infrared remote control fan source program

Publisher:会哭的蓝精灵Latest update time:2020-09-04 Source: 51hei Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Before conducting this experiment, you need to complete the "16_Infrared Decoding Digital Tube Display" and "19_DC Motor Small Fan" experiments.

Then connect the motor wires and motor accordingly.


Infrared wireless remote control fan + speed up, press - to slow down, the default is the lowest speed, after burning, you can press the "+" on the remote control to speed up. The motor will not rotate in the 4~9 range, which may be due to insufficient power supply current. 1-4 can almost rotate if the wiring is correct.


Note: The test time should not exceed 1 minute. Just observe the experimental phenomena.


The microcontroller source program is as follows:

/*

Infrared wireless remote control fan + Speed ​​up Press - Speed ​​down

*/

#include


sbit DU = P2^6; //digital tube segment selection

sbit WE = P2^7; //digital tube bit selection

sbit S2 = P3^0;

sbit S3 = P3^1;


/*====================================

Custom type names

====================================*/

typedef unsigned char INT8U;

typedef unsigned char uchar;


typedef unsigned int INT16U;

typedef unsigned int uint;

/*====================================

Hardware interface bit declaration

====================================*/

sbit IR = P3^2; //Define infrared pulse data interface external interrupt O input port


uchar IRtime; //Detect infrared high level duration (pulse width)

uchar IRcord[4]; //This array is used to store the separated 4 bytes of data (2 bytes of user code + 2 bytes of key value code)

uchar IRdata[33]; //This array is used to store 33 bits of infrared data (the first bit is the boot code user code 16 + key code 16)

bit IRpro_ok, IRok; //The first one is used to complete the infrared reception of 4 bytes. IRok is used to detect the completion of the pulse width


unsigned char const discode[] ={ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,0x6F,0x40,0x00/*-*/};


unsigned char pwm_left_val = 225; //Left motor duty cycle value range 0-170, 0 is the fastest

unsigned char pwm_t; //cycle




void time0() interrupt 1 //define timer 0

{

        IRtime++; //Detect pulse width, 1 time is 278us

}

//Timer 1 interrupt

void timer1() interrupt 3

{

        pwm_t++;

        if(pwm_t == 250)

                pwm_t = P1 = 0;

        if(pwm_left_val == pwm_t)

                        P1 = 0xff;                                         

}

void int0() interrupt 0 //define external interrupt 0

{

        static uchar i; // declare static variables (the value will not be lost when the function is exited and the execution is returned) i is used to store the duration of the 33 high levels into IRdata

        static bit startflag; //Start storing pulse width flag

        if(startflag) //Start receiving pulse width detection

        {

                if( (IRtime < 53) && (IRtime >= 32) ) /*Judge whether it is a boot code, bottom level 9000us + high level 4500us       

                You can calculate this yourself. I calculated it with 11.0592. The boot code of the NEC protocol is 8000-10000 low + 4000-5000 high.

                If the boot code has been received, i will not be set to 0 and the pulse width will be stored in sequence.

                        i = 0; //If it is a boot code, execute i=0 and save it to the first bit of IRdata

                IRdata[i] = IRtime; //Calculate the pulse width based on the number of overflows of T0, and store this time in the array for later judgment

                IRtime = 0; //Count is cleared, and the pulse width is stored at the next falling edge

                i++; //Count the number of times the pulse width is stored

                if(i == 33) //If the index of the 34th group is stored, it starts from 0. i equals 33, which means it has been executed 34 times.

                {

                         IRok = 1; //Then it means the pulse width detection is completed

                        i = 0; // Clear the pulse width count to prepare for the next storage

                }

        }

        else                  

        {

                IRtime = 0; //Start entering the boot code and clear the pulse width count to start counting

                startflag = 1; //Start processing flag position 1

        }

}


void IRcordpro() //Extract its 33 pulse widths for data decoding

{

        uchar i, j, k, cord, value; /*i is used to process 4 bytes, j is used to process each bit in a byte, and k is used for which bit in the 33 pulse widths

        cord is used to extract the pulse width time to determine whether it meets the pulse width time of 1*/

        k = 1; //Start from the first pulse width and discard the lead code pulse width

        for(i = 0; i < 4; i++)

        {

                for(j = 0; j < 8; j++)

                {

                        cord = IRdata[k]; //Store the pulse width in cord

                        if(cord > 5) //If the pulse width is greater than my 11.0592, the t0 overflow rate is about 278us*5=1390, then it is judged as 1

                        value = value | 0x80; /*When receiving, the lowest bit is received first.

                        Put the lowest bit first into the highest bit of value and then bitwise OR it with 0x08

                        This will not change the value of other bits of Valua, but only make the highest bit 1*/

                        if(j < 7)

                        {

                                value = value >> 1; //Shift value left and receive 8 bits of data in sequence.

                        }

                        k++; //Each execution increases the pulse width by 1

                }

                IRcord[i] = value; //After processing each byte, put it into the IRcord array.

                value = 0; // Clear value to facilitate storing data next time

        }

        IRpro_ok = 1; //After receiving 4 bytes, IRpro ok is set to 1 to indicate that infrared decoding is completed       

}


void main()

{

        unsigned char i = 9;

        TMOD |= 0x20; //T1 8-bit automatic reload module

        TH1 = 245;

        TL1 = 245; //The maximum duty ratio under 11.0592M crystal is 256, output 100HZ

        TR1 = 1; //Start timer 0

        ET1 = 1; // Enable timer 0 interrupt

        EA = 1; //General interrupt enabled


        TMOD |= 0x02; //Timer 0 working mode 2, 8-bit automatic reload

        TH0 = 0x00; //The upper 8 bits are loaded with 0, so the timer overflows once in 256 machine cycles.

        TL0 = 0x00;

        ET0 = 1; //Timer 0 interrupt

        TR0 = 1; //Start timer 0


        IT0 = 1; //Set external interrupt 0 to edge trigger mode, trigger once on a falling edge

        EX0 = 1; //Start external interrupt 0

        //delay(2000);

        WE = 1;

        P0 = 0XFE;

        WE = 0;

        DU = 1;

        P0 = discode[i];

        while(1)

        {

               

                if(IRok) //Judge whether the pulse width detection is completed                    

                {   

                        IRcordpro(); //Decode 4 bytes of data based on pulse width

                        IRok = 0; // Wait for pulse width detection again

                        if(IRpro_ok) //Judge whether decoding is completed  

                        {

                        switch(IRcord[2])

                                   {

                                     case 0x15:   //+

                                         if(i > 0)

                                        {

                                                pwm_left_val = pwm_left_val - 15;

                                                i--;

                                                P0 = discode[i];

                                        }

                                             break;

                                     case 0x07:   //-

                                if(i < 9)

                                {

                                        pwm_left_val = pwm_left_val + 15;

                                        i++;

                                        P0 = discode[i];

                                }

                                             break;

                                   }

                                IRpro_ok = 0;

                        }

                }       

        }

}


Reference address:MCU infrared remote control fan source program

Previous article:51 single chip temperature + pwm controls the fan speed, and the temperature is displayed on LCD1602
Next article:Design of temperature-controlled speed fan based on single-chip infrared sensing

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号