去年做2020电赛省赛E题的时候(练习用的,比赛做了A题),需要对一个正弦交流、而且峰峰值较大的信号进行ADC采样进单片机处理,而且采样率还得有个十几K的(采五次谐波)。如果用Stm32的自带ADC加上ADC前端处理也能直接采,不过实在懒得做板子,刚好看到AD7606:±5/10V、最高200ksps、16位分辨率,完美符合要求,就上手调试了一下。
AD7606
使用的AD7606模块是淘宝直接购买的现成的模块(见图),价格不贵。
商家提供的例程代码是Stm32F103平台的,使用SPI与AD7606通信,花点时间对着数据手册改了改就移植到了F4平台上了。
使用方法
AD7606将所有功能的配置都引出到了外部引脚进行配置,内部没有可以写入的寄存器。因为使用SPI进行通信,没有用到并行数据口的输出,也不需要过采样,所以我是直接将配置过采样的几个引脚焊接到地,将并行数据接口悬空。
采样率的控制
一般来说,可以有两种通过单片机控制AD7606以一定的采样率进行采样的方式。
PWM控制 + 中断读取
一种是,对CONVST A/B 引脚输出固定频率的PWM波形,然后使用一路外部中断连接BUSY引脚,每当一次转换完成,便触发一次中断事件读取数据值。
定时器中断事件读取
另一种则是直接使用定时器中断事件直接读取,也就是转换期间读取,并不需要AD7606完成整个转换周期。
每次定时器中断事件中,将数据读取回单片机后,还要重新给AD7606一个开始转换的信号。
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //溢出中断
{
AD_CS = 0;
volt_data = ((Ad7606_ReadBytes() + 5000) * 255 / 10000); //读取数据处理
AD_CS = 1;
printf("add 1,0,%d",volt_data*10);//串口屏图表显示曲线
hmi_end();
Ad7606_StartConv();//转换开始信号
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除中断标志位
}
调试时遇到的问题
电压值不对
能够成功读取出数据值后,首先接入稳定的直流电压进行测试,发现计算得到的电压值不对,怀疑是SPI的问题。仔细研究了一下数据手册,发现了几个小问题:
1、5V供电时,SCK时钟频率最高可以到23.5MHz,实际使用发现,时钟频率调低时,读取出来的数据值反而会出错,而将SCK频率尽量提高则正常。
2、串行同步时钟的空闲状态需要为高电平,一开始直接使用以前写好的spi代码,配置的是空闲低电平;在SCK的第一个边沿读取数据。
最后的SPI配置:(Stm32F4,主时钟168M)
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI1, &SPI_InitStructure);
AD7606读取电压函数:(使用±5V量程)
int16_t data = 0;
float Ad7606_ReadBytes(void)
{
float v = 0;
data = SPI1_ReadWriteByte(0x0000);
v = (data * 0.000152);
// printf("%f\r\n",v);
return v;
}
采样率提高时电压值跳动
在解决了通讯的问题后,便可以读取出正确的电压值了。然后就使用信号发生器对AD7606输入了一个交流正弦信号,单片机读取到采样值后,使用串口屏显示波形,以观察连续采样的完整度。
测试发现,当采样率即定时器中断溢出频率提高时(约10K以上),所得到的电压值偶尔会出现跳动。经过观察,这个偶尔跳动所得到的电压值恰好就是AD7606输入悬空时所得到的采样值,猜测是隔壁通道虽然没有使用但处于悬空状态,而AD7606又是8通道同时转换的,有可能是隔壁通道产生的干扰。将没有使用的输入通道进行接地后,采样率提高到20K也没有出现跳动了。
参考的链接
上面简单只是写了下碰上的问题和解决过程,调试过程还参考了其他文章。