⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 用ATMEL 的 AVR MEGA168做RDS解码程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
        
      //reset decoder
      if (usart0RxDByte == 'r') {
        wdt_enable(WDTO_15MS);
        for(;;) {};
      }
        
      //switch group display on (B) or off (b)
      if (usart0RxDByte == 'B')
        displayBitstream = 0;
      else if (usart0RxDByte == 'b')
        displayBitstream = 1;
        
    } else {
      sei();
    }
    
    //we have got 26 bits raw rds data
    cli();
    if (event & eventBitstreamSnapshot) {
      event &= ~eventBitstreamSnapshot;
      sei();
      
      if (displayBitstream) {
        printf_P(PSTR("B: 0x%07lX\r\n"), bitstreamData);
      }
    } else {
      sei();
    }
    
    cli();
    if (event & eventTimerOverflow) {
      event &= ~eventTimerOverflow;
      sei();
      
      /* no rds signal message */
      if (syncQuality == 0 && syncMessage < 12) {
        syncMessage++;
        if (syncMessage == 12) {
          printf_P(PSTR("INFO: 0x02, No RDS signal.\r\n"));
          programmeIdentificationCode = 0;
        }
      }
          
      if (syncQuality > 0)
          syncMessage = 0;
          
      if (PORTC & _BV(PC0))
        PORTC &= ~_BV(PC0); //heartbeat led off
      else
        PORTC |= _BV(PC0); //heartbeat led on
      
    } else {
      sei();
    }
    
    //reset vars when sync lost. Warning, sync lost happens 26 times as many as groupcomlete, do not do anything lenghty here
    cli();
    if (event & eventSyncLost) {
      event &= ~eventSyncLost;
      sei();
      group0CodeBitsSteadyCount = 5;
    } else {
      sei();
    }
    
    cli();
    if (event & eventGroupComplete) {
        event &= ~eventGroupComplete;
        sei();
        
      //Group type code
      groupType = block2 / 0x1000; //bits 12-15 (2^12)
      
      //Group version code
      if (block2 & _BV(11))
        groupVersion = 'B';
      else
        groupVersion = 'A';
      
      if (displayRaw)
        printf_P(PSTR("GROUP%02u%c: 0x%04X 0x%04X 0x%04X 0x%04X\r\n"), groupType, groupVersion, block1, block2, block3, block4);
      
      //PI Codes of block 3 B-version groups are not decoded.
      
      //Programme Identification code
      if (programmeIdentificationCode != block1) {
        displayInfo();
        programmeIdentificationCode = block1;
        printf_P(PSTR("PI: 0x%04X, Detected new station.\r\n"), programmeIdentificationCode);
        
        /* reset variables because PI code changed */
        trafficProgrammeIdentificationCode = 0xFF;
        programmeTypeCode = 0xFF;
        trafficAnnouncementCode = 0xFF;
        musicSpeechSwitchScode = 0xFF;
  
        group0CodeBitsSteadyCount = 0;
        for(i = 0; i < sizeof(programmeServiceName); i++)
          programmeServiceName[i] = 0xFF;
          
        decoderIdentificationControlCode = 0xFF;        
        for(i = 0; i < sizeof(alternativeFrequencyCodes); i++)
          alternativeFrequencyCodes[i] = 0;
          
        linkageActuator = 0xFF;
        
        extendedCountryCode = 0;
        
        for(i = 0; i < sizeof(radioText); i++) {
          radioText[i] = 0;
          radioTextPrevious[i] = 0;
        }
        
        textSegmentAddress0Seen = 0;
          
        textVersionPrevious = 0;        textSegmentAddressPrevious = 0;
        
        utcMinutesPrevious = 0xFF;
        
      }
  
      //Programme Type code
      if (programmeTypeCode != ((block2 / 0x20) & 0x1F)) {
        programmeTypeCode = ((block2 / 0x20) & 0x1F); //bits 5-9 (2^5)
        printf_P(PSTR("PTY: 0x%02X, "), programmeTypeCode);
        switch(programmeTypeCode) {
          case 0:
            printf_P(PSTR("None."));
            break;
          case 1:
            printf_P(PSTR("News."));
            break;
          case 2:
            printf_P(PSTR("Current Affairs."));
            break;
          case 3:
            printf_P(PSTR("Information."));
            break;
          case 4:
            printf_P(PSTR("Sport."));
            break;
          case 5:
            printf_P(PSTR("Education."));
            break;
          case 6:
            printf_P(PSTR("Drama."));
            break;
          case 7:
            printf_P(PSTR("Cultures."));
            break;
          case 8:
            printf_P(PSTR("Science."));
            break;
          case 9:
            printf_P(PSTR("Varied Speech."));
            break;
          case 10:
            printf_P(PSTR("Pop Music."));
            break;
          case 11:
            printf_P(PSTR("Rock Music."));
            break;
          case 12:
            printf_P(PSTR("Easy Listening."));
            break;
          case 13:
            printf_P(PSTR("Light Classics."));
            break;
          case 14:
            printf_P(PSTR("Serious Classics."));
            break;
          case 15:
            printf_P(PSTR("Other Music."));
            break;
          case 16:
            printf_P(PSTR("Weather."));
            break;
          case 17:
            printf_P(PSTR("Finance."));
            break;
          case 18:
            printf_P(PSTR("Children."));
            break;
          case 19:
            printf_P(PSTR("Social Affairs."));
            break;
          case 20:
            printf_P(PSTR("Religion."));
            break;
          case 21:
            printf_P(PSTR("Phone In."));
            break;
          case 22:
            printf_P(PSTR("Travel & Touring."));
            break;
          case 23:
            printf_P(PSTR("Leisure & Hobby."));
            break;
          case 24:
            printf_P(PSTR("Jazz Music."));
            break;
          case 25:
            printf_P(PSTR("Country Music."));
            break;
          case 26:
            printf_P(PSTR("National Music."));
            break;
          case 27:
            printf_P(PSTR("Oldies Music."));
            break;
          case 28:
            printf_P(PSTR("Folk Music."));
            break;
          case 29:
            printf_P(PSTR("Documentary."));
            break;
          case 30:
            printf_P(PSTR("Alarm Test."));
            break;
          case 31:
            printf_P(PSTR("Alarm - Alarm !"));
            break;
          default:
            printf_P(PSTR("Unknown."));
            break;
        }
        printf_P(PSTR("\r\n"));
      }
  
      //Type 0 groups: Basic tuning and switching information
      if (groupType == 0) {
      
        //Traffic Programme Identification code
        //Traffic announcement code
        if (trafficAnnouncementCode != ((block2 / 0x10) & 0x01) ||
            trafficProgrammeIdentificationCode != (block2 & _BV(10)) / 0x400) {
          
          trafficAnnouncementCode = (block2 / 0x10) & 0x01; //bit 4 (2^4)
          trafficProgrammeIdentificationCode = (block2 & _BV(10)) / 0x400; //bit 10
          
          printf_P(PSTR("TP&TA: 0x%02X 0x%02X, "), trafficProgrammeIdentificationCode, trafficAnnouncementCode);

          if (trafficProgrammeIdentificationCode == 0) {
          
            if (trafficAnnouncementCode == 0) {
              printf_P(PSTR("No traffic announcements available."));
            } else {
              printf_P(PSTR("Traffic announcements available via EON on another station."));
            }
          
          } else {
          
            if (trafficAnnouncementCode == 0) {
              printf_P(PSTR("Traffic announcements available on this station and maybe via EON on another station."));
            } else {
              printf_P(PSTR("Traffic announcement in progress."));
            }
            
          }
          
          printf_P(PSTR("\r\n"));
          
        }
      
        //Music Speech switch code
        if (musicSpeechSwitchScode != ((block2 / 0x08) & 0x01)) {
          musicSpeechSwitchScode = (block2 / 0x08) & 0x01;  //bit 3 (2^3)
          printf_P(PSTR("MS: 0x%02X, "), musicSpeechSwitchScode);

          if (musicSpeechSwitchScode) 
            printf_P(PSTR("Music is being broadcasted or station does not use MS flag."));
          else
            printf_P(PSTR("Speech is being broadcasted."));
          printf_P(PSTR("\r\n"));
        }
        
        //Decode program service name and decoder identification control code
        group0CodeBits = block2 & 0x03; //0, 1, 2, 3;
        
        
        //TODO: improve decoderIdentificationControlCode detection, decouple from PS name
        //Decoder-identification control code-bit is bit 3 in block2
        if (group0CodeBits == 0) {
          if (block2 & 0x04)
            decoderIdentificationControlCodeNew |= _BV(3);
          else 
            decoderIdentificationControlCodeNew &= ~_BV(3);
        }
        if (group0CodeBits == 1) {
          if (block2 & 0x04)
            decoderIdentificationControlCodeNew |= _BV(2);
          else 
            decoderIdentificationControlCodeNew &= ~_BV(2);
        }
        if (group0CodeBits == 2) {
          if (block2 & 0x04)
            decoderIdentificationControlCodeNew |= _BV(1);
          else 
            decoderIdentificationControlCodeNew &= ~_BV(1);
        }
        if (group0CodeBits == 3) {
          if (block2 & 0x04)
            decoderIdentificationControlCodeNew |= _BV(0);
          else 
            decoderIdentificationControlCodeNew &= ~_BV(0);
        }
  
        //fill in information
        i = group0CodeBits * 2;
        programmeServiceNameNew[i] = block4 / 0xFF; //bits 8-16 (2^8)
        programmeServiceNameNew[i + 1] = block4; //bit 0-8
        
        if (programmeServiceNameNew[i] != programmeServiceName[i] ||
            programmeServiceNameNew[i + 1] != programmeServiceName[i + 1]) {
          //detected change, reset counter if not already counting
          if (group0CodeBitsSteadyCount > 4)
                group0CodeBitsSteadyCount = 0;
        }
        
        //increase counter only when there are less then 4 received words
        if (group0CodeBitsSteadyCount < 4)
          group0CodeBitsSteadyCount++;
        
        programmeServiceName[i] = programmeServiceNameNew[i];
        programmeServiceName[i + 1] = programmeServiceNameNew[i + 1];
        
        //when we detected 4 new PS words then display it
        if (group0CodeBitsSteadyCount == 4) {
          printf_P(PSTR("PS: "));
          for(i = 0; i < sizeof(programmeServiceName); i++) {
            printf_P(PSTR("%c"), programmeServiceName[i]);
          }
          printf_P(PSTR("\r\n"));
          //prevent redisplay
          group0CodeBitsSteadyCount++;
          
          if (decoderIdentificationControlCode != decoderIdentificationControlCodeNew) {
            decoderIdentificationControlCode = decoderIdentificationControlCodeNew;
            printf_P(PSTR("DI: 0x%02X"), decoderIdentificationControlCode);
            
            if (decoderIdentificationControlCode & 0b0001)
              printf_P(PSTR(", Stereo"));
            else
              printf_P(PSTR(", Mono"));
              
            if (decoderIdentificationControlCode & 0b0010)
              printf_P(PSTR(", Artificial Head"));
              
            if (decoderIdentificationControlCode & 0b0100)
              printf_P(PSTR(", Compressed"));
              
            if (decoderIdentificationControlCode & 0b1000)
              printf_P(PSTR(", Static PTY"));
            else
              printf_P(PSTR(", Dynamic PTY"));
              
            printf_P(PSTR(".\r\n"));
          }
        }
        
  
        if (groupVersion == 'A') {
        
          //Alternative frequency codes
          for (h = 0; h < 2; h++) {
            if (h == 0)
              j = block3; //first AF is in bits 0-7 of block3
            else
              j = block3 / 256; //second bits 8-15
              
            //only frequencies we want, no control codes

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -