STM32F103C8T6硬件spi读取ADS1118

硬件SPI读取ADS1118

`


前言

现在要用到SPI去读取数据,读取的芯片是ADX的一款,但是和ADS1118是一模一样的
分享一下读取的过程

一、ADS1118技术手册

在拿到一块芯片时第一件事要做的就是看数据手册分析时序图。时序图网上很多就不贴了
分析它的时钟极性和相位 可以看出来他是极性为0 相位为1。
然后我们就可以配置SPI了

二、SPI的配置

1.spi.c和.h的配置

这里用spi1,先配置spi的引脚以及模式 用的stm32的spi1 PA4 5 6 7
6是MISO主设备输入从设备输出 接从设备的DOUT
7是MOSI主设备输出从设备输入 接从设备的DIN
spi.c

#include "spi.h"

//以下是SPI模块的初始化代码,配置成主机模式				  
//SPI口初始化
//这里针是对SPI1的初始化

void MySPI_Init(void)
{
    
    
 	GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_5|GPIO_Pin_7;//7  SPI_MOSI    5  SPI_SCLK
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;    //SPI_NSS
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	GPIO_SetBits(GPIOA,GPIO_Pin_4);//拉高CS
	
	GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;        //SPI_MISO
	GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; 
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//主机模式
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//十六位数据 
	//这里选择的是ADS1118芯片16位数据传输的方式,就把SPI配置成了十六位数据  
	SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex;//双线全双工
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
	SPI_Init(SPI1,&SPI_InitStructure);
	SPI_Cmd(SPI1,ENABLE);
}   

写SPI交换数据的函数(SPI总线发送和接收16位数据的函数)
在使用spi交换数据的时候必须要有发送,没有发送就没有接收
如果配置的时候卡在了while里面 这个时候检查一下gpio有没有使能 (这里我刚开始忘记使能了,卡住了很久)

uint16_t MySPI_SwapByte(uint16_t ByteSend)
{
    
    

	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);
  
	SPI_I2S_SendData(SPI1, ByteSend);
	
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);
	
	return SPI_I2S_ReceiveData(SPI1);
}

spi.h

#ifndef __SPI_H
#define __SPI_H
#include "sys.h"
 		  	    													  

void MySPI_Init();
uint16_t MySPI_SwapByte(uint16_t ByteSend);

#endif

2.ads1118.c

下面就是数据的读取怎么根据手册拿到我们想要的数据
通信的方式比较简单 就是把CS拉低然后开始通信 交换数据 (看数据手册上的寄存器指令有哪些)
根据数据手册对数据进行处理

#include "ADS1118.h"
#include "spi.h"
#include "delay.h"
//连续模式先调用ADS1118_ADC_Init()初始化,在调用ADS1118_Get_ADC_Continuous_Data()
void ADS1118_ADC_Init(uint16_t channel,uint16_t PGA,uint16_t SPS)
{
    
    
	      MySPI_Init();
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低CS开始通信
        delay_us(5);
        MySPI_SwapByte(ADS1118_SS_START|channel|PGA|ADS1118_Continuous_MODE|SPS|ADS1118_Temp_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据  初始化
        delay_us(10);
        GPIO_SetBits(GPIOA,GPIO_Pin_4);//拉高CS停止通信
        delay_ms(1);
}
/*********************************************************************
 *     ADS1118_Get_ADC_Continuous_Data
 *     连续模式获取ADC数据,使用前初始化 ADS1118_ADC_Init()
 *     单位V
 *********************************************************************/
float  ADS1118_Get_ADC_Continuous_Data(uint16_t channel,uint16_t PGA,uint16_t SPS)
{
    
    
        uint16_t ADC_Data = 0;
        float Tempture_data= 0;
        GPIO_ResetBits(GPIOA,GPIO_Pin_4);//拉低CS开始通信
        delay_us(1);
	    
        while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6));//DOUT拉低ADS1118数据更新准备完毕
       
        ADC_Data = MySPI_SwapByte(ADS1118_SS_START|channel|PGA|ADS1118_Continuous_MODE|SPS|ADS1118_ADC_MODE|ADS1118_PUUP_EN|ADS1118_NOP_UPDATA);//发送寄存器命令,交换数据
        delay_us(1);
        GPIO_SetBits(GPIOA,GPIO_Pin_4);//拉高CS停止通信
	     
        if(ADC_Data&0X8000)//MSB=1
        {
    
    
				ADC_Data = (~ADC_Data)+1 ;
				if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
				else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
				else if(PGA == ADS1118_PGA_4096)Tempture_data=ADC_Data*0.125;
				else if(PGA == ADS1118_PGA_2048)Tempture_data=ADC_Data*0.0625;
				else if(PGA == ADS1118_PGA_1024)Tempture_data=ADC_Data*0.03125;
				else if(PGA == ADS1118_PGA_0512)Tempture_data=ADC_Data*0.015625;
				else Tempture_data=ADC_Data*0.0078125;
				return Tempture_data;
        }
        else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
        else if(PGA == ADS1118_PGA_6144)Tempture_data=ADC_Data*0.1875;
        else if(PGA == ADS1118_PGA_4096)Tempture_data=ADC_Data*0.125;
        else if(PGA == ADS1118_PGA_2048)Tempture_data=ADC_Data*0.0625;
        else if(PGA == ADS1118_PGA_1024)Tempture_data=ADC_Data*0.03125;
        else if(PGA == ADS1118_PGA_0512)Tempture_data=ADC_Data*0.015625;
        else Tempture_data=ADC_Data*0.0078125;
        return Tempture_data/1000;
} 
void ads_print()
{
    
    
	  float ads_value=0;
     ads_value=ADS1118_Get_ADC_Continuous_Data(ADS1118_MUX_AIN0,ADS1118_PGA_4096,ADS1118_DR_128SPS);
		printf("单通道AIN0采集电压%.3fV\r\n",ads_value);
	  delay_ms(2000);	
}

3.ads1118.h

这个就是根据【CONFIG寄存器字段说明】来写

#ifndef __ADS1118_H
#define __ADS1118_H
#include "stm32f10x.h"
#include "SPI.h"

#define ADS1118_SS_START        0X8000    //0--》NO effect,1-->start ADC

#define ADS1118_MUX_AIN0_AIN1   0X0000    //000 = AINP is AIN0 and AINN is AIN1 (default)
#define ADS1118_MUX_AIN0_AIN3   0x1000    //001 = AINP is AIN0 and AINN is AIN3
#define ADS1118_MUX_AIN1_AIN3   0X2000    //010 = AINP is AIN1 and AINN is AIN3
#define ADS1118_MUX_AIN2_AIN3   0X3000    //011 = AINP is AIN2 and AINN is AIN3
#define ADS1118_MUX_AIN0        0X4000    //100 = AINP is AIN0 and AINN is GND
#define ADS1118_MUX_AIN1        0X5000    //101 = AINP is AIN1 and AINN is GND
#define ADS1118_MUX_AIN2        0X6000    //110 = AINP is AIN2 and AINN is GND
#define ADS1118_MUX_AIN3        0X7000    //111 = AINP is AIN3 and AINN is GND

#define ADS1118_PGA_6144        0X0000    //000 = FSR is ±6.144 V
#define ADS1118_PGA_4096        0X0200    //001 = FSR is ±4.096 V
#define ADS1118_PGA_2048        0X0400    //010 = FSR is ±2.048 V (default)
#define ADS1118_PGA_1024        0X0600    //011 = FSR is ±1.024 V
#define ADS1118_PGA_0512        0X0800    //100 = FSR is ±0.512 V
#define ADS1118_PGA_0256        0X0A00    //101 = FSR is ±0.256 V

#define ADS1118_Continuous_MODE 0X0000    //0->Continuous
#define ADS1118_Sigle_SHOT_MODE 0X0100    //1->SIGNEL ADC

#define ADS1118_DR_8SPS         0X0000    //000 = 8 SPS
#define ADS1118_DR_16SPS        0X0020    //001 = 16 SPS
#define ADS1118_DR_32SPS        0X0040    //010 = 32 SPS
#define ADS1118_DR_64SPS        0X0060    //011 = 64 SPS
#define ADS1118_DR_128SPS       0X0080    //100 = 128 SPS (default)
#define ADS1118_DR_250SPS       0X00A0    //101 = 250 SPS
#define ADS1118_DR_470SPS       0X00C0    //110 = 475 SPS
#define ADS1118_DR_860SPS       0X00E0    //111 = 860 SPS

#define ADS1118_ADC_MODE        0x0000    //ADC MODE
#define ADS1118_Temp_MODE       0X0010    //Temperature sensor mode

#define ADS1118_PUUP_DIS        0X0000    //inside pullup disabled
#define ADS1118_PUUP_EN         0x0008    //inside pullup enabled

#define ADS1118_NOP_UPDATA      0X0002    //update the Config register
void ADS1118_ADC_Init(uint16_t channel,uint16_t PGA,uint16_t SPS);
void ADS1118_Temp_Init();
float ADS1118_Get_Tempture_Data();
float ADS1118_Get_ADC_SIGLE_SHOT_Data(uint16_t channel,uint16_t PGA,uint16_t SPS);
float  ADS1118_Get_ADC_Continuous_Data(uint16_t channel,uint16_t PGA,uint16_t SPS);
#endif


最后就是主函数了


#include "delay.h"
#include "sys.h"
#include "usart.h"	  
 #include "ADS1118.h"	
#include "spi.h"	  

 
/************************************************

************************************************/
 		 	
 int main(void)
 {
    
    	 
	 float ads_value;
	delay_init();	    	 //延时函数初始化	  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	uart_init(115200);	 	//串口初始化为115200 	 	
  MySPI_Init();
	ADS1118_ADC_Init(ADS1118_MUX_AIN0 ,ADS1118_PGA_4096,ADS1118_DR_128SPS);
	while(1)
	{
    
    
  ads_print();
	}
}

结果还是比较可观的,3.2v的电池测出来3.270v
在这里插入图片描述

总结

第一步看时序图配置spi
第二步根据数据手册读数据

猜你喜欢

转载自blog.csdn.net/qq_51963216/article/details/134418563