STM32F103C8T6硬件spi读取ADS1118

硬件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_SCLKGPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;    //SPI_NSSGPIO_InitStructure.GPIO_Pin =GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_4);//拉高CSGPIO_InitStructure.GPIO_Mode =GPIO_Mode_IPU;        //SPI_MISOGPIO_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
第二步根据数据手册读数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/179932.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Android 】android13 新权限获取 读写文件权限

android13 新权限获取 参考:Android 13(API 33)读写SD卡权限的调整适配 - Mr,Han - 博客园 android在 获取文件读写权限(尤其是音视频、图片等等资源)的权限获取逻辑更换了。 必须申请如下权限: public static final String READ…

SpringCloudalibaba

一、分布式和微服务 分布式系统和服务是现代软件开发中的两个重要概念。它们为复杂的应用程序提供了模块化和可扩展性,使其能够在多台机器上运行,并为大量用户提供服务。 分布式系统 定义: 分布式系统是由多个独立组件组成的系统,这些组件…

cuda编程

参考资料 https://nyu-cds.github.io/python-gpu/02-cuda/ https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/ thread执行过程: https://docs.nvidia.com/cuda/cuda-c-programming…

学c语言可以过CCT里的c++吗?

学习 C 语言可以为学习 C 奠定一些基础,但它们是不同的语言,有各自独特的特点和用途。最近很多小伙伴找我,说想要一些c语言的资料,然后我根据自己从业十年经验,熬夜搞了几个通宵,精心整理了一份「c语言资料…

用于部署汽车AI项目的全面自动化数据流程

如何创建、优化和扩展汽车 AI 的数据流程 想到汽车行业的人工智能 (AI) 时,脑海中可能会立即浮现未来的道路上遍布自动驾驶汽车的情景。虽然这一切尚未实现,但汽车行业已在 AI 方面取得诸多进步,不仅安全性提高,车内体验也得到改…

jenkins+centos7上传发布net6+gitlab

工作中实践了一下jenkins的操作,所以记录一下这次经验 首先安装好jenkins并注册自己的jenkins账号 因为我们的项目代码管理使用的是gitlab,在开始之前先在jenkins上安装gitlab的插件,安装之后应该是要重启jenkins的服务,后续jen…

OpenAI 上线新功能力捧 RAG,开发者真的不需要向量数据库了?

近期, OpenAI 的开发者大会迅速成为各大媒体及开发者的热议焦点,有人甚至发出疑问“向量数据库是不是失宠了?” 这并非空穴来风。的确,OpenAI 在现场频频放出大招,宣布推出 GPT-4 Turbo 模型、全新 Assistants API 和一…

使用Postman进行压力测试

1.打开Postman新建测试接口 2.点击右边保存,选择一个文件集合,如果没有就创建,然后保存 就是这个东西,这里不便展示出来,压力测试需要在文件夹里面进行 3.选择要测试的接口,iterations 表示请求发起次数&a…

模组知识(1)-CRA-光学知识

#灵感# CRA算是光学基础知识的一部分,而且最近项目确实color shading 挺严重的。以前记的知识不全,这次再次整理一下。常学常新。 目录 sensor CRA: CRA : Lens CRA: lens CRA和sensor CRA不同大小关…

不变式和橄榄树-UMLChina建模知识竞赛第4赛季第20轮

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 只要最先答对前3题,即可获得本轮优胜。第4题为附加题,对错不影响优胜者…

springBoot 入门一 :创建springBoot项目

创建springBoot项目 配置maven 项目报错处理