AD7797芯片驱动调试

        今天在测试拉力传感器,调校后,发现拉力值还是零。查看AD采样值,结果如图:

先不去分析为啥是零,只看AD采样数据就不对,怎么会偏差这么大,而且有极大值和极小值。

驱动是同事写的,目前已经不负责这个项目了,我只能一点点来看手册调试。

一、AD7797引脚

引脚图,如下图:

注:和通信相关的就是标注的几个引脚,单个芯片(CS可以一直拉低,表示一直选中,不建议这么做)。DOUT/RDY为低表示

转换完成,数据读走或者在数据更新之前为高(数据跟新完后为低)。

时序图:

二、复位

AD7797有上电复位和软件复位。

说的很清楚了,DIN引脚保持至少32个时钟周期,则复位;复位后,经过500us间隔

才能和AD7797通信。

void reset_Ad7797(void)  
{    
    uint8_t i=0;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        AD_DIN_HIGH;
        for(i = 0; i < 36; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            AD_SCLK_HIGH;
            //100ns
        }  
        //AD_CS_HIGH;
        //80nS
        //__NOP();
    )
    //500us
    delay(300);
}

三、读写寄存器

AD7797怎么读写寄存,怎么配置,请看数据手册,这里只讲大概思路。

(数据传输的时候,先传输高字节的高bit)

COMMUNICATION REGISTER

所以有的后续操作,都需要先操作通信寄存器。

CR7写0,可以操作本寄存器;CR6写0,代表后续是写操作;CR6写1,代表后续是读操作;RS2-RS0表示后续操作寄存器地址。

STATUS REGISTER

MODE REGISTER

转换模式有两种:单次转换模式和连续转换模式;转换完后,OUT/RDY为低;

校准模式有三种:内准基准零点校准,系统零点校准和系统满量程校准(系统校准需要硬件支持)。

CONFIGURATION REGISTER

读写时候,按着时序图:

1)写入数据:MCU低电平改变;AD7797高电平读取;

2)读取数据:AD7797电平输出;MCU高电平读取;

测试ID寄存器,发现读取是0x5A,芯片没有焊接错误,只能在时序上看:

 

最后一个Bit在下降沿变低,查看时序图:

最后一个Bit要求上升沿后10ns读取,反应没这么快;下降沿后80ns数据就稳定了,而读取IO需要百ns级,因此

改成下降沿读取,测试成功。

void write_8bit(uint8_t chAddress,uint8_t writedata)  
{    
    U8 i;  
    union{
        uint8_t chCRBD[2];
        struct{
        uint8_t         :2;
        uint8_t Cread   :1;
        uint8_t chRS    :3;
        uint8_t RW      :1;
        uint8_t WEN     :1;
        };
    }tCRBD = {0};
    tCRBD.chCRBD[0] = 0;
    tCRBD.chCRBD[1] = writedata;
    tCRBD.WEN = 0;
    tCRBD.RW  = 0;
    tCRBD.chRS= chAddress;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        for(i = 0; i < 16; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            if(tCRBD.chCRBD[i>>3] & 0x80){
                AD_DIN_HIGH;
            }else{
                AD_DIN_LOW;
            }
            AD_SCLK_HIGH;
            //100ns
            tCRBD.chCRBD[i>>3] = tCRBD.chCRBD[i>>3] << 1;
        }
        //AD_CS_HIGH;
        //80nS
    ) 
    AD_DIN_HIGH;
}


void write_16bit(uint8_t chAddress,uint16_t writedata)  
{    
    U8 i;  
    union{
        uint8_t chCRBD[3];
        struct{
        uint8_t         :2;
        uint8_t Cread   :1;
        uint8_t chRS    :3;
        uint8_t RW      :1;
        uint8_t WEN     :1;
        };
    }tCRBD = {0};
    tCRBD.chCRBD[0] = 0;
    tCRBD.chCRBD[1] = (writedata>>8) & 0x00FF;
    tCRBD.chCRBD[2] = writedata & 0x00FF;
    tCRBD.WEN = 0;
    tCRBD.RW  = 0;
    tCRBD.chRS= chAddress;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        for(i = 0; i < 24; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            if(tCRBD.chCRBD[i>>3] & 0x80){
                AD_DIN_HIGH;
            }else{
                AD_DIN_LOW;
            }
            AD_SCLK_HIGH;
            //100ns
            tCRBD.chCRBD[i>>3] = tCRBD.chCRBD[i>>3] << 1;
        }
        //AD_CS_HIGH;
        //80nS
    ) 
    AD_DIN_HIGH;
}

void write_24bit(uint8_t chAddress,uint32_t writedata)  
{    
    U8 i;  
    union{
        uint8_t chCRBD[4];
        struct{
        uint8_t         :2;
        uint8_t Cread   :1;
        uint8_t chRS    :3;
        uint8_t RW      :1;
        uint8_t WEN     :1;
        };
    }tCRBD = {0};
    tCRBD.chCRBD[0] = 0;
    tCRBD.chCRBD[1] = (writedata>>16) & 0x000000FF;
    tCRBD.chCRBD[2] = (writedata>>8)  & 0x000000FF;
    tCRBD.chCRBD[3] = writedata & 0x000000FF;
    tCRBD.WEN = 0;
    tCRBD.RW  = 0;
    tCRBD.chRS= chAddress;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        for(i = 0; i < 32; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            if(tCRBD.chCRBD[i>>3] & 0x80){
                AD_DIN_HIGH;
            }else{
                AD_DIN_LOW;
            }
            AD_SCLK_HIGH;
            //100ns
            tCRBD.chCRBD[i>>3] = tCRBD.chCRBD[i>>3] << 1;
        }
        //AD_CS_HIGH;
        //80nS
    ) 
    AD_DIN_HIGH;
}
uint8_t read_8bit(uint8_t chAddress)  
{     
    uint8_t readdata = 0;  
    uint8_t i;  
    union{
        uint8_t chCRBD;
        struct{
        uint8_t         :2;
        uint8_t Cread   :1;
        uint8_t chRS    :3;
        uint8_t RW      :1;
        uint8_t WEN     :1;
        };
    }tCRBD = {0};
    tCRBD.chCRBD= 0;
    tCRBD.WEN = 0;
    tCRBD.RW  = 1;
    tCRBD.chRS= chAddress;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        for(i = 0; i < 8; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            if(tCRBD.chCRBD & 0x80){
                AD_DIN_HIGH;
            }else{
                AD_DIN_LOW;
            }
            AD_SCLK_HIGH;
            //100ns
            tCRBD.chCRBD = tCRBD.chCRBD<<1;
        }
        AD_DIN_HIGH;
        for(i = 0; i < 8; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            readdata = readdata << 1;
            if(AD_DOUT){
                readdata += 1;
            }
            AD_SCLK_HIGH;
            //100ns
        }
        //AD_CS_HIGH;
        //80nS
    ) 
    return readdata;
}


uint16_t read_16bit(uint8_t chAddress)  
{     
    uint16_t readdata = 0;  
    uint8_t  i;  
    union{
        uint8_t chCRBD;
        struct{
        uint8_t         :2;
        uint8_t Cread   :1;
        uint8_t chRS    :3;
        uint8_t RW      :1;
        uint8_t WEN     :1;
        };
    }tCRBD = {0};
    tCRBD.chCRBD= 0;
    tCRBD.WEN = 0;
    tCRBD.RW  = 1;
    tCRBD.chRS= chAddress;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        for(i = 0; i < 8; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            if(tCRBD.chCRBD & 0x80){
                AD_DIN_HIGH;
            }else{
                AD_DIN_LOW;
            }

            AD_SCLK_HIGH;
            //100ns
            tCRBD.chCRBD = tCRBD.chCRBD<<1;
        }
        AD_DIN_HIGH;
        for(i = 0; i < 16; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            readdata = readdata << 1;
            if(AD_DOUT){
                readdata += 1;
            }
            AD_SCLK_HIGH;
            //100ns
        }
        //AD_CS_HIGH;
        //80nS
    )
    return readdata;
}

uint32_t read_24bit(uint8_t chAddress)  
{     
    uint32_t readdata = 0;  
    uint8_t  i;  
    union{
        uint8_t chCRBD;
        struct{
        uint8_t         :2;
        uint8_t Cread   :1;
        uint8_t chRS    :3;
        uint8_t RW      :1;
        uint8_t WEN     :1;
        };
    }tCRBD = {0};
    tCRBD.chCRBD= 0;
    tCRBD.WEN = 0;
    tCRBD.RW  = 1;
    tCRBD.chRS= chAddress;
    SAFE_ATOM_CODE(
        //AD_CS_LOW;
        //80nS
        for(i = 0; i < 8; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            if(tCRBD.chCRBD & 0x80){
                AD_DIN_HIGH;
            }else{
                AD_DIN_LOW;
            }
            AD_SCLK_HIGH;
            //100ns
            tCRBD.chCRBD = tCRBD.chCRBD<<1;
        }
        AD_DIN_HIGH;
        for(i = 0; i < 24; i++)  
        {  
            AD_SCLK_LOW;
            //100ns
            readdata = readdata << 1;
            if(AD_DOUT){
                readdata += 1;
            }
            AD_SCLK_HIGH;
            //100ns
        }
        //AD_CS_HIGH;
        //80nS
    )
    return readdata;
}

四、读取数据

1、初始化

void Init_ad7797(void)
{
	unsigned char id = 0;
    unsigned int  con= 0;
    //复位
    reset_Ad7797();
    //读取复位状态
    while(1){
        if(0x08 == (read_8bit(AD7797_SR) & 0x08)){
            break;
        }
    }
    //校准
    sys_calibration();
    //读取ID
    while(1){
        if(0x5B == read_8bit(AD7797_IDR)){
            break;
        }
    }
    //设置模式
    Ad7797_Ini();
}

校准:

void sys_calibration(void)    
{  
    //内部零点校准
    write_16bit(AD7797_MR,0x8009);
    while(0x00 != (read_8bit(AD7797_SR) & 0x80));
    //系统零点校准
    //write_16bit(AD7797_MR,0xC009);
    //系统满量程校准
    //write_16bit(AD7797_MR,0xE009);
} 

设置模式:

void Ad7797_Ini(void)     
{     	
//	write_16bit(AD7797_MR,0x0710);

//    while(1){
//        if(0x0710 == read_16bit(AD7797_MR)){
//            break;
//        }
//    }

    while(1){
        write_16bit(AD7797_MR,0x200A);
        if(0x200A == read_16bit(AD7797_MR)){
            break;
        }
    }
}

读取数据流程:

单词模式:

write_16bit(AD7797_MR,0x200A);//启动转换(每次转换完成后,都要从新启动)

等待转换完成,DOUT/RDY引脚边变低

读取数据:

read_24bit(AD7797_DR)

连续模式:

write_16bit(AD7797_MR,0x000A);//配置模式(启动一次就行)

 

等待转换完成,DOUT/RDY引脚边变低

读取数据:

read_24bit(AD7797_DR)

 

采样数据:

2021.04.30

昨天把CS一直使能的驱动调试没有问题了,同事说不建议这样用,还是要启用CS,于是今天又把CS使能了,但是发现一个奇怪的问题,

就是AD一直读取不到数据,查看是读取不到DOUT/RDY拉低,肯定不是驱动函数的事,只能从时序着手了。查看单词读取时序:

启动转换后,等待转换期间,CS要保持低电平,修改逻辑后,测试OK。

 

下图是连续转换模式,需要CS一直使能:

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
ad7606是一款16位模数转换器(ADC)芯片,常用于工业自动化和仪器仪表领域。编写ad7606单片机驱动程序的目的是实现对该芯片的控制和数据采集功能。 首先,驱动程序需要初始化ad7606芯片。这包括设置数据通信接口(如SPI或I2C)、设置AD转换通道(选择输入信号源)、设置采样率和信号精度,并配置其他相关参数。 然后,驱动程序需要通过适当的通信协议与ad7606进行通信。在SPI接口下,驱动程序需要发送特定的命令或配置字节以开始转换、读取转换结果或清除转换寄存器。通过与ad7606进行适当的通信,驱动程序可以确保正确的数据采集和处理。 接下来,驱动程序需要实现数据的读取和处理。一旦转换完成,ad7606将转换结果存储在内部缓冲区中。驱动程序需要读取并处理这些数据,以便进一步的分析或显示。具体的数据处理方法将根据实际应用而定,可以包括数据滤波、信号处理、储存或显示等。 最后,在驱动程序的设计中,需要考虑到芯片的特性和应用的要求。这可能包括时序控制、中断处理、错误处理和异常情况的处理等。驱动程序的设计需要兼顾芯片的功能和性能,以确保系统的稳定性和可靠性。 总之,ad7606单片机驱动程序的编写涉及到芯片的初始化、通信、数据读取和处理等方面。通过合理的设计和调试驱动程序可以实现对ad7606芯片的有效控制和数据采集,从而满足不同应用领域的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值