找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STM32实现ADS1256进行数据电压采集程序

  [复制链接]
跳转到指定楼层
楼主
ID:489280 发表于 2019-3-12 15:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
通过cubeMX配置STM32RCT6的IO口与ads1256ADC模块的连接IO口工作模式SPI,还有接受中断接受状态引脚,最终ADC采集数据经过卡尔曼滤波器滤波输出,详情请见附件

单片机源程序如下:
  1. #include "ads1256.h"
  2. int32_t adcVaule = 0x00;
  3. float voltage = 0x00;
  4. float filterVoltage = 0.0;
  5. float filterVoltage2 = 0.0;
  6. void delayXus(uint16_t us) {
  7.     uint16_t diff = 0xffff - 5 - us;
  8.     //设置定时器的计数值
  9.     __HAL_TIM_SET_COUNTER(&htim6, diff);
  10.     //启动定时器计数
  11.     HAL_TIM_Base_Start(&htim6);
  12.     //判定计数结束
  13.     while(diff < 0xffff - 5) {
  14.         diff = __HAL_TIM_GET_COUNTER(&htim6);
  15.     }
  16.     //延时完成关闭定时器计数
  17.     HAL_TIM_Base_Stop(&htim6);
  18. }

  19. /*
  20. *   功  能:实现SPI协议总线发送一个字节的数据信息
  21. *   参  数:待发送的数据信息
  22. *   返回值:无
  23. */
  24. void spiWriteByte(uint8_t txData) {
  25.     uint8_t tempData = 0x00;
  26.     HAL_SPI_TransmitReceive(&hspi1, &txData, &tempData, 1, 100);
  27. }

  28. /*
  29. *   功  能:实现SPI协议总监接受一个字节的数据信息
  30. *   参  数:无
  31. *   返回值:接受到的数据信息
  32. */
  33. uint8_t spiReadByte(void) {
  34.     uint8_t tempDataT = 0xff;
  35.     uint8_t tempData = 0x00;
  36.     HAL_SPI_TransmitReceive(&hspi1, &tempDataT, &tempData, 1, 100);
  37.     return tempData;
  38. }

  39. /*
  40. *   功  能:向ads1256寄存器中写入一个字节的数据
  41. *   参  数:regAdd寄存器地址 regData待写入的数据信息
  42. *   返回值:无
  43. */
  44. void spiWriteRegData(uint8_t regAdd, uint8_t regData) {
  45.     //拉低SPI协议的CS引脚
  46.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  47.     //等待RDY的引脚变低
  48.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  49.     //写入寄存地地址
  50.     spiWriteByte(WREG | (regAdd & 0x0F));
  51.     //写入即将写入数据的个数
  52.     spiWriteByte(0x00);
  53.     //写入数据信息
  54.     spiWriteByte(regData);
  55.     //拉高SPI协议的CS引脚
  56.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  57. }

  58. /*
  59. *   功  能:初始化ads1256
  60. *   参  数:无
  61. *   返回值:无
  62. */
  63. void ads1256Init(void) {
  64.     disableInterrupt();
  65.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  66.     //开启芯片的自校准
  67.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  68.     spiWriteByte(SELFCAL);
  69.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  70.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  71.     //设置ads1256的状态寄存器
  72.     spiWriteRegData(STATUS, 0x06);      //数据发送高位在前 自动校准 启用buf
  73.     spiWriteRegData(MUX, MUXP_AIN0 | MUXN_AIN1); //单端模式
  74.     //设置ads1256的增益
  75.     spiWriteRegData(ADCON, GAIN_1);
  76.     //设置ads采样速率
  77.     spiWriteRegData(DRATE, RATE_30000);
  78.     //设置IO状态
  79.     spiWriteRegData(IO, 0x00);
  80.     //再次进行校准
  81.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  82.     //开启芯片的自校准
  83.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  84.     spiWriteByte(SELFCAL);
  85.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  86.     enableInterrupt();
  87. }

  88. /*
  89. *   功  能:从ads1256中读取出相关数据信息
  90. *   参  数:下一次转换通道
  91. *   返回值:读取到的数据信息
  92. */
  93. int32_t ads1256ReadValue(uint8_t channel) {
  94.     int32_t sum = 0;
  95.     //等待准备好信号变低
  96.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  97.     //设置下次转换的通道
  98.     spiWriteRegData(MUX, channel);

  99.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  100.     spiWriteByte(SYNC);     //发送同步命令
  101.     delayXus(5);
  102.     spiWriteByte(WAKEUP);   //发送唤醒命令
  103.     delayXus(5);            //延时一下
  104.     spiWriteByte(RDATA);    //发送读数据命令
  105.     delayXus(25);
  106.     sum |= (spiReadByte() << 16);
  107.     sum |= (spiReadByte() << 8);
  108.     sum |= (spiReadByte());
  109.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  110.     if(sum > 0x7fffff)
  111.         sum -= 0x1000000;
  112.     adcVaule = sum;
  113.     voltage = (float)(adcVaule * 5.0 / 8388607); //计算电压
  114.     printf("ADC采集数据:%0x,%f\n", adcVaule, voltage);
  115.     HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
  116.     return sum;
  117. }
  118. /*
  119. *   功  能:实现ads的增益设置
  120. */
  121. void setGain(uint8_t gain) {
  122.     disableInterrupt();
  123.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  124.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  125.     switch(gain) {
  126.     case 0:
  127.         spiWriteRegData(ADCON, GAIN_1);
  128.         break;
  129.     case 1:
  130.         spiWriteRegData(ADCON, GAIN_2);
  131.         break;
  132.     default:
  133.         break;
  134.     }
  135.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  136.     enableInterrupt();
  137. }
  138. /*
  139. *   功  能:设置ads1256的采集速率
  140. */
  141. void setRate(uint8_t rate) {
  142.     disableInterrupt();
  143.     while(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4));
  144.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  145.     switch(rate) {
  146.     case 0:
  147.         spiWriteRegData(DRATE, RATE_2_5);
  148.         break;
  149.     case 1:
  150.         spiWriteRegData(DRATE, RATE_10);
  151.         break;
  152.     default:
  153.         break;
  154.     }
  155.     HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  156.     enableInterrupt();
  157. }
  158. /*
  159. *   功  能:实现屏蔽所有中断函数
  160. */
  161. void disableInterrupt(void) {
  162.     __set_PRIMASK(1);
  163. }

  164. /*
  165. *   功  能:开启全局中断
  166. */
  167. void enableInterrupt(void) {
  168.     __set_PRIMASK(0);
  169. }
  170. /*
  171. *   功  能:实现外部中断回调函数
  172. */
  173. void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
  174.     int32_t sum = 0x00;
  175.     disableInterrupt();
  176.     if((GPIO_Pin == GPIO_PIN_4) && (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4) == GPIO_PIN_RESET)) {
  177.         //设置下次转换的通道
  178.         spiWriteRegData(MUX, MUXP_AIN0 | MUXN_AINCOM);
  179.         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
  180.         spiWriteByte(SYNC);     //发送同步命令
  181.         delayXus(5);
  182.         spiWriteByte(WAKEUP);   //发送唤醒命令
  183.         delayXus(5);            //延时一下
  184.         spiWriteByte(RDATA);    //发送读数据命令
  185.         delayXus(25);
  186.         sum |= (spiReadByte() << 16);
  187.         sum |= (spiReadByte() << 8);
  188.         sum |= (spiReadByte());
  189.         HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_SET);
  190.         if(sum > 0x7fffff)
  191.             sum -= 0x1000000;
  192.         adcVaule = sum;
  193.         HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_4);
  194.     }
  195.     enableInterrupt();
  196. }

  197. float filterlowerpass(float adc) {
  198.     //y(n) = qX(n)+(1-q)Y(n-1)
  199.     float filterVaule = 0;
  200.     static float adcold = 0;
  201.     filterVaule = 0.5 * adc + 0.5 * adcold;
  202.     adcold = adc;
  203.     return filterVaule;
  204. }

  205. float kalman_filter(float ADC_Value) {
  206.     float x_k1_k1, x_k_k1;
  207.     static float ADC_OLD_Value;
  208.     float Z_k;
  209.     static float P_k1_k1;

  210.     static float Q = 0.0001;
  211.     static float R = 5;
  212.     static float Kg = 0;
  213.     static float P_k_k1 = 1;

  214.     float kalman_adc;
  215.     static float kalman_adc_old = 0;
  216.     Z_k = ADC_Value;

  217.     if (abs(kalman_adc_old - ADC_Value) >= 10) {
  218.         x_k1_k1 = ADC_Value * 0.382 + kalman_adc_old * 0.618;
  219.     } else {
  220.         x_k1_k1 = kalman_adc_old;
  221.     }
  222.     x_k_k1 = x_k1_k1;
  223.     P_k_k1 = P_k1_k1 + Q;

  224.     Kg = P_k_k1 / (P_k_k1 + R);

  225.     kalman_adc = x_k_k1 + Kg * (Z_k - kalman_adc_old);
  226.     P_k1_k1 = (1 - Kg) * P_k_k1;
  227.     P_k_k1 = P_k1_k1;

  228.     ADC_OLD_Value = ADC_Value;
  229.     kalman_adc_old = kalman_adc;

  230.     return kalman_adc;
  231. }
复制代码
  1. /* Includes ------------------------------------------------------------------*/
  2. #include "main.h"
  3. #include "spi.h"
  4. #include "tim.h"
  5. #include "usart.h"
  6. #include "gpio.h"

  7. /* Private includes ----------------------------------------------------------*/
  8. /* USER CODE BEGIN Includes */
  9. #include "ads1256.h"
  10. /* USER CODE END Includes */

  11. /* Private typedef -----------------------------------------------------------*/
  12. /* USER CODE BEGIN PTD */

  13. /* USER CODE END PTD */

  14. /* Private define ------------------------------------------------------------*/
  15. /* USER CODE BEGIN PD */

  16. /* USER CODE END PD */

  17. /* Private macro -------------------------------------------------------------*/
  18. /* USER CODE BEGIN PM */

  19. /* USER CODE END PM */

  20. /* Private variables ---------------------------------------------------------*/

  21. /* USER CODE BEGIN PV */

  22. /* USER CODE END PV */

  23. /* Private function prototypes -----------------------------------------------*/
  24. void SystemClock_Config(void);
  25. /* USER CODE BEGIN PFP */

  26. /* USER CODE END PFP */

  27. /* Private user code ---------------------------------------------------------*/
  28. /* USER CODE BEGIN 0 */

  29. /* USER CODE END 0 */

  30. /**
  31.   * @brief  The application entry point.
  32.   * @retval int
  33.   */
  34. int main(void) {
  35.     /* USER CODE BEGIN 1 */

  36.     /* USER CODE END 1 */

  37.     /* MCU Configuration--------------------------------------------------------*/

  38.     /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  39.     HAL_Init();

  40.     /* USER CODE BEGIN Init */

  41.     /* USER CODE END Init */

  42.     /* Configure the system clock */
  43.     SystemClock_Config();

  44.     /* USER CODE BEGIN SysInit */

  45.     /* USER CODE END SysInit */

  46.     /* Initialize all configured peripherals */
  47.     MX_GPIO_Init();
  48.     MX_TIM6_Init();
  49.     MX_SPI1_Init();
  50.     MX_USART1_UART_Init();
  51.     /* USER CODE BEGIN 2 */
  52.     ads1256Init();
  53.     /* USER CODE END 2 */

  54.     /* Infinite loop */
  55.     /* USER CODE BEGIN WHILE */
  56.     while (1) {
  57.         /* USER CODE END WHILE */

  58.         /* USER CODE BEGIN 3 */
  59.         voltage = (float)(adcVaule * 5.0 / 8388607); //计算电压
  60.         //filterVoltage = filterlowerpass(voltage);    //低通滤波
  61.                 filterVoltage2 = kalman_filter(voltage);                 //卡尔玛滤波
  62.         //printf("voltage:%f\n\t", voltage);
  63.         //printf("filterVoltage:%f\n\t", filterVoltage2);
  64.         //HAL_Delay(5);
  65.     }
  66.     /* USER CODE END 3 */
  67. }

  68. /**
  69.   * @brief System Clock Configuration
  70.   * @retval None
  71.   */
  72. void SystemClock_Config(void) {
  73.     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  74.     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  75.     /** Initializes the CPU, AHB and APB busses clocks
  76.     */
  77.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  78.     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  79.     RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  80.     RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  81.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  82.     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  83.     RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  84.     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  85.         Error_Handler();
  86.     }
  87.     /** Initializes the CPU, AHB and APB busses clocks
  88.     */
  89.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  90.                                   | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  91.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  92.     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  93.     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  94.     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  95.     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
  96.         Error_Handler();
  97.     }
  98. }

  99. /* USER CODE BEGIN 4 */
  100. int fputc(int ch, FILE *f) {
  101.     HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
  102.     return ch;
  103. }
  104. /* USER CODE END 4 */

  105. /**
  106.   * @brief  This function is executed in case of error occurrence.
  107.   * @retval None
  108.   */
  109. void Error_Handler(void) {
  110.     /* USER CODE BEGIN Error_Handler_Debug */
  111.     /* User can add his own implementation to report the HAL error return state */

  112.     /* USER CODE END Error_Handler_Debug */
  113. ……………………

  114. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
ADS1256_INT.7z (268.5 KB, 下载次数: 459)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

沙发
ID:489675 发表于 2019-3-13 09:16 来自手机 | 只看该作者
好东西,用用
回复

使用道具 举报

板凳
ID:489833 发表于 2019-3-13 12:04 | 只看该作者
感谢,试试看
回复

使用道具 举报

地板
ID:98985 发表于 2019-4-17 12:49 | 只看该作者
谢谢分享,下载下来学习下
回复

使用道具 举报

5#
ID:328263 发表于 2019-5-6 20:10 | 只看该作者
最近正好遇到中断的问题,看看怎么样
回复

使用道具 举报

6#
ID:384522 发表于 2019-7-25 17:52 | 只看该作者
学习学习
回复

使用道具 举报

7#
ID:689409 发表于 2020-2-29 16:46 | 只看该作者
尝试HAL驱动ADS1256一直没有成功,谢谢分享!
回复

使用道具 举报

8#
ID:68875 发表于 2020-2-29 22:33 | 只看该作者
good,
回复

使用道具 举报

9#
ID:491246 发表于 2020-4-19 10:02 | 只看该作者
谢谢分享!
回复

使用道具 举报

10#
ID:260417 发表于 2020-7-16 13:32 | 只看该作者
感谢分享  驱动一直未成功
回复

使用道具 举报

11#
ID:356526 发表于 2020-9-24 21:56 | 只看该作者
很棒的资料
回复

使用道具 举报

12#
ID:875880 发表于 2021-1-13 22:23 | 只看该作者
很好的资料,已经下载。实验下,作者很辛苦,写的代码直接对 iO操作,可移植性还是不强。
回复

使用道具 举报

13#
ID:577974 发表于 2021-3-22 15:08 | 只看该作者
这份源码可以使用吗
回复

使用道具 举报

14#
ID:653833 发表于 2021-3-28 20:32 | 只看该作者
怎么找不到io对应的端口呐
回复

使用道具 举报

15#
ID:953850 发表于 2021-7-16 15:31 | 只看该作者
很好的资料。j就是要硬件SPI
回复

使用道具 举报

16#
ID:954626 发表于 2021-7-23 10:42 | 只看该作者
这个好用吗,为啥我用完数据只有零啊,不采集数据
回复

使用道具 举报

17#
ID:956451 发表于 2021-7-26 15:19 | 只看该作者
请问如何接线
回复

使用道具 举报

18#
ID:893692 发表于 2021-7-30 14:45 | 只看该作者
能用吗?
回复

使用道具 举报

19#
ID:165291 发表于 2021-10-2 01:43 来自手机 | 只看该作者
不知道可以移植滤波程序吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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