This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

使用外部单片机控制AIC3254EVM评估板的问题

如题,使用STM32单片机开发板控制AIC3254EVM评估板,走I2C总线,只链接了SCL SDA和地线三根线:

首先确认了单片机那边的I2C接口是没有问题的,I2C时序是软件模拟的。AIC3254功能板的WCLK BCLK悬空,MCLK接底板母板。

然后使用PPS生成初始化代码头文件并加入到工程中:

现在的问题是,程序访问AIC3254的各个寄存器都没有问题的,都能正常读写,但是就是【无法听到声音,也就是AIC3254的配置没有完全正确】,这也是我这次发帖求助的原因,请各位看下是哪里配置错了,是硬件问题还是软件问题?

STM32 I2C驱动代码贴出来:


void I2C_Init()
{
I2C_GPIO_CLKEN;
GPIO_Initure.Pin=I2C_SCL_PIN|I2C_SDA_PIN;
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP;
GPIO_Initure.Pull=GPIO_PULLUP;
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(I2C_GPIO,&GPIO_Initure);

I2C_SDA_SET;
I2C_SCL_SET;
}

void IIC_Start()
{
SDA_OUT();
I2C_SDA_SET;
I2C_SCL_SET;
Delay_us(4);
I2C_SDA_CLR;
Delay_us(4);
I2C_SCL_CLR;
}

void IIC_Stop()
{
SDA_OUT();
I2C_SCL_CLR;
I2C_SDA_CLR;
Delay_us(4);
I2C_SCL_SET;
I2C_SDA_SET;
Delay_us(4);
}

unsigned char IIC_Wait_Ack()
{
unsigned char ucErrTime=0;
SDA_IN();
I2C_SDA_SET;
Delay_us(1);
I2C_SCL_SET;
Delay_us(1);
while(I2C_SDA_READ)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
I2C_SCL_CLR;
return 0;
}

void IIC_Ack()
{
I2C_SCL_CLR;
SDA_OUT();
I2C_SDA_CLR;
Delay_us(2);
I2C_SCL_SET;
Delay_us(2);
I2C_SCL_CLR;
}

void IIC_NAck()
{
I2C_SCL_CLR;
SDA_OUT();
I2C_SDA_SET;
Delay_us(2);
I2C_SCL_SET;
Delay_us(2);
I2C_SCL_CLR;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(unsigned char txd)
{
unsigned char t;
SDA_OUT();
I2C_SCL_CLR;
//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
if((txd&0x80)==0x80)
I2C_SDA_SET;
else if((txd&0x80)==0)
I2C_SDA_CLR;
txd<<=1;
Delay_us(2);
I2C_SCL_SET;
Delay_us(2);
I2C_SCL_CLR;
Delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
unsigned char IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();
for(i=0;i<8;i++ )
{
I2C_SCL_CLR;
Delay_us(2);
I2C_SCL_SET;
receive<<=1;
if(I2C_SDA_READ)receive++;
Delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}

unsigned char AIC3254_ReadOneRes(int addr)
{
unsigned char temp=0;
IIC_Start();
IIC_Send_Byte(0x30);
IIC_Wait_Ack();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0x31);
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();
return temp;
}

void AIC3254_WriteOneRes(int addr,unsigned char data)
{
IIC_Start();
IIC_Send_Byte(0x30);
IIC_Wait_Ack();
IIC_Send_Byte(addr);
IIC_Wait_Ack();
IIC_Send_Byte(data);
IIC_Wait_Ack();
IIC_Stop();
//Delay_ms(1);
}

void AIC3254_WriteMultiRes(int addr,unsigned char data[],int size)
{
int i=0;
IIC_Start();
IIC_Send_Byte(0x30);
IIC_Wait_Ack();
for(i=0;i<size;i++)
{
IIC_Send_Byte(data[i]);
IIC_Wait_Ack();
}
IIC_Stop();
Delay_ms(1);
}

void minidsp_get_burst(const reg_value * program_ptr, int program_size, minidsp_parser_data * parse_data)
{
int index = parse_data->current_loc;
int burst_write_count = 0;
/* check if first location is page register, and populate page addr */
if (program_ptr[index].reg_off == 0){
parse_data->page_num = program_ptr[index].reg_val;
parse_data->reg_num = program_ptr[index].reg_off;
parse_data->burst_array[burst_write_count++] = program_ptr[index].reg_val;
index++;
goto finish_out;
}
/* if it’s not page register, store the reg_off and val into array */
parse_data->reg_num = program_ptr[index].reg_off;
parse_data->burst_array[burst_write_count++] = program_ptr[index].reg_val;
index++;
/* check if the reg addr is continue or not */
for (; index < program_size; index++){
if (program_ptr[index].reg_off != (program_ptr[index - 1].reg_off + 1)){
break;
}
else{
parse_data->burst_array[burst_write_count++] = program_ptr[index].reg_val;
}
}
finish_out:
parse_data->burst_size = burst_write_count;
if (index == program_size){
/* parsing completed */
parse_data->current_loc = -1;
}
else{
parse_data->current_loc = index;
}
}


void minidsp_burst_transfer(const reg_value *program_ptr, int program_size)
{
int i;

minidsp_parser_data parse_data;
/* point the current location to start of program array */
parse_data.current_loc = 0;
parse_data.page_num = 0;
parse_data.reg_num = 0;
do {
/* Prepare burst data */
minidsp_get_burst(program_ptr, program_size, &parse_data);
/* Send burst data */
AIC3254_WriteMultiRes(parse_data.reg_num,parse_data.burst_array,parse_data.burst_size);
} while (parse_data.current_loc != -1);
}

void process_flow_download(reg_value *REG_Section, int program_size)
{
static int reg_index = 0;
unsigned char result,page;
for ( ; reg_index < program_size; reg_index++)
{
if (REG_Section[reg_index].reg_off == 254)
{
Delay_ms(REG_Section[reg_index].reg_val);
continue;
}
else if (REG_Section[reg_index].reg_off == 255)
{
if (REG_Section[reg_index].reg_val == 0)
{
// Program_miniDSP_A;
printf("对miniDSP_A编程\n");
minidsp_burst_transfer(miniDSP_A_reg_values, miniDSP_A_reg_values_COEFF_SIZE + miniDSP_A_reg_values_INST_SIZE);
}
if (REG_Section[reg_index].reg_val == 1)
{
// Program_miniDSP_D;
printf("对miniDSP_D编程\n");
minidsp_burst_transfer (miniDSP_D_reg_values, miniDSP_D_reg_values_COEFF_SIZE + miniDSP_D_reg_values_INST_SIZE);
}
continue;
}
else if(REG_Section[reg_index].reg_off==0)
page=REG_Section[reg_index].reg_val;
AIC3254_WriteOneRes(REG_Section[reg_index].reg_off,REG_Section[reg_index].reg_val);
result=AIC3254_ReadOneRes(REG_Section[reg_index].reg_off);
if(result!=REG_Section[reg_index].reg_val)
printf("写入不正确 %d页 %d 0x%x 0x%x\n",page,REG_Section[reg_index].reg_off,REG_Section[reg_index].reg_off,result);
}
}


main函数:
I2C_Init();
process_flow_download(REG_Section_program,sizeof(REG_Section_program)/sizeof(REG_Section_program[0]));

printf("全部写入完成\n");
AIC3254_WriteOneRes(0,0);
//AIC3254_WriteOneRes(1,0x04);
AIC3254_WriteOneRes(81,0xc0);
AIC3254_WriteOneRes(63,0xd4);

//printf("0x%x\n",AIC3254_ReadOneRes(1));
printf("第0页第81个寄存器 ADC通道启动寄存器值:0x%x\n",AIC3254_ReadOneRes(81));
printf("第0页第63个寄存器 DAC通道启动寄存器值:0x%x\n",AIC3254_ReadOneRes(63));

AIC3254_WriteOneRes(0,8);
AIC3254_WriteOneRes(1,0x04);
printf("第8页第1个寄存器 ADC滤波寄存器值:0x%x\n",AIC3254_ReadOneRes(1));

AIC3254_WriteOneRes(0,44);
AIC3254_WriteOneRes(1,0x04);
printf("第8页第1个寄存器 DAC滤波寄存器值:0x%x\n",AIC3254_ReadOneRes(1));

  • 能否用 EVM 正常发声的状态连接单片机, 读出寄存器, 再来与无声做对比
  • 昨天已经修复该问题,STM32单片机可以与EVM评估板正常通信且有声音,修改相应的DSP寄存器也有效果了,经查明,STM32单片机那边必须提供一路PWM方波脉冲给评估板的mclk引脚用,一路5V供电和一路3V供电给评估板用,并且最重要的是,两个板子必须共地。
x 出现错误。请重试或与管理员联系。