STM32配置CODEC之AD1939
一、简介
因芯片价格上涨,所有使用AD1939代替原来的方案。
二、芯片框图
三、AD1939寄存器
芯片总共有17个寄存器.具体的细节要看数据手册.
四、配置代码
下面的配置的代码:
H文件
/**************************************************START OF FILE*****************************************************/
#ifndef HH__XBSP_AD1939__HH
#define HH__XBSP_AD1939__HH
/* ------------------------------------------------------------------------------------------------------------------
includes
*/
/* ------------------------------------------------------------------------------------------------------------------
Definitions
*/
// AD1939 Register address definitions
#define CLKCTRL0 (0) // PLL and Clock Control register 0
#define CLKCTRL1 (1) // PLL and Clock Control register 1
#define DACCTRL0 (2) // DAC control register 0 (R/W)
#define DACCTRL1 (3) // DAC control register 1 (R/W)
#define DACCTRL2 (4) // DAC control register 2 (R/W)
#define DACMUTE (5) // DAC Individual Channel Mutes
#define DACVOL_L1 (6) // DAC volume - left 1 (R/W)
#define DACVOL_R1 (7) // DAC volume - right 1 (R/W)
#define DACVOL_L2 (8) // DAC volume - left 2 (R/W)
#define DACVOL_R2 (9) // DAC volume - right 2 (R/W)
#define DACVOL_L3 (10) // DAC volume - left 3 (R/W)
#define DACVOL_R3 (11) // DAC volume - right 3 (R/W)
#define DACVOL_L4 (12) // DAC volume - left 4 (R/W)
#define DACVOL_R4 (13) // DAC volume - right 4 (R/W)
#define ADCCTRL0 (14) // ADC control 0 (R/W)
#define ADCCTRL1 (15) // ADC control 1 (R/W)
#define ADCCTRL2 (16) // ADC control 2 (R/W)
#define AD1939_ADDR (4) // Global Address of any ad1939
//-------------------------------------------------------------------------------
// PLL and Clock Control 0 Register
#define DIS_ADC_DAC (0x00)
#define ENA_ADC_DAC (0x80)
#define PLL_IN_MCLK (0x00)
#define PLL_IN_DLRCLK (0x20)
#define PLL_IN_ALRCLK (0x40)
#define MCLK_OUT_XTAL (0x00)
#define MCLK_OUT_256FS (0x08)
#define MCLK_OUT_512FS (0x10)
#define MCLK_OUT_OFF (0x18)
#define INPUT256 (0x00)
#define INPUT384 (0x02)
#define INPUT512 (0x04)
#define INPUT768 (0x06)
#define PLL_PWR_UP (0x00)
#define PLL_PWR_DWN (0x01)
//-------------------------------------------------------------------------------
// PLL and Clock Control 1 Register
#define AD1938_PLL_LOCK (0x08)
#define DIS_VREF (0x04)
#define ENA_VREF (0x00)
#define ADC_CLK_PLL (0x00)
#define ADC_CLK_MCLK (0x02)
#define DAC_CLK_PLL (0x00)
#define DAC_CLK_MCLK (0x01)
//-------------------------------------------------------------------------------
// DAC Control Register 0
#define DAC_FMT_I2S (0x00)
#define DAC_FMT_TDM (0x40)
#define DAC_FMT_AUX (0x80)
#define DAC_FMT_DUALTDM (0xc0)
#define DAC_BCLK_DLY_1 (0x00)
#define DAC_BCLK_DLY_0 (0x08)
#define DAC_BCLK_DLY_8 (0x01)
#define DAC_BCLK_DLY_12 (0x18)
#define DAC_BCLK_DLY_16 (0x20)
#define DAC_SR_48K (0x00)
#define DAC_SR_96K (0x02)
#define DAC_SR_192K (0x04)
#define DAC_PWR_UP (0x00)
#define DAC_PWR_DWN (0x01)
//-------------------------------------------------------------------------------
// DAC Control Register 1
#define DAC_BCLK_POL_NORM (0x00)
#define DAC_BCLK_POL_INV (0x80)
#define DAC_BCLK_SRC_PIN (0x00)
#define DAC_BCLK_SRC_INTERNAL (0x40)
#define DAC_BCLK_SLAVE (0x00)
#define DAC_BCLK_MASTER (0x20)
#define DAC_LRCLK_SLAVE (0x00)
#define DAC_LRCLK_MASTER (0x10)
#define DAC_LRCLK_POL_NORM (0x00)
#define DAC_LRCLK_POL_INV (0x08)
#define DAC_CHANNELS_2 (0x00)
#define DAC_CHANNELS_4 (0x02)
#define DAC_CHANNELS_8 (0x04)
#define DAC_CHANNELS_16 (0x06)
#define DAC_LATCH_MID (0x00)
#define DAC_LATCH_END (0x01)
//-------------------------------------------------------------------------------
// DAC Control Register 2
#define DAC_OUT_POL_NORM (0x00)
#define DAC_OUT_POL_INV (0x20)
#define DAC_WIDTH_24 (0x00)
#define DAC_WIDTH_20 (0x08)
#define DAC_WIDTH_16 (0x18)
#define DAC_DEEMPH_FLAT (0x00)
#define DAC_DEEMPH_48K (0x02)
#define DAC_DEEMPH_44_1K (0x04)
#define DAC_DEEMPH_32K (0x06)
#define DAC_UNMUTE_ALL (0x00)
#define DAC_MUTE_ALL (0x01)
//-------------------------------------------------------------------------------
// DAC Individual Channel Mute Register
#define DACMUTE_R4 (0x80)
#define DACMUTE_L4 (0x40)
#define DACMUTE_R3 (0x20)
#define DACMUTE_L3 (0x10)
#define DACMUTE_R2 (0x08)
#define DACMUTE_L2 (0x04)
#define DACMUTE_R1 (0x02)
#define DACMUTE_L1 (0x01)
//-------------------------------------------------------------------------------
//DAC Volume Control Register - 8-bit granularity (256 levels)
#define DACVOL_MIN (0xFF)
#define DACVOL_LOW (0xC0)
#define DACVOL_MED (0x80)
#define DACVOL_HI (0x40)
#define DACVOL_MAX (0x00)
#define DACVOL_MASK (0xFF) // Volume in dB
//-------------------------------------------------------------------------------
// ADC Control 0 Register
#define ADC_SR_48K (0x00)
#define ADC_SR_96K (0x40)
#define ADC_SR_192K (0x80)
#define ADC_R2_UNMUTE (0x00)
#define ADC_R2_MUTE (0x20)
#define ADC_L2_UNMUTE (0x00)
#define ADC_L2_MUTE (0x10)
#define ADC_R1_UNMUTE (0x00)
#define ADC_R1_MUTE (0x08)
#define ADC_L1_UNMUTE (0x00)
#define ADC_L1_MUTE (0x04)
#define ADC_HP_FILT_OFF (0x00)
#define ADC_HP_FILT_ON (0x02)
#define ADC_PWR_UP (0x00)
#define ADC_PWN_DWN (0x01)
//-------------------------------------------------------------------------------
// ADC Control 1 Register
#define ADC_LATCH_MID (0x00)
#define ADC_LATCH_END (0x80)
#define ADC_FMT_I2S (0x00)
#define ADC_FMT_TDM (0x20)
#define ADC_FMT_AUX (0x40)
#define ADC_BCLK_DLY_1 (0x00)
#define ADC_BCLK_DLY_0 (0x04)
#define ADC_BCLK_DLY_8 (0x08)
#define ADC_BCLK_DLY_12 (0x0c)
#define ADC_BCLK_DLY_16 (0x10)
#define ADC_WIDTH_24 (0x00)
#define ADC_WIDTH_20 (0x01)
#define ADC_WIDTH_16 (0x03)
//-------------------------------------------------------------------------------
// ADC Control 2 Register
#define ADC_BCLK_SRC_PIN (0x00)
#define ADC_BCLK_SRC_INTERNAL (0x80)
#define ADC_BCLK_SLAVE (0x00)
#define ADC_BCLK_MASTER (0x40)
#define ADC_CHANNELS_2 (0x00)
#define ADC_CHANNELS_4 (0x10)
#define ADC_CHANNELS_8 (0x20)
#define ADC_CHANNELS_16 (0x30)
#define ADC_LRCLK_SLAVE (0x00)
#define ADC_LRCLK_MASTER (0x08)
#define ADC_LRCLK_POL_NORM (0x00)
#define ADC_LRCLK_POL_INV (0x04)
#define ADC_BCLK_POL_NORM (0x00)
#define ADC_BCLK_POL_INV (0x02)
#define ADC_LRCLK_FMT_50_50 (0x00)
#define ADC_LRCLK_FMT_PULSE (0x01)
/* ------------------------------------------------------------------------------------------------------------------
Prototypes
*/
/* ------------------------------------------------------------------------------------------------------------------
Variables
*/
/*------------------------------------------------------------------------------------------------------------------
Code
*/void xBSP_AD1939_Config(void);
#endif
/**************************************************END OF FILE**********************************************************/
C文件
/**************************************************START OF FILE*****************************************************/
/*------------------------------------------------------------------------------------------------------------------
Includes
*/
#include "stm32f4xx.h"
#include "xBSP_AD1939.h"
/*------------------------------------------------------------------------------------------------------------------
Definitions
*/
//是否读取寄存器的值
#define CONFIG_READAD1939_REG 0
#define SET_CS(value) GPIO_WriteBit(GPIOB, GPIO_Pin_2,(BitAction)value)
#define SET_RST(value) GPIO_WriteBit(GPIOC, GPIO_Pin_12,(BitAction)value)
#if(CONFIG_READAD1939_REG == 1)
uint8_t ReceiveBuffer[16];
#endif
/*------------------------------------------------------------------------------------------------------------------
Variables
*/
const uint8_t ConfigParam1939 [] = {
(AD1939_ADDR), CLKCTRL0, DIS_ADC_DAC | INPUT256 | PLL_IN_MCLK | MCLK_OUT_OFF | PLL_PWR_DWN,
(AD1939_ADDR), CLKCTRL1, DAC_CLK_PLL | ADC_CLK_PLL | DIS_VREF,
(AD1939_ADDR), DACMUTE, 0xFF, //DAC输出静音
//DAC配置
(AD1939_ADDR), DACCTRL1, DAC_LRCLK_POL_INV | DAC_BCLK_POL_INV | DAC_CHANNELS_2 | DAC_LATCH_MID | DAC_BCLK_SLAVE | DAC_LRCLK_SLAVE,
(AD1939_ADDR), DACCTRL1, DAC_LRCLK_POL_INV | DAC_BCLK_POL_INV | DAC_CHANNELS_2 | DAC_LATCH_MID | DAC_BCLK_SLAVE | DAC_LRCLK_SLAVE,
(AD1939_ADDR), DACCTRL2, DAC_WIDTH_24,
(AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_48K,
(AD1939_ADDR), DACCTRL0, DAC_FMT_I2S | DAC_BCLK_DLY_1 | DAC_SR_48K,
//ADC配置
(AD1939_ADDR), ADCCTRL0, ADC_SR_48K,
(AD1939_ADDR), ADCCTRL1, ADC_LATCH_MID | ADC_FMT_I2S | ADC_WIDTH_24,
(AD1939_ADDR), ADCCTRL2, ADC_BCLK_SRC_INTERNAL | ADC_BCLK_SLAVE | ADC_CHANNELS_2 | ADC_LRCLK_SLAVE | ADC_LRCLK_POL_INV | ADC_BCLK_POL_INV | ADC_LRCLK_FMT_PULSE,
(AD1939_ADDR), DACVOL_L1, DACVOL_MAX,
(AD1939_ADDR), DACVOL_R1, DACVOL_MAX,
(AD1939_ADDR), DACVOL_L2, DACVOL_MAX,
(AD1939_ADDR), DACVOL_R2, DACVOL_MAX,
(AD1939_ADDR), DACVOL_L3, DACVOL_MAX,
(AD1939_ADDR), DACVOL_R3, DACVOL_MAX,
(AD1939_ADDR), DACVOL_L4, DACVOL_MAX,
(AD1939_ADDR), DACVOL_R4, DACVOL_MAX,
(AD1939_ADDR), CLKCTRL0, DIS_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP,
(AD1939_ADDR), CLKCTRL0, ENA_ADC_DAC | PLL_IN_MCLK | MCLK_OUT_OFF | INPUT256 | PLL_PWR_UP,
(AD1939_ADDR), DACMUTE, 0x00,
};
/*------------------------------------------------------------------------------------------------------------------
Code
*/
static uint8_t SPI1_ReadWriteByte(uint8_t TxData);
static void SPI1_Init(void);
extern void Delay_ms(__IO u32 nTime);
/*
*********************************************************************************************************************
@ Brief : 写寄存器
@ Param : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data : 2021-04-02 16:53
*********************************************************************************************************************
*/
static void xBSP_AD1939_WriteReg (uint8_t rwaddr , uint8_t regaddr , uint8_t regdata)
{
SET_CS(0);
SPI1_ReadWriteByte(rwaddr<<1);
SPI1_ReadWriteByte(regaddr);
SPI1_ReadWriteByte(regdata);
SET_CS(1);
}
/*
*********************************************************************************************************************
@ Brief : 读寄存器
@ Param : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data : 2021-04-02 16:54
*********************************************************************************************************************
*/
static uint8_t xBSP_AD1939_ReadReg (uint8_t rwaddr , uint8_t regaddr)
{
uint8_t Result;
SET_CS(0);
SPI1_ReadWriteByte((rwaddr<<1)|1);
SPI1_ReadWriteByte(regaddr);
Result = SPI1_ReadWriteByte(0);
SET_CS(1);
return Result;
}
/*
*********************************************************************************************************************
@ Brief : 配置AD1939
@ Param : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data : 2021-04-02 17:01
*********************************************************************************************************************
*/
void xBSP_AD1939_Config(void)
{
uint32_t configSize;
//外设解初始化
SPI1_Init();
//复位
SET_RST(0);
Delay_ms(200);
SET_RST(1);
configSize = sizeof(ConfigParam1939);
for(uint32_t i = 0; i < configSize; i+=3)
{
xBSP_AD1939_WriteReg(ConfigParam1939[i], ConfigParam1939[i+1], ConfigParam1939[i+2]);
Delay_ms(10);
}
#if(CONFIG_READAD1939_REG == 1)
Delay_ms(200);
for (uint32_t i = 0; i < 16; i++)
{
ReceiveBuffer[i] = xBSP_AD1939_ReadReg(ConfigParam1939[i], i);
Delay_ms(10);
}
#endif
}
/*
*********************************************************************************************************************
@ Brief : SPI外设初始化
@ Param : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data : 2021-04-02 16:55
*********************************************************************************************************************
*/
static void SPI1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOB时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOB时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能GPIOB时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);//使能SPI1时钟
//GPIOA 3,4,5初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化
//PB3 CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
//复位
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//复用功能
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化
GPIO_PinAFConfig(GPIOA,GPIO_PinSource5,GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource6,GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource7,GPIO_AF_SPI1);
//这里只针对SPI口初始化
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,ENABLE);//复位SPI1
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1,DISABLE);//停止复位SPI1
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //设置SPI工作模式:设置为主SPI
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //串行同步时钟的空闲状态为高电平
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //串行同步时钟的第二个跳变沿(上升或下降)数据被采样
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 7; //CRC值计算的多项式
SPI_Init(SPI1, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI1, ENABLE); //使能SPI外设
}
/*
*********************************************************************************************************************
@ Brief : 读写一个字节
@ Param : NONE
@ Return : NONE
@ Author : YWJ(QQ:872180981)
@ Data : 2021-04-02 16:46
*********************************************************************************************************************
*/
static uint8_t SPI1_ReadWriteByte(uint8_t TxData)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET){}//等待发送区空
SPI_I2S_SendData(SPI1, TxData); //通过外设SPIx发送一个byte 数据
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){} //等待接收完一个byte
return SPI_I2S_ReceiveData(SPI1); //返回通过SPIx最近接收的数据
}
/**************************************************END OF FILE*******************************************************/
五、资料下载
以上相关的资料,我会整理放到网盘.
由于百度网盘会更新,可以进群看QQ公告.所以资料都会在同一个地址分享.
QQ:872180981
群号:339420387