【GD32F427开发板试用】04使用SPI与32位ADC(CS5552)通讯采集数据

news/2024/11/27 8:49:16/

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动,更多开发板试用活动请关注极术社区网站。作者:汪阳

CS5552 为一款 SPI 接口的双信道、32 位高精度 ADC 芯片,内置 1~128 倍可程序设计的低噪声仪表放大器、高精度 Sigma-Delta ADC,同时内部集成温度传感器、高精度基准电压源、晶体起振电路、高频内部 RC 时钟源。ADC 实际有效精度(ENOB)24.3BIT@1 倍 PGA,22.9BIT@64 倍 PGA,等效输入噪声低至 3nV/√ ,零漂 0.5uV,零漂温度系数低于 5nV/℃。输出码率可配置为 6.25Hz 至51200Hz。可用于各类电子秤、分析天平、工业过程控制、直流/交流电能测量、耳温枪等需要高精度、低零漂的应用场合。CS5552的SPI 接口支持最高 10MHz。

本来是使用GD32F427R的硬件SPI0与CS5552通信,但CS5552在连续模式下SPI的SDO会拉低表示数据转换完成。由于我的SPI连接线上MISO没有外部上拉电阻而5552在数据没准备完成是高阻状态,需要有外部上拉电阻才能读出高电平,否则一直是低电平,不能产生中断。尝试了打开GD32的上拉也是不管用,其实对于GD32的IO口还是要吐槽一点,IO口的设计比较中规中矩,没有太大亮点。像有些友商IO口缓冲电阻能配置(驱动强度),连I2C等上拉电阻都可以配置不需要外部上拉电阻以及缓冲电阻,硬件设计起来还是挺方便的,甚至有些厂商的IO口还支持滤波并且滤波时间可以配置,在工业上用起来还是很方便的。无奈只能使用软件模拟SPI了,这样把MISO引脚设置成输入,并且使能上拉,就能顺利通讯了。关键代码如下:
1.SPI宏定义

/\*  
PA4 CS  
PA5 CLK  
PA6 miso  
PA7 mosi  
\*/  #  #define SET\_SPI0\_NSS\_HIGH         gpio\_bit\_set(GPIOA,GPIO\_PIN\_4);  #  #define SET\_SPI0\_NSS\_LOW           gpio\_bit\_reset(GPIOA,GPIO\_PIN\_4);  #  #define CLK\_HIGH         gpio\_bit\_set(GPIOA,GPIO\_PIN\_5);  # #define CLK\_LOW           gpio\_bit\_reset(GPIOA,GPIO\_PIN\_5);  # #define MOSI\_HIGH          gpio\_bit\_set(GPIOA,GPIO\_PIN\_7);  # #define MOSI\_LOW           gpio\_bit\_reset(GPIOA,GPIO\_PIN\_7);  # #define READ\_MISO         gpio\_input\_bit\_get(GPIOA,GPIO\_PIN\_6)

2.初始化SPI,保留了硬件SPI作为参考

void spi0\\\\\_init(void)  
{  
rcu\\\\\_periph\\\\\_clock\\\\\_enable(RCU\\\\\_GPIOA);  
//    rcu\\\\\_periph\\\\\_clock\\\\\_enable(RCU\\\\\_SPI0);  
//  
// /\* configure SPI0 GPIO \*/  
//    gpio\\\\\_af\\\\\_set(GPIOA, GPIO\\\\\_AF\\\\\_5, GPIO\\\\\_PIN\\\\\_5 | GPIO\\\\\_PIN\\\\\_6 | GPIO\\\\\_PIN\\\\\_7);  
//    gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_AF, GPIO\\\\\_PUPD\\\\\_NONE, GPIO\\\\\_PIN\\\\\_5 | GPIO\\\\\_PIN\\\\\_6 | GPIO\\\\\_PIN\\\\\_7);  gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_AF, GPIO\\\\\_PUPD\\\\\_PULLUP, GPIO\\\\\_PIN\\\\\_6);  
//    gpio\\\\\_output\\\\\_options\\\\\_set(GPIOA, GPIO\\\\\_OTYPE\\\\\_PP, GPIO\\\\\_OSPEED\\\\\_50MHZ, GPIO\\\\\_PIN\\\\\_5 | GPIO\\\\\_PIN\\\\\_6 | GPIO\\\\\_PIN\\\\\_7);  //    /\* set SPI0\\\\\_NSS as GPIO\*/  
//    gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_OUTPUT, GPIO\\\\\_PUPD\\\\\_PULLUP, GPIO\\\\\_PIN\\\\\_4);  
//    gpio\\\\\_output\\\\\_options\\\\\_set(GPIOA, GPIO\\\\\_OTYPE\\\\\_PP, GPIO\\\\\_OSPEED\\\\\_50MHZ, GPIO\\\\\_PIN\\\\\_4);  // spi\\\\\_parameter\\\\\_struct spi\\\\\_init\\\\\_struct;  //    /\* configure SPI1 parameter \*/  
//    spi\\\\\_init\\\\\_struct.trans\\\\\_mode           = SPI\\\\\_TRANSMODE\\\\\_FULLDUPLEX;  
//    spi\\\\\_init\\\\\_struct.device\\\\\_mode          = SPI\\\\\_MASTER;  
//    spi\\\\\_init\\\\\_struct.frame\\\\\_size           = SPI\\\\\_FRAMESIZE\\\\\_8BIT;  
//    spi\\\\\_init\\\\\_struct.clock\\\\\_polarity\\\\\_phase = SPI\\\\\_CK\\\\\_PL\\\\\_LOW\\\\\_PH\\\\\_1EDGE;  
//    spi\\\\\_init\\\\\_struct.nss                  = SPI\\\\\_NSS\\\\\_SOFT;  
//    spi\\\\\_init\\\\\_struct.prescale             = SPI\\\\\_PSC\\\\\_128;//128-800k  
//    spi\\\\\_init\\\\\_struct.endian               = SPI\\\\\_ENDIAN\\\\\_MSB;  
//    spi\\\\\_init(SPI0, &spi\\\\\_init\\\\\_struct);  
//  
// SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
//    /\* enable SPI \*/  
//    spi\\\\\_enable(SPI0);  
//    SET\\\\\_SPI0\\\\\_NSS\\\\\_LOW;  /\*模拟IO-spi\*/  
/\* set SPI0\\\\\_NSS as GPIO\*/  gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_OUTPUT, GPIO\\\\\_PUPD\\\\\_PULLUP, GPIO\\\\\_PIN\\\\\_4);  gpio\\\\\_output\\\\\_options\\\\\_set(GPIOA, GPIO\\\\\_OTYPE\\\\\_PP, GPIO\\\\\_OSPEED\\\\\_50MHZ, GPIO\\\\\_PIN\\\\\_4);  gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_OUTPUT, GPIO\\\\\_PUPD\\\\\_PULLUP, GPIO\\\\\_PIN\\\\\_5);  gpio\\\\\_output\\\\\_options\\\\\_set(GPIOA, GPIO\\\\\_OTYPE\\\\\_PP, GPIO\\\\\_OSPEED\\\\\_50MHZ, GPIO\\\\\_PIN\\\\\_5);  gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_OUTPUT, GPIO\\\\\_PUPD\\\\\_PULLUP, GPIO\\\\\_PIN\\\\\_7);  gpio\\\\\_output\\\\\_options\\\\\_set(GPIOA, GPIO\\\\\_OTYPE\\\\\_PP, GPIO\\\\\_OSPEED\\\\\_50MHZ, GPIO\\\\\_PIN\\\\\_7);  gpio\\\\\_mode\\\\\_set(GPIOA, GPIO\\\\\_MODE\\\\\_INPUT, GPIO\\\\\_PUPD\\\\\_PULLUP, GPIO\\\\\_PIN\\\\\_6);  CLK\\\\\_LOW;  SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
}

3.SPI收发数据,保留硬件SPI收发

uint16\\\\\_t  spi\\\\\_data(uint16\\\\\_t data)  
{  // while (spi\\\\\_i2s\\\\\_flag\\\\\_get(SPI0, SPI\\\\\_FLAG\\\\\_TBE) == RESET);  //    spi\\\\\_i2s\\\\\_data\\\\\_transmit(SPI0, data);  //    while (spi\\\\\_i2s\\\\\_flag\\\\\_get(SPI0, SPI\\\\\_FLAG\\\\\_RBNE) == RESET);  //    return spi\\\\\_i2s\\\\\_data\\\\\_receive(SPI0);  unsigned char i;  
uint8\\\\\_t rdata = 0;  
for(i=8;i>0;i--)  
{  
if((data&0x80)==0)  
{MOSI\\\\\_LOW;}  
else  
{MOSI\\\\\_HIGH;}  
Delay(10);  
CLK\\\\\_HIGH;  
Delay(20);  
rdata <<= 1;  
if(READ\\\\\_MISO == SET)  
rdata++;  
CLK\\\\\_LOW;  
data<<=1;  
Delay(10);  
}  
return rdata;  
}

4.读写CS5552寄存器

void WRITE\\\\\_REGISTER(unsigned char COMMAND,unsigned char H\\\\\_DATA,unsigned char M\\\\\_DATA,unsigned char L\\\\\_DATA,unsigned char S\\\\\_DATA)  
{  
spi\\\\\_data(COMMAND);  
Delay(1);  
spi\\\\\_data(H\\\\\_DATA);  
spi\\\\\_data(M\\\\\_DATA);  
spi\\\\\_data(L\\\\\_DATA);  
spi\\\\\_data(S\\\\\_DATA);  
}  uint32\\\\\_t READ\\\\\_REGISTER(unsigned char COMMAND)  
{  
uint32\\\\\_t data = 0;  
uint8\\\\\_t datav\[4\];  
spi\\\\\_data(COMMAND);  
Delay(1);  
datav\[0\] = spi\\\\\_data(0x00);  
datav\[1\] = spi\\\\\_data(0x00);  
datav\[2\] = spi\\\\\_data(0x00);  
datav\[3\] = spi\\\\\_data(0x00);  
data = (datav\[0\]<<24)|(datav\[1\]<<16) | (datav\[2\]<<8) | (datav\[3\]<<0);  
return data;  
}

5.初始化CS5552

void cs5552\\\\\_init(void)  
{  
spi0\\\\\_init();  
SET\\\\\_SPI0\\\\\_NSS\\\\\_LOW;  
spi\\\\\_data(0x00);  
spi\\\\\_data(0xa5);  
spi\\\\\_data(0xff);  
spi\\\\\_data(0x5a);  
SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
Delay(0xffff);  
SET\\\\\_SPI0\\\\\_NSS\\\\\_LOW;  
WRITE\\\\\_REGISTER(0x30,0x80,0x00,0x00,0x00); // RESET  
SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
Delay(0xffff);  
SET\\\\\_SPI0\\\\\_NSS\\\\\_LOW;  
WRITE\\\\\_REGISTER(0x00,0x00,0x00,0x00,0x00); // OS\\\\\_CH0  
WRITE\\\\\_REGISTER(0x09,0x02,0x00,0x00,0x00); // GAIN\\\\\_CH0  
WRITE\\\\\_REGISTER(0x21,0x00,0x00,0x00,0x81); // CONV\\\\\_CONF0 //C1-PGA=128 DATA RATE=12.5Hz 81-128-200hz  
WRITE\\\\\_REGISTER(0x28,0x00,0x00,0x00,0x00); // CONV\\\\\_CONF1  
WRITE\\\\\_REGISTER(0x30,0x00,0x01,0x00,0x00); // SYS\\\\\_CONF0 //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*HBF\\\\\_EN=0;  
WRITE\\\\\_REGISTER(0x39,0x00,0x11,0x02,0x10); // SYS\\\\\_CONF1 //\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*FR\\\\\_SEL=0;  
WRITE\\\\\_REGISTER(0x41,0x00,0x02,0x00,0x00); // SYS\\\\\_CONF2  
SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
Delay(0xf);  
SET\\\\\_SPI0\\\\\_NSS\\\\\_LOW;  
/\*测试读出数据\*/  
uint32\\\\\_t data = READ\\\\\_REGISTER(0x24);//读SYS\\\\\_CONF0  
printf("CONF0 = %d\\r\\n",data);  
data = READ\\\\\_REGISTER(0x05);//读OS-CH0  
printf("OS-CH0 = %d\\r\\n",data);  
data = READ\\\\\_REGISTER(0xC0);//读GAIN-CH0  
printf("GAIN-CH0 = %d\\r\\n",data);  
data = READ\\\\\_REGISTER(0x14);//读OS-CH1  
printf("OS-CH1 = %d\\r\\n",data);  
data = READ\\\\\_REGISTER(0x1D);//读GAIN-CH1  
printf("GAIN-CH1 = %d\\r\\n",data);  
spi\\\\\_data(0x82);//开启连续转换  
SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
}

6.SDO拉低连续读CS5552转换数据

uint32\\\\\_t read\\\\\_cs5552(void)  
{  
uint32\\\\\_t data = 0;  
SET\\\\\_SPI0\\\\\_NSS\\\\\_LOW;  
Delay(2);  
SDO\\\\\_L;//等待SDO拉低  
data = READ\\\\\_REGISTER(0xff);  
SET\\\\\_SPI0\\\\\_NSS\\\\\_HIGH;  
return data;  
}

7.通过软件模拟SPI,使用sck为800k,cs5552采样速率为200次,读出数据精度比较好,经过滤波处理看来达到了高精度采样AD的行列。


http://www.ppmy.cn/news/117141.html

相关文章

windows 下使用arthas

工具版本&#xff1a;arthas-packaging-3.0.4-bin 使用步骤&#xff1a; &#xff08;1&#xff09; 打开cmd as.bat [进程号] 如 as.bat 5552 &#xff08;2&#xff09;拷贝需要分析的方法 copy refrence, 注意最后的 方法名和类名之间的连接符 可能为#&#xff0c;改为 空…

转载:ultraiso制作超过4G的系统U盘启动盘教程

转载自&#xff1a;http://www.winwin7.com/JC/5552.html ultraiso也算是老牌的光盘镜像工具了&#xff0c;使用ultraiso来制作U盘启动盘非常简单&#xff0c;在之前的《UltraISO制作U盘启动盘》中就有分享&#xff0c;不过鉴于很多朋友反馈4G以上的系统ISO镜像文件无法制作成…

bat添加到windows服务

1、 编写bat脚本 ::注释 echo off ::显示当前日期时间 echo %data% %time%::切换到指定的VUE服务器工作路径 cd /d e:\ColleagueFiles\pvGrid_nanRui_demo::执行vue服务启动命令::前提条件&#xff1a;::1、npm install 完成::2、npm run dev 可以正常启动服务::3、指定网站可…

SQL 连接 表,取副表的第一条数据

两个表是一(A表)对多(B表)的关系&#xff0c;join的时候&#xff0c;B表只对应显示第一条数据&#xff08;某些条件&#xff09;。sql该如何写&#xff1f; 表A Aid title days 1 清远二天游 2 2 东莞一天游 1 3 深圳小梅沙二天 2表BBid …

5545

题意 对于每组数据有n&#xff08;1e5&#xff09;个村庄&#xff0c;m&#xff08;1e5&#xff09;个战场 对于村庄i&#xff0c;曹操可以选择支付c[i]*num元&#xff0c;&#xff08;0<c[i]<1e5&#xff09;使得这个村庄派出num个士兵&#xff0c;在战场x[i]为曹操作战…

RabbitMQ模块使用的默认端口

详见rabbitmq networking port 端口范围英文描述中文描述4369epmd, a peer discovery service used by RabbitMQ nodes and CLI toolserlang发现口5672, 5671used by AMQP 0-9-1 and 1.0 clients without and with TLSclient端通信口5552, 5551used by the RabbitMQ Stream pr…

A002-185-2531

目录 第一页作业 2 1.1验收承认(acceptance) 2 1.2要求需要(requirement) 5 1.3最初形态(Prototype) 6 1.4Model(模型) 7 1.5异义词(Homonym) 8 1.6检查(Inspection) 8 1.7敏捷式项目管理(Agile project management) 9 1.8特征(Feature) 10 1.9实体(Entity) 12 1.10错误(Error)…

RGB888与RGB565

真彩色是指图像中的每个像素值都分成R&#xff08;红&#xff09;、G&#xff08;绿&#xff09;、B&#xff08;蓝&#xff09;三个基色分量&#xff0c;每个基色分量直接决定其基色的强度&#xff0c;这样产生的色彩称为彩色。彩色图像是一种用三个或更多字节描述像素的计算机…