打印
[程序源码]

cs5530 驱动

[复制链接]
3073|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
babyrabbit|  楼主 | 2018-5-7 21:00 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教各位大神,用stm32驱动的cs5530,用的是模拟SPI,用串口发到上位机,时而能采集到数,但是大多时候采集的是0.时而采到的数是正确的,猜想还是模拟SPI哪里出现了问题。请问各位大神有什么好的解决办法吗
#include "cs5530.h"
#include "delay.h"
#include "sys.h"


//毫秒级延时函数
#define        TIME  1


#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

相关帖子

沙发
babyrabbit|  楼主 | 2018-5-8 12:33 | 只看该作者
本帖最后由 babyrabbit 于 2018-5-9 09:37 编辑

这个软件调试、时钟和sdi都能正常写指令的,用示波器看 时钟质量非常不好,sdi看不到数据 sdo根本没有。

使用特权

评论回复
板凳
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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

88

帖子

3

粉丝