knight_avr 发表于 2009-4-12 13:32:53

求助--我使用CS5532做AD转换SDO一直不会变低

求助--我使用CS5532做AD转换SDO一直不会变低
调试很久都不行,不知道为什么

哪位高手有成功使用 的 代码, 先谢谢了!

我的代码如下:
#ifndef _cs5532_h_
#define _cs5532_h_ 1
/*
//================================
//                CS5532驱动
//                AVR_C代码M8
//                knight
//=================================
*/
#include <avr/io.h>
#include "macros.h"
#include "define.h"
#include "func.h"
#include "spi.h"

#define SYNC1               0xff
#define SYNC0               0xfe

#define CMD0                  0
#define ARA                   BIT(6)      /*整列方式访问通道0、1的寄存器*/
#define CS0                   4
#define CS1                   5
#define CMD0_COMM0         (BIT(CS0))
#define CMD0_COMM1         (BIT(CS1))
#define CMD0_WRITE            0
#define CMD0_READ             BIT(3)
#define CMD0_reg_offset       0x01
#define CMD0_reg_gain         0x02
#define CMD0_reg_config       0x03
#define CMD0_reg_data         0x04
#define CMD0_reg_cconfig      0x05

#define CMD1                  0x80
#define CMD1_step             0
#define CMD1_continue         BIT(6)
#define CMD1_cconfig(x)       ((x)<<3)
#define CMD1_convert          0
#define CMD1_adj_offset       1
#define CMD1_adj_gain         2
#define CMD1_adj_sys_offset   5
#define CMD1_adj_sys_gain   6

////配置寄存器
#define PSS      7   /* 节电模式选择 */
#define PDW      6   /* 节电模式 */
#define RS       5   /* 系统复位 */
#define RV       4   /* 复位有效 */
#define IS       3   /* 输入短路 */
#define GB       2   /* 保护信号位 */
#define VRS      1   /* 参考电压选择 */
#define A1       0   /* 输出锁存位1 */

#define A0       7   /* 输出锁存位0 */
#define OLS      6   /* 输出锁存选择 */

////通道配置寄存器
#define cc_CS17
#define cc_CS06
#define cc_G2   5
#define cc_G1   4
#define cc_G0   3
#define GEN64   ( BIT(cc_G2)|BIT(cc_G1) )
#define GEN32   ( BIT(cc_G2)|BIT(cc_G0) )
#define cc_WR32
#define cc_WR21
#define cc_WR10

#define cc_WR07
#define cc_UB   6
#define cc_OL15
#define cc_OL04
#define cc_DT   3
#define cc_OCD2

#define    isADCnotReady()    ( PINB & BIT(SDO) )
//=======================================
//         CS5532初始化程序
//      作用:cs5532 AD转换器
//=======================================
void
init_cs5532(void)
{
    uint8_t i;

    disable_spi();//SPI禁止
    delay1us();
    enable_spi();//SPI使能
    delay1us();
    clrbit(SPI_PORT,SDI);
        setbit(SPI_PORT,SDO);
        clrbit(SPI_PORT,SCK);

////进入命令模式
    for (i=0;i<18;i++) SPI_RWBYTE(SYNC1);
    SPI_RWBYTE(SYNC1);                       
    delay1us();

////RS=1复位 (写配置寄存器)
    SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
    SPI_RWBYTE(BIT(RS));
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    delay1us();

    i=0;
    while ( !isbit(i,RV) )   //等待复位完毕
    {
      SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_config); //读配置寄存
      delay1us();
      i=SPI_RWBYTE(0x00);
      SPI_RWBYTE(0x00);
      SPI_RWBYTE(0x00);
      SPI_RWBYTE(0x00);
    }

////配置寄存器
    SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x58);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x58);

//通道0设置寄存器
    SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_cconfig);
    SPI_RWBYTE( 0x40 );//GEN64|BIT(cc_WR1) );
    SPI_RWBYTE( 0x30 );
    SPI_RWBYTE( 0x40 );//GEN64|BIT(cc_WR1) );
    SPI_RWBYTE( 0x30 );

//偏移寄存器 0
    SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_offset);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);

//增益寄存器 增益64倍
    SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_gain);
    SPI_RWBYTE( 0x3f );//BIT(5));
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);

    delay1us();

//执行校准
    SPI_RWBYTE(CMD1|CMD1_adj_offset);//自偏移校准
        _delay_us(100);
    SPI_RWBYTE(CMD1|CMD1_adj_gain);//自增益校准
        _delay_us(100);
////while(isADCnotReady());
}



//=======================================
//          CS5532开始转换
//      作用:发送转换命令
//                  i=0,1 通道号
//=======================================
uint8_t adcstatu;
#define isADCOver   0
#define isoverflow1

void
start_adc(uint8_t n)
{
    if ( isbit(adcstatu,isADCOver) )
    {
      clrbit(SPI_PORT,SCK);//时钟低
      enable_spi();
      delay1us();
      SPI_RWBYTE( CMD1 | CMD1_step | CMD1_cconfig(n)| CMD1_convert );

      clrbit(adcstatu,isADCOver); //清0 标记正在转换中,数据还未读取
      delay1us();
      disable_spi();        
    }
}


//=======================================
//          读CS5534转换数据
//      作用:当ADC转换完毕后
//                                  发送空字节,读取数据
//                  i=0,1,2,3 通道号
//=======================================
bool
cs5532_read(int32_t* value)
{
    uint32_tval;
    uint8_t c;

    start_adc(0);

    clrbit(SPI_PORT,SCK);
        NOP();
    clrbit(SPI_PORT,SDI);
    clrbit(SPI_PORT,SDO);
        enable_spi(); //SPI禁止
        _delay_us(100);

        delay1us();
    if ( isbit(SPI_PIN,SDO) )
    {
       return false;
    };
    uart_send_byte(2);


    clrbit(SPI_PORT,SCK); //时钟低
        enable_spi();         //SPI使能
        delay1us();

    //SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_data);
        //SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_gain);
    //SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_config);
        delay1us();
    val=SPI_RWBYTE(0x00);

    val<<=8;
    val|=SPI_RWBYTE(0x00);
        val<<=8;
    val|=SPI_RWBYTE(0x00);
        val<<=8;
    val|=SPI_RWBYTE(0x00);

    setbit(adcstatu,isADCOver); //置1 标记这次转换完成,数据已经读取

    disable_spi();//SPI禁止
    delay1us();

    c=val.arr;
    if (val.arr&0x80)
    {

      *value=(((~val.val)+1)/0x100);
    }
    else
    {
      *value = (val.val/0x100);
    }

    if (c&0x04)
    {
      adcstatu|=BIT(isoverflow);
      return false;
    }
    else
    {
      adcstatu&=~BIT(isoverflow);
    }
    return true;

}

#endif

knight_avr 发表于 2009-4-12 13:39:09

#ifndef _spi_h_
#define _spi_h_

#include <avr/io.h>
#include "macros.h"
#include "define.h"


//=================================
//       SPI 硬件接口引脚定义
//=================================
#define    SPI_PORT   PORTB
#define    SPI_DDR    DDRB
#define    SPI_PIN    PINB
#define    SCK      PB5      /*数据传输脉冲*/
#define    MISO       PB4      /*主机--数据输入*/
#define        MOSI       PB3           /*主机--数据输出*/
#define        SS       PB2           /*片选 低电平有效*/
#define    INT      PD3      /*中断信号 低电平有效*/

#define           SCLK          SCK
#define           SDO          MISO
#define           SDI          MOSI
#define           CS          SS

#define    enable_spi()    clrbit( SPI_PORT,SS )
#define           disable_spi()   setbit( SPI_PORT,SS )


//================================
//       SPI 初始化
//接收和发送:高位在前
//================================
void
init_spi(void)
{
    clrbit(SPI_PORT,MOSI);
    clrbit(SPI_PORT,SCK);
    clrbit(SPI_PORT,MISO);
    setbit(SPI_PORT,SS);
    setbit(PORTD,INT);

    setbit(SPI_DDR,SCK);
    setbit(SPI_DDR,MOSI);
    setbit(SPI_DDR,SS);
    clrbit(SPI_DDR,MISO);
    clrbit(DDRD,INT);

    SPCR = BIT(SPE)|BIT(MSTR)|BIT(SPR1)|BIT(SPR0);////SPI使能主机模式fos/128频率
}


//================================
//      spi 发送 1个字节
//================================
uint8_t
SPI_RWBYTE(uint8_t byte)
{
    //enable_spi();
    delay1us();
    SPDR = byte;
    while (!(SPSR & BIT(SPIF)));
    delay1us();
    //disable_spi();
    return SPDR;
}

#endif

knight_avr 发表于 2009-4-12 14:03:03

自己顶一下

在线等哦!

ilikemcu 发表于 2009-4-12 15:33:04

N年前用过CS5532AS,用的也是M8,用SPI的查询模式做读取的,还可以,不过后来让人给模仿了,呵呵,后来就没再去捣鼓它了。
之所以没用中断读取,是因为项目时间紧迫,加上使用4.9M的晶振,M8的实际大多富裕到没事可干的地步,所以本着稳定压倒一切的原则用了查询模式,呵呵。

代码已经找不到了,不过SPI的初始化我依稀记得就是参考那帮蓝色封面的AVR的C语言编程书上修改过来的,好用。

quray 发表于 2009-4-12 17:06:56

能发出来吗?

knight_avr 发表于 2009-4-12 18:15:19

TO ilikemcu 我爱单片机 非常感谢!

SPI 初始化是肯定没有错的

SPI和其他一块芯片CS1180通讯是没有问题的,但是CS1180位数稍微少了点 只有20位 放大128倍的时候 只有17位是稳定的(经过实践,最好效果也只有这么多了)

所以改用 CS5532 但是M8对CS5532操作 采用查询SDO是否为低电平 来取数据的但是SDO总是为高 不知道为什么

本来想用ADS1246 但是申请样片的时候 说没有库存了 郁闷啊!

knight_avr 发表于 2009-4-12 18:20:47

to quray
你是要我发出来什么?

代码都在上面的俄

knight_avr 发表于 2009-4-12 19:11:06

=啊
=啊
=个兄弟给我提供一代码哦
非常感谢!!!^-^

ilikemcu 发表于 2009-4-12 19:38:41

估计你没做好CS5532的初始化了,呵呵,所以它没启动转换,当然SDO当然没有出来了。

knight_avr 发表于 2009-4-13 08:18:43


应该是初始化没有成功!

我的初始化 是按照芯片手册上 一步步 写的,后来对照了很久,还是没有查出原因,

今天又是新的一天,继续等哦 ^-^

illusion 发表于 2009-4-13 09:44:19

////进入命令模式
    for (i=0;i<18;i++) SPI_RWBYTE(SYNC1);
    SPI_RWBYTE(SYNC1);                        
    delay1us();
这里好像不太对吧,是先发送15个0xff,再发送一个0xfe!

knight_avr 发表于 2009-4-14 19:14:52

LS
你真好
我查了这么多可能出现问题 的地方 就是这个地方没有查 ,应该是

////进入命令模式
    for (i=0;i<18;i++) SPI_RWBYTE(SYNC1);
    SPI_RWBYTE(SYNC0);                        
    delay1us();

呵呵
我改过来 明天去公司试试
太感谢了!!

knight_avr 发表于 2009-4-14 19:15:58

不知道为什么当初都写成了 “SYNC1”粗心啊 会害死人的

knight_avr 发表于 2009-4-17 09:46:05

呵呵试过了
还是不行
估计还有其他问题没有解决
如果不检测SDO电平的话,读出来都是0xFF

knight_avr 发表于 2009-4-17 09:47:13

继续求助!

===========一直到天荒地老

ThinkCell 发表于 2009-4-17 13:07:42

knight_avr:

   你可以试一下这个办法,SYNC1+SYNC0共计发送31个字节的FFH,一个字节FEH

   天道酬勤,祝你好运。

knight_avr 发表于 2009-4-17 13:21:45

谢谢!!

您是不是王工,看你的签名很像的哦,

太感谢您了,我去试试!看

knight_avr 发表于 2009-4-21 23:33:54

搞定,能读出数据了

现在还有些参数没有调试好
1、输出速率我选择的是 30HZ 感觉数据变化好慢了
2、数据有点不稳定,24位我屏蔽了最后2位 感觉还是有点跳动太大,加上滤波之后,有感觉数据滞后太大了

knight_avr 发表于 2009-4-21 23:34:14

正确代码如下:
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef _cs5532_h_
#define _cs5532_h_

#include <util/delay.h>
#include "macros.h"
#include "define.h"
#include "spi.h"

/*
//================================
//                CS5532驱动
//                AVR_C代码M8
//                谭志平 2009-4-21
//=================================
*/
#include <avr/io.h>
#include "macros.h"
#include "define.h"
#include "func.h"
#include "spi.h"

#define SYNC1               0xff
#define SYNC0               0xfe

#define CMD0                  0
#define ARA                   BIT(6)      /*整列方式访问通道0、1的寄存器*/
#define _CS0                  4
#define _CS1                  5
#define CMD0_COMM0            0
#define CMD0_COMM1            BIT(_CS0)
#define CMD0_WRITE            0
#define CMD0_READ             BIT(3)
#define CMD0_reg_offset       0x01
#define CMD0_reg_gain         0x02
#define CMD0_reg_config       0x03
#define CMD0_reg_data         0x04
#define CMD0_reg_cconfig      0x05

#define CMD1                  0x80
#define CMD1_step             0
#define CMD1_continue         BIT(6)
#define CMD1_cconfig(x)       ((x)<<3)
#define CMD1_convert          0
#define CMD1_adj_offset       1
#define CMD1_adj_gain         2
#define CMD1_adj_sys_offset   5
#define CMD1_adj_sys_gain   6

////配置寄存器
#define PSS      7   /* 节电模式选择 */
#define PDW      6   /* 节电模式 */
#define RS       5   /* 系统复位 */
#define RV       4   /* 复位有效 */
#define IS       3   /* 输入短路 */
#define GB       2   /* 保护信号位 */
#define VRS      1   /* 参考电压选择 */
#define A1       0   /* 输出锁存位1 */

#define A0       7   /* 输出锁存位0 */
#define OLS      6   /* 输出锁存选择 */

////通道配置寄存器
#define cc_CS17
#define cc_CS06
#define cc_G2   5
#define cc_G1   4
#define cc_G0   3
#define GEN64   ( BIT(cc_G2)|BIT(cc_G1) )
#define GEN32   ( BIT(cc_G2)|BIT(cc_G0) )
#define cc_WR32
#define cc_WR21
#define cc_WR10

#define cc_WR07
#define cc_UB   6
#define cc_OL15
#define cc_OL04
#define cc_DT   3
#define cc_OCD2

#define    isADCnotReady()    ( isbit(SPI_PIN,SDO) )

boolisADCOver;
//=======================================
//         CS5532初始化程序
//      作用:cs5532 AD转换器
//=======================================
void
init_cs5532(void)
{
    uint8_t i;

        isADCOver=true;

    enable_spi_0();//SPI使能
    delay1us();

    clrbit(SPI_PORT,SDI);       
        clrbit(SPI_PORT,SCK);

////进入命令模式
    for (i=0;i<31;i++) SPI_RWBYTE(SYNC1);
    SPI_RWBYTE(SYNC0);                       
    delay1us();

////RS=1复位 (写配置寄存器)
    SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
    SPI_RWBYTE(BIT(RS));
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
        _delay_ms(5);
    delay1us();

////等待复位完毕
    i=0;
    while ( isbit(i,RV) )
    {
      SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_READ|CMD0_reg_config);
      delay1us();
      i=SPI_RWBYTE(0x00);
      SPI_RWBYTE(0x00);
      SPI_RWBYTE(0x00);
      SPI_RWBYTE(0x00);
    }

////配置寄存器
    SPI_RWBYTE( CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_config);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);

//通道0设置寄存器
    SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_cconfig);
    SPI_RWBYTE( GEN64 | 0x01);
    SPI_RWBYTE( 0x00   );
    SPI_RWBYTE( 00);
    SPI_RWBYTE( 00);

//偏移寄存器 0
    SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_offset);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);
    SPI_RWBYTE(0x00);

//增益寄存器 增益64倍
    SPI_RWBYTE(CMD0|CMD0_COMM0|CMD0_WRITE|CMD0_reg_gain);
    SPI_RWBYTE( 0b00100000 );
    SPI_RWBYTE( 0x00   );
    SPI_RWBYTE( 0x00   );
    SPI_RWBYTE( 0x00   );

    delay1us();

//执行校准
    SPI_RWBYTE(CMD1|CMD1_adj_offset);//自偏移校准
        _delay_us(100);
    SPI_RWBYTE(CMD1|CMD1_adj_gain);//自增益校准

    while(isADCnotReady());
}



//=======================================
//          CS5532开始转换
//      作用:发送转换命令
//                  i=0,1 通道号
//=======================================

void
start_adc(void)
{
    if ( isADCOver )
    {
               clrbit(SPI_PORT,SDI);
      clrbit(SPI_PORT,SCK);//时钟低

      enable_spi_0();
      delay1us();
      SPI_RWBYTE( CMD1 | CMD1_step | CMD1_cconfig(0)| CMD1_convert );

      isADCOver=false; // 标记正在转换中,数据还未读取
      delay1us();
      disable_spi_0();        
    }
}


//=======================================
//          读CS5534转换数据
//      作用:当ADC转换完毕后
//                                  发送空字节,读取数据
//                  i=0,1,2,3 通道号
//=======================================
bool
cs5532_read(int32_t* value)
{
    Tint32val;

    start_adc();

        enable_spi_0();
    clrbit(SPI_PORT,SCK);
    clrbit(SPI_PORT,SDI);
       
    if ( isADCnotReady() )
    {
       return false;
    };

        delay1us();

        SPI_RWBYTE(00); //清SDO标志
        delay1us();

    //uart_send_byte( SPI_RWBYTE(0x00) );
        //uart_send_byte( SPI_RWBYTE(0x00) );
        //uart_send_byte( SPI_RWBYTE(0x00) );
        //uart_send_byte( SPI_RWBYTE(0x00) );

        val.arr=SPI_RWBYTE(0x00);
    val.arr=SPI_RWBYTE(0x00);
    val.arr=SPI_RWBYTE(0x00);
    val.arr=SPI_RWBYTE(0x00);

        *value=( val.val / (256 * 4) ); ///去掉无效低8位 和跳动2位

    disable_spi_0();//SPI禁止
    delay1us();

        isADCOver=true;

        return true;
}

#endif

knight_avr 发表于 2009-4-21 23:40:20

搞定,能读出数据了

现在还有些参数没有调试好
1、输出速率我选择的是 30HZ 感觉数据变化好慢了
2、数据有点不稳定,24位我屏蔽了最后2位 感觉还是有点跳动太大,加上滤波之后,有感觉数据滞后太大了

ourdev_bear 发表于 2009-5-5 20:57:54

呵呵,大家好,我也在做CS5532,数据是读出来了,但是不知道如何校准什么的,希望和大家一起交流学习

ourdev_bear 发表于 2009-5-5 21:17:07

求助,请问自偏移校准、自增益校准及其滤波那些如何操作

ourdev_bear 发表于 2009-5-6 10:21:21

我也是数据很不稳定,怎么处理一下呀

ourdev_bear 发表于 2009-5-6 17:44:28

大家交流一下吧,qq 113630402

quray 发表于 2009-7-3 19:04:48

我现在用vhdl来写这个程序,从示波器上看到RV位已经置1,说明ad复位成功了,但是sdo始终不能变低,为什么啊?
有哪位用vhdl写过这个啊?

wjchang724 发表于 2009-7-13 09:50:05

问一下:
我读写cs5532的设置寄存器和通道寄存器时,均没问题。

但是读采集值时,老是0001ff00其中的01是最后的通道数,修改通道会变,但总能读对。
还有 0001ff   00老是循环被读出。

leofoolish 发表于 2011-11-23 18:13:28

CS5532 MARK一下

watch186 发表于 2012-11-1 23:03:12

你好LZ我现在搞CS5532也是遇到你的问题SDO一直都是高电平   您当时是哪里出问题啦呢???
页: [1]
查看完整版本: 求助--我使用CS5532做AD转换SDO一直不会变低