ST32F407VGT6+ADS8638调试记录(CubeMX)

 ST32F407VGT6+ADS8638调试记录

ADS8638简介

ADS8638 是12位的模数转换器(ADCs),他能够在1MSPS下测量达到±10V的输入电压。 使用逐次求近寄存器(SAR) 核心,这些模数转换器可以提供一个采样保持前端的无延迟转换。ADS8638可以测量最多八位的输入。

除了输入复用器,ADS8638特别装有内部温度传感器、电压基准和一个数字比较器以为每个输入设定报警阀值;因此,最少数量的外部部件是必需的。一个简单的SPI兼容接口提供了通信和控制。数字电源可一直工作在5伏电压或下至1.8伏电压以便与多种多样的处理器和控制器进行直接连接。

对于那些要求严格的测量仪器,ADS8638可以在工业温度–40°C 到 +125°C 下工作并有小规格的QFN-24封装。

特性

  • 可选输入范围:
    ±10V、±5V、±2.5V、0V 至 10V,或
    0V 至 5V
    高达 ±12V,具有外部基准
  • 速率高达 1MSPS 的无延迟转换
  • 出色的性能:
    12 位无漏失码
    INL:±0.9LSB
    SNR:71.8dB
  • 高度集成:
    4 通道或 8 通道输入多路复用器
    温度传感器
    内部电压基准
    用于每个通道的报警门限
  • 低功耗:
    14.45mW(在 1MSPS 时)
    5.85mW(在 0.1MSPS 时)
    灵活的断电模式
  • SPI兼容型串行接口
  • 扩展温度范围:
    –40°C 至 +125°C
  • 小占位面积:4mm × 4mm QFN 封装

电路原理图

 ADS8638电路图

 

4-20mA 输入信号调理电路

CubeMX初始化芯片

根据硬件选择SPI3接口, Mode选择Full-Duplex-Master模式,将Prescaler改成8,其余默认。

根据硬件将PA4接口配置成输出模式作为ADS8638芯片的片选信号。

时钟配置如下:

 驱动程序编写

使用自动模式读取采样数据,根据数据手册,添加ADS8638.h和ADS8638.c文件,代码如下:

#ifndef __ADS8638_H_
#define __ADS8638_H_
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdlib.h>



#include "stm32f4xx_hal.h"


#define ADS8638_REG_MANUAL         0x04
#define ADS8638_REG_AUTO           0x05
#define ADS8638_REG_RESET          0x01
#define ADS8638_REG_AUX_CONFIG     0x06
#define ADS8638_REG_CHAN_SEL       0x0C // channel select for auto mode
#define ADS8638_REG_RANGE_SEL_BASE 0x10

#define ADS8638_REG_TEMP_FLAG      0x20
#define ADS8638_REG_TRIPPED_FLAG_0 0x21
#define ADS8638_REG_ALARM_FLAG_0   0x22
#define ADS8638_REG_TRIPPED_FLAG_4 0x23
#define ADS8638_REG_ALARM_FLAG_4   0x24

#define ADS8638_REG_PAGE_SEL       0x7F

#define ADS8638_READ_FLAG 0x1

#define ADS8638_RANGE_CONFIG   0x00 // Ranges as selected through the configuration registers
#define ADS8638_RANGE_10V      0x01 // Range is set to ±10V
#define ADS8638_RANGE_5V       0x02 // Range is set to ±5V
#define ADS8638_RANGE_2_5V     0x03 // Range is set to ±2.5V
#define ADS8638_RANGE_PLUS_10V 0x05 // Range is set to 0V to 10V
#define ADS8638_RANGE_PLUS_5V  0x06 // Range is set to 0V to 5V
#define ADS8638_POWER_DOWN     0x07 // Powers down the device immediately
                                   // after the 16th SCLK falling edge

#define ADS8638_INTERNAL_VREF_ON 0x0C

#define ADS8638_SPI_WRITE_FLAG 0x1

enum {
    ADS8638_CHANNEL_0,
    ADS8638_CHANNEL_1,
    ADS8638_CHANNEL_2,
    ADS8638_CHANNEL_3,
    ADS8638_CHANNEL_4,
    ADS8638_CHANNEL_5,
    ADS8638_CHANNEL_6,
    ADS8638_CHANNEL_7,
};

void ads8638Init(void);

uint8_t ads8638Read(uint16_t *value,uint8_t channel, uint8_t range);

uint8_t ads8638RegRead(uint8_t address);
void ads8638RegWrite(uint8_t address, uint8_t data);
uint8_t ads8638_conver_result1( uint16_t **convert_result );
void PowerDown(void);
void PowerUP(void);
uint8_t ads8638AutoRead(uint16_t *value);
#endif
#include "ads8638.h"
#include "spi.h"
extern SPI_HandleTypeDef hspi3;

#define ADS8638_SPI_ENABLE()   {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET );}
#define ADS8638_SPI_DISABLE()  {HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET );}

uint8_t adsChannel;
uint8_t adsRange;


uint8_t ads8638RegRead(uint8_t address)
{
    uint8_t result[1];
    uint8_t buffer[1];
    ADS8638_SPI_ENABLE();
  
    buffer[0]=(address << 1) | ADS8638_SPI_WRITE_FLAG;
    HAL_SPI_Transmit( &hspi3,buffer,1,0xFFFF );
   

    HAL_SPI_Receive( &hspi3, result, 1, 0xFFFF );
    ADS8638_SPI_DISABLE();
    return result[0];
}

void ads8638RegWrite(uint8_t address, uint8_t data)
{
    ADS8638_SPI_ENABLE();
   
    uint8_t buffer[2];
	
    buffer[0]=(address << 1) ;
   
    buffer[1]=data;
    HAL_SPI_Transmit( &hspi3,buffer,2,0xFFFF );
    ADS8638_SPI_DISABLE();
}



void ads8638Init(void)
{
   
  



    HAL_Delay(100);

//    PowerDown();
//    PowerUP();
//    PowerUP();
//    PowerUP();
    ads8638RegWrite(ADS8638_REG_RESET, 0X01);

    HAL_Delay(100);
   
  
    ads8638RegWrite(ADS8638_REG_AUX_CONFIG, ADS8638_INTERNAL_VREF_ON);
    HAL_Delay(100);
	
	/*输入范围配置*/
    ads8638RegWrite(ADS8638_REG_RANGE_SEL_BASE, 0x66);
    ads8638RegWrite(ADS8638_REG_RANGE_SEL_BASE+1, 0x66);
    ads8638RegWrite(ADS8638_REG_RANGE_SEL_BASE+2, 0x66);
    ads8638RegWrite(ADS8638_REG_RANGE_SEL_BASE+3, 0x66);



//    do
//    {
//        // TODO: enter the block content here
//        test=ads8638RegRead(ADS8638_REG_AUX_CONFIG);
//        osDelay(100);

//    } while (test!=ADS8638_INTERNAL_VREF_ON);



     /*自动模式通道选择*/
    ads8638RegWrite( ADS8638_REG_CHAN_SEL, 0xff);


    /*启动自动模式*/
    ads8638RegWrite(ADS8638_REG_AUTO,  ADS8638_RANGE_CONFIG);
}

  /*MANUAL模式数据读取*/

uint8_t ads8638Read(uint16_t *value,uint8_t channel, uint8_t range)
{
    uint8_t b0, b1;
    uint8_t RXbuffer[2];
    uint8_t TXbuffer[2];

    ads8638RegWrite(ADS8638_REG_MANUAL, (channel << 4) | (range << 1));

    ADS8638_SPI_ENABLE();

    TXbuffer[0]=0;
    TXbuffer[1]=0;
    HAL_SPI_TransmitReceive( &hspi3,TXbuffer ,RXbuffer, 2, 0xFFFF );


    ADS8638_SPI_DISABLE();



    b0 = RXbuffer[0];
    b1 = RXbuffer[1];


    *value = b0 & 0x0f;
    *value <<= 8;
    *value |= b1;

    return 1;
}


 /*Auto模式数据读取*/
/*
value :读取到的数据
返回值:通道号

*/

uint8_t ads8638AutoRead(uint16_t *value)
{
    uint8_t b0, b1;
    uint8_t buffer[2];
    uint8_t txbuffer[2];

    ADS8638_SPI_ENABLE();

    // HAL_SPI_Receive( &SPI3_InitStructure, buffer, 2, 0xFFFF );

    txbuffer[0]=0;
    txbuffer[1]=0;
    HAL_SPI_TransmitReceive(&hspi3, txbuffer, buffer, 2,0xFFFF);

    ADS8638_SPI_DISABLE();

    b0 = buffer[0];
    b1 = buffer[1];
    *value = b0 & 0x0f;
    *value <<= 8;
    *value |= b1;


    return buffer[0]>>4;
}

void PowerDown(void)
{
    ADS8638_SPI_ENABLE();
    // spiWriteByte(ADS8638_SPI_ID, address << 1);
    uint8_t buffer[2];
    buffer[0]=0x08 ;
    //HAL_SPI_Transmit( &SPI3_InitStructure,buffer,1,0xFFFF );

    // spiWriteByte(ADS8638_SPI_ID, data);

    buffer[1]=0x0e;
    HAL_SPI_Transmit( &hspi3,buffer,2,0xFFFF );
    ADS8638_SPI_DISABLE();


}

void PowerUP(void)
{
    ADS8638_SPI_ENABLE();
    // spiWriteByte(ADS8638_SPI_ID, address << 1);
    uint8_t buffer[2];
    buffer[0]=0x08 ;
    //HAL_SPI_Transmit( &SPI3_InitStructure,buffer,1,0xFFFF );

    // spiWriteByte(ADS8638_SPI_ID, data);

    buffer[1]=0x00;
    HAL_SPI_Transmit( &hspi3,buffer,2,0xFFFF );
    ADS8638_SPI_DISABLE();


}




在main.c文件添加对应的程序,全部main.c代码如下:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "spi.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "ads8638.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
uint16_t buffer[8];  	//采集的数据值

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    /* USER CODE BEGIN 1 */
    uint16_t rbuffer[1];  	//接收缓存
    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

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

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_SPI3_Init();
    /* USER CODE BEGIN 2 */
    ads8638Init();
	 
	 HAL_Delay(100);
    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {

        int t=0;
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */


        for( int i = 0; i <8; i++ )
        {
           
           /*确保返回的数据时相应的通道号*/
            do
            {
					 HAL_Delay(10);
                // TODO: enter the block content here
                t=ads8638AutoRead(rbuffer);

            } while (t!=i);
            buffer[i] = rbuffer[0]*1.2207; //转换为mA值

        }

    }
    /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Configure the main internal regulator output voltage
    */
    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    /** Initializes the RCC Oscillators according to the specified parameters
    * in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 25;
    RCC_OscInitStruct.PLL.PLLN = 336;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 4;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
    /** Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                  |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
    {
        Error_Handler();
    }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while (1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

程序烧写测试

 下载好程序后,使用仿真器查看运行结构如下:

 如图,在1、2、3通道接入跳动的电流,在6通道用电流源接入13.7mA的电流输出结果正常。

完整代码地址icon-default.png?t=M3K6https://download.csdn.net/download/u013191466/85187681?spm=1001.2014.3001.5501

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u013191466

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值