AVR遥控器设计

来源:互联网 发布:蜂群算法 编辑:程序博客网 时间:2024/05/08 14:38

原理图如下,用的是AVR64,后面是代码,调试了一部分,待续ing

#include <mega64.h>#include <delay.h>#define UDRE 5#define BAUD 9600#define CLOCK 8000000#define BAUD_Setting (unsigned int)((unsigned long)CLOCK/(16*(unsigned long)BAUD)-1)#define DATA_REGISTER_EMPTY (1<<UDRE) unsigned char TX1_data[4]={0x01,0x00,0x00,0x00};// 字头 地址 地址 校验和unsigned int p=0;unsigned int num=20;int time=0;unsigned int protect=0;int send=0;unsigned int nuflag1=0;unsigned int nuflag2=0;unsigned int nuflag3=0;unsigned int nuflag4=0;unsigned int nuflag5=0;unsigned int nuflag6=0;unsigned int nuflag7=0;unsigned int nuflag8=0;unsigned int nuflag9=0;unsigned int nuflag10=0;unsigned int nuflag11=0;unsigned int nuflag12=0;unsigned int nuflag13=0;unsigned int nuflag14=0;unsigned int nuflag15=0;unsigned int nuflag16=0;unsigned int nuflag17=0;void USART_Init(void);void TX1_data_function(void);void action(void);void Getnum(void);unsigned int get=0;//unsigned int t=0;interrupt [TIM1_OVF] void time1_ovf_isr(void)  //定时器1中断{       protect++;       TIMSK |= 0x04;//中断允许       TCNT1H = 0xA4;       TCNT1L = 0x72;//初始值       OCR1AH = 0xA3;       OCR1AL = 0xFF;//匹配A值       OCR1BH = 0xA3;       OCR1BL = 0xFF;//匹配B值       ICR1H  = 0xFF;       ICR1L  = 0xFF;//输入捕捉匹配值       TCCR1A = 0x00;       TCCR1B = 0x04;//启动定时器}interrupt [EXT_INT0] void EXT_INT0_isf(void)   //IRQ0中断向量,按下发送按钮就中断,判断是哪个键{        EIMSK=0x00;//屏蔽外部中断0        get=1;}void USART_Init(void)              //串口初始化  {                   UCSR0A=0x00;    UCSR0B=0x98;                    //接受为中断    UCSR0C=0x06;    UBRR0L=(unsigned char)(BAUD_Setting);    UBRR0H=(unsigned char)(BAUD_Setting<<8);        } void TX1_data_function(void)            //串行发送中断{    for(p=0;p<4;p++)   {    while(!( UCSR0A&DATA_REGISTER_EMPTY ) );    UDR0 = TX1_data[p];   }   p=0;}void Getnum(void)                      //获取是哪个按键{         unsigned int temp;         PORTB=0xfe;                              //赋给键盘端口;         temp= PIND&0x06;         //把键盘端口实际值赋给temp;         if(temp!=0x06)                //有按键按下去就不是0x03了         {             delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                                  switch(temp)                  {                     case 0x04:                     num=0;                     break;  //第一个按键                     case 0x02:                     num=1;                     break;  //第二个按键                 }                 }                PORTB=0x00;         }                 PORTB=0xfd;                       //赋给键盘端口;         temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {             delay_ms(10);                    //消抖             temp=PIND&0x06;            //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                    switch(temp)                 {                     case 0x04:                     num=2;                     break;  //执行第3个按键的操作                     case 0x02:                     num=3;                        break;  //执行第4个按键的操作                 }             }                PORTB=0x00;         }                 PORTB=0xfb;                              //赋给键盘端口;         temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {             delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                            switch(temp)                 {                     case 0x04:                    num=4;                       break;  //执行第5个按键的操作                     case 0x02:                    num=5;                       break;  //执行第6个按键的操作                 }             }              PORTB=0x00;         }                  PORTB=0xf7;                              //赋给键盘端口;         temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {             delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                  switch(temp)                 {                     case 0x04:                     num=6;                       break;  //执行第7个按键的操作                     case 0x02:                     num=7;                       break;  //执行第8个按键的操作                 }             }                PORTB=0x00;         }                  PORTB=0xef;                              //赋给键盘端口;         temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {                     delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                 switch(temp)                 {                 case 0x04:                     num=8;                        break;  //执行第9个按键的操作                 case 0x02:                     num=9;                       break;  //执行第10个按键的操作                 }             }               PORTB=0x00;         }                  PORTB=0xdf;                              //赋给键盘端口;          temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {             delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                 switch(temp)                 {                 case 0x04:                      num=10;                                          break;  //o.5秒                 case 0x02:                      num=11;                                          break;  //1.5秒                 }             }                PORTB=0x00;         }                  PORTB=0xbf;                              //赋给键盘端口;         temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {             delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                  switch(temp)                 {                 case 0x04:                     num=12;                     break;  //2秒                 case 0x02:                     num=13;                     break;  //5秒                 }             }                PORTB=0x00;         }                  PORTB=0x7f;                              //赋给键盘端口;         temp=PIND&0x06;                    //把键盘端口实际值赋给cTemp_Value;         if(temp!=0x06)                //有按键按下去就不是0x03了         {            delay_ms(10);                    //消抖             temp=PIND&0x06;                //再次确认PD口是不是变了             if(temp!=0x06)            //如果真的变了就进行判断             {                             switch(temp)                 {                     case 0x04:                     num=14;                       break;  //时间待定                     case 0x02:                     num=15;                       break;  //时间待定                 }             }               PORTB=0x00;         }         action();    }void action()       //按键后进行操作(可以判断第二次按下){        switch(num)        {                                      case 0:         if(nuflag1==0)                {        TX1_data[2]|=0x01;          PORTA.3=1;        nuflag1=1;        }else        {        TX1_data[2]&=0xfe;        PORTA.3=0;        nuflag1=0;        }        break;  //第1个按键                         case 1:         if (nuflag2==0)        {TX1_data[2]|=0x02;        PORTA.4=1;        nuflag2=1;        }else        {        TX1_data[2]&=0xfd;        PORTA.4=0;        nuflag2=0;        }        break;  //第2个按键                         case 2:        if(nuflag3==0)        {TX1_data[2]|=0x04;        PORTA.5=1;        nuflag3=1;}        else        {        TX1_data[2]&=0xfb;        PORTA.5=0;          nuflag3=0;        }        break;  //第3个按键                              case 3:        if(nuflag4==0)        {TX1_data[2]|=0x08;         PORTA.6=1;         nuflag4=1;}        else        {        TX1_data[2]&=0xf7;        PORTA.6=0;        nuflag4=0;        }        break;  //第4个按键                            case 4:        if(nuflag5==0)        {TX1_data[2]|=0x10;        PORTA.7=1;nuflag5=1;}         else        {        TX1_data[2]&=0xef;        PORTA.7=0;         nuflag5=0;        }        break;  //第5个按键                                case 5:        if(nuflag6==0)        {TX1_data[2]|=0x020;        PORTC.0=1;nuflag6=1; }        else        {        TX1_data[2]&=0xdf;        PORTC.0=0;         nuflag6=0;        }        break;  //第6个按键                              case 6:        if(nuflag7==0)        {TX1_data[2]|=0x40;        PORTC.1=1;nuflag7=1;}         else        {        TX1_data[2]&=0xbf;        PORTC.1=0;         nuflag7=0;        }        break;  //第7个按键                              case 7:        if(nuflag8==0)        {TX1_data[2]|=0x80;        PORTC.2=1;nuflag8=1;}          else        {        TX1_data[2]&=0x7f;        PORTC.2=0;        nuflag8=0;        }        break;  //第8个按键                              case 8:        if(nuflag9==0)        {TX1_data[1]|=0x01;        PORTC.3=1;nuflag9=1;}         else        {        TX1_data[2]&=0xfe;        PORTC.3=0;         nuflag9=0;        }        break;  //第9个按键                              case 9:        if(nuflag10==0)        {TX1_data[1]|=0x02;        PORTC.4=1;nuflag10=1;}        else        {        TX1_data[2]&=0xfd;        PORTC.4=0;        nuflag10=0;        }        break;  //第10个按键                             case 10:        if(nuflag11==0)                  {time=time+1;           PORTC.5=1;nuflag11=1;}         else        {        PORTC.5=0;         nuflag11=0;        }                       break;  //第11个按键                         case 11:        if(nuflag12==0)        {time=time+2;        PORTC.6=1;nuflag12=1;}        else        {        PORTC.6=0;         nuflag12=0;        }        break;  //第12个按键                                 case 12:        if(nuflag13==0)        {time=time+4;        PORTC.7=1;nuflag13=1;}        else        {        PORTC.7=0;        nuflag13=0;        }                                    break;  //第13个按键                               case 13:        if(nuflag14==0)        {time=time+10;         PORTF|=0x01;nuflag14=1;}        else        {        PORTF&=0;        nuflag14=0;        }        break;  //第14个按键                                case 14:         if(nuflag15==0)        {PORTF|=0x02;nuflag15=1;}        else        {        PORTF&=0;        nuflag15=0;        }                break;  //第15个按键                                  case 15:        if(nuflag16==0)        {PORTF|=0x04;nuflag16=1;}        else        {        PORTF&=0xfb;        nuflag16=0;        }        break;  //第16个按键                                 case 16:        if(nuflag17==0)        {PORTA.0=1;nuflag17=1;}        else        {        PORTA.0=0;        nuflag17=0;        }        break;  //第17个按键              }         }void time0_init(void){    TCCR1B = 0x00;//停止定时器    TIMSK |= 0x04;//中断允许    TCNT1H = 0xF4;    TCNT1L = 0x24;//初始值    (设置为0.5秒)    OCR1AH = 0xA3;    OCR1AL = 0xFF;//匹配A值    OCR1BH = 0xA3;    OCR1BL = 0xFF;//匹配B值    ICR1H  = 0xFF;    ICR1L  = 0xFF;//输入捕捉匹配值    TCCR1A = 0x00;                        TCCR1B = 0x04;//启动定时器 }void main(void){    DDRB=0xff;  //定义端口    PORTB=0X00;    DDRD=0x00;    PORTD=0Xff;    DDRE=0xc2;    PORTE=0x3f;    DDRA=0xff;    PORTA=0x00;    DDRC=0xff;    PORTC=0X00;    DDRF|=0x07;    PORTF&=0X08;    USART_Init();    EICRA=0x02;//外部中断0下降沿触发    EIMSK=0x00;//屏蔽外部中断0    EIFR|=0x01;//清除外部中断0标志位    MCUCR=0x02;//下降沿触发    SREG|=0x80;//开启全局中断    delay_ms(200);    #asm("sei")     delay_ms(200);     EIMSK=0x01;        while(1)    {                    if(get==1)            {                Getnum();                  delay_ms(260);            EIFR|=0x01;              //清除中断标记             PORTB=0x00;            get=0;            EIMSK=0x01;                          }                                                              if(PIND.3==0)            {                delay_ms(100);                 if(PIND.3==0)                {                num=16;                action();                }             }                       if(PIND.4==0)           {                    delay_ms(10);                if(PIND.4==0)                {                   send=1;                }           }            if(send==1)                   //  起倒指令           {                      if(time>0)                        {                    time0_init();                     TX1_data_function();                     if(protect==time)                    {                        protect=0;                        TX1_data_function();                        TCCR1B = 0x00;//停止定时器                        send=0;                    }                }                else                               {                    TX1_data_function();                    send=0;                                       }             }    }      }

0 0
原创粉丝点击