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

📄 ba1924.c

📁 lc72130.收音机软件 #include "saa6588.c" #include "ba1924.c"
💻 C
字号:
#ifdef SUPPORT_BA1924
#include "global.h"
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include "carcav.h"
#include "ba1924.h"
#include "rds.h"

/*26x10 matrix*/
UINT16  rds_decoding_matrix[26] ={					//H  图F3
	0x0200,0x0100,0x0080,0x0040,
	0x0020,0x0010,0x0008,0x0004,
	0x0002,0x0001,0x02dc,0x016e,
	0x00b7,0x0287,0x039f,0x0313, 
	0x0355,0x0376,0x01bb,0x0201,
	0x03dc,0x01ee,0x00f7,0x02a7,
	0x038f,0x031b,
};
 
#ifdef RDS_ENCODER
/*16*26*/ 
UINT32  rds_encoding_matrix[16] = {					//G,图F1
	0x02000077,0x010002e7,0x008003af,0x0040030b,	
	0x00200359,0x00100370,0x000801b8,0x000400dc,
	0x0002006e,0x00010037,0x000082c7,0x000043bf,
	0x00002303,0x0000135d,0x00000b72,0x000005b9,
};

/*A B C C' D*/
UINT16  rds_offset_word[5] ={0x00fc,0x0198,0x0168,0x0350,0x01b4};//表F1,偏置码
#endif


/*10bits A B C C' D*/
UINT16  rds_syndrome[5]={0x03d8,0x03d4,0x025c,0x03cc,0x0258};//表F1,同步码



typedef  struct  {
	UINT32  rds_buffer;		//32bit 的数据,实际为26bit
	BYTE rds_bit_cnt;		//结构?
	BYTE rds_sync_state;	//同步状态
	BYTE rds_block_id;		//快地址
	BYTE rds_crc_ok;	//校验成功
	UINT16 rds_block_data[4]; //块数据
}rds_var;
rds_var rds_var1;
//volatile BYTE rdsDataReady=0;
extern void rds_process_group(UINT16 a, UINT16 b, UINT16 c, UINT16 d);
unsigned char new_bit_received=0;

#ifdef RDS_ENCODER
void rds_encode(UINT16  data,BYTE block_id)
{
	BYTE i;
	UINT16 check_word = 0;
	UINT32 sent_word = 0;
	
	for(i=0;i<16;i++)
	{
		if(data & (0x01<<i))
		{
			check_word ^= (rds_encoding_matrix[15-i]&0x03ff);
		}
	}
	sent_word = ((data<<10)|(check_word^rds_offset_word[block_id]));
	rds_var1.rds_buffer = sent_word;
	//printf("che %x sent %x\n",check_word,sent_word);
}
#endif

void rds_calculate_crc(void)
{//crc	校验,校验结果通过rds_var1.rds_crc_ok返回
	//同时完成对rds_var1.rds_block_id的判定
	BYTE i=0;
	BYTE j=0;
	UINT16 rds_check_word=0;
	//UINT16 rds_data_word;
	//UINT16 rds_compare = 0;
	UINT32 k=1;
	rds_var1.rds_crc_ok = 0;
	for(i=0;i<26;i++)
	{
		if(rds_var1.rds_buffer & (k<<i))
		{
			rds_check_word^=(rds_decoding_matrix[25-i]);
		}
	}
	for(j=0;j<5;j++)
	{
		if(rds_check_word==rds_syndrome[j])
		{
			rds_var1.rds_crc_ok = 1;
			rds_var1.rds_block_id = j;
			break;
		}
	}
}
/*
  state shift:

  state0-(1)->state1-(2)->state2-(3)->state3-(4)->state4
                |           |        |     
                |------<<(5)|    	
                |-----<<---(6)-------|    


                                          
1--in state 0,init rd_-bit_cnt to 0,and state shift to 1;
2--in state 1,wait the shift buffer to be full;once the buffer is full(>26 bit),
     calculate the syndrome and check it up from the syndrome table.if 
     we get the rds_sync_ok flag,shift state to 2,and store the block data to
     the buffer.
3--in state 1,if we didn't get rds_sync_ok flag(it often happen),we just break,
     and wait for the next bit come in.Then do the same as title 2.
4--in state 2,it is quite similar with state1,we wait for the shift buffer to be full
     and check it up fot rds_sync_ok;if we get the rds_sync_ok flag,store data
     and shift to the next state.if we don't get the rds_sync_ok flag,just wait for
     the next bit until sync ok.
5--in state 3,also similar with the previous state.The different is      
*/
 
void rds_get_data(void)
{
	//ASSERT((rds_var1.rds_sync_state<=4), "rds_get_data");
	switch(rds_var1.rds_sync_state)
		{
		case 0: //reset cnt
			rds_var1.rds_bit_cnt = 0;
			rds_var1.rds_sync_state = 1;
			break;
		case 1: //cnt ==26
			if(rds_var1.rds_bit_cnt>=26)
			{
				rds_calculate_crc();
				if(rds_var1.rds_crc_ok)
				{ 
					if(rds_var1.rds_block_id == 0)
					{
						rds_var1.rds_sync_state = 2;
						rds_var1.rds_bit_cnt = 0;
						rds_var1.rds_block_data[0] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff; 
						//printf("sync 0\n");	
					}		
				} 	

			}	
			break;
		case 2: //next block
			if(rds_var1.rds_bit_cnt >= 26)
			{
				rds_calculate_crc();
				if(rds_var1.rds_crc_ok)
				{
					if(rds_var1.rds_block_id == 1)
					{
						rds_var1.rds_bit_cnt = 0;
						rds_var1.rds_sync_state = 3;
						rds_var1.rds_block_data[1] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
					}
				}
			}
			break;
		case 3:
			if(rds_var1.rds_bit_cnt == 26)
			{
				rds_var1.rds_bit_cnt = 0;
				rds_calculate_crc();
				if(rds_var1.rds_crc_ok)
				{
					if((rds_var1.rds_block_id ==2)||(rds_var1.rds_block_id ==3)) //block C or C'
					{
						rds_var1.rds_sync_state = 4;
						rds_var1.rds_block_data[2] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
					}
					else
					{
						rds_var1.rds_sync_state = 2;
					}
				}
				else
				{
					rds_var1.rds_sync_state = 2;
				} 
			}
			
			break;
		case 4:
			if(rds_var1.rds_bit_cnt == 26)
			{
				rds_var1.rds_bit_cnt = 0;
				rds_calculate_crc();
				if(rds_var1.rds_crc_ok)
				{
					if(rds_var1.rds_block_id ==4) //block D
					{
						//printf("sync 3 id %d\n",rds_var1.rds_block_id);
						rds_var1.rds_block_data[3] = (UINT16)(rds_var1.rds_buffer>>10)&0xffff;
						rds_process_group(rds_var1.rds_block_data[0],rds_var1.rds_block_data[1],rds_var1.rds_block_data[2],rds_var1.rds_block_data[3]);
					}
					else
					{
						rds_var1.rds_sync_state = 2;
					}
				}
				else
				{
					rds_var1.rds_sync_state = 2;
				}
			}
			break;
		default:
			rds_var1.rds_sync_state = 0;
			break;
	}
}

/*
MSB first
return 0:no new bit is get
          1:new bit in
*/
/*
BYTE rds_collect_one_bit(void)
{

	static BYTE prev_state= 0;
	BYTE ret = 0;

	if(PIN_RDS_CLK)
	{
		prev_state = 1;
		
	}
	else
	{
		if(prev_state == 1)
		{

			if(RDS_DATA_SET)	
			{	
				//TUNER_CLK_SET(1);
				rds_var1.rds_buffer<<=1;
				rds_var1.rds_buffer |= 0x00000001;
			}
			else
			{
				//TUNER_CLK_SET(0);
				rds_var1.rds_buffer<<=1;
				rds_var1.rds_buffer &= 0xfffffffe;
			}
			rds_var1.rds_bit_cnt ++; 
			ret = 1;
		}
		prev_state = 0;
	}

	return ret;
} 
*/
/*
void rds_collect_data(void)
{ 
	_delay_us(10);
	if(rds_collect_one_bit())		//调用一次rds_collect_one_bit,判断是否有新的数据收到
	{				//如果收到新的数据,则执行rds_get_data
		rds_get_data();
	}
}
*/

//INTERRUPT(SIG_INTERRUPT1)
SIGNAL(SIG_INTERRUPT1)
{
#ifdef	_DIFFER_ENCODE_
	static BYTE prev_state= 0;
	//sei();
	if(prev_state == 1){
		if (RDS_DATA_SET) {	//差分编码,之前为高现在为高则收到0
			rds_var1.rds_buffer<<=1;
			rds_var1.rds_buffer &= 0xfffffffe;
		}else{					//差分编码,之前为高现在为低则收到1
			rds_var1.rds_buffer<<=1;
			rds_var1.rds_buffer |= 0x00000001;	
			prev_state = 0; 
		}
	}else{
		if (RDS_DATA_SET) {	//差分编码,之前为低现在为高则收到1
			rds_var1.rds_buffer<<=1;
			rds_var1.rds_buffer |= 0x00000001;	
		}else{					//差分编码,之前为低现在为低则收到0
			rds_var1.rds_buffer<<=1;
			rds_var1.rds_buffer &= 0xfffffffe;
			prev_state = 0;
		}
	}
#else
	//sei();
	if (RDS_DATA_SET) {
		rds_var1.rds_buffer<<=1;
		rds_var1.rds_buffer |= 0x00000001;
	}else{
		rds_var1.rds_buffer<<=1;
		rds_var1.rds_buffer &= 0xfffffffe;
	}
#endif
	rds_var1.rds_bit_cnt++;
	rds_get_data(); //CRC
}
#endif

⌨️ 快捷键说明

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