找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 918|回复: 1
打印 上一主题 下一主题
收起左侧

国产8通道24位ADC SGM58601(替代ADS1256)GD32单片机驱动程序调试

[复制链接]
跳转到指定楼层
楼主
ID:337280 发表于 2024-1-19 20:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
调试过程中遇到的问题:
最大的问题,使用SPI驱动时读数为0  -1  或者其他很大的数(都是不对的数),经过反复验证后发现与SPI时钟有关,参考STM32 驱动ADS1256程序 硬件SPI 时钟分频为256,烧录后驱动正常,修改分频系数后,读数异常。但是256分频后 时钟频率约1.几KHz 速度太慢。有反复调试了一会,发现SPI时钟速度 ,ADC采样频率都可能会导致读数错误,具体问题没有细究。经过调试后可以使用该程序驱动SGM58601。下面附上代码,单片机为GD32E103。

单片机源程序如下:
  1. #ifndef _SGM58601_H
  2. #define _SGM58601_H
  3. #include "gd32e10x.h"
  4. #include "systick.h"
  5. #include "spi.h"

  6. #define SGM58601_DRDY_PIN                GPIO_PIN_3
  7. #define SGM58601_DRDY                        gpio_input_bit_get(GPIOA, SGM58601_DRDY_PIN)

  8. //define commands
  9. #define SGM58601_CMD_WAKEUP   0x00
  10. #define SGM58601_CMD_RDATA    0x01
  11. #define SGM58601_CMD_RDATAC   0x03
  12. #define SGM58601_CMD_SDATAC   0x0f
  13. #define SGM58601_CMD_RREG     0x10
  14. #define SGM58601_CMD_WREG     0x50
  15. #define SGM58601_CMD_SELFCAL  0xf0
  16. #define SGM58601_CMD_SELFOCAL 0xf1
  17. #define SGM58601_CMD_SELFGCAL 0xf2
  18. #define SGM58601_CMD_SYSOCAL  0xf3
  19. #define SGM58601_CMD_SYSGCAL  0xf4
  20. #define SGM58601_CMD_SYNC     0xfc
  21. #define SGM58601_CMD_STANDBY  0xfd
  22. #define SGM58601_CMD_REST    0xfe

  23. //define the SGM58601 register values
  24. #define SGM58601_STATUS       0x00   
  25. #define SGM58601_MUX          0x01   
  26. #define SGM58601_ADCON        0x02   
  27. #define SGM58601_DRATE        0x03   
  28. #define SGM58601_IO           0x04   
  29. #define SGM58601_OFC0         0x05   
  30. #define SGM58601_OFC1         0x06   
  31. #define SGM58601_OFC2         0x07   
  32. #define SGM58601_FSC0         0x08   
  33. #define SGM58601_FSC1         0x09   
  34. #define SGM58601_FSC2         0x0A


  35. //define multiplexer codes
  36. #define SGM58601_MUXP_AIN0   0x00
  37. #define SGM58601_MUXP_AIN1   0x10
  38. #define SGM58601_MUXP_AIN2   0x20
  39. #define SGM58601_MUXP_AIN3   0x30
  40. #define SGM58601_MUXP_AIN4   0x40
  41. #define SGM58601_MUXP_AIN5   0x50
  42. #define SGM58601_MUXP_AIN6   0x60
  43. #define SGM58601_MUXP_AIN7   0x70
  44. #define SGM58601_MUXP_AINCOM 0x80

  45. #define SGM58601_MUXN_AIN0   0x00
  46. #define SGM58601_MUXN_AIN1   0x01
  47. #define SGM58601_MUXN_AIN2   0x02
  48. #define SGM58601_MUXN_AIN3   0x03
  49. #define SGM58601_MUXN_AIN4   0x04
  50. #define SGM58601_MUXN_AIN5   0x05
  51. #define SGM58601_MUXN_AIN6   0x06
  52. #define SGM58601_MUXN_AIN7   0x07
  53. #define SGM58601_MUXN_AINCOM 0x08   


  54. //define gain codes
  55. #define SGM58601_GAIN_1      0x00
  56. #define SGM58601_GAIN_2      0x01
  57. #define SGM58601_GAIN_4      0x02
  58. #define SGM58601_GAIN_8      0x03
  59. #define SGM58601_GAIN_16     0x04
  60. #define SGM58601_GAIN_32     0x05
  61. #define SGM58601_GAIN_64     0x06
  62. //#define SGM58601_GAIN_64     0x07

  63. //define drate codes
  64. #define SGM58601_DRATE_30000SPS   0xF0
  65. #define SGM58601_DRATE_15000SPS   0xE0
  66. #define SGM58601_DRATE_7500SPS   0xD0
  67. #define SGM58601_DRATE_3750SPS   0xC0
  68. #define SGM58601_DRATE_2000SPS   0xB0
  69. #define SGM58601_DRATE_1000SPS   0xA1
  70. #define SGM58601_DRATE_500SPS    0x92
  71. #define SGM58601_DRATE_100SPS    0x82
  72. #define SGM58601_DRATE_60SPS     0x72
  73. #define SGM58601_DRATE_50SPS     0x63
  74. #define SGM58601_DRATE_30SPS     0x53
  75. #define SGM58601_DRATE_25SPS     0x43
  76. #define SGM58601_DRATE_15SPS     0x33
  77. #define SGM58601_DRATE_10SPS     0x23
  78. #define SGM58601_DRATE_5SPS      0x13
  79. #define SGM58601_DRATE_2_5SPS    0x03

  80. // define commands
  81. #define SGM58601_CMD_WAKEUP   0x00
  82. #define SGM58601_CMD_RDATA    0x01
  83. #define SGM58601_CMD_RDATAC   0x03
  84. #define SGM58601_CMD_SDATAC   0x0f
  85. #define SGM58601_CMD_RREG     0x10
  86. #define SGM58601_CMD_WREG     0x50
  87. #define SGM58601_CMD_SELFCAL  0xf0
  88. #define SGM58601_CMD_SELFOCAL 0xf1
  89. #define SGM58601_CMD_SELFGCAL 0xf2
  90. #define SGM58601_CMD_SYSOCAL  0xf3
  91. #define SGM58601_CMD_SYSGCAL  0xf4
  92. #define SGM58601_CMD_SYNC     0xfc
  93. #define SGM58601_CMD_STANDBY  0xfd
  94. #define SGM58601_CMD_REST    0xfe

  95. //define the SGM58601 register values
  96. #define SGM58601_STATUS       0x00   
  97. #define SGM58601_MUX          0x01   
  98. #define SGM58601_ADCON        0x02   
  99. #define SGM58601_DRATE        0x03   
  100. #define SGM58601_IO           0x04   
  101. #define SGM58601_OFC0         0x05   
  102. #define SGM58601_OFC1         0x06   
  103. #define SGM58601_OFC2         0x07   
  104. #define SGM58601_FSC0         0x08   
  105. #define SGM58601_FSC1         0x09   
  106. #define SGM58601_FSC2         0x0A


  107. //define multiplexer codes
  108. #define SGM58601_MUXP_AIN0   0x00
  109. #define SGM58601_MUXP_AIN1   0x10
  110. #define SGM58601_MUXP_AIN2   0x20
  111. #define SGM58601_MUXP_AIN3   0x30
  112. #define SGM58601_MUXP_AIN4   0x40
  113. #define SGM58601_MUXP_AIN5   0x50
  114. #define SGM58601_MUXP_AIN6   0x60
  115. #define SGM58601_MUXP_AIN7   0x70
  116. #define SGM58601_MUXP_AINCOM 0x80

  117. #define SGM58601_MUXN_AIN0   0x00
  118. #define SGM58601_MUXN_AIN1   0x01
  119. #define SGM58601_MUXN_AIN2   0x02
  120. #define SGM58601_MUXN_AIN3   0x03
  121. #define SGM58601_MUXN_AIN4   0x04
  122. #define SGM58601_MUXN_AIN5   0x05
  123. #define SGM58601_MUXN_AIN6   0x06
  124. #define SGM58601_MUXN_AIN7   0x07
  125. #define SGM58601_MUXN_AINCOM 0x08   


  126. //define gain codes
  127. #define SGM58601_GAIN_1      0x00
  128. #define SGM58601_GAIN_2      0x01
  129. #define SGM58601_GAIN_4      0x02
  130. #define SGM58601_GAIN_8      0x03
  131. #define SGM58601_GAIN_16     0x04
  132. #define SGM58601_GAIN_32     0x05
  133. #define SGM58601_GAIN_64     0x06
  134. //#define SGM58601_GAIN_64     0x07

  135. //define drate codes
  136. #define SGM58601_DRATE_30000SPS   0xF0
  137. #define SGM58601_DRATE_15000SPS   0xE0
  138. #define SGM58601_DRATE_7500SPS   0xD0
  139. #define SGM58601_DRATE_3750SPS   0xC0
  140. #define SGM58601_DRATE_2000SPS   0xB0
  141. #define SGM58601_DRATE_1000SPS   0xA1
  142. #define SGM58601_DRATE_500SPS    0x92
  143. #define SGM58601_DRATE_100SPS    0x82
  144. #define SGM58601_DRATE_60SPS     0x72
  145. #define SGM58601_DRATE_50SPS     0x63
  146. #define SGM58601_DRATE_30SPS     0x53
  147. #define SGM58601_DRATE_25SPS     0x43
  148. #define SGM58601_DRATE_15SPS     0x33
  149. #define SGM58601_DRATE_10SPS     0x23
  150. #define SGM58601_DRATE_5SPS      0x13
  151. #define SGM58601_DRATE_2_5SPS    0x03

  152. void SGM58601_Gpio_Init(void);                                                                                                //SGM58601 GPIO初始化

  153. void SGM58601AWREG(unsigned char regaddr,unsigned char databyte);                        //SGM58601A 写寄存器
  154. void SGM58601BWREG(unsigned char regaddr,unsigned char databyte);                        //SGM58601B 写寄存器

  155. signed int SGM58601AReadData(unsigned char channel);                                                //SGM58601 读数据
  156. signed int SGM58601BReadData(unsigned char channel);                                                //SGM58601 读数据

  157. void SGM58601A_Init(void);                                                                                                        //SGM58601A 单端采集初始化
  158. void SGM58601B_Init(void);                                                                                                        //SGM58601B        差分采集初始化

  159. int  SGM58601_Read_SingleData(unsigned char channel);                                                //SGM58601A 单端ADC读取
  160. int  SGM58601_Read_DiffData(void);                                                                                        //SGM58601B 差分ADC读取


  161. #endif


复制代码
  1. #include "SGM58601.H"

  2. void SGM58601_Gpio_Init(void)
  3. {
  4.         gpio_init(SGM58601_GPIO_RCU,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ, SGM58601_DRDY_PIN);
  5. }

  6. void SGM58601AWREG(unsigned char regaddr,unsigned char databyte)                        //A
  7. {
  8.    
  9.         SPI_CS1_ENABLE();
  10.         while(SGM58601_DRDY);//当SGM58601_DRDY为低时才能写寄存器
  11.         //向寄存器写入数据地址
  12.     SPI0_ReadWriteByte(SGM58601_CMD_WREG | (regaddr & 0x0F));
  13.     //写入数据的个数n-1
  14.     SPI0_ReadWriteByte(0x00);
  15.     //向regaddr地址指向的寄存器写入数据databyte
  16.     SPI0_ReadWriteByte(databyte);
  17.         SPI_CS1_DISABLE();
  18. }

  19. void SGM58601BWREG(unsigned char regaddr,unsigned char databyte)                        //B
  20. {
  21.    
  22.         SPI_CS2_ENABLE();
  23.         while(SGM58601_DRDY);//当SGM58601_DRDY为低时才能写寄存器
  24.         //向寄存器写入数据地址
  25.     SPI0_ReadWriteByte(SGM58601_CMD_WREG | (regaddr & 0x0F));
  26.     //写入数据的个数n-1
  27.     SPI0_ReadWriteByte(0x00);
  28.     //向regaddr地址指向的寄存器写入数据databyte
  29.     SPI0_ReadWriteByte(databyte);
  30.         SPI_CS2_DISABLE();
  31. }

  32. //初始化SGM58601  //  单端采集
  33. void SGM58601A_Init(void)        //A                                                                                       
  34. {
  35.         //*************自校准****************
  36. //  while(SGM58601_DRDY);
  37. //        SPI_CS1_ENABLE();
  38. //        SPI0_ReadWriteByte(SGM58601_CMD_SELFCAL);
  39. //        while(SGM58601_DRDY);
  40. //        SPI_CS1_DISABLE();
  41.         //**********************************

  42.         SGM58601AWREG(SGM58601_STATUS,0x06);               // 高位在前、使用缓冲
  43. //        SGM58601AWREG(SGM58601_STATUS,0x04);               // 高位在前、不使用缓冲

  44. //        SGM58601AWREG(SGM58601_MUX,0x08);                  // 初始化端口A0为‘+’,AINCOM位‘-’
  45.         SGM58601AWREG(SGM58601_ADCON,SGM58601_GAIN_1);                // 放大倍数1
  46.         SGM58601AWREG(SGM58601_DRATE,SGM58601_DRATE_7500SPS);  // 数据10sps
  47.         SGM58601AWREG(SGM58601_IO,0x00);               

  48.         //*************自校准****************
  49. //        while(SGM58601_DRDY);
  50. //        SPI_CS1_ENABLE();
  51. //        SPI0_ReadWriteByte(SGM58601_CMD_SELFCAL);
  52. //        while(SGM58601_DRDY);
  53. //        SPI_CS1_DISABLE();
  54.         //**********************************
  55. }


  56. //初始化SGM58601  //  差分采集
  57. void SGM58601B_Init(void)        //B
  58. {
  59.         //*************自校准****************
  60. //  while(SGM58601_DRDY);
  61. //        SPI_CS2_ENABLE();
  62. //        SPI0_ReadWriteByte(SGM58601_CMD_SELFCAL);
  63. //        while(SGM58601_DRDY);
  64. //        SPI_CS2_DISABLE();
  65.         //**********************************

  66.         SGM58601BWREG(SGM58601_STATUS,0x06);               // 高位在前、使用缓冲
  67. //        SGM58601BWREG(SGM58601_STATUS,0x04);               // 高位在前、不使用缓冲

  68.         SGM58601BWREG(SGM58601_MUX,0x08);                  // 初始化端口A0为‘+’,AINCOM位‘-’
  69.         SGM58601BWREG(SGM58601_ADCON,SGM58601_GAIN_64);                // 放大倍数1
  70.         SGM58601BWREG(SGM58601_DRATE,SGM58601_DRATE_2000SPS);  // 数据10sps
  71.         SGM58601BWREG(SGM58601_IO,0x00);               

  72.         //*************自校准****************
  73. //        while(SGM58601_DRDY);
  74. //        SPI_CS2_ENABLE();
  75. //        SPI0_ReadWriteByte(SGM58601_CMD_SELFCAL);
  76. //        while(SGM58601_DRDY);
  77. //        SPI_CS2_DISABLE();
  78.         //**********************************
  79. }

  80. //读取单端AD值
  81. signed int SGM58601AReadData(unsigned char channel)  //A
  82. {
  83.     unsigned int sum=0;
  84.         
  85.          while(SGM58601_DRDY);//当SGM58601_DRDY为低时才能写寄存器
  86.         SGM58601AWREG(SGM58601_MUX,channel);                //设置通道
  87.         SPI_CS1_ENABLE();
  88.         SPI0_ReadWriteByte(SGM58601_CMD_SYNC);
  89.         SPI0_ReadWriteByte(SGM58601_CMD_WAKEUP);                       
  90.         SPI0_ReadWriteByte(SGM58601_CMD_RDATA);
  91.            sum |= (SPI0_ReadWriteByte(0xff) << 16);
  92.         sum |= (SPI0_ReadWriteByte(0xff) << 8);
  93.         sum |= SPI0_ReadWriteByte(0xff);
  94.         SPI_CS1_DISABLE();

  95.         if (sum>0x7FFFFF)           // if MSB=1,
  96.         {
  97.                 sum -= 0x1000000;       // do 2's complement

  98.         }
  99.     return sum;
  100. }

  101. signed int SGM58601BReadData(unsigned char channel)  //B
  102. {
  103.     unsigned int sum=0;
  104.         
  105.          while(SGM58601_DRDY);//当SGM58601_DRDY为低时才能写寄存器
  106.         SGM58601BWREG(SGM58601_MUX,channel);                //设置通道
  107.         SPI_CS2_ENABLE();
  108.         SPI0_ReadWriteByte(SGM58601_CMD_SYNC);
  109.         SPI0_ReadWriteByte(SGM58601_CMD_WAKEUP);                       
  110.         SPI0_ReadWriteByte(SGM58601_CMD_RDATA);
  111.            sum |= (SPI0_ReadWriteByte(0xff) << 16);
  112.         sum |= (SPI0_ReadWriteByte(0xff) << 8);
  113.         sum |= SPI0_ReadWriteByte(0xff);
  114.         SPI_CS2_DISABLE();

  115.         if (sum>0x7FFFFF)           // if MSB=1,
  116.         {
  117.                 sum -= 0x1000000;       // do 2's complement

  118.         }
  119.     return sum;
  120. }

  121. int SGM58601_Read_SingleData(unsigned char channel)
  122. {
  123.         return SGM58601AReadData( (channel << 4) | SGM58601_MUXN_AINCOM);
  124. }

  125. int SGM58601_Read_DiffData(void)
  126. {
  127.         return SGM58601BReadData( SGM58601_MUXP_AIN0 | SGM58601_MUXN_AIN1);
  128. }
复制代码

GD32_SGM58601.7z

202.25 KB, 下载次数: 12

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:301191 发表于 2024-1-20 15:06 | 只看该作者
顶一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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