[STM32] 驱动cs530

[复制链接]
 楼主| babyrabbit 发表于 2018-5-9 09:40 | 显示全部楼层 |阅读模式
pi, gp, GPIO, IO, ni
请教各位大神,用stm32驱动的cs5530,用的是模拟SPI,用串口发到上位机,时而能采集到数,但是大多时候采集的是0.时而采到的数是正确的,猜想还是模拟SPI哪里出现了问题。请问各位大神有什么好的解决办法吗,这个软件调试、时钟和sdi都能正常写指令的,用示波器看 时钟质量非常不好,sdi看不到数据 sdo根本没有。
  1. #include "cs5530.h"
  2. #include "delay.h"
  3. #include "sys.h"


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


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

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

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

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


  13. void CS5530_PORT_INIT( void )  /* 由于使用软件模拟SPI读写时序,所以进行初始化 */
  14. {
  15.         
  16.         GPIO_InitTypeDef GPIO_InitStructure;
  17.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); //使能pc端口时钟
  18.   
  19.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_12|GPIO_Pin_15; //
  20.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  21.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  22.     GPIO_Init(GPIOB,&GPIO_InitStructure);
  23.         
  24.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
  25.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     //上拉输入
  26.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  27.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  28.                

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


  32. void Write_CS5530(unsigned char Dat)
  33. {
  34.    
  35.   unsigned char Count;
  36.         for( Count=0; Count<8; Count++ )
  37.          {
  38.                 if(Dat & 0x80)
  39.                  {SET_ADI;}
  40.                 else
  41.                  {CLR_ADI;}
  42.                 delay_us(1);
  43.                 SET_ADSCK;
  44.                 delay_us(1);
  45.                 CLR_ADSCK;
  46.                 delay_us(1);
  47.                 Dat <<= 1;
  48.      }
  49. CLR_ADI;
  50. delay_us(1);
  51.    
  52. }
  53. //
  54. unsigned char Recive_CS5530(void)
  55. {
  56.    unsigned char Count;
  57.    unsigned char Dat=0;
  58.    CLR_ADI;
  59.    delay_us(3);
  60.         for( Count=0; Count<8; Count++ )
  61.         {
  62.                 SET_ADSCK;
  63.                 delay_us(1);
  64.                 Dat <<= 1;
  65.                 if( GET_ADO ) Dat |= 0x01 ;
  66.                 CLR_ADSCK;
  67.                 delay_us(1);
  68.         }
  69. return(Dat);

  70. }

  71. void Write_CS5530_Register(unsigned char Command,unsigned long setData)
  72. {

  73.    Write_CS5530( Command );
  74.    Write_CS5530( (unsigned char)(setData>>24) );
  75.    Write_CS5530( (unsigned char)(setData>>16) );
  76.    Write_CS5530( (unsigned char)(setData>>8) );
  77.    Write_CS5530( (unsigned char)(setData>>0) );

  78. }


  79. unsigned long Read_CS5530_Register(unsigned char Command)
  80. {
  81.    unsigned long temp=0;
  82.    Write_CS5530( Command );
  83.    temp = Recive_CS5530();
  84.    temp = temp << 8;
  85.    temp += Recive_CS5530();
  86.    temp = temp << 8;
  87.    temp = Recive_CS5530();
  88.    temp = temp << 8;
  89.    temp += Recive_CS5530();
  90.    return temp;

  91. }

  92. void Init_CS5530(void)
  93. {
  94.   unsigned long temp;
  95.   unsigned char i;
  96. // SPI IO 初始化行为

  97.   CS5530_PORT_INIT();

  98.   CLR_ADSCK;
  99.   CLR_ADCS;
  100.   delay_ms(100);
  101. // SPI 串口归位
  102.         for( i=0; i<20; i++ )
  103.         {
  104.         Write_CS5530(SYNC1);
  105.         }
  106.         Write_CS5530(SYNC0);
  107. // 系统复位

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


  114.         // 设置偏移寄存器
  115.         Write_CS5530_Register(Write_OFFSET,0x00000000);
  116.         delay_ms(50);
  117.         // 设置增益寄存器
  118.         Write_CS5530_Register(Write_GAIN,0x0f000000);
  119.         delay_ms(50);
  120.         // 设置配置寄存器,设置参考电压,信号极性,字速度等等
  121.         //Write_CS5530_Register(Write_CONFIG,0x02004800);
  122.         //Delay_ms(50);
  123.         temp = 0x00;
  124.         temp |= UNIPOLAR_MODE; // 单极性
  125.         temp |= LINE_FREQ_50; // 滤波选择缺省滤波字
  126.         temp |= DATARATE_25;
  127.         temp |= NORMAL_MODE; // 普通操作
  128.         temp |= VREF_LOW; // VREF_HIGH 为 2.5V 基准; VREF_LOW 为 1-2.5V 基准
  129.         temp |= CR_A0_0;
  130.         temp |= CR_A1_0;
  131.         temp |= TURN_OFF_300NA; // 不激活电流源
  132.         Write_CS5530_Register(Write_CONFIG,temp);
  133.         delay_ms(50);
  134.         //启动转换
  135.         Write_CS5530( START_CONTINUOUS + NORMAL_CONVERSION); // 单次转换
  136. }

  137. // 读取数据转换的结果
  138. unsigned long Get_Ad(void)
  139. {
  140.         unsigned long temp;
  141.         do                          //等待转换完成
  142.         {
  143.         ;
  144.         }while(GET_ADO);
  145.         CLR_ADI;
  146.         Write_CS5530( NULL_BYTE ); // 清除串口标志同时选择转换模式(单次连续还是结束单次连续)
  147.         temp = Recive_CS5530();
  148.         temp = temp << 8;
  149.         temp += Recive_CS5530();
  150.         temp = temp << 8;
  151.         temp += Recive_CS5530();
  152.         temp = temp << 8;
  153.         temp += Recive_CS5530();
  154.         //Write_CS5530( START_SINGLE + NORMAL_CONVERSION); // 单次转换
  155. return temp;
  156. }

  157. #ifndef __CS5530_H__
  158. #define __CS5530_H__

  159. #include "delay.h"
  160. #include "sys.h"

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

  212. void Init_CS5530(void);
  213. unsigned long Get_Ad(void);
  214. //void CS5530_PORT_INIT( void );
  215. #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 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

23

主题

88

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部