搜索
bottom↓
回复: 5

用radio 录音,保存成wav 是否可行

[复制链接]

出0入0汤圆

发表于 2011-5-26 18:28:08 | 显示全部楼层 |阅读模式
用radio硬件录音,保存成wav 是否可行

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2011-5-26 21:45:01 | 显示全部楼层
STM32的IIS只支持半双工.因此无法同时放音和录音.
且RADIO板上面用的WM8978的数据输出不支持设置为三态,因此RADIO的配件并不支持录音.
不过V3的CODEC模块可以单独拆卸.CODEC模块是可以支持线路/MIC输入的.可以接全双工的IIS主机以实现录音.

出0入0汤圆

 楼主| 发表于 2011-5-28 08:44:34 | 显示全部楼层
请教楼上wm8978 录音电路看看是否可行

想实现的录音部分电路 (原文件名:是否能实现录音.jpg)

出0入0汤圆

 楼主| 发表于 2011-5-29 00:00:05 | 显示全部楼层
又看看资料,上图只能是放音状态,不能录音,因为stm32的i2s是不支持双工的,如果要输入,要把第9脚引出来用模拟开关和第十脚切换,放音时切到10脚,录音切到9脚,这样实现半双工。

还有疑问:用收音机里面的程序初始化后,通过spi3 往wm8978写随机数据,想听听杂音,就是写不进去数据,。

我的初始化函数:
static void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Disable the JTAG interface and enable the SWJ interface */
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

    /* PC5 CODEC CS */
    GPIO_InitStructure.GPIO_Pin = CODEC_CSB_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(CODEC_CSB_PORT, &GPIO_InitStructure);

    // WS
    GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
#if CODEC_MASTER_MODE
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
#else
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
#endif
    GPIO_Init(CODEC_I2S_WS_PORT, &GPIO_InitStructure);

    // CK
    GPIO_InitStructure.GPIO_Pin = CODEC_I2S_CK_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
#if CODEC_MASTER_MODE
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
#else
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
#endif
    GPIO_Init(CODEC_I2S_CK_PORT, &GPIO_InitStructure);

    // SD
    GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SD_PIN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(CODEC_I2S_SD_PORT, &GPIO_InitStructure);

#ifdef CODEC_USE_MCO
    /*    MCO    configure */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);

    RCC_MCOConfig(RCC_MCO_HSE);
#endif
}


static void I2S_Configuration(uint32_t I2S_AudioFreq)
{
    I2S_InitTypeDef I2S_InitStructure;

    /* I2S peripheral configuration */
    I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
    I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq;
    I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;

    /* I2S2 configuration */
#if CODEC_MASTER_MODE
    I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
#else
    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
#endif
    I2S_Init(CODEC_I2S_PORT, &I2S_InitStructure);
}


uint8_t SPI3_WriteByte(unsigned char data)
{
    //Wait until the transmit buffer is empty
    while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);
    // Send the byte
    SPI_I2S_SendData(SPI3, data);

    //Wait until a data is received
//    while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
//    // Get the received data
//    data = SPI_I2S_ReceiveData(SPI3);

    // Return the shifted data
    return data;
}

void spi1_configration(void)
{
                GPIO_InitTypeDef GPIO_InitStructure;
        SPI_InitTypeDef SPI_InitStructure;

        /* Enable SPI1 Periph clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
                               | RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1,
                               ENABLE);
        /* Configure SPI1 pins: PA5-SCK, PA6-MISO and PA7-MOSI */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        /*------------------------ SPI1 configuration ------------------------*/
        SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx;
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
        SPI_InitStructure.SPI_NSS  = SPI_NSS_Soft;
        SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;/* 72M/64=1.125M */
        SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_CRCPolynomial = 7;

        SPI_I2S_DeInit(SPI1);
        SPI_Init(SPI1, &SPI_InitStructure);

        /* Enable SPI_MASTER */
        SPI_Cmd(SPI1, ENABLE);
        SPI_CalculateCRC(SPI1, DISABLE);
}

uint8_t SPI1_WriteByte(unsigned char data)
{
    //Wait until the transmit buffer is empty
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    // Send the byte
    SPI_I2S_SendData(SPI1, data);

    //Wait until a data is received
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    // Get the received data
    data = SPI_I2S_ReceiveData(SPI1);

    // Return the shifted data
    return data;
}

static void codec_send(rt_uint16_t s_data)
{
//    rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
    /* SPI1 configure */
//   rt_hw_spi2_baud_rate(SPI_BaudRatePrescaler_64);/* 72M/64=1.125M */
        SPI1->CR1 &= ~SPI_BaudRatePrescaler_256;
        SPI1->CR1 |= SPI_BaudRatePrescaler_64;

    codec_reset_csb();
    SPI1_WriteByte((s_data >> 8) & 0xFF);
    SPI1_WriteByte(s_data & 0xFF);
    codec_set_csb();

//   rt_sem_release(&spi1_lock);
}

static rt_err_t codec_init(rt_device_t dev)
{
        spi1_configration();
    codec_send(REG_SOFTWARE_RESET);

    // 1.5x boost power up sequence.
    // Mute all outputs.
//    codec_send(REG_LOUT1_VOL | LOUT1MUTE);
//    codec_send(REG_ROUT1_VOL | ROUT1MUTE);
//    codec_send(REG_LOUT2_VOL | LOUT2MUTE);
//    codec_send(REG_ROUT2_VOL | ROUT2MUTE);
    // Enable unused output chosen from L/ROUT2, OUT3 or OUT4.
    codec_send(REG_POWER_MANAGEMENT3 | OUT4EN);
    // Set BUFDCOPEN=1 and BUFIOEN=1 in register R1
    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN);
    // Set SPKBOOST=1 in register R49.
    codec_send(REG_OUTPUT | SPKBOOST);
    // Set VMIDSEL[1:0] to required value in register R1.
    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
    // Set L/RMIXEN=1 and DACENL/R=1 in register R3.
    codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR);
    // Set BIASEN=1 in register R1.
    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN);
    // Set L/ROUT2EN=1 in register R3.
    codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR | LOUT2EN | ROUT2EN);
    // Enable other mixers as required.
    // Enable other outputs as required.
    codec_send(REG_POWER_MANAGEMENT2 | LOUT1EN | ROUT1EN | BOOSTENL | BOOSTENR | INPPGAENL | INPPGAENR);

    // Digital inferface setup.
    codec_send(REG_AUDIO_INTERFACE | BCP_NORMAL | LRP_NORMAL | WL_16BITS | FMT_I2S);

    // PLL setup.
    // fs = 44.1KHz * 256fs = 11.2896MHz
    // F_PLL = 11.2896MHz * 4 * 2 = 90.3168MHz
    // R = 90.3168MHz / 12.288MHz = 7.35
    // PLL_N = 7
    // PLL_K = 0x59999A (0x5A5A5A for STM32's 44.117KHz fs generated from 72MHz clock)
    codec_send(REG_PLL_N | 7);
#if CODEC_MASTER_MODE
    codec_send(REG_PLL_K1 | 0x16);
    codec_send(REG_PLL_K2 | 0xCC);
    codec_send(REG_PLL_K3 | 0x19A);
#else
    codec_send(REG_PLL_K1 | 0x16);
    codec_send(REG_PLL_K2 | 0x12D);
    codec_send(REG_PLL_K3 | 0x5A);
#endif
    codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN | PLLEN);
    codec_send(r06);

    // Enable DAC 128x oversampling.
    codec_send(REG_DAC | DACOSR128);

    // Set LOUT2/ROUT2 in BTL operation.
    codec_send(REG_BEEP | INVROUT2);

    // Set output volume.
    vol(25);

    return RT_EOK;
}

void spi3_test(void)
{
    u32 i;
    vol(80);
        I2S_Cmd(CODEC_I2S_PORT, ENABLE);
        for(i=0;i<1000;i++)
        {
            SPI3_WriteByte(i);
        }
}


最后是调用
while(1)
{
     spi3_test();
rt_thread_delay(10);
}

出0入0汤圆

 楼主| 发表于 2011-5-29 00:07:22 | 显示全部楼层
思路是用spi1 配置wm8978 ,用i2s3来送数据,现在是pb3 和pa15 没有波形,pb3一直是高电平,pa15一直低电平,
参考 这个网站 http://bbs.21ic.com/icview-111525-1-1.html,上面说有波形输出的,不知道是我的设置有问题还是硬件问题,我的两个硬件都是一样,哪位能帮我判断下是哪里问题

出0入0汤圆

发表于 2011-5-30 18:26:00 | 显示全部楼层
1.给SPI上面挂个逻辑分析仪,确认命令是有正确发送出去.
2.冷上电后.VMID,VMIC都是没电的.正常接收
  codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
  这个命令后,VMID会输出电压 1/2vcc.
  (不确认是这条,大概是这条,最好单步测反应)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-4 20:28

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表