开发环境如下:

开发板:米联客ZYNQ7100,MZ7100FA开发板;

AD7606模块:米联客的AD7606,串行输出模式,这里只有通道1有输入,所以只需要输出通道1;

EDA:VIVADO2019.2;

硬件连接实物如图:

706resa典型电路_zynq


设计框图如下:

706resa典型电路_fpga开发_02


AD7606的FPGA采集部分请看我前面的文章

不同的是,为了配合zynq使用,我把源码封装成了自定义IP,如下:

706resa典型电路_zynq_03


IP配置如下:

706resa典型电路_706resa典型电路_04


大概原理:

稳压电源输出一个电压到AD7606模块,zynq7100的PL采集数据,并做16位的并行输出;

调用一个AXI GPIO的IP,BANK1设置为输入,16位,用于连接PL采集到的6位的并行数据,BANK2设置为输出,1位,用于控制蜂鸣器,蜂鸣器是有源的,给高电平触发,AXI GPIO配置如下:

706resa典型电路_ADC_05


最后,导出bit,加载SDK,在SDK里做浮点运算,算出实时采集到的电压值,再做比较,若采集到的电压值大于阈值,则蜂鸣器响。

BD如下图:

706resa典型电路_zynq_06


AD7606输入电压值得算法如下:

706resa典型电路_AD7606_07


我的采集用的是±10V模式,在verilog代码里有,如图:

706resa典型电路_AD7606_08


AD7606模块使用的是内部参考电压2.5V,所以公式中的REF/2.5V=1;

所以,根据公式自然可以得出,VIN=CODE*10/32768;其中CODE就是采集到的通道1的16位采集数据;

SDK主函数如下:

int main()
{
    init_platform();
	u16 ad7606;
	float V;
	XGpioCfg = XGpio_LookupConfig(GPIO_BUZZER_DEVICE_ID);
	XGpio_CfgInitialize(&buzzer, XGpioCfg, XGpioCfg->BaseAddress);
	XGpio_SetDataDirection(&buzzer, XGPIO_BANK1, 1);	//in
	XGpio_SetDataDirection(&buzzer, XGPIO_BANK2, 0);	//out
	XGpio_DiscreteWrite(&buzzer, XGPIO_BANK2, 0);	//buzzer not work

	while(1){
		ad7606=XGpio_DiscreteRead(&buzzer, XGPIO_BANK1);
		V=(float)ad7606*10/32768;
		if(V>=6.2){	//threshold=6.2V
			XGpio_DiscreteWrite(&buzzer, XGPIO_BANK2, 1);	//buzzer not work
		}
		else XGpio_DiscreteWrite(&buzzer, XGPIO_BANK2, 0);	//buzzer not work
		//sleep(1);
		//printf("V=%f",V);
	}
    cleanup_platform();
    return 0;
}

我们来DEBUG一下看看效果:

先将电源输出设置为6.125,如下:

706resa典型电路_zynq_09


看看此时的采集到的值:

706resa典型电路_zynq_10


此时采集到的电压不足6.2V,再单步运行,程序跳到了蜂鸣器不工作的语句,如下:

706resa典型电路_706resa典型电路_11


现在把电源输出调到6.5246,如下:

706resa典型电路_fpga开发_12


再来看看DEBUG,

706resa典型电路_zynq_13


此时采集到的电压超过阈值6.2V,再单步运行,程序跳到了蜂鸣器工作的语句,如下:

706resa典型电路_fpga开发_14


注意事项:

1、AD7606采集的verilog代码,一定要认真读官方数据手册里面的几个时序图,特别是几个关键信号的持续时间,不然采集失败,不过还好,因为我已经帮你们做好了,工程拿去直接用就是,代码里也有注释,不过请原谅我数学老师教的英语注释;

2、电源输入时一定要注意电源地要和信号地共地,不然采集到的数据是乱的;

3、浮点运算时要把采集到的数据强制转换为浮点型,我不是专业搞软件的,最开始没注意,所以算出过总是没有小数点;