首先要确定好各个晶振频率,因为有的过程有时序长短需求,不同的频率,执行的每句代码的时间都不同,使用HAL库和使用标准库的速度也有差别。
一.硬件接口介绍
汇总:
1.OS[0-2]过采样率设置
2.6号PAS/SER,接1串口输出,接0并口输出(这里直接接3.3V)
3.7号STBY(这里直接接3.3V,到什么手持设备考虑节约用电时再考虑)
4.8号RANGE,=1(+-10v量程) =0(+-5v量程),(单片机控制)
5.9,10号CONVST A, CONVST B 用于启动ADC通道采样, 这里将这两个一起短接(1个负责4个ADC通道),上升沿后开始转化,所以常态为1,要开始转化的时候,拉低后,在拉高,引出上升沿
6.RESET,上升沿复位,所以默认是0,要复位拉1.
7.12. RD/SCLK SPI_SCK 时钟线
8.13.CS片选 低电平有效,对于串行传输,(默认高电平)给低电平时,开始读取data
如图
9.14脚BUSY,CONVST A和B同时到达上升沿后,BUSY拉高表示开始转换,拉低后,表示转换完成,可以开始拉低cs来读data
如图
10.15脚FRSTDATA可以先不管
11.22 to 16 DB[6:0]并行输出,先不管我们用串行
12.24脚 DB7/DOUTA 串行data输出口,这里用成SPI_MISO
13.DB8/DOUTB,不管
其余DB接口都想不管接地
14.34脚REF SELECT:1内部电压基准源使用 0外部使用
15.42脚 REFIN/ REFOUT,if ࡕREF SELECT=1,则输出2.5v基准源给外部,
else ifࡕREF SELECT=0,则作为基准源输入
二.代码流程思路;
1.初始化:
/* 设置过采样模式 */
Ad7606_SetOS(5);//32倍过采样
/* 设置采集量程模式 */
AD_RANGE_5V_HAL();
/* 硬件复位复AD7606 */
Ad7606_Reset();
2.开始转化工作
此阶段参考思路图
/* CONVST脚设置为高电平 CONVSTAB同时进入高电平 方便一起拉低 来下一步进行AD转换*/
AD_CONVST_HIGH();
注意:
/* 上升沿开始转换,低电平持续时间至少25ns 1/25ns=40Mhz
上升沿开始转换,低电平持续时间至少25ns, 1/25ns=40Mhz,延时的确定和单片机的主频有关 */
//直接操作寄存器 提升10倍速度
//拉低CONVSTA或者CONVSTB持续最多0.5ms(500ns),注意这里是最多,所以在代码里只需一个参考时钟周期足以,比如你用的100M,一个参考时钟周期就是10ns,当然,CONVSTA和CONVSTB也可同时拉低,这样就是8个通道同时采集
/* CONVST脚设置为高电平 CONVST同时进入高电平 上升沿时开始转换*/
AD_CONVST_LOW_HAL();
/* 连续执行1次,低电平约200ns */(硬件上CONVEST A和B接一起了)
外部BUSY开始拉高(我们要读下降沿,也是低电平,来确认转换完成)
/* BUSY = 0 时.ad7606处于空闲状态ad转换结束 */
if (HAL_GPIO_ReadPin(AD_BUSY_GPIO_PORT, AD_BUSY_PIN)== 0)
3.开始接受data
//准备开始读取拉低CS失能AD_7606 停止转换
AD_CS_LOW_HAL();
for (i = 0; i < CH_NUM; i++)
{
pusData[i] =Ad7606_MN_ReadBytes();
//串行输出模式下只有两个数字输出通道,每个输入通道输出16位采样数据;
//AD一共有8个通道,从时序上说,每返回一次,下一次spi返回下一个通道的值
//所以此处使用for 8次循环 获取8次通道值8*16bit位
//所以此处 pusData[0-7]正是 AD7606的八个通道值
//所以此处使用for 8次循环 获取8次通道值
}
其中Ad7606_MN_ReadBytes函数
在SCLK的上升沿AD7606输出一位数据(但根据时序图,我感觉是SCLK高电平期间输出的)当一个通道一次转换后输出16位采样数据;
for (i = 0; i < 16; i++)//18次循环
{
SCLK_LOW_HAL();
uiData = uiData << 1;
uiData |= DATA_HAL();
SCLK_HIGH_HAL();
}
usData =uiData;
对于AD7608这里16变成18就可以了
4.接收data后开始数据转换
具体原理参考python将AD7606B原始补码数据数组转换原码数据数组并进行处理_ad7606补码转换计算-优快云博客
AD_V[0]=5000*AD_Value[0]/32768;
if(AD_V[0]>5000)
{
AD_V[0]=-(10000-AD_V[0]);
}
AD_V[1]=5000*AD_Value[1]/32768;
if(AD_V[1]>5000)
{
AD_V[1]=-(10000-AD_V[1]);
}
AD_V[2]=5000*AD_Value[2]/32768;
if(AD_V[2]>5000)
{
AD_V[2]=-(10000-AD_V[2]);
}
AD_V[3]=5000*AD_Value[3]/32768;
if(AD_V[3]>5000)
{
AD_V[3]=-(10000-AD_V[3]);
}
到此读取完成,有朋友需要单片机搭配CUBEMX,全源代码工程的私聊我,自己手搓实属不易。