stm32配置ADS8681

​ 被提醒了,很多驱动写了就忘了,能用是能用,怎么配置的忘记了,故记录一下。

一、设置引脚

1
2
3
4
5
6
7
8
9
/*******ADS8681引脚初始化*******
* RVS --> PB15 input
* SCLK --> PD9 output
* nCS --> PD10 output
* RST --> PD13 output
* SDI --> PD11 output
* SDO1 --> PB14 input
* SDO0 --> PD8 input
********************************/

​ output引脚Speed全部拉very high

image-20230331204934635

添加.h .c文件到工程中去,并添加引入路径

二、导入设置文件

ads8681.h文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/*** 
* @Author: RoxyKko
* @Date: 2023-03-31 20:07:22
* @LastEditors: RoxyKko
* @LastEditTime: 2023-03-31 21:45:18
* @Description: 这店家把丝印印错了,绷不住
*/

#ifndef _ADS8681_H_
#define _ADS8681_H_
#include "main.h"
// 基准电压
#define Vref 4.096

/*******ADS8681引脚初始化*******
* RVS --> PB15 input
* SCLK --> PD9 output
* nCS --> PD10 output
* RST --> PD13 output
* SDI --> PD11 output
* SDO1 --> PB14 input
* SDO0 --> PD8 input
********************************/
#define RVS HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15)

#define SCLK_H HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_SET)
#define SCLK_L HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_RESET)

#define nCS_H HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_SET)
#define nCS_L HAL_GPIO_WritePin(GPIOD, GPIO_PIN_10, GPIO_PIN_RESET)

#define nRESET_H HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_SET)
#define nRESET_L HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, GPIO_PIN_RESET)

#define SDI_H HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_SET)
#define SDI_L HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11, GPIO_PIN_RESET)

#define SDO_1 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14)

#define SDO_0 HAL_GPIO_ReadPin(GPIOD, GPIO_PIN_8)

#define _ref3 0x0000
#define _ref25 0x0001
#define _ref15 0x0002
#define _ref125 0x0003
#define _ref0625 0x0004

#define ref3 0x0008
#define ref25 0x0009
#define ref15 0x000A
#define ref125 0x000B

#define INTREF_Internal 0x0000 //内部参考输入
#define INTREF_External 0x0100 //外部参考输入


void ADS8681_Init_Mult(void);
void ADS8681_GPIO_Init(void) ;
void Delay(__IO uint32_t nCount);
void ADS8681_COM_Wreg(uint16_t Addr,uint16_t Com);
uint16_t ADS8681_COM_Rreg(uint16_t Addr);
void ADS8681_Reset(void);

// 读取ADS8681数据
uint16_t ADS8681_GetData(void);
float ADS8681_GetVoltage(uint16_t data);




#endif /* ADS8681_ADS8681_H_ */

ads8681.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
* @Author: RoxyKko
* @Date: 2023-03-31 20:07:33
* @LastEditors: RoxyKko
* @LastEditTime: 2023-03-31 21:43:21
* @Description: 这店家把丝印印错了,绷不住
*/

#include "asd8681.h"
#include "base.h"
#include "main.h"

volatile uint16_t ALARM; // 报警寄存器

/**
* @name: ADS8681_GPIO_Init(void)
* @description: ADS8681 GPIO初始化,gpio设置已经用CubeMX配置好了,这里只是初始化一下引脚默认电平{其实用Cubemx一起配好也可以}
* @return {*}
*/
void ADS8681_GPIO_Init(void)
{
nRESET_H;
SCLK_L;
nCS_H;
}

/**
* @name: ADS8681_Reset(void)
* @description: ASD8681复位,复位时序为:nRESET低电平5us,nRESET高电平5us
* @return {*}
*/
void ADS8681_Reset(void)
{
delay_us(5);
nRESET_L;
delay_us(5);
nRESET_H;
delay_us(5);
}

/**
* @name: ADS8681_COM_Rreg(uint16_t Addr)
* @description: ASD8681读寄存器函数,Addr为寄存器地址,返回值为寄存器值
* @param {uint16_t} Addr 寄存器地址
* @return {uint16_t} Rdata 寄存器值
*/
uint16_t ADS8681_COM_Rreg(uint16_t Addr)
{
u8 s = 0;
uint32_t DTemp = 0;
uint16_t Rdata = 0;
DTemp += Addr;
DTemp <<= 16;
DTemp |= 0xC8000000;

while (!RVS)
;
nCS_L;
for (s = 0; s < 32; s++)
{
if (DTemp & 0x80000000)
{
SDI_H;
}
else
{
SDI_L;
}
SCLK_H;
DTemp <<= 1;
SCLK_L;
}
nCS_H;

while (!RVS)
;
nCS_L;
for (s = 0; s < 16; s++)
{
Rdata <<= 1;
SCLK_H;
if (SDO_0)
{
Rdata++;
}
SCLK_L;
}
for (s = 0; s < 16; s++)
{
SCLK_H;
SCLK_L;
}
nCS_H;
return Rdata;
}

/**
* @name: ADS8681_COM_Wreg(uint16_t Addr,uint16_t Com)
* @description: ADS8681写寄存器函数,Addr为寄存器地址,Com为寄存器值
* @param {uint16_t} Addr 寄存器地址
* @param {uint16_t} Com 寄存器值
* @return {*}
*/
void ADS8681_COM_Wreg(uint16_t Addr, uint16_t Com)
{
u8 s = 0;
uint32_t DTemp = 0;
DTemp += Addr;
DTemp <<= 16;
DTemp += Com;
DTemp |= 0xD0000000;

while (!RVS)
;
nCS_L;
for (s = 0; s < 32; s++)
{
if (DTemp & 0x80000000)
{
SDI_H;
}
else
{
SDI_L;
}
SCLK_H;
DTemp <<= 1;
SCLK_L;
}
nCS_H;
}

/**
* @name: ADS8681_Init_Mult(void)
* @description: ASD8681初始化函数,初始化时序为:复位,设置量程,设置SDO模式,读取报警寄存器
* @return {*}
*/
void ADS8681_Init_Mult(void)
{
u8 a = 0;
ADS8681_Reset();
ADS8681_COM_Wreg(0x14, _ref3 | INTREF_External); // 量程设置,外部参考基准电压
ADS8681_COM_Wreg(0x0C, 0x0100); // SDO模式设置,时钟为内部时钟

for (a = 0; a < 2; a++)
{
nCS_L;
delay_us(5);
nCS_H;
while (!RVS)
;
}
ALARM = ADS8681_COM_Rreg(0x0020);
}

/**
* @name: ADS8681_GetData(void)
* @description: ADS8681读取数据函数,返回值为16位数据
* @return {uint16_t} data_tmp 16位数据
*/
uint16_t ADS8681_GetData(void)
{
uint16_t data_tmp = 0;
nCS_H; // 释放片选
while(!RVS); // 等待转换完成
nCS_L; // 选中片选
int i = 0;
for(i=0;i<16;i++)
{
data_tmp<<=1;
SCLK_H;
if(SDO_0)
{
data_tmp++;
}
SCLK_L;
}
return data_tmp;
}

/**
* @name: ADS8681_GetVoltage(uint16_t data)
* @description: ADS8681数据转换为电压值函数,返回值为电压值
* @param {uint16_t} data 16位数据
* @return {float}voltage 电压值
*/
float ADS8681_GetVoltage(uint16_t data)
{
float voltage,temp = 0;
temp = data - 0x8000;
voltage = (float)temp / 32768 * Vref * 3; //电压转换公式,一定要乘以内部设置的倍数 和校准基准电压值
return voltage;
}

三、使用方法

这里懒得设置定时器了,直接放在while(1)里面取值,之后工程里面使用的时候可以放在定时器里面定时获取值。

​ 这里测试使用信号源输出直流10mv,效果如图示,误差在1mv左右

参数:

uint16_t Rdata 16位数据

float Vol 电压

image-20230331220224037