硬件SPI读取ADS1118
`
文章目录
- 硬件SPI读取ADS1118
- 前言
- 一、ADS1118技术手册
- 二、SPI的配置
- 1.spi.c和.h的配置
- 2.ads1118.c
- 3.ads1118.h
- 总结
前言
现在要用到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
第二步根据数据手册读数据