📄 sa5753.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 + -