RDS相关信息
RDS相关概念
- PS (program service)---提供8个字符的电台名称显示
- PTY (program type)---提供电台节目类型显示
- TP (traffic program)---提供电台是否为交通电台(不一定在播放交通信息)
- TA (traffic announcement)---提供电台是否正在播放交通指示信息
- AF (alternative frequencies) ---提供某个电台的替换发射频率表
- PI (program identification)---提供电台识别码
- EON (enhanced other network)---提供其它电台的信息,如PS,TA。
- RT (radio text)---提供最多64个字符的广播文本显示信息
每个RDS信息由4个16位Block组成,分别是BlockA, BlockB, BlockC, blockD
- BlockA: PI 电台ID
- BlockB:
- b5~b9: PTY 节目类型
- b11: 版本 0: VERSION_A, 1: VERSION_B
- b12~b15: 分组类型
- 分组0, VERSION_B时: (b0~1) * 2 是PS字符索引idx, BlockD 高低两字节分别是PS[idx], PS[idx+1]的内容
- 分组2, VERSION_A时: (b0~3) * 4 是RT字符索引idx BlockC, BlockD高低两字节分别是RT[idx], RT[idx+1], RT[idx+2], RT[idx+3]
- 分组2, VERSION_A时: b5 是 abFlag
- BlockC:
- 如果是VERSION_B, BlockC也是PI,也就是说BlockA == BlockC, 我们始终使用BlockA就可以了
// 接收到RDS中断后进行处理(或者90ms定时调用)
void _RDS_Update() {
#if !(SUPPORT_RADIO)
return;
#endif
Si475x6x_Rds& rds = Si475x6x.Rds;
_RDS_FmRdsStatus(1, 0);
while (rds.RdsFifoUsed) {
if (rds.BlockErrorB > _BLOCK_B_ERROR_MAX) {
_RDS_FmRdsStatus(1, 0);
continue;
}
// PI = BlockA, 如果groupVersion=B, PI = BlockA = BlockC
// IDX = (BlockB&0x03)*2(分组0,PS) 或者 (BlockB&0x0F)*4(分组2,版本A, RT) 或者 (BlockB&0x0F)*2(分组2,版本B, RT)
// (BlockB&0x03)*2(分组0,PS)时, BlockD高低字节分别代表PS[IDX], PS[IDX+1]两个字符
// (BlockB&0x0F)*4(分组2,版本A, RT), BlockC, BlockD高低字节分别代表RT[IDX], RT[IDX+1], RT[IDX+2], RT[IDX+3]四个字符
// (BlockB&0x0F)*2(分组2,版本B, RT), BlockD高低字节分别代表RT[IDX], RT[IDX+1]两个字符
// TA = BlockB>>4&0x01
// PTY = BlockB>>5&0x1F
// TP = BlockB>>10&0x01
// 分组版本和分组类型
uint8_t groupVersion = rds.BlockB>>11&0x01; // 0:版本A, 1:版本B
uint8_t groupType = rds.BlockB>>12&0x0F;
switch (groupType) {
case 0: // 分组0
rds.F_TA = (rds.BlockB>>4)&0x01;
RadioService_RDS_OnTA(rds.F_TA);
printf(">>>>>>>>> RDS F_TA = %d\n", rds.F_TA);
// 电台名称 (版本A,B都有电台名称)
if (rds.BlockErrorD <= _BLOCK_D_ERROR_MAX) {
uint8_t index = (rds.BlockB & 0x3) * 2;
_RDS_UpdatePS(index, rds.BlockD>>8);
_RDS_UpdatePS(index+1, rds.BlockD);
// 打印PS
if (rds.PS_Mask == 0xFF) {
char buffer[9];
memcpy(buffer, rds.PS, 8);
buffer[8] = 0;
printf(">>>>>>>>> RDS PS = %s\n", buffer);
RadioService_RDS_OnPS(buffer);
} else {
printf(">>>>>>>>> RDS PS = \n");
RadioService_RDS_OnPS("");
}
} else {
printf("rds.BlockErrorD > %d\n", _BLOCK_D_ERROR_MAX);
}
// 可选的频率列表
if (groupVersion == 0) { // 版本A才有可选的频率列表
if (rds.BlockErrorC <= _BLOCK_C_ERROR_MAX) {
_RDS_UpdateAF_List(rds.BlockC>>8);
_RDS_UpdateAF_List(rds.BlockC);
// 打印AF_List
printf(">>>>>>>>> RDS AF_List [");
for (int i = 0; i < rds.AF_CurrentCnt; i++) {
if (i) {
printf(", ");
}
printf("%d", rds.AF_List[i]);
}
printf("]\n");
} else {
printf("rds.BlockErrorC > %d\n", _BLOCK_C_ERROR_MAX);
}
}
break;
case 2: { // 分组2
uint8_t abFlag = rds.BlockB>>4&0x01;
if (rds.RT_AbFlag != abFlag) {
rds.RT_AbFlag = abFlag;
rds.RT_Size = 0;
}
if (groupVersion == 0) { // 版本A,长度为4
uint8_t index = (rds.BlockB & 0xF) * 4;
if (rds.BlockErrorC <= _BLOCK_C_ERROR_MAX) {
_RDS_UpdateRT(index, rds.BlockC>>8);
_RDS_UpdateRT(index+1, rds.BlockC);
} else {
}
if (rds.BlockErrorD <= _BLOCK_D_ERROR_MAX) {
_RDS_UpdateRT(index+2, rds.BlockD>>8);
_RDS_UpdateRT(index+3, rds.BlockD);
} else {
}
} else { // 版本B,长度为2
uint8_t index = (rds.BlockB & 0xF) * 2;
if (rds.BlockErrorD <= _BLOCK_D_ERROR_MAX) {
_RDS_UpdateRT(index, rds.BlockD>>8);
_RDS_UpdateRT(index+1, rds.BlockD);
}
}
// 打印RT
if (rds.RT_Size) {
char buffer[65];
memcpy(buffer, rds.PS, rds.RT_Size);
buffer[rds.RT_Size] = 0;
printf(">>>>>>>>> RDS RT = %s\n", buffer);
RadioService_RDS_OnRT(buffer);
} else {
printf(">>>>>>>>> RDS RT = \n");
RadioService_RDS_OnRT("");
}
break;
}
case 4:
if (groupVersion == 0) { // 版本A
_RDS_UpdateClock();
}
break;
default:
break;
}
// Get the RDS status from the part.
_RDS_FmRdsStatus(1, 0);
}
}