[测量] 称重 cs5530

[复制链接]
128|4
 楼主 | 2018-5-11 21:32 | 显示全部楼层 |阅读模式
本帖最后由 babyrabbit 于 2018-5-11 21:42 编辑

用stm32配置的cs5530,配置代码如下,现在采集的数,放大一倍,能稳定到零点几个毫伏,精度不够。看芯片手册,需要进行校准,没太看懂,那个CC2-CC0位没找到。请问大神这个怎么具体执行校准啊,还有就是硬件电路输入信号部分我直接输入的,有什么滤波电路推荐吗?(除了算法滤波)
  1. // 设置偏移寄存器
  2.         Write_CS5530_Register(Write_OFFSET,0x00000000);
  3.         delay_ms(50);
  4.         // 设置增益寄存器
  5.         Write_CS5530_Register(Write_GAIN,0x0f000000);
  6.         delay_ms(50);
  7.         // 设置配置寄存器,设置参考电压,信号极性,字速度等等
  8.         //Write_CS5530_Register(Write_CONFIG,0x02004800);
  9.         //Delay_ms(50);
  10.         temp = 0x00;
  11.         temp |= UNIPOLAR_MODE; // 单极性
  12.         temp |= LINE_FREQ_60; // 滤波选择缺省滤波字
  13.         temp |= DATARATE_25;
  14.         temp |= NORMAL_MODE; // 普通操作
  15.         temp |= VREF_HIGH; // VREF_HIGH 为 2.5V 基准; VREF_LOW 为 1-2.5V 基准
  16.         temp |= CR_A0_0;
  17.         temp |= CR_A1_0;
  18.         temp |= TURN_OFF_300NA; // 不激活电流源
  19.         Write_CS5530_Register(Write_CONFIG,temp);
  20.         delay_ms(50);        
  21.         Write_CS5530( SYSTEM_OFFSET_CAL);        //执行系统偏移校准
  22.         Write_CS5530( SYSTEM_GAIN_CAL);                // 执行系统增益校准
  23.         //启动转换
  24.         Write_CS5530( START_CONTINUOUS + NORMAL_CONVERSION); // 单次转换
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
| 2018-5-12 14:22 | 显示全部楼层
  1. /*========================CS5530驱动程序头文件==========================*/
  2. //cs5530.h
  3. #ifndef __cs5530_h__
  4. #define __cs5530_h__
  5. #define SYNC1 0xff
  6. #define SYNC0 0xfe
  7. #define NULL_BYTE 0x00
  8. // Command Register
  9. #define CMD_WRITE (0x00<<3)                //写寄存器命令
  10. #define CMD_READ (0x01<<3)                //读寄存器命令
  11. #define REG_OFFSET 0x01                    //偏移寄存器
  12. #define REG_GAIN 0x02                    //增益寄存器
  13. #define REG_CONFIG 0x03                    //配置寄存器
  14. #define START_SINGLE (0x00<<6)            //单次转换
  15. #define START_CONTINUOUS (0x01<<6)        //连续转换
  16. #define NORMAL_CONVERSION (0x80+0x00)    //转换命令
  17. #define SYSTEM_OFFSET_CAL (0x80+0x05)    //执行偏移校准
  18. #define SYSTEM_GAIN_CAL (0x80+0x06)        //执行增益校准
  19. // Configuration Register
  20. #define STANDBY_MODE (0x00L<<31)        //待机模式
  21. #define SLEEP_MODE (0x01L<<31)            //休眠模式
  22. #define POWER_SAVE_MODE (0x01L<<30)        //节电模式
  23. #define NORMAL_MODE (0x00L<<29)            //正常操作
  24. #define SYSTEM_RESET (0x01L<<29)        //激活一个复位周期,复位后自动清0
  25. #define RESET_STATUS (0x01L<<28)        //复位有效,系统已复位,只读
  26. #define SHORT_INPUTS (0x00L<<27)        //输入正常输入 个通道输入不断接
  27. #define VREF_HIGH (0x00L<<25)            //参考电压 2.5~((VA+)-(VA-))V
  28. #define VREF_LOW (0x01L<<25)            //参考电压 1~2.5V
  29. #define CR_A1_0 (0x00L<<24)
  30. #define CR_A1_1 (0x01L<<24)
  31. #define CR_A0_0 (0x00L<<23)
  32. #define CR_A0_1 (0x01L<<23)
  33. #define LINE_FREQ_60 (0x00L<<19)        //滤波数率选择 缺省输入字
  34. #define LINE_FREQ_50 (0x01L<<19)        //输出字数率及相应滤波器特性乘以系数5/6
  35. #define DATARATE_100 (0x00L<<11)        //字数率 不同位就不同
  36. #define DATARATE_50 (0x01L<<11)
  37. #define DATARATE_25 (0x02L<<11)
  38. #define DATARATE_12P5 (0x03L<<11)
  39. #define DATARATE_6P25 (0x04L<<11)
  40. #define DATARATE_3200 (0x08L<<11)
  41. #define DATARATE_1600 (0x09L<<11)
  42. #define DATARATE_800 (0x0aL<<11)
  43. #define DATARATE_400 (0x0bL<<11)
  44. #define DATARATE_200 (0x0cL<<11)
  45. #define BIPOLAR_MODE (0x00L<<10)        //极性选择双极性模式
  46. #define UNIPOLAR_MODE (0x01L<<10)        //极性选择单极性模式
  47. #define TURN_OFF_300NA (0x00L<<9)        //不激活电流源
  48. #define TURN_ON_300NA (0x01L<<9)        //激活电流源300ma
  49. void CS5530_Serial_Reset(void);
  50. void CS5530_System_Reset(void);
  51. void CS5530_Config(void);
  52. unsigned char CS5530_ADC_Ready(void);
  53. unsigned long CS5530_Result(void);
  54. #endif
  55. //============================CS5530驱动程序实现文件==============================
  56. //CS5530.C
  57. /*============================================================================
  58. 程序来源: 网络
  59. 排版加注: 孤独的牧羊人(http://tywood.blog.163.com)
  60. 日期:     2012.03.24
  61. ==============================================================================*/
  62. #include "w79e824.h"
  63. #include "cs5530.h"
  64. //#include                                //?
  65. sbit cs5530_clk=P0^5;                    //时钟脚
  66. sbit cs5530_cs=P1^6;                    //片选脚
  67. sbit cs5530_sdo=P0^6;                    //数据输出脚
  68. sbit cs5530_sdi=P0^7;                    //数据输入脚
  69. sbit SCK=P0^5;                            //时钟脚
  70. sbit MISO=P0^6;                            //数据MISO(主入从出)脚
  71. sbit MOSI=P0^7;                            //数据MOSI(主出从入)脚
  72. #define cs5530_clk_h    cs5530_clk=1    //时钟线拉高
  73. #define cs5530_clk_l    cs5530_clk=0;    //时钟线拉低
  74. #define cs5530_cs_h        cs5530_cs=1        //片选拉高(禁止器件)
  75. #define cs5530_cs_l        cs5530_cs=0        //片选拉低(选中器件)
  76. #define cs5530_in_h        cs5530_sdi=1    //MOSI输出1
  77. #define cs5530_in_l        cs5530_sdi=0    //MOSI输出0
  78. #define cs5530_out        cs5530_sdo        //读CS5530的输出数据位
  79. #define uint8_t unsigned char
  80. #define uint32_t unsigned long
  81. #define uchar unsigned char
  82. #define uint unsigned int
  83. //毫秒级延时函数
  84. void delay5530(uint iMs)
  85. {
  86.     uint cou;
  87.     uchar i;
  88.     for(cou=0;cou<iMs;cou++)
  89.     {
  90.         for(i=0;i<130;i++)
  91.         {_nop_();}
  92.     }
  93. }
  94. //SPI读写函数
  95. uchar SPI_RW(uchar byte)
  96. {
  97.     uchar ctr;
  98. //    cs5530_cs_l;                        //选中cs5530
  99.     for(ctr=0;ctr<8;ctr++)                //送出8个数据位
  100.     {
  101.         MOSI=(byte & 0x80);                //输出1个数据位(MSB)到MOSI
  102.         byte=(byte<<1);                    //移位,为送下一位数据作准备
  103.         SCK=1;                            //拉高时钟线让对方以旧换新数据位
  104.         _nop_();_nop_();_nop_();_nop_();//..
  105.         _nop_();_nop_();_nop_();_nop_();//
  106.         _nop_();_nop_();_nop_();_nop_();//..
  107.         _nop_();_nop_();_nop_();_nop_();//
  108.         byte|=MISO;                        //接收对方送出的数据位(MISO)
  109.         SCK=0;                            //拉低时钟线,使对方发送下一个数据位到总线上
  110.         _nop_();_nop_();_nop_();_nop_();//..
  111.         _nop_();_nop_();_nop_();_nop_();//
  112.         _nop_();_nop_();_nop_();_nop_();//..
  113.         _nop_();_nop_();_nop_();_nop_();//
  114.     }
  115.     // cs5530_cs_h;                        //取消cs5530片选信号
  116.     return(byte);                         //返回收到的字节数据
  117. }
  118. //向cs5530写一个字节
  119. void cs5530_write(uint8_t write_cs5530data)
  120. {
  121.     cs5530_cs_l;                        //选中cs5530
  122. /*    SPDR=write_cs5530data;                //使用SPI部件发数据
  123.     while(!(SPSR & (1<
  124. */
  125.     SPI_RW(write_cs5530data);            //使用模拟spi收发一个字节
  126.     cs5530_cs_h;                        //取消cs5530片选信号
  127. }
  128. //从cs5530读取一个字节
  129. uint8_t cs5530_read(void)
  130. {
  131.     uint8_t ad_number;
  132.     cs5530_cs_l;
  133. /*
  134.     SPDR=0xFF;                            //先发送一个空操作指令
  135.     while(!(SPSR & (1< ad_number=SPI_RW(0x00);
  136. /*    ad_number=SPDR;                        //读SPI
  137.     SPSR=0x00;
  138. */
  139.     cs5530_cs_h;
  140.     return ad_number;
  141. }
  142. //从cs5530读取一个双字
  143. uint32_t CS5530_Read_Dword ( void )
  144. {
  145.     unsigned long return_data;
  146.     return_data=cs5530_read();
  147.     return_data<<=8;
  148.     return_data+=cs5530_read();
  149.     return_data<<=8;
  150.     return_data+=cs5530_read();
  151.     return_data<<=8;
  152.     return_data+=cs5530_read();
  153.     return_data=return_data>>9;            //?
  154.     return (return_data);
  155. }
  156. //读取cs5530数据就绪状态
  157. uint8_t cs5530_check_over(void)
  158. {
  159.     uint8_t return_data;
  160.     cs5530_cs_h;                        //取消cs5530片选信号
  161.     _nop_();
  162.     cs5530_clk_l;                        //先把时钟信号置为低电平
  163.     _nop_();
  164.     _nop_();
  165.     cs5530_cs_l;                        //选中cs5530
  166.     _nop_();
  167.     _nop_();
  168.     _nop_();
  169.     return_data=cs5530_out;                //读取cs5530在SDO/RDY线上给出的数据就绪状态
  170.     return_data>>=3;                    //???
  171.     cs5530_cs_h;                        //取消cs5530片选信号
  172.     return (return_data);                //返回结果
  173. }
  174. //向cs5530写入一个双字
  175. void CS5530_Write_Dword ( uint32_t ld )
  176. {
  177.     union type1
  178.     {
  179.         uchar ch[4];
  180.         unsigned long lon;
  181.     };                                    //定义用于将32位整数转为4个字节的联合体数据结构
  182.     union type1 temp;
  183.     temp.lon= ld;                        //
  184.     cs5530_write (temp.ch[0]);            //逐个字节发送数据
  185.     cs5530_write (temp.ch[1]);
  186.     cs5530_write (temp.ch[2]);
  187.     cs5530_write (temp.ch[3]);
  188. }
  189. //cs5530 SPI串口复位函数
  190. void CS5530_Serial_Reset(void) //1
  191. {
  192.     uint8_t i = 18;
  193.     while (i--)cs5530_write(SYNC1);        //发送18个SYNC1(至少15个)
  194.     cs5530_write(SYNC0);                //发送1个SYNC0
  195. }
  196. //cs5530系统复位函数
  197. void CS5530_System_Reset ( void ) //
  198. {
  199.     uint8_t read_data,cs5530_rst;
  200.     cs5530_write(CMD_WRITE+REG_CONFIG);//发出"写配置寄存器"命令
  201.     CS5530_Write_Dword(SYSTEM_RESET);    //初始化(CFG_REG=0x20000000)
  202.     delay5530(1);                        //延时
  203.     cs5530_write(CMD_READ+REG_CONFIG);    //发出"读配置寄存器"命令
  204.     read_data=cs5530_read();            //读取结果
  205.     cs5530_rst=read_data;                //配置寄存器有32位,RV在D28位上
  206.     read_data=cs5530_read();            //后面三个字节不用管
  207.     read_data=cs5530_read();
  208.     read_data=cs5530_read();
  209.     while(cs5530_rst&0x10)                //如果RV位为1表明复位成功,读配置寄存器后RV自动清0
  210.     {                                    //重新读取RV位确保它已经清0
  211.         cs5530_write(CMD_READ+REG_CONFIG);//发读配置寄存器命令
  212.         read_data=cs5530_read();
  213.         cs5530_rst=read_data;
  214.         read_data=cs5530_read();
  215.         read_data=cs5530_read();
  216.         read_data=cs5530_read();
  217.     }
  218.     cs5530_write(CMD_WRITE+REG_CONFIG);    //发"写配置寄存器"命令
  219.     CS5530_Write_Dword(NORMAL_MODE);    //写配置寄存器清除RS位(CFG_REG=0x00000000),退出复位状态
  220. }
  221. //配置cs5530
  222. void CS5530_Config (void) //3
  223. {
  224.     cs5530_write(CMD_WRITE+REG_CONFIG);    //发"写配置寄存器"命令
  225.     //DATARATE_800 LINE_FREQ_50DATARATE_960 UNIPOLAR_MODEDATARATE_6P25
  226.     CS5530_Write_Dword(NORMAL_MODE+VREF_HIGH+CR_A0_0+CR_A1_0+SHORT_INPUTS+LINE_FREQ_60+DATARATE_200+BIPOLAR_MODE+TURN_OFF_300NA);
  227.     cs5530_write(START_CONTINUOUS+NORMAL_CONVERSION);    //开始连续转换START_SINGLE
  228. //    cs5530_read();                        //读转换结果吗?应该要先查实数据是否就绪吧?
  229. //    cs5530_read();
  230. //    cs5530_read();
  231. //    cs5530_read();
  232. }
  233. //读取cs5530模数转换结果
  234. uint32_t CS5530_Result (void)
  235. {
  236.     cs5530_write (NULL_BYTE) ;            //发出8个时钟信号来清除SDO标志(数据就绪标志?)
  237.     return (uint32_t)(CS5530_Read_Dword());//读取并返回32位结果(24位ADC转换结果加上1个溢出标志和7个无意义的0位)
  238. }
  239. //启动cs5530进行A/D转换,读取并回返AD转换结果
  240. long CS5530_Adc(void)
  241. {
  242.     long temp;
  243.     cs5530_cs=1;                        //禁止cs5530片选
  244.     cs5530_clk=0;                        //时钟空闲
  245.     cs5530_cs=0;                        //选中cs5530
  246.     _nop_();_nop_();_nop_();_nop_();    //..
  247.     _nop_();_nop_();_nop_();_nop_();    //
  248.     _nop_();_nop_();_nop_();_nop_();    //..
  249.     _nop_();_nop_();_nop_();_nop_();    //
  250.     SPI_RW(0x80);                        //发出"执行单次转换"命令
  251.     while(cs5530_sdo==1);                //等待数据就绪
  252.     SPI_RW(0x00);                        //NULL命令,用来清除端口标志位使得转换器保持在连续转换模式
  253.     temp=0;
  254.     temp+=SPI_RW(0x00);                    //读取结果的最高字节
  255.     temp<<=8;
  256.     temp+=SPI_RW(0x00);                    //读取结果的次高字节
  257.     temp<<=8;
  258.     temp+=SPI_RW(0x00);                    //读取结果的次低字节
  259.     temp<<=8;
  260.     temp+=SPI_RW(0x00);                    //读取结果的最低字节
  261.     cs5530_cs_h;                        //取消cs5530片选信号
  262.     return(temp);                        //返回32位结果
  263. }
  264. //读取并返回参数指明的cs5530特定寄存器的内容
  265. unsigned long CS5530_ReadReg(uchar reg)
  266. {
  267.     unsigned long temp;
  268.     cs5530_cs=1;                        //禁止cs5530片选
  269.     cs5530_clk=0;                        //时钟空闲
  270.     cs5530_cs=0;                        //选中cs5530
  271.     _nop_();_nop_();_nop_();_nop_();    ///..
  272.     _nop_();_nop_();_nop_();_nop_();    //
  273.     _nop_();_nop_();_nop_();_nop_();    ///..
  274.     _nop_();_nop_();_nop_();_nop_();    //
  275.     SPI_RW(reg);                        //发出读取指定寄存器内容的命令
  276.     temp=SPI_RW(0X00);                    //连续读取4个字节的数据
  277.     temp<<=8;
  278.     temp+=SPI_RW(0x00);
  279.     temp<<=8;
  280.     temp+=SPI_RW(0x00);
  281.     temp<<=8;
  282.     temp+=SPI_RW(0x00);
  283.     cs5530_cs=1;                        //取消cs5530片选信号
  284.     return(temp);
  285. }
复制代码
| 2018-5-12 17:48 | 显示全部楼层
硬件电路稳定不? 抗干扰和滤波电路都有吗?
先把硬件搞稳定了,再调试软件部分
 楼主 | 2018-5-12 19:20 | 显示全部楼层
ningling_21 发表于 2018-5-12 17:48
硬件电路稳定不? 抗干扰和滤波电路都有吗?
先把硬件搞稳定了,再调试软件部分
...

硬件部分,输入信号能稳定到小数点后三位,稳定到0.01mv,供电电压能稳定到第三位,现在是采集的信号还没有输入的信号稳定性好。看datasheet需要校准,但是不会做。。。或者会不会是其他问题  。我的供电电压模拟是5v,因为用的32单片机做的,所以数字供电是3.3v。不知有没有影响。
| 2018-5-13 15:20 | 显示全部楼层
babyrabbit 发表于 2018-5-12 19:20
硬件部分,输入信号能稳定到小数点后三位,稳定到0.01mv,供电电压能稳定到第三位,现在是采集的信号还没 ...

3.3V影响不大,数字电路和模拟电路应该隔离,如果不能隔离两个地也要单点相连

扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式
我要创建版块 申请成为版主

论坛热帖

关闭

热门推荐上一条 /4 下一条

分享 快速回复 返回顶部 返回列表