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

📄 sa5753.c

📁 c8051单片机使用smbus(I2C)接口的测试程序
💻 C
字号:

#include "absacc.h"
#include "intrins.h"
#include "string.h"

#include "hand_serial_all_h.h"
#include "sa5753_h.h"
#include "sa5753_fun_h.h"




#define SMB_CLK_RATE	80000   //时钟频率
#define SMB_CLK_RATE_TIMER	-SYSCLK/SMB_CLK_RATE/2+2

#define 	WRITE	0x00						// SMBus WRITE command
#define		READ 	0x01						// SMBus READ command

// SMBus states:
// MT = Master Transmitter
// MR = Master Receiver
#define	SMB_BUS_ERROR	0x00			// (all modes) BUS ERROR
#define	SMB_START		0x08			// (MT & MR) START transmitted
#define	SMB_MTADDACK	0x18			// (MT) Slave address + W transmitted;
																//  ACK received
#define	SMB_MTADDNACK	0x20			// (MT) Slave address + W transmitted;
																//  NACK received
#define	SMB_MTDBACK		0x28			// (MT) data byte transmitted; ACK rec'vd
#define	SMB_MTDBNACK	0x30			// (MT) data byte transmitted; NACK rec'vd
#define	SMB_MTARBLOST	0x38			// (MT) arbitration lost


bit SM_BUSY;								// This bit is set when a send or receive
												// is started. It is cleared by the
												// ISR when the operation is finished.
bit g_fist_data_flag;   //由于5753数据只有寄存器+数据2个,用单bit判断,如果>2个,用byte判断												
BYTE idata g_chip_address;	//器件地址
BYTE idata g_reg_address;		//寄存器地址
BYTE idata g_reg_data;			//寄存器数据


void SM_Send (BYTE chip_select, BYTE address, BYTE out_byte)
{
	while (SM_BUSY);									// Wait for SMBus to be free.
	SM_BUSY = 1;										// Occupy SMBus (set to busy)
	SMB0CN = 0x44;										// SMBus enabled, ACK on acknowledge cycle

	g_fist_data_flag=1;							//first数据=寄存器地址
	g_chip_address = (chip_select | WRITE);				// 器件地址 + WRITE
	g_reg_address = address;										//寄存器地址
	g_reg_data = out_byte;									// Data to be writen

	STA = 1;												// Start transfer

}

//------------------------------------------------------------------------------------
// Interrupt Service Routine
//------------------------------------------------------------------------------------


// SMBus interrupt service routine:
void SMBUS_ISR (void) interrupt 7 using 2
{
	switch (SMB0STA)				// Status code for the SMBus (SMB0STA register)
	{									
		// Master Transmitter/Receiver: START condition transmitted.  
		// The R/W bit of the COMMAND word sent after this state will 
		// always be a zero (W) because for both read and write, 
		// the memory address must be written first.
		case SMB_START:					
			SMB0DAT = g_chip_address;			//写器件地址
			STA = 0;										// Manually clear START bit
		break;
		
		// Master Transmitter: Slave address + WRITE transmitted.  ACK received. 
		case SMB_MTADDACK:
			SMB0DAT = g_reg_address;				//写寄存器地址
		break;			
		
		// Master Transmitter: Slave address + WRITE transmitted.  NACK received.
		// The slave is not responding.  Send a STOP followed by a START to try again.
		case SMB_MTADDNACK:				//写器件地址后失败
			STO = 1;
			STA = 1;
//			SM_BUSY = 0;
		break;

		case SMB_MTDBACK: //对多个地址或者数据在这里处理,固定为2个数据,用一个bit判断
			if(_testbit_(g_fist_data_flag))
			{
				SMB0DAT = g_reg_data;				// 发送第二个数据
			}
			else   									//发送完成
			{
				STO = 1;
				SM_BUSY = 0;						// Free SMBus
			}
		break;					
		
		// Master Transmitter: Data byte transmitted.  NACK received.
		// Slave not responding.  Send STOP followed by START to try again.
		case SMB_MTDBNACK:				//写寄存器地址后失败
			STO = 1;
			STA = 1;
		break;
		
		// Master Transmitter: Arbitration lost.
		// Should not occur.  If so, restart transfer.
		case SMB_MTARBLOST:				//仲裁失败
			STO = 1;
			STA = 1;
		break;

		// All other status codes meaningless in this application. Reset communication.
		default:
			STO = 1;										// Reset communication.
			SM_BUSY = 0;
		break;
	}
	SI=0;													// clear interrupt flag
}

void smbus_init(void)
{
	SMB0CN = 0x44;									// Enable SMBus with ACKs on acknowledge cycle
	SMB0CR = SMB_CLK_RATE_TIMER;									// SMBus clock rate = 100kHz.

	EIE1 |= 2;										// SMBus interrupt enable

	SM_BUSY = 0;									// Free SMBus for first transfer.
}


//#define NOTE_TIME  75   //1/16音符持续时间,按80/分计算 60s/80 = 750ms = 75 *10

#define NOTE_TIME  100   //1/16音符持续时间,按100/分计算 60s/100 = 1000ms = 100 *10


BYTE xdata g_R0_data;
BYTE xdata g_R1_data;
BYTE xdata g_R2_data;
BYTE xdata g_R3_data;
BYTE xdata g_R4_data;
BYTE xdata g_R5_data;
BYTE xdata g_R6_data;
BYTE xdata g_R7_data;
BYTE xdata g_R8_data;

/*
ST5753高音值(HD)=1.2M(I2C时钟)/6/频率 范围(778.21Hz to 66.66kHz)
ST5753低音值(LD)=1.2M(I2C时钟)/14/频率  范围(333.52Hz to 28.57kHz)
因为频率范围不满足音调频率,用高8度频率

音调 频率(Hz)  高8度频率	高高8度(HD产生)	数组索引  ST5753低音值(FD)  ST5753高音值(HD)
1      262   *2  	524		*2 		  						 1         163   0xa3        190     
2      294     		588			 		  						 2         145   0x91        170     
3      330      	660			 		  						 3         130   0x82        151     
4      349      	698			 		  						 4         123   0x7b        143     
5      392      	784			 		  						 5         109   0x6d        127     
6      440      	880			 		  						 6          97   0x61        113     
7      494      	998			 		  						 7          86   0x56        100     
1^     523      	1046		 		  						 8          81   0x51        95     
2^                1176     		    				   9          72   0x48        85                           																								
3^                1320     		    				   a          65   0x41        75                           																								
4^                1396     		    				   b          61   0x3d        71                           																								
5^                1568     		    				   c          54   0x36        63                           																								
5_                392      		    				   d          218  0xda        255                          																								
6_                440      		    				   e          194  0xc2        227                          																								
7_                494      		    				   f          173  0xad        202                          																								
        关       	关			 		  						 0           2   0x02        2   0x02   
*/                                            

//定义低音值索引表
BYTE code DTMF_LD_TABLE[16]=
{
	0x02,0xa3,0x91,0x82,0x7b,0x6d,0x61,0x56,
	0x51,0x48,0x41,0x3d,0x36,0xda,0xc2,0xad,
};
//定义高音值索引表
BYTE code DTMF_HD_TABLE[16]=
{
	2, 190,170,151,143,127,113,100,
	95,85, 75, 71, 63, 255,227,202,
};

type_of_timer m_music_delay_timer;
BYTE idata m_music_play_index=0; 
bit m_music_space_flag; //两个音节之间的间隔标志

//#define MUSIC_CONSTANT_LEN 9
//BYTE xdata m_music_constant[]={0x14,0x24,0x34,0x44,0x54,0x64,0x74,0x84,0x04};

/*
//两只老虎
#define MUSIC_CONSTANT_LEN 32
BYTE xdata m_music_constant[]=
{
	0x14,0x24,0x34,0x14,0x14,0x24,0x34,0x14,
	0x34,0x44,0x58,0x34,0x44,0x58,0x53,0x61,
	0x52,0x42,0x34,0x14,0x53,0x61,0x52,0x42,
	0x34,0x14,0x14,0xd4,0x18,0x14,0xd4,0x18,
};
*/
//玛丽的小羊
#define MUSIC_CONSTANT_LEN 25
BYTE xdata m_music_constant[]=
{
	0x34,0x24,0x14,0x24,0x34,0x34,0x38,
	0x24,0x24,0x28,     0x34,0x54,0x58,
	0x34,0x24,0x14,0x24,0x34,0x34,0x38,
	0x24,0x24,0x34,0x24,0x1c,
};


void sa5753_test_DTMF()
{
	BYTE idata l_5753_reg_addr;
	
	l_5753_reg_addr=R6_5753;
	b_5753_reg_data=g_R6_data;
	PWDN = 0;
	IDLE1 = 0;
	IDLE0 = 0;
	g_R6_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //normal工作模式
	
	l_5753_reg_addr=R2_5753;
	b_5753_reg_data=g_R2_data;
	b_5753_reg_data = 0x02;
	g_R2_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //关闭 high单音

	l_5753_reg_addr=R3_5753;
	b_5753_reg_data=g_R3_data;
	b_5753_reg_data = 0x02;
	g_R3_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //low单音
	
	l_5753_reg_addr=R1_5753;
	b_5753_reg_data=g_R1_data;
	DTC = 1; //连续单音
	S4 = 1;  //开关
	S8 = 1;
	g_R1_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //开通路S4,S8,连续单音
	
	l_5753_reg_addr=R8_5753;
	b_5753_reg_data=g_R8_data;
	S3 = 1;
	S11 = 1;
	TxP = 1; //tx_mute 选项1,和外部18脚一样
	g_R8_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //

	l_5753_reg_addr=R0_5753;
	b_5753_reg_data=g_R0_data;
	S9 =1;
	S10  = 1;
	TxM = 0;
	g_R0_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //
	
	l_5753_reg_addr=R5_5753;
	b_5753_reg_data=g_R5_data;
	b_5753_reg_data=0x13;
	g_R5_data=b_5753_reg_data;	
	SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //控制attn6的增益,开HPDN,VOX
}

void sa5753_change_DTMF(BYTE l_index)
{
	BYTE idata l_5753_reg_addr;
	
	if(l_index<=16)
	{	
		l_5753_reg_addr=R3_5753;
		b_5753_reg_data=g_R3_data;
		b_5753_reg_data = DTMF_LD_TABLE[l_index];
		g_R3_data=b_5753_reg_data;	
		SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //low单音
		
		
		l_5753_reg_addr=R2_5753;
		b_5753_reg_data=g_R2_data;
		b_5753_reg_data = DTMF_HD_TABLE[l_index];
		g_R2_data=b_5753_reg_data;	
		SM_Send(SA5753_ADDR,l_5753_reg_addr,b_5753_reg_data); //high单音

	}
}

void sa5753_init(void)
{
	init_timer(&m_music_delay_timer);
	sa5753_test_DTMF();
	m_music_play_index=0; 
} 

void sa5753_start_music(void)
{
	m_music_play_index=0;
	opentimer(&m_music_delay_timer,50);
	m_music_space_flag=0;
}

void sa5753_stop_music(void)
{
	m_music_play_index=0;
	closetimer(&m_music_delay_timer);
	sa5753_change_DTMF(0);
}

void sa5753_play_music_proc(void)
{
	if(m_music_delay_timer.timer_off)
	{
//		closetimer(&m_music_delay_timer);
		if(_testbit_(m_music_space_flag))
		{
			sa5753_change_DTMF(0);
			opentimer(&m_music_delay_timer,5);
		}
		else
		{
			m_music_space_flag=1;
			sa5753_change_DTMF(m_music_constant[m_music_play_index]>>4);
			opentimer(&m_music_delay_timer,(m_music_constant[m_music_play_index]&0x0f)*NOTE_TIME);
			m_music_play_index++;
			if(m_music_play_index>=MUSIC_CONSTANT_LEN)
				m_music_play_index=0;
		}
	}
}

⌨️ 快捷键说明

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