当前位置: 首页 > news >正文

树莓派 ADS1263 各种库程序

不用库:完全底层代码(使用 spidevsysfs

main.c(完全底层,不依赖任何库)
// build: sudo make
// run:   sudo ./ads1263#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/spi/spidev.h>
#include <sys/ioctl.h>
#include <time.h>
#include <errno.h>/********* 引脚(BCM 编号) *********/
#define PIN_DRDY   17   // 输入
#define PIN_RESET  18   // 输出
#define PIN_CS     22   // 输出(软CS)/********* ADS1263 命令与寄存器 *********/
#define CMD_RESET   0x06
#define CMD_START1  0x08
#define CMD_STOP1   0x0A
#define CMD_RDATA1  0x12
#define CMD_RREG    0x20
#define CMD_WREG    0x40
#define REG_MODE2   0x05
#define REG_INPMUX  0x06
#define REG_REFMUX  0x0F// 参考:AVDD-AVSS
#define REF_AVDD    0x24
// 单端:AINx+ 对 AINCOM-
#define AINCOM      0x0A/********* SPI 配置 *********/
static const char *SPI_PATH = "/dev/spidev0.0";
static const uint32_t SPI_SPEED = 1000000; // 1 MHz
static const uint8_t  SPI_BITS  = 8;
static uint8_t        SPI_MODE  = SPI_MODE_1 | SPI_NO_CS; // 模式1,禁用硬件CS,用GPIO22做软CS
static int spi_fd = -1;/********* sysfs GPIO 工具函数 *********/
static int gpio_export(int pin){int fd = open("/sys/class/gpio/export", O_WRONLY);if(fd<0) return -1;char buf[16];int n = snprintf(buf,sizeof(buf),"%d",pin);write(fd, buf, n);close(fd);// 等待目录就绪char path[64];for(int i=0;i<50;i++){snprintf(path,sizeof(path),"/sys/class/gpio/gpio%d/direction",pin);if(access(path,F_OK)==0) return 0;usleep(2000);}return 0;
}
static void gpio_unexport(int pin){int fd = open("/sys/class/gpio/unexport", O_WRONLY);if(fd<0) return;char buf[16];int n = snprintf(buf,sizeof(buf),"%d",pin);write(fd, buf, n);close(fd);
}
static int gpio_set_dir(int pin, const char* dir){char path[64];snprintf(path,sizeof(path),"/sys/class/gpio/gpio%d/direction",pin);int fd = open(path, O_WRONLY);if(fd<0) return -1;write(fd, dir, strlen(dir));close(fd);return 0;
}
static int gpio_write(int pin, int val){char path[64];snprintf(path,sizeof(path),"/sys/class/gpio/gpio%d/value",pin);int fd = open(path, O_WRONLY);if(fd<0) return -1;if(val) write(fd,"1",1); else write(fd,"0",1);close(fd);return 0;
}
static int gpio_read(int pin){char path[64];char v='1';snprintf(path,sizeof(path),"/sys/class/gpio/gpio%d/value",pin);int fd = open(path, O_RDONLY);if(fd<0) return -1;read(fd,&v,1);close(fd);return (v=='0')?0:1;
}/********* 微延时 *********/
static inline void delay_us(unsigned int us){struct timespec ts;ts.tv_sec = us/1000000;ts.tv_nsec = (us%1000000)*1000;nanosleep(&ts,NULL);
}/********* SPI 基础 *********/
static int spi_open(){spi_fd = open(SPI_PATH, O_RDWR);if(spi_fd<0){ perror("open spidev"); return -1; }if(ioctl(spi_fd, SPI_IOC_WR_MODE, &SPI_MODE)<0){ perror("SPI_IOC_WR_MODE"); return -1; }if(ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &SPI_BITS)<0){ perror("SPI_IOC_WR_BITS"); return -1; }if(ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &SPI_SPEED)<0){ perror("SPI_IOC_WR_SPEED"); return -1; }return 0;
}
static void spi_close(){if(spi_fd>=0) close(spi_fd);spi_fd=-1;
}
static int spi_xfer(uint8_t *tx, uint8_t *rx, uint32_t len){struct spi_ioc_transfer tr = {0};tr.tx_buf        = (unsigned long)tx;tr.rx_buf        = (unsigned long)rx;tr.len           = len;tr.speed_hz      = SPI_SPEED;tr.bits_per_word = SPI_BITS;int ret = ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr);if(ret<0){ perror("SPI_IOC_MESSAGE"); return -1; }return 0;
}/********* 片选 *********/
static inline void cs_low(){  gpio_write(PIN_CS, 0); }
static inline void cs_high(){ gpio_write(PIN_CS, 1); }/********* ADS1263 基础 *********/
static int write_cmd(uint8_t cmd){uint8_t tx[1] = { cmd };cs_low();int r = spi_xfer(tx, NULL, 1);cs_high();delay_us(50);return r;
}
static int write_reg(uint8_t reg, uint8_t val){uint8_t tx[3] = { (uint8_t)(CMD_WREG | reg), 0x00, val };cs_low();int r = spi_xfer(tx, NULL, 3);cs_high();delay_us(50);return r;
}
static int wait_drdy(double timeout_s){const uint64_t deadline_ns = (uint64_t)(timeout_s*1e9);struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);uint64_t t0 = (uint64_t)ts.tv_sec*1000000000ull + ts.tv_nsec;for(;;){int lev = gpio_read(PIN_DRDY);if(lev==0) return 0;delay_us(100);clock_gettime(CLOCK_MONOTONIC, &ts);uint64_t now = (uint64_t)ts.tv_sec*1000000000ull + ts.tv_nsec;if(now - t0 > deadline_ns) break;}return -1;
}// RDATA1 返回顺序:STATUS(1) + DATA(4) + CRC(1)
// 我们发送 1+6 共7字节,rx[1..5] 有效,其中 rx[2..5] 是 32bit 数据
static int32_t read_data(){uint8_t tx[7] = { CMD_RDATA1, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };uint8_t rx[7] = {0};cs_low();spi_xfer(tx, rx, 7);cs_high();int32_t val = ((int32_t)rx[2]<<24) | ((int32_t)rx[3]<<16) | ((int32_t)rx[4]<<8) | ((int32_t)rx[5]);return val;
}static void select_single_ended(uint8_t pos_ain){write_reg(REG_REFMUX, REF_AVDD);write_reg(REG_INPMUX, (uint8_t)((pos_ain<<4) | AINCOM));delay_us(20); // MUX 建立时间
}static void ads_reset_pulse(){// RESET 为低脉冲再拉高gpio_write(PIN_RESET, 0);delay_us(1000);gpio_write(PIN_RESET, 1);delay_us(5000);
}static void init_ads1263(){ads_reset_pulse();write_cmd(CMD_RESET);usleep(50000);// MODE2:0x8D(高数据率/低延迟,保持与参考算法一致)write_reg(REG_MODE2, 0x8D);
}/********* 算法:码->电压 *********/
static inline double code_to_volt(int32_t code, double vref, int gain){// 32位有符号,参考算法:code / 2^31 * (vref/gain)return ((double)code / 2147483648.0) * (vref / gain);
}int main(void){// 导出并配置 GPIOgpio_export(PIN_DRDY);gpio_export(PIN_RESET);gpio_export(PIN_CS);gpio_set_dir(PIN_DRDY,  "in");gpio_set_dir(PIN_RESET, "out");gpio_set_dir(PIN_CS,    "out");gpio_write(PIN_CS, 1);gpio_write(PIN_RESET, 1);// 打开 SPIif(spi_open()<0){fprintf(stderr,"open spidev failed\n");return 1;}printf("ADS1263 initialized.\n");init_ads1263();printf("Reset complete.\n");const double vref = 5.32; // 按你的实际 AVDD 或外参电压const int gain = 1;// 预选通道并启动select_single_ended(0);write_cmd(CMD_START1);printf("Started sampling...\n");// 丢弃第一帧if(wait_drdy(0.5)==0) (void)read_data();int32_t code[4]={0};for(;;){// AIN0..3 轮询for(int ch=0; ch<4; ch++){select_single_ended((uint8_t)ch);if(wait_drdy(0.5)==0) code[ch] = read_data();}double v0 = code_to_volt(code[0], vref, gain);double v1 = code_to_volt(code[1], vref, gain);double v2 = code_to_volt(code[2], vref, gain);double v3 = code_to_volt(code[3], vref, gain);printf("\rAIN0= %.6f V   AIN1= %.6f V   AIN2= %.6f V   AIN3= %.6f V   ", v0,v1,v2,v3);fflush(stdout);// 轻微节流usleep(1000);}// 不会到达write_cmd(CMD_STOP1);spi_close();gpio_unexport(PIN_DRDY);gpio_unexport(PIN_RESET);gpio_unexport(PIN_CS);return 0;
}

makefile

CC     = gcc
CFLAGS = -Wall -O2
LDFLAGS=TARGET = ads1263
SRC    = main.c
OBJ    = $(SRC:.c=.o)all: $(TARGET)$(TARGET): $(OBJ)$(CC) $(OBJ) -o $@ $(LDFLAGS)%.o: %.c$(CC) $(CFLAGS) -c $< -o $@clean:rm -f $(OBJ) $(TARGET)

pigpio 库 (兼容性一般)

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <pigpio.h>
#include <time.h>// 引脚定义 (BCM)
#define PIN_DRDY   17  // BCM17 (Data Ready)
#define PIN_RESET  18  // BCM18 (Reset)
#define PIN_CS     22  // BCM22 (Chip Select)// 命令与寄存器
#define CMD_RESET   0x06
#define CMD_START1  0x08
#define CMD_STOP1   0x0A
#define CMD_RDATA1  0x12
#define CMD_RREG    0x20
#define CMD_WREG    0x40
#define REG_MODE2   0x05
#define REG_INPMUX  0x06
#define REG_REFMUX  0x0F// 参考选择:AVDD-AVSS
#define REF_AVDD    0x24
// AIN 编码
#define AINCOM      0x0A// 初始化 SPI 设置
#define SPI_CHANNEL 0
#define SPI_SPEED    500000  // 500 kHz(适当减慢 SPI 时钟频率)
#define SPI_BITS     8// 初始化 ADS1263
void init_ads1263(int spi_handle){uint8_t tx[3] = {CMD_RESET, 0x00, 0x00};gpioWrite(PIN_CS, 0);spiWrite(spi_handle, (char*)tx, 3);gpioWrite(PIN_CS, 1);gpioDelay(50000); // 延时50000微秒,等待重置完成
}// 选择单端模式
void select_single_ended(int spi_handle, uint8_t pos_ain){uint8_t tx[3] = {REG_REFMUX, REF_AVDD, 0x00};gpioWrite(PIN_CS, 0);spiWrite(spi_handle, (char*)tx, 3);gpioWrite(PIN_CS, 1);tx[0] = REG_INPMUX;tx[1] = (pos_ain << 4) | AINCOM;gpioWrite(PIN_CS, 0);spiWrite(spi_handle, (char*)tx, 3);gpioWrite(PIN_CS, 1);gpioDelay(20000); // MUX切换延时
}// 读取数据
int32_t read_data(int spi_handle){uint8_t tx[7] = {CMD_RDATA1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};uint8_t rx[7];gpioWrite(PIN_CS, 0);spiXfer(spi_handle, (char*)tx, (char*)rx, 7);gpioWrite(PIN_CS, 1);int32_t val = ((int32_t)rx[2] << 24) | ((int32_t)rx[3] << 16) |((int32_t)rx[4] << 8)  | ((int32_t)rx[5]);return val;
}// 计算电压
double calculate_voltage(int32_t raw_data, double vref, int gain) {return ((double)raw_data / 2147483648.0) * (vref / gain);
}// 等待数据准备好
int wait_drdy(double timeout_s){uint64_t t0 = gpioTick();while(1){if (gpioRead(PIN_DRDY) == 0) {printf("Data is ready!\n");  // Debug: Data is readyreturn 0;}if ((gpioTick() - t0) > (timeout_s * 1000000)) break;}printf("Timeout while waiting for data!\n");  // Debug: Timeoutreturn -1;
}int main(void){if (gpioInitialise() < 0) {printf("GPIO initialization failed\n");return 1;}// 设置引脚gpioSetMode(PIN_DRDY, PI_INPUT);gpioSetMode(PIN_RESET, PI_OUTPUT);gpioSetMode(PIN_CS, PI_OUTPUT);gpioWrite(PIN_CS, 1);  // 拉高CSgpioWrite(PIN_RESET, 1);  // 拉高RESET// 打开SPI通道int spi_handle = spiOpen(SPI_CHANNEL, SPI_SPEED, 0);if (spi_handle < 0) {printf("Failed to open SPI\n");gpioTerminate();return 1;}printf("ADS1263 initialized.\n");init_ads1263(spi_handle);printf("Reset complete.\n");// 参考电压和增益const double vref = 3.3; // 确保参考电压为 5Vconst int gain = 1;        // 假设增益为1// 选择 AIN0 并启动select_single_ended(spi_handle, 0);uint8_t tx[1] = {CMD_START1};gpioWrite(PIN_CS, 0);spiWrite(spi_handle, (char*)tx, 1);gpioWrite(PIN_CS, 1);printf("Started sampling...\n");// 丢弃第一帧if (wait_drdy(0.5) == 0) (void)read_data(spi_handle);// 采集数据并计算电压int32_t code = read_data(spi_handle);double voltage = calculate_voltage(code, vref, gain);// 输出电压printf("AIN0 Voltage: %.6f V\n", voltage);// 停止采样tx[0] = CMD_STOP1;gpioWrite(PIN_CS, 0);spiWrite(spi_handle, (char*)tx, 1);gpioWrite(PIN_CS, 1);spiClose(spi_handle);gpioTerminate();return 0;
}

http://www.dtcms.com/a/541369.html

相关文章:

  • 基于NodeJs实现一个MCP客户端(会话模式和无会话模式)
  • 小迪安全v2023学习笔记(一百三十九讲)—— Linux系统权限提升篇Vulnhub辅助项目SUID权限SUDO指令版本漏洞
  • 《电子工程师基础篇:全面解析电容分类、核心MLCC与选型参数》
  • opencv学习笔记7:对mnist数据集分类
  • 房地产公司网站建设报价方案涂料网站模板
  • 深圳手机网站网站恶意点击
  • 网站优化搜索东莞企业网络推广运营技巧
  • 网站关键词怎么设置莲塘网站建设
  • 跨院区数据不通、停机风险高?浙人医靠电科金仓多活架构破信创难题
  • 免费网站建设优化做一个付费网站多少钱
  • Redis - hash list (常用命令/内部编码/应用场景)
  • 广水网站定制淘宝可以在哪些网站上面打做推广
  • elasticSearch之API:Ingest Pipeline Painless Script
  • elasticsearch安装分词器和操作
  • ubuntu系统安装elasticsearch
  • 网站seo分析常用的工具是华建河北住房和城乡建设厅网站
  • 做网站客户尾款老不给怎么办h5登录页面
  • 黑马JAVA+AI基础11-面向对象编程-常用API-String-ArrayList
  • 平东网站建设引流量的网站
  • 解决Docker容器中出现的错误“Pangolin X11: Failed to open X display”
  • Spring DAO与JDBC优化实战
  • asp access网站架设教程网站如何做即时聊天
  • R 语言科研绘图第 80 期 --- 词云图
  • 通信算法之336 :3GPPMixed Mode Turbo Decoder
  • 如何创建自己的网站店面设计装修网
  • 【软考】信息系统项目管理师
  • WEBSTORM前端 —— 第6章:JavaScript进阶 —— 第2节:构造函数数据常用函数
  • 可以做软件的网站有哪些功能吗现在最火的推广平台有哪些
  • 数字化总架构师:在浪潮中锚定方向,成就组织与自我梦想
  • 网站开发主流语言用文字工具在页面中间输入主标题和副