DSP28335 红外遥控改变LED状态等实现其他功能

发布于:2022-11-15 ⋅ 阅读:(507) ⋅ 点赞:(0)

开发环境ccs6.0版本以上

正点原子stm320 F28335开发板 

红外遥控器: 

 

实现功能:

// 远程遥控系统通过红外遥控器对板载资源进行控制。
//按下“1”时,LED快速闪烁。
//按下“2”时,LED慢速闪烁。
//按下“3”时,蜂鸣器鸣叫。
//按下“4”时,LED呈现呼吸灯效果。
//按下“5”时,数码管从10s开始倒计时一直到0,倒计时完成后,蜂鸣器鸣叫。

首先红外遥控用到了NEC协议大家可以自行了解或者参考正点原子写的原理跟硬件

(134条消息) 单片机:红外遥控实验(内含红外遥控介绍+硬件原理+软件编程+配置环境)_努力成为焦耳定律鸭的博客-CSDN博客_单片机红外遥控icon-default.png?t=M85Bhttps://blog.csdn.net/wo12369874/article/details/125330782?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166847981716800192217540%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166847981716800192217540&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-125330782-null-null.142^v63^js_top,201^v3^add_ask,213^v2^t3_esquery_v1&utm_term=%E7%BA%A2%E5%A4%96%E9%81%A5%E6%8E%A7&spm=1018.2226.3001.4187

 然后本工程中是写了一个NEC函数用来检测是否接受到了信号

Uint32 Read_SIG(void){
   static Uint16 count=0;
   static Uint32 Last=0;
   Uint32 u=0;
   Uint16 j=0;
   Uint16 i=0;
   Uint16 TimeOut=0;
   while(!DATA){
     DELAY_US(5000);
     if(DATA) break;
     TimeOut=2;
     while((!DATA) && TimeOut++); //等待变高,4.5ms高
     if(TimeOut == 1) break;
     DELAY_US(2530);
     if(!DATA){
         if(count >= 3) {count=0;return Last;}
         else  count++;
       }
     for(;i<32;i++){
         TimeOut=2;
         while(DATA && TimeOut++); //等待变低, 0.56ms低
         if(TimeOut == 1) return 0;
         TimeOut=2;
         while((!DATA) && TimeOut++); //等待变高
         if(TimeOut == 1) return 0;
         DELAY_US(840); //延时0.84ms
         u <<= 1;
         if(DATA) u++;
     }
     i = u>>16;
     j=~(i>>8) & 0x00FF;
     i &= 0x00FF;
if(i!= j) return 0;
     j = u;
     i=~(j>>8) & 0x00FF;
     j &= 0x00FF;
if(i!= j) return 0;
   Last = u;
   count=0;
   return u;
   }
   return 0;
}

 同时这个函数放在主函数里面用来实现是否接收到信号且能否解码

 while(1)
    {
      do
      {
         o = Read_SIG();
      }
      while( o == 0);

如果能够完整的接受的一个信号并且符合协议那会有一个返回值给到o,并且跳出这个do..while..语句。

然后逻辑代码用到了swich...case..语句用来判断不同的遥控器按下的放回值

  ReceivedChar= o & 0x00FF;
     ReceivedChar= (o >> 8) & 0x00FF;
     switch(ReceivedChar)
     {
        case 80:  flag=1;break;
        case 216: flag=2;break;
        case 248 : flag=3;break;
        case 48:flag=4;break;
        case 176 : flag=5;break;
        default: break;
     }

然后实现功能都是在定时器中断中实现,当时想过用外部中断并且也试过,外部中断的触发方式的GPIO51==0;也就是当接受到了信号就进入中断,然后在跑一遍Read_SIG(void)函数用来解码,但是可能因为配置或者这个协议的原因导致没有成功,理论上应该试可行的,这样子很多逻辑代码就可以在主函数里面写。但是后面想到了一个更简单的逻辑代码,在定时器中断里面写逻辑代码,主函数里面就只执行判断接受到的编码值并且赋予标志位,从而进入不同的if语句从而实现不同的功能(这些执行代码同样也是在定时器中断里面)附上代码

interrupt void ISRTimer0(void)
{
   // Acknowledge this interrupt to receive more interrupts from group 1
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; //0x0001赋给12组中断ACKnowledge寄存器,对其全部清除,不接受其他中断
    CpuTimer0Regs.TCR.bit.TIF=1;  // 定时到了指定时间,标志位置位,清除标志
    CpuTimer0Regs.TCR.bit.TRB=1;  // 重载Timer0的定时数据
Count++;
if(flag==1&&Count%10==0){
    LED2=~LED2; LED3=~LED3; LED4=~LED4; LED5=~LED5;BUZZ_C  EPwm2Regs.CMPA.half.CMPA =0;EPwm2Regs.CMPB=0;}
if(flag==2 && Count%50==0){
    LED2=~LED2; LED3=~LED3; LED4=~LED4; LED5=~LED5;BUZZ_C  EPwm2Regs.CMPA.half.CMPA =0;EPwm2Regs.CMPB=0;}
if(flag==3){
    BUZZ_O  }
if(flag==4 ){               BUZZ_C
                            EPwm2Regs.CMPA.half.CMPA =0;
                            EPwm2Regs.CMPB=0;
                            if(Count%100==0)
                            i--;
                            SEG_DATA(table[i]);    //右边第一个显示
                            SBIT0=0;DELAY_US(1);
                            SBIT2=1;DELAY_US(1);
                            SBIT1=1;DELAY_US(1);
                            SBIT3=1;
                            DELAY_US(100);
                            SBIT0=1;
                            SEG_DATA(0);
                            if(i==0) {i=10;BUZZ_O BUZZ_O BUZZ_O}
                }
if(flag==5&&Count%20==0){
    if(fx==0)
                     {
                         x=x+10;
                         if(x==400)
                         {
                             fx=1;
                         }
                     }
                     else
                     {
                         x=x-10;
                         if(x==0)
                         {
                             fx=0;
                         }
                     }
                     EPwm2Regs.CMPA.half.CMPA =x;
                     EPwm2Regs.CMPB=x;
}
if(Count==100000) Count=0;
}

定义变量Count;中断是0.01s进一次所以0.01s可进行一次Count的变化,通过不同的Count值来进行不能的操作,比如快闪Count%10==0;即表示每0.1s进行一次操作,同理我们就实现了不同时间进行不同操作 也就是实现LED灯的快闪和慢闪的现象。数码管倒计时就更不用说了,同理的道理。 

这是本人第一次写的csdn,如果有什么地方有问题有错误还希望大家指出,一起进步。


网站公告

今日签到

点亮在社区的每一天
去签到