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_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
第二步根据数据手册读数据

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于纵横交叉算法优化概率神经网络PNN的分类预测 - 附代码

基于纵横交叉算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于纵横交叉算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于纵横交叉优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神…

Freeswitch中CHANNEL_UNHOLD取回事件

1. CHANNEL_UNHOLD取回事件 2023-11-15T09:18:45.3740800 INFO c.e.c.v.s.c.i.FsServerEventHandler - eventReceived:CHANNEL_UNHOLD 2023-11-15T09:18:45.3740800 INFO c.e.c.v.s.c.i.FsServerEventHandler - EventBody********:{variable_effective_caller_id_number1000,…

【开源】基于微信小程序、Vue和SpringBoot的智慧家政系统

项目编号: S 063 ,文末获取源码。 \color{red}{项目编号:S063,文末获取源码。} 项目编号:S063,文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询家政服…

上海亚商投顾:沪指震荡反弹 汽车产业链多股涨停

上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。 一.市场情绪 指数早间高开后震荡回落,三大股指最终均小幅上涨。汽车产业链持续活跃,华为汽车方向领…

场景图形管理 - (1)

本章主要介绍在场景图形中如何管理场景数据及交互过程,这在实际开发中非常重要。 视图与相机 什么是视图?在《OpenGL编程指南》中有下面的比喻,从笔者开始学习图形学就影响深刻,相信对读者学习场景管理也会非常有帮助。 产生目标场景视图的变…

【JUC】七、读写锁

文章目录 1、读写锁2、读写锁的体验3、读写锁的特点4、锁的演变5、读写锁的降级6、复习:悲观锁和乐观锁 1、读写锁 JUC下的锁包的ReadWriteLock接口,以及其实现类ReentrantReadWriteLock ReadWriteLock 维护了一对相关的锁,即读锁和写锁&…

TikTok对文化艺术的影响:传统与现代的碰撞

在这个数字时代,社交媒体平台不仅改变了我们的社交方式,也对文化和艺术产生了深远的影响。其中,TikTok是一个备受欢迎的应用,已成为传统与现代文化艺术交汇的独特平台。本文将深入探讨TikTok对文化艺术的影响,以及传统…

Freeswitch中CHANNEL_HOLD保持事件

1.CHANNEL_HOLD保持事件 2023-11-15T09:18:42.6920800 INFO c.e.c.v.s.c.i.FsServerEventHandler - eventReceived:CHANNEL_HOLD 2023-11-15T09:18:42.6920800 INFO c.e.c.v.s.c.i.FsServerEventHandler - EventBody********:{variable_effective_caller_id_number1000, , va…

OpenCV必知必会基础3(包括色彩空间的变换、ROI、OpenCV中最重要的结构体Mat以及获取图像的属性)

文章目录 OpenCV的色彩空间——RGB与BGROpenCV的色彩空间——HSV与HSLHSV主要用于OpenCV中HSL OpenCV色彩空间转换YUV主要用于视频中题目 图像操作的基石Numpy【基础操作】np.arraynp.zerosnp.onesnp.fullnp.identitynp.eye Numpy基本操作之矩阵的检索与赋值Numpy基本操作三——…

Kylin-Server-V10-SP3+Gbase+宝兰德信创环境搭建

目录 一、Kylin-Server-V10-SP3 安装1.官网下载安装包2.创建 VMware ESXi 虚拟机3.加载镜像,安装系统 二、Gbase 安装1.下载 Gbase 安装包2.创建组和用户、设置密码3.创建目录4.解压包5.安装6.创建实例7.登录8.常见问题 三、宝兰德安装1.获取安装包2.解压安装3.启动…

黑马程序员微服务 分布式搜索引擎3

分布式搜索引擎03 0.学习目标 1.数据聚合 **聚合(aggregations)**可以让我们极其方便的实现对数据的统计、分析、运算。例如: 什么品牌的手机最受欢迎?这些手机的平均价格、最高价格、最低价格?这些手机每月的销售…

【JavaEE初阶】 HTML基础详解

文章目录 🎋什么是HTML?🍀HTML 结构🚩认识标签🚩HTML 文件基本结构🚩快速生成代码框架 🎄HTML 常见标签🚩注释标签🚩标题标签: h1-h6🚩段落标签: p&#x1f6…

【差旅游记】启程-新疆哈密(2)

哈喽,大家好,我是雷工。 最近需要出差,11月02号第一次去新疆特意记录下去新疆的过程。 01 又过北京西站 本来订的是途径成都中转的路线,结果飞机改点,中转时间太短导致赶不上下班飞机,只好改道北京。 又到…

c# - - - Application.StartupPath(程序安装目录)和Environment.CurrentDirectory(程序工作目录)

Application.StartupPath 应用程序的安装目录,不会改变。 在C:\Users\Administrator\source\repos\ConsoleApp6\bin\Debug目录中,运行ConsoleApp6.exe。 安装目录为:C:\Users\Administrator\source\repos\ConsoleApp6\bin\Debug 在C:\Users…

【文件读取/包含】任意文件读取漏洞 afr_1

1.1漏洞描述 漏洞名称任意文件读取漏洞 afr_1漏洞类型文件读取漏洞等级⭐漏洞环境docker攻击方式 1.2漏洞等级 高危 1.3影响版本 暂无 1.4漏洞复现 1.4.1.基础环境 靶场docker工具BurpSuite 1.4.2.靶场搭建 1.创建docker-compose.yml文件 version: 3.2 services: web: …

EMNLP 2023 | 用于开放域多跳推理的大语言模型的自我提示思想链

©PaperWeekly 原创 作者 | 王金元 单位 | 上海交通大学 研究方向 | 大模型微调及应用 论文标题: Self-prompted Chain-of-Thought on Large Language Models for Open-domain Multi-hop Reasoning 模型&代码地址: https://github.com/noewangj…

idea中git 移除对某个文件的跟踪

应用场景如下 某个log 文件,被同事用git 提交到了服务器,本地拉去之后我们的跟踪也会受影响 取消跟踪的方法如下: 删除本地缓存 git rm --cached "logs/test.log" 提交无效的log git commit -m "ignore log" 再将lo…

三子棋——C语言初阶

一.游戏思路: 设计菜单,选择开始游戏(1)还是退出游戏(0)(若是输入数字不再输入范围内,则“选择错误”)初始化棋盘打印棋盘(步骤二和三不可调换位置)玩家下棋(坐标落子)—…

Java排序算法之堆排序

图解 堆排序是一种常见的排序算法,它借助了堆这种数据结构。堆是一种完全二叉树,它可以分为两种类型:最大堆和最小堆。在最大堆中,每个结点的值都大于等于它的子结点的值,而在最小堆中,每个结点的值都小于等…

力扣第84 题柱状图中最大的矩形 C++ 单调栈 Java

题目 84. 柱状图中最大的矩形 困难 相关标签 栈 数组 单调栈 给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。 求在该柱状图中,能够勾勒出来的矩形的最大面积。 示例 1: 输入:heigh…