项目上使用到该转换芯片,写点笔记,希望对大家有帮助。我接触这个芯片也就几天,整体来说,没寄存器,很好控制。但是我的代码仅提供思路,现在没有板子,不能验证。刚入职的硬件开发岗萌新,先写这么多,有机会再更新,如有错误地方请各位指正,谢谢。
1. 芯片关键参数介绍
AD7606支持8通道模拟输入;7种过采样率设置;SPI/QSPI™/MICROWIRE™/DSP多种通信协议;模拟输入范围选择;参考电压选择。
Pin OS0~PinOS2用于控制过采样率选择,OS2是MSB控制位,OS0是LSB控制位。可以根据需要选择硬件或者软件的方式控制过采样,真值表如下:
Pin6(PAR_N/SER/BYTE SEL)管脚用于选择通信方式,我这里用的是并行方式,直接将管脚接地即可。数据吞吐量大,GPIO口不够用则改用字节传输或者串行模式。
Pin7(STBY_N)用于选择省电模式,不在意功耗直接拉高即可,如果需要切换芯片工作模式,则需要配合使用RANG引脚。
Pin8(RANG)用于选择输入电压范围,RANG=0,输入电压范围是±5 V;RANG=1,输入电压范围是±10 V。
Pin9和Pin10(CONVST A, CONVST B)用于控制转换选择,A对应1234,B对应5678,通常直接将AB短接,一起控制,逻辑1表示开始转换,逻辑0表示未转换。
Pin12(RD_N/SCLK),并行模式下是读数据控制信号,低电平有效;串行模式下是时钟输出控制引脚。
Pin13(CS_N),片选引脚,并行模式下通常将其与Pin12短接,低电平有效。
Pin14(BUSY),在CONVST A, CONVST B的上升沿跳转为高电平,表示开始转换;所有通道转换结束后才转为低电平;下降沿表明数据已存储在输出寄存器。
Pin15(FRSTDATA):目前我觉得没用的引脚
2. 时序分析
首先是读数据的时机,可以在转换结束之后在读取本次转换结果,也可以在转换的过程中读取上一次的转换结果,分别对应下面图片中的Figure 2和Figure 3。区别在于前者在BUSY为低之后才拉低CS管脚开始读数据,而后者则是在BUSY期间就拉低了CS管脚进行读数据。注意:手册提到,在BUSY高时读取的任何数据必须在BUSY下降沿发生之前完成。当BUSY信号高时,CONVST A或CONVST B上的上升沿没有影响。
下面是并行模式下读取数据的时序图,为了方便,直接将CS和RD管脚短接,一起控制数据读取过程。另外,根据该时序图和手册说明,FRSTDATA仅表示通道1的数据读取情况。
3. 参考代码
#管脚定义,根据自己的电路图做调整
uint16_t ADC_Data[8];
//尽量将控制Pins和数据Pins分别接到同名GPIO口
#define ADC_DataPort GPIOB //16 bits并行数据端口
#define ADC_CtrlPort GPIOC //其它的必要控制端口
//关键控制Pins
#define ADC_RANG GPIO_PIN_9 //输入电压范围选择;0:+-5V;1:+-10V
#define ADC_STBY GPIO_PIN_8 //下电模式选择;低电平有效;默认电平:1
#define ADC_OS0 GPIO_PIN_7 //默认电平:0
#define ADC_OS1 GPIO_PIN_6 //默认电平:0
#define ADC_OS2 GPIO_PIN_5 //默认电平:0
#define ADC_RD GPIO_PIN_4 //读取和片选控制信号;低电平有效;默认电平:1
#define ADC_RESET GPIO_PIN_3 //复位信号;高电平有效;默认电平:0
//#define ADC_FRSTDATA GPIO_PIN_2 //低电平有效;默认电平:0
#define ADC_BUSY GPIO_PIN_1 //转换状态信号;输入0:转换结束;1:正在转换
#define ADC_CONVST_AB GPIO_PIN_0 //开始转换信号;高电平有效;默认电平:0
//用于设置over sampling率
#define ADC_SetOS0() gpio_bit_set(ADC_CtrlPort, ADC_OS0)
#define ADC_SetOS1() gpio_bit_set(ADC_CtrlPort, ADC_OS1)
#define ADC_SetOS2() gpio_bit_set(ADC_CtrlPort, ADC_OS2)
#define ADC_ResetOS0() gpio_bit_reset(ADC_CtrlPort, ADC_OS0)
#define ADC_ResetOS1() gpio_bit_reset(ADC_CtrlPort, ADC_OS1)
#define ADC_ResetOS2() gpio_bit_reset(ADC_CtrlPort, ADC_OS2)
#过采样率设置
/*!
\brief ADC过采样选择
\param[in] OS: 过采样率选择
可选择参数:0、2、4、8、16、32、64
\param[out] 无
\retval 无
*/
void AD7606_SetOversampling(uint8_t OS)
{
switch(OS)
{
case 0: // 000
ADC_ResetOS2();
ADC_ResetOS1();
ADC_ResetOS0();
break;
case 2: // 001
ADC_ResetOS2();
ADC_ResetOS1();
ADC_SetOS0();
break;
case 4: // 010
ADC_ResetOS2();
ADC_SetOS1();
ADC_ResetOS0();
break;
case 8: // 011
ADC_ResetOS2();
ADC_SetOS1();
ADC_SetOS0();
break;
case 16: // 100
ADC_SetOS2();
ADC_ResetOS1();
ADC_ResetOS0();
break;
case 32: // 101
ADC_SetOS2();
ADC_ResetOS1();
ADC_SetOS0();
break;
case 64: // 110
ADC_SetOS2();
ADC_SetOS1();
ADC_ResetOS0();
break;
default: // default case
ADC_ResetOS2();
ADC_ResetOS1();
ADC_ResetOS0();
break;
}
}
#AD7606初始化
/*!
\brief ADC初始化配置
\param[in] 无
\param[out] 无
\retval 无
*/
void AD7606_Init(void)
{
rcu_periph_clock_enable(ADC_DataPort | ADC_CtrlPort);
//数据输入引脚配置
gpio_mode_set(ADC_DataPort, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_ALL);
//输入反馈信号
gpio_mode_set(ADC_CtrlPort, GPIO_MODE_INPUT, GPIO_PUPD_NONE, ADC_BUSY);
//输出控制信号:默认低电平的信号
gpio_mode_set(ADC_CtrlPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, ADC_RANG | ADC_OS0 | ADC_OS1 | ADC_OS2 | ADC_RESET | ADC_CONVST_AB);
gpio_output_options_set(ADC_CtrlPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ADC_RANG | ADC_OS0 | ADC_OS1 | ADC_OS2 | ADC_RESET | ADC_CONVST_AB);
//输出控制信号:默认高电平的信号
gpio_mode_set(ADC_CtrlPort, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, ADC_STBY | ADC_RD);
gpio_output_options_set(ADC_CtrlPort, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, ADC_STBY | ADC_RD);
//上电复位ADC芯片
gpio_bit_set(ADC_CtrlPort, ADC_RESET);
delay_1ms(1);
gpio_bit_reset(ADC_CtrlPort, ADC_RESET);
}
#AD7606转换的开始和结束
/*!
\brief ADC开始转换
\param[in] 无
\param[out] 无
\retval 无
*/
void AD7606_StartConv(void)
{
gpio_bit_set(ADC_CtrlPort, ADC_CONVST_AB);
}
/*!
\brief ADC结束转换
\param[in] 无
\param[out] 无
\retval 无
*/
void AD7606_StopConv(void)
{
gpio_bit_reset(ADC_CtrlPort, ADC_CONVST_AB);
}
#省电模式选择
void AD7606_SwitchPowerDownMode(uint8_t Mode)
{
switch(Mode)
{
case 1 :
gpio_bit_reset(ADC_CtrlPort, ADC_STBY);
gpio_bit_set(ADC_CtrlPort, ADC_RANG);
break;
case 0 :
gpio_bit_reset(ADC_CtrlPort, ADC_STBY);
gpio_bit_reset(ADC_CtrlPort, ADC_RANG);
break;
default :
gpio_bit_reset(ADC_CtrlPort, ADC_STBY);
gpio_bit_set(ADC_CtrlPort, ADC_RANG);
break;
}
}
#读取转换结果
uint16_t* AD7606_ReadData(void)
{
//开始单次转换
AD7606_StartConv();
//等待转换结束
while(gpio_input_bit_get(ADC_CtrlPort, ADC_BUSY));
//结束转换准备读取数据寄存器中的数据
AD7606_StopConv();
//读取数据:并行模式读取数据
for(uint8_t i = 0; i < 8; i ++)
{
//这两个延时有点长了,或许不需要延时也许,30ns的时间内即可读完一个通道数据
gpio_bit_reset(ADC_CtrlPort, ADC_RD);
//delay_1ms(1);
ADC_Data = gpio_input_port_get(ADC_DataPort);
delay_1ms(1);
gpio_bit_set(ADC_CtrlPort, ADC_RD);
}
return ADC_Data;
}
/*!
\brief ADC复位
\param[in] 无
\param[out] 无
\retval 无
*/
void AD7606_Reset(void)
{
gpio_bit_set(ADC_CtrlPort, ADC_RESET);
delay_1ms(1); //最小50 ns
gpio_bit_reset(ADC_CtrlPort, ADC_RESET);
}
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/magicssss/article/details/143205014
|
|