kehuadong

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);
	}
}

 

posted on 2023-04-20 10:06  kehuadong  阅读(105)  评论(0编辑  收藏  举报

导航