babyrabbit 发表于 2018-5-9 09:40

驱动cs530

请教各位大神,用stm32驱动的cs5530,用的是模拟SPI,用串口发到上位机,时而能采集到数,但是大多时候采集的是0.时而采到的数是正确的,猜想还是模拟SPI哪里出现了问题。请问各位大神有什么好的解决办法吗,这个软件调试、时钟和sdi都能正常写指令的,用示波器看 时钟质量非常不好,sdi看不到数据 sdo根本没有。#include "cs5530.h"
#include "delay.h"
#include "sys.h"


//毫秒级延时函数
#define      TIME1


#define          SET_ADCS         PBout(15)=1;
#define          CLR_ADCS            PBout(15)=0;

#define   SET_ADSCK    PBout(12)=1;         //spiSCK输出高
#define   CLR_ADSCK    PBout(12)=0;         //spiSCK输出低

#define   SET_ADI      PBout(14)=1;         //MOSI输出高
#define   CLR_ADI      PBout(14)=0;         //MOSI输出低

#define   GET_ADO      PBin(13)               //MISO输入高


void CS5530_PORT_INIT( void )/* 由于使用软件模拟SPI读写时序,所以进行初始化 */
{
      
      GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); //使能pc端口时钟

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_12|GPIO_Pin_15; //
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB,&GPIO_InitStructure);
      
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   //上拉输入
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOB, &GPIO_InitStructure);
               

/* 对于双向I/O引脚模拟SPI接口,那么必须在此设置SPI_SCS,SPI_SCK,SPI_SDI为输出方向,SPI_SDO为输入方向 */
         
}


void Write_CS5530(unsigned char Dat)
{
   
unsigned char Count;
      for( Count=0; Count<8; Count++ )
         {
                if(Dat & 0x80)
               {SET_ADI;}
                else
               {CLR_ADI;}
                delay_us(1);
                SET_ADSCK;
                delay_us(1);
                CLR_ADSCK;
                delay_us(1);
                Dat <<= 1;
   }
CLR_ADI;
delay_us(1);
   
}
//
unsigned char Recive_CS5530(void)
{
   unsigned char Count;
   unsigned char Dat=0;
   CLR_ADI;
   delay_us(3);
      for( Count=0; Count<8; Count++ )
      {
                SET_ADSCK;
                delay_us(1);
                Dat <<= 1;
                if( GET_ADO ) Dat |= 0x01 ;
                CLR_ADSCK;
                delay_us(1);
      }
return(Dat);

}

void Write_CS5530_Register(unsigned char Command,unsigned long setData)
{

   Write_CS5530( Command );
   Write_CS5530( (unsigned char)(setData>>24) );
   Write_CS5530( (unsigned char)(setData>>16) );
   Write_CS5530( (unsigned char)(setData>>8) );
   Write_CS5530( (unsigned char)(setData>>0) );

}


unsigned long Read_CS5530_Register(unsigned char Command)
{
   unsigned long temp=0;
   Write_CS5530( Command );
   temp = Recive_CS5530();
   temp = temp << 8;
   temp += Recive_CS5530();
   temp = temp << 8;
   temp = Recive_CS5530();
   temp = temp << 8;
   temp += Recive_CS5530();
   return temp;

}

void Init_CS5530(void)
{
unsigned long temp;
unsigned char i;
// SPI IO 初始化行为

CS5530_PORT_INIT();

CLR_ADSCK;
CLR_ADCS;
delay_ms(100);
// SPI 串口归位
      for( i=0; i<20; i++ )
      {
      Write_CS5530(SYNC1);
      }
      Write_CS5530(SYNC0);
// 系统复位

   Write_CS5530_Register(Write_CONFIG,SYSTEM_RESET); //写配置寄存器写入 CS5530RS 为 1
   delay_ms(50);
      do
      {//检测 RV 是否为 0(复位成功后为 0),如果不为 0 再继续读取配置寄存器
      temp = Read_CS5530_Register( Read_CONFIG );
      } while( temp & RESET_STATUS );


      // 设置偏移寄存器
      Write_CS5530_Register(Write_OFFSET,0x00000000);
      delay_ms(50);
      // 设置增益寄存器
      Write_CS5530_Register(Write_GAIN,0x0f000000);
      delay_ms(50);
      // 设置配置寄存器,设置参考电压,信号极性,字速度等等
      //Write_CS5530_Register(Write_CONFIG,0x02004800);
      //Delay_ms(50);
      temp = 0x00;
      temp |= UNIPOLAR_MODE; // 单极性
      temp |= LINE_FREQ_50; // 滤波选择缺省滤波字
      temp |= DATARATE_25;
      temp |= NORMAL_MODE; // 普通操作
      temp |= VREF_LOW; // VREF_HIGH 为 2.5V 基准; VREF_LOW 为 1-2.5V 基准
      temp |= CR_A0_0;
      temp |= CR_A1_0;
      temp |= TURN_OFF_300NA; // 不激活电流源
      Write_CS5530_Register(Write_CONFIG,temp);
      delay_ms(50);
      //启动转换
      Write_CS5530( START_CONTINUOUS + NORMAL_CONVERSION); // 单次转换
}

// 读取数据转换的结果
unsigned long Get_Ad(void)
{
      unsigned long temp;
      do                        //等待转换完成
      {
      ;
      }while(GET_ADO);
      CLR_ADI;
      Write_CS5530( NULL_BYTE ); // 清除串口标志同时选择转换模式(单次连续还是结束单次连续)
      temp = Recive_CS5530();
      temp = temp << 8;
      temp += Recive_CS5530();
      temp = temp << 8;
      temp += Recive_CS5530();
      temp = temp << 8;
      temp += Recive_CS5530();
      //Write_CS5530( START_SINGLE + NORMAL_CONVERSION); // 单次转换
return temp;
}

#ifndef __CS5530_H__
#define __CS5530_H__

#include "delay.h"
#include "sys.h"

//------------------------------------
//-- CS5530 专有宏定义
#define SYNC1 0xff //串行口初始化序列命令之一
#define SYNC0 0xfe //串行口初始化序列结束命令
#define NULL_BYTE 0x00 //用来清除端口标志位使得转换器保持在连续转换模式
#define CMD_WRITE (0x00<<3) // 写寄存器命令
#define CMD_READ (0x01<<3) // 读寄存器命令
//Command Register
#define Write_OFFSET 0x01 //写偏移寄存器
#define Read_OFFSET 0x09 //读偏移寄存器
#define Write_GAIN 0x02 //写增益寄存器
#define Read_GAIN 0x0a //读增益寄存器
#define Write_CONFIG 0x03 //写配置寄存器
#define Read_CONFIG 0x0b //读配置寄存器
#define START_SINGLE (0X00<<6) //单次转换
#define START_CONTINUOUS (0X01<<6) //连续转换
#define NORMAL_CONVERSION (0x80+0x00)//转换命令
#define SYSTEM_OFFSET_CAL 0x85 //执行系统偏移校准
#define SYSTEM_GAIN_CAL 0x86 //执行系统增益校准
//Configuration Register
#define STANDBY_MODE (0x00L<<31) //待机模式
#define SLEEP_MODE (0x01L<<31) //休眠模式
#define POWER_SAVE_MODE (0x01L<<30) //节电模式
#define NORMAL_MODE (0x00L<<29) //正常操作
#define SYSTEM_RESET (0x01L<<29) //激活一个复位周期复位后自动清0
#define RESET_STATUS (0x01L<<28) //复位有效系统已复位只读
//#define SHORT_INPUTS (0x00L<<27) //输入正常输入个通道输入不断接
#define SHORT_INPUTS (0x01L<<27) //输入正常输入个通道输入不断接
#define VREF_HIGH (0x00L<<25) //参考电压 2.5~((VA+)-(VA-))V
#define VREF_LOW (0x01L<<25) //参考电压 1~2.5V
#define CR_A1_0 (0x00L<<24)
#define CR_A1_1 (0x01L<<24)
#define CR_A0_0 (0x00L<<23)
#define CR_A0_1 (0x01L<<23)
#define LINE_FREQ_60 (0x00L<<19) //滤波数率选择缺省输入字
#define LINE_FREQ_50 (0x01L<<19) //输出字数率及相应滤波器特性乘以系数5/6
#define DATARATE_100 (0x00L<<11) //字数率不同位就不同
#define DATARATE_50 (0x01L<<11)
#define DATARATE_25 (0x02L<<11)
#define DATARATE_12P5 (0x03L<<11)
#define DATARATE_6P25 (0x04L<<11)
#define DATARATE_3200 (0x08L<<11)
#define DATARATE_1600 (0x09L<<11)
#define DATARATE_800 (0x0aL<<11)
#define DATARATE_400 (0x0bL<<11)
#define DATARATE_200 (0x0cL<<11)
#define DATARATE_BIT (0x0fL<<11)
#define BIPOLAR_MODE (0x00L<<10) //极性选择双极性模式
#define UNIPOLAR_MODE (0x01L<<10) //极性选择单极性模式
#define TURN_OFF_300NA (0x00L<<9) //不激活电流源
#define TURN_ON_300NA (0x01L<<9) //激活电流源 300ma

void Init_CS5530(void);
unsigned long Get_Ad(void);
//void CS5530_PORT_INIT( void );
#endif


一路向北lm 发表于 2018-5-9 11:14

调下延时,是不是读取速度太快了,可以添加个定时器,每秒读取一次数据。

babyrabbit 发表于 2018-5-12 19:26

一路向北lm 发表于 2018-5-9 11:14
调下延时,是不是读取速度太快了,可以添加个定时器,每秒读取一次数据。 ...

经调试,能采集数了,不过非常不稳定,采集的信号还没有输入的信号稳定。。硬件部分输入信号能稳定到0.01mv。供电电压也是。所以软件配置可能还有问题,请问有什么解决办法吗,另外这个芯片需要校准,我不会用,有没有用过这个芯片的大神啊,请教一下。。

linda_6000 发表于 2018-12-28 14:17

可以用STM32的SPI来读数据,我用SPI2可以读数据,但是有时有串位的情况,强制调整可以用,只是不知道为什么。

slot867 发表于 2024-1-31 15:14

fully compatible. 板子拿来,换个芯片,性能更佳。MCU不用改 c code。

平替Cirrus Logic芯片
SIG5532B 平替 CS5532BS(32-bit)
SIG5534B 平替 CS5534BS(32-bit)
SIG5532A 平替 CS5532AS(24-bit)
SIG5534A 平替 CS5534AS(24-bit)
SIG5530 平替 CS5530 (24-bit)
SIG5530B 平替 CS5530(32-bit)

平替ADI芯片
SIG7792 平替 AD7792
SIG7793 平替 AD7793
SIG7794 平替 AD7794
SIG7795 平替 AD7795
SIG7796 平替 AD7796
SIG7797 平替 AD7797
SIG7798 平替 AD7798
SIG7799 平替 AD7799

平替TI芯片
SIG1230A 平替 ADS1230 (20-bit)
SIG1232A 平替 ADS1232 (24-bit)

平替ADI芯片
SIG7190 平替 AD7190
SIG7192 平替 AD7192
SIG7193 平替 AD7193

功能替代TI芯片
SIG24130/SIG24131/SIG24132 替代 ADS1220、ADS1247、ADS1248
SIG16130/SIG16131/SIG16132 替代 ADS1120、ADS1147、ADS1148

zwsam 发表于 2024-2-9 14:21

zwsam 发表于 2024-2-9 14:22

页: [1]
查看完整版本: 驱动cs530