rda7805 rds

Ответить
lsm
Рядовой
Сообщения: 34
Зарегистрирован: 16.12.2018{, 21:58}
Репутация: 0
Имя: serg

rda7805 rds

#1

Сообщение lsm » 14.03.2021{, 18:11}

Помогите из скетча сделать блок для вывода rds текста на екран сейчас там выход на сом порт

#include <Wire.h>

#define RDA5807M_RANDOM_ACCESS_ADDRESS 0x11
// регистры
#define RDA5807M_REG_CONFIG 0x02
#define RDA5807M_REG_TUNING 0x03
#define RDA5807M_REG_VOLUME 0x05
#define RDA5807M_REG_STATUS1 0x0A
#define RDA5807M_REG_STATUS2 0x0B
#define RDA5807M_REG_BLER_CD 0x10
#define RDA5807M_REG_BLOCK_A 0x0C
#define RDA5807M_REG_BLOCK_B 0x0D
#define RDA5807M_REG_BLOCK_C 0x0E
#define RDA5807M_REG_BLOCK_D 0x0F
// флаги
#define RDA5807M_FLG_DHIZ 0x8000
#define RDA5807M_FLG_DMUTE 0x4000
#define RDA5807M_FLG_SEEK 0x0100
#define RDA5807M_FLG_SEEKUP 0x0200
#define RDA5807M_FLG_ENABLE word(0x0001)
#define RDA5807M_FLG_TUNE word(0x0010)
#define RDA5807M_FLG_RDS word(0x0008)
#define RDA5807M_FLAG_RDSR 0x8000
#define RDA5807M_FLAG_STC 0x4000
//маски
#define RDA5807M_CHAN_MASK 0xFFC0
#define RDA5807M_CHAN_SHIFT 6
#define RDA5807M_VOLUME_MASK word(0x000F)
#define RDA5807M_VOLUME_SHIFT 0
#define RDA5807M_BLERA_MASK word(0x000C)
#define RDA5807M_BLERA_SHIFT 2
#define RDA5807M_BLERB_MASK word(0x0003)
#define RDA5807M_BLERC_MASK 0xC000
#define RDA5807M_BLERC_SHIFT 14
#define RDA5807M_BLERD_MASK 0x3000
#define RDA5807M_BLERD_SHIFT 12

//группы RDS
#define RDS_ALL_GROUPTYPE_MASK 0xF000
#define RDS_ALL_GROUPTYPE_SHIFT 12
#define RDS_ALL_GROUPVER 0x800
#define RDS_ALL_TP 0x400
#define RDS_ALL_PTY_MASK 0x3E0
#define RDS_ALL_PTY_SHIFT 5
#define RDS_GROUP0_TA 4
#define RDS_GROUP0_MS 3
#define RDS_GROUP0_DI 2
#define RDS_GROUP0_C1C0_MASK word(0x03)
#define RDS_GROUP4A_MJD15_16_MASK word(0x03)
//#define RDS_GROUP4A_MJD0_14_MASK 0xFFFE
#define RDS_GROUP4A_MJD0_14_SHIFT 1
#define RDS_GROUP4A_HOURS4_MASK word(0x01)
#define RDS_GROUP4A_HOURS0_3_MASK 0xF000
#define RDS_GROUP4A_HOURS0_3_SHIFT 12
#define RDS_GROUP4A_MINUTES_MASK 0x0FC0
#define RDS_GROUP4A_MINUTES_SHIFT 6
#define RDS_GROUP4A_LTO_SIGN_MASK 0x0020
#define RDS_GROUP4A_LTO_MASK 0x001F
#define RDS_GROUP2_ABFLAG_MASK 0x0010
#define RDS_GROUP2_ADDRESS_MASK 0x000F

const char PTy_0[] PROGMEM = "No program type or undefined";
const char PTy_1[] PROGMEM = "News";
const char PTy_2[] PROGMEM = "Current affairs";
const char PTy_3[] PROGMEM = "Information";
const char PTy_4[] PROGMEM = "Sport";
const char PTy_5[] PROGMEM = "Education";
const char PTy_6[] PROGMEM = "Drama";
const char PTy_7[] PROGMEM = "Culture";
const char PTy_8[] PROGMEM = "Science";
const char PTy_9[] PROGMEM = "Varied";
const char PTy_10[] PROGMEM = "Pop music";
const char PTy_11[] PROGMEM = "Rock music";
const char PTy_12[] PROGMEM = "Easy listening";
const char PTy_13[] PROGMEM = "Light classical";
const char PTy_14[] PROGMEM = "Serious classical";
const char PTy_15[] PROGMEM = "Other music";
const char PTy_16[] PROGMEM = "Weather";
const char PTy_17[] PROGMEM = "Finance";
const char PTy_18[] PROGMEM = "Children’s programs";
const char PTy_19[] PROGMEM = "Social affairs";
const char PTy_20[] PROGMEM = "Religion";
const char PTy_21[] PROGMEM = "Phone-in";
const char PTy_22[] PROGMEM = "Travel";
const char PTy_23[] PROGMEM = "Leisure";
const char PTy_24[] PROGMEM = "Jazz music";
const char PTy_25[] PROGMEM = "Country music";
const char PTy_26[] PROGMEM = "National music";
const char PTy_27[] PROGMEM = "Oldies music";
const char PTy_28[] PROGMEM = "Folk music";
const char PTy_29[] PROGMEM = "Documentary";
const char PTy_30[] PROGMEM = "Alarm test";
const char PTy_31[] PROGMEM = "Alarm";

const char* const PTyList[] PROGMEM = {PTy_0, PTy_1, PTy_2, PTy_3, PTy_4, PTy_5, PTy_6, PTy_7,
PTy_8, PTy_9, PTy_10, PTy_11, PTy_12, PTy_13, PTy_14, PTy_15,
PTy_16, PTy_17, PTy_18, PTy_19, PTy_20, PTy_21, PTy_22, PTy_23,
PTy_24, PTy_25, PTy_26, PTy_27, PTy_28, PTy_29, PTy_30, PTy_31};

#define RDSR_CHECK_INTERVAL 30 // Интервал опроса флага RDSR
unsigned long RDSCheckTime = 0; // Предыдущее время опроса RDSR
bool RDSR_prev = false; // Предыдущее значение RDSR
char PSName[9]; // Значение PSName
char PSName_prev[9];
uint8_t PSNameUpdated = 0; // Для отслеживания изменений в PSName
uint16_t ID = 0;
bool ID_printed = false;
uint16_t MaybeThisIDIsReal = 0;
uint8_t IDRepeatCounter = 0;
#define REPEATS_TO_BE_REAL_ID 3
uint8_t PTy = 255;
bool PTy_printed = false;

void setup() {
uint16_t r;
Serial.begin(9600);
Wire.begin();
//Включаем приемник, разрешаем прием RDS, настраиваемся на следующую радиостанцию
setRegister(0x02, RDA5807M_FLG_ENABLE | RDA5807M_FLG_DHIZ | RDA5807M_FLG_DMUTE |
RDA5807M_FLG_SEEK | RDA5807M_FLG_SEEKUP | RDA5807M_FLG_RDS );
memset(PSName, 0, 9);

do // Ждем пока приемник найдет станцию
r = getRegister(RDA5807M_REG_STATUS1);
while (!(r & RDA5807M_FLAG_STC));

setRegister(RDA5807M_REG_VOLUME, 0x86C0); // Убавим громкость

// Покажем текущую частоту
r = getRegister(RDA5807M_REG_TUNING);
Serial.println(87 + double((r & RDA5807M_CHAN_MASK) >> RDA5807M_CHAN_SHIFT) / 10);
}

void loop() {
uint16_t reg0Ah, reg0Bh, reg10h;
uint16_t blockA, blockB, blockC, blockD;
uint8_t errLevelA, errLevelB, errLevelC, errLevelD, groupType;
bool groupVer;
if (millis() - RDSCheckTime >= RDSR_CHECK_INTERVAL) {
// Пора проверить флаг RDSR
RDSCheckTime = millis();
reg0Ah = getRegister(RDA5807M_REG_STATUS1);
if ((reg0Ah & RDA5807M_FLAG_RDSR) and (!RDSR_prev)) { // RDSR изменился с 0 на 1
// Сравним содержимое блока A (ID станции) с предыдущим значением
blockA = getRegister(RDA5807M_REG_BLOCK_A);
if (blockA == MaybeThisIDIsReal) {
if (IDRepeatCounter < REPEATS_TO_BE_REAL_ID) {
IDRepeatCounter++; // Значения совпадают, отразим это в счетчике
if (IDRepeatCounter == REPEATS_TO_BE_REAL_ID)
ID = MaybeThisIDIsReal; // Определились с ID станции
}
}
else {
IDRepeatCounter = 0; // Значения не совпадают, считаем заново
MaybeThisIDIsReal = blockA;
}
if (ID == 0) return; // Пока не определимся с ID, разбирать RDS не будем
if (blockA != ID) return; // ID не совпадает. Пропустим эту RDS группу
// ID станции не скачет, вероятность корректности группы в целом выше
if (!ID_printed) { // Выведем ID
Serial.print("ID: ");
Serial.println(ID, HEX);
ID_printed = true; // Установим флаг чтобы больше не выводить ID
}
reg0Bh = getRegister(RDA5807M_REG_STATUS2);
errLevelB = (reg0Bh & RDA5807M_BLERB_MASK);
if (errLevelB < 3) {
// Блок B корректный, можем определить тип и версию группы
blockB = getRegister(RDA5807M_REG_BLOCK_B);
if (!PTy_printed) { // Но сначала считаем PTy
if (PTy == (blockB & RDS_ALL_PTY_MASK) >> RDS_ALL_PTY_SHIFT) {
// Считаем PTy корректным, выведем его
char *PTy_buffer = (char*) malloc(30);
strcpy_P(PTy_buffer, (char*)pgm_read_word(&(PTyList[PTy])));
Serial.print("PTy: ");
Serial.println(PTy_buffer);
free(PTy_buffer);
PTy_printed = true;
}
else PTy = (blockB & RDS_ALL_PTY_MASK) >> RDS_ALL_PTY_SHIFT;
}
groupType = (blockB & RDS_ALL_GROUPTYPE_MASK) >> RDS_ALL_GROUPTYPE_SHIFT;
groupVer = (blockB & RDS_ALL_GROUPVER) > 0;

reg10h = getRegister(RDA5807M_REG_BLER_CD);
errLevelC = (reg10h & RDA5807M_BLERC_MASK) >> RDA5807M_BLERC_SHIFT;
errLevelD = (reg10h & RDA5807M_BLERD_MASK) >> RDA5807M_BLERD_SHIFT;

// ************* 0A, 0B - PSName, PTY ************
if ((groupType == 0) and (errLevelD < 3)) {
blockD = getRegister(RDA5807M_REG_BLOCK_D);
// Сравним новые символы PSName со старыми:
char c = uint8_t(blockD >> 8); // новый символ
uint8_t i = (blockB & RDS_GROUP0_C1C0_MASK) << 1; // его позиция в PSName
if (PSName != c) { // символы различаются
PSNameUpdated &= !(1 << i); // сбросим флаг в PSNameUpdated
PSName = c;
}
else // символы совпадают, установим флаг в PSNameUpdated:
PSNameUpdated |= 1 << i;
// Аналогично для второго символа
c = uint8_t(blockD & 255);
i++;
if (PSName != c) {
PSNameUpdated &= !(1 << i);
PSName = c;
}
else
PSNameUpdated |= 1 << i;
// Когда все 8 флагов в PSNameUpdated установлены, считаем что PSName получено полностью
if (PSNameUpdated == 255) {
// Дополнительное сравнение с предыдущим значением, чтобы не дублировать в Serial
if (strcmp(PSName, PSName_prev) != 0) {
Serial.print("PSName: ");
Serial.println(PSName);
strcpy(PSName_prev, PSName);
}
}


Буду очень благодарен за помощь!!!

Ответить

Вернуться в «Помогите, а то я "нимагу"»