软件SPI ADS8684/ADS8688驱动程序
使用
利用ADS8688采集互感器电压信号,使用软件SPI。
硬件电路
模拟信号输入
ADS8688外围电路
变量及宏定义
//位带操作#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2))
#define MEM_ADDR(addr) *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C
#define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C
#define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C
#define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808
#define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08
#define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008
#define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 //IO口操作,只对单一的IO口,确保n的值小于16#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //输出
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //输入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //输出
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //输入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //输出
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //输入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //输出
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //输入 /**************************************引脚定义*************************************************/#define ADS8688_CS PAout(4)
#define ADS8688_SCK PAout(5)
#define ADS8688_RST PBout(0)
#define ADS8688_MOSI PAout(7)#define ADS8688_MISO1 PAin(6)
#define ADS8688_MISO2 PCin(4)
#define ADS8688_MISO3 PCin(5) /**************************************ADS8688寄存器********************************************///与命令寄存器相关的命令#define NO_OP 0x0000
#define STDBY 0x8200
#define PWR_DN 0x8300
#define RST 0x8500
#define AUTO_RST 0xA000
#define MAN_Ch_0 0xC000
#define MAN_CH_1 0xC400
#define MAN_Ch_2 0xC800
#define MAN_Ch_3 0xCC00
#define MAN_Ch_4 0xD000
#define MAN_Ch_5 0xD400
#define MAN_Ch_6 0xD800
#define MAN_Ch_7 0xDC00
#define MAN_AUX 0xE000//与程序寄存器相关的命令#define WRITE 1
#define READ 0#define AUTO_SEQ_EN 0x01
#define Channel_Power_Down 0x02
#define Feature_Select 0x03#define CH7_EN 0x80
#define CH6_EN 0x40
#define CH5_EN 0x20
#define CH4_EN 0x10
#define CH3_EN 0x08
#define CH2_EN 0x04
#define CH1_EN 0x02
#define CH0_EN 0x01 #define CH7_PD 0x80
#define CH6_PD 0x40
#define CH5_PD 0x20
#define CH4_PD 0x10
#define CH3_PD 0x08
#define CH2_PD 0x04
#define CH1_PD 0x02
#define CH0_PD 0x01#define Channel_0_Input_Range 0x05
#define Channel_1_Input_Range 0x06
#define Channel_2_Input_Range 0x07
#define Channel_3_Input_Range 0x08
#define Channel_4_Input_Range 0x09
#define Channel_5_Input_Range 0x0A
#define Channel_6_Input_Range 0x0B
#define Channel_7_Input_Range 0x0C #define VREF_B_25 0x00 //通道输入范围:±2.5×VREF
#define VREF_B_125 0x01 //通道输入范围:±1.25×VREF
#define VREF_B_0625 0x02 //通道输入范围:±0.625×VREF
#define VREF_U_0_25 0x05 //通道输入范围:0-2.5×VREF
#define VREF_U_0_125 0x06 //通道输入范围:0-1.25×VREF#define Ch_0_Hysteresis 0x15
#define Ch_0_High_Threshold_MSB 0x16
#define Ch_0_High_Threshold_LSB 0x17
#define Ch_0_Low_Threshold_MSB 0x18
#define Ch_0_Low_Threshold_LSB 0x19 #define Ch_7_Hysteresis 0x38
#define Ch_7_High_Threshold_MSB 0x39
#define Ch_7_High_Threshold_LSB 0x3A
#define Ch_7_Low_Threshold_MSB 0x3B
#define Ch_7_Low_Threshold_LSB 0x3C #define Command_Read_Back 0x3F/*******************************变量声明************************************/extern u8 Rxh[3]; //存储输出数据的高8位
extern u8 Rxl[3]; //存储输出数据的低8位extern u16 ADC1_Data[7]; //存储 ADC1 8个通道的输出数据
extern u16 ADC2_Data[7]; //存储 ADC2 8个通道的输出数据
extern u16 ADC3_Data[7]; //存储 ADC3 8个通道的输出数据extern u16 Transfer_Data[21]; //存储3个 ADC 21个通道的输出数据/*******************************函数声明************************************/void SPI_GPIO_Init(void);
void SPI_ReadWriteByte(u8 Tx_Data, u8 *MISO1, u8 *MISO2, u8 *MISO3);
void ADS8688_WriteCmdReg(u16 cmd);
void Enter_AUTO_RST_Mode(void);
void ADS8688_WriteProgramRegister(u8 Addr, u8 data);
void ADS8688_ReadProgramRegister(u8 Addr);
void Set_Auto_Scan_Sequence(u8 seq);
void Set_CH_Range_Select(u8 ch, u8 range);
void Set_Channel_Power_Down(u8 pwd);
void ADS8688_Init(void);
void Get_AUTO_RST_Mode_Data(u8 chn);
void Data_Transfer(void);
函数功能
/*===============================================================
函数名称:SPI_GPIO_Init函数功能:模拟SPI端口初始化输入参数:无返 回 值:无
================================================================*/
void SPI_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE); //使能PC端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7; //ADS8688_CS->PA4、ADS8688_SCK->PA5、ADS8688_MOSI->PA7GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化端口GPIO_ResetBits(GPIOA,GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7); //PA4、PA5、PA7输出低电平GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //ADS8688_RST->PB0GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHzGPIO_SetBits(GPIOB, GPIO_Pin_0); //PB0输出高电平 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //ADS8688_MISO1->PA6GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化端口GPIO_ResetBits(GPIOA, GPIO_Pin_6); //PA6输入低电平GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; //ADS8688_MISO2->PC4,ADS8688_MISO3->PC5GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz GPIO_Init(GPIOC, &GPIO_InitStructure); //根据设定参数初始化端口GPIO_ResetBits(GPIOC,GPIO_Pin_4 | GPIO_Pin_5); //PC4、PC5输入低电平
}
/*===============================================================
函数名称:SPI_ReadWriteByte函数功能:模拟SPI读写8位数据,上升沿写数据,下降沿读数据输入参数:Tx_Data:写入的数据,MISO1:ADC1输出数据的指针,MISO2:ADC2输出数据的指针,MISO3:ADC3输出数据的指针返 回 值:无
================================================================*/
void SPI_ReadWriteByte(u8 Tx_Data, u8 *MISO1, u8 *MISO2, u8 *MISO3)
{u8 i = 0;for(i = 0; i < 8; i++){ADS8688_SCK = 0; //上升沿写入8位数据if(Tx_Data & (1 << (7 - i))){ADS8688_MOSI = 1;}else{ADS8688_MOSI = 0;}ADS8688_SCK = 1; //下降沿读取8位数据*MISO1 <<= 1; if(ADS8688_MISO1){*MISO1 |= 1; }*MISO2 <<= 1;if(ADS8688_MISO2){*MISO2 |= 1; }*MISO3 <<= 1;if(ADS8688_MISO3){*MISO3 |= 1; }ADS8688_SCK = 0; }
}
/*===============================================================
函数名称:ADS8688_WriteCmdReg函数功能:写ADS8688命令寄存器输入参数:cmd:写入的命令返 回 值:无
================================================================*/void ADS8688_WriteCmdReg(u16 cmd)
{ ADS8688_CS = 0;SPI_ReadWriteByte((cmd & 0xFF00) >> 8, Rxh, Rxh+1, Rxh+2); SPI_ReadWriteByte(cmd & 0xFF, Rxh, Rxh+1, Rxh+2);ADS8688_CS = 1;
}
/*===============================================================
函数名称:Enter_AUTO_RST_Mode函数功能:进入AUTO_RST模式输入参数:无返 回 值:无
================================================================*/void Enter_AUTO_RST_Mode(void)
{ADS8688_WriteCmdReg(AUTO_RST);
}
/*===============================================================
函数名称:ADS8688_WriteProgramRegister函数功能:向程序寄存器中写入地址和数据输入参数:Addr:地址位:BIT[15:9]、读写位:BIT8,data:数据位:BIT[7:0]返 回 值:无
================================================================*/void ADS8688_WriteProgramRegister(u8 Addr, u8 data)
{ADS8688_CS = 0;SPI_ReadWriteByte((Addr << 1) | WRITE, Rxh, Rxh+1, Rxh+2);SPI_ReadWriteByte(data, Rxh, Rxh+1, Rxh+2);ADS8688_CS = 1;
}/*===============================================================
函数名称:ADS8688_ReadProgramRegister函数功能:读取程序寄存器中的数据输入参数:Addr:地址位:BIT[15:9]、读写位:BIT8返 回 值:data:读取的8位数据
================================================================*/void ADS8688_ReadProgramRegister(u8 Addr)
{ ADS8688_CS = 0;SPI_ReadWriteByte((Addr << 1) | READ, Rxh, Rxh+1, Rxh+2);SPI_ReadWriteByte(0xFF, Rxh, Rxh+1, Rxh+2);SPI_ReadWriteByte(0xFF, Rxh, Rxh+1, Rxh+2); //24个SCLK周期后,可以读取8位数据ADS8688_CS = 1;
}
/*===============================================================
函数名称:Set_Auto_Scan_Sequence函数功能:设置自动扫描通道顺序输入参数:seq:所选的扫描通道返 回 值:无
================================================================*/void Set_Auto_Scan_Sequence(u8 seq)
{ADS8688_WriteProgramRegister(AUTO_SEQ_EN, seq);
}/*===============================================================
函数名称:Set_CH_Range_Select函数功能:设置通道输入范围输入参数:ch(通道地址),可选参数:Channel_n_Input_Range,n=0-7range(输入范围),可选参数:VREF_B_25、VREF_B_125、VREF_B_0625、VREF_U_0_25、VREF_U_0_125
返 回 值:无
==================================== ============================*/
void Set_CH_Range_Select(u8 ch, u8 range)
{ ADS8688_WriteProgramRegister(ch, range);
}/*===============================================================
函数名称:Set_Channel_Power_Down函数功能:设置通道输入范围输入参数:pwd:0x00(通道全部上电),0xFF(通道全部掉电)
返 回 值:无
==================================== ============================*/ void Set_Channel_Power_Down(u8 pwd)
{ ADS8688_WriteProgramRegister(Channel_Power_Down, pwd);
}/*===============================================================
函数名称:ADS8688_Init函数功能:ADS8688初始化输入参数:无返 回 值:无
================================================================*/
void ADS8688_Init(void)
{SPI_GPIO_Init(); //模拟SPI端口初始化Set_CH_Range_Select(Channel_0_Input_Range, VREF_B_25); //设置通道0输入范围为:±2.5×VREFSet_CH_Range_Select(Channel_1_Input_Range, VREF_B_25); //设置通道1输入范围为:±2.5×VREFSet_CH_Range_Select(Channel_2_Input_Range, VREF_B_25); //设置通道2输入范围为:±2.5×VREF Set_CH_Range_Select(Channel_3_Input_Range, VREF_B_25); //设置通道3输入范围为:±2.5×VREFSet_CH_Range_Select(Channel_4_Input_Range, VREF_B_25); //设置通道4输入范围为:±2.5×VREFSet_CH_Range_Select(Channel_5_Input_Range, VREF_B_25); //设置通道5输入范围为:±2.5×VREFSet_CH_Range_Select(Channel_6_Input_Range, VREF_B_25); //设置通道6输入范围为:±2.5×VREFSet_Channel_Power_Down(0x80); //通道0-6上电Set_Auto_Scan_Sequence(0x7F); //自动扫描通道0-6Enter_AUTO_RST_Mode(); //进入自动扫描通道模式(具有复位功能)
}/*===============================================================
函数名称:Get_AUTO_RST_Mode_Data函数功能:读取AUTO_RST模式下的输出数据输入参数:chn:总通道号
返 回 值:无
================================================================*/
void Get_AUTO_RST_Mode_Data(u8 chn)
{ u16 i = 0;for(i=0; i<chn; i++){ADS8688_CS = 0;SPI_ReadWriteByte(0x00, Rxh, Rxh+1, Rxh+2); //先写后读SPI_ReadWriteByte(0x00, Rxl, Rxl+1, Rxl+2);SPI_ReadWriteByte(0xFF, Rxh, Rxh+1, Rxh+2);SPI_ReadWriteByte(0xFF, Rxl, Rxl+1, Rxl+2);SPI_ReadWriteByte(0xFF, Rxh, Rxh+1, Rxh+2);SPI_ReadWriteByte(0xFF, Rxl, Rxl+1, Rxl+2);SPI_ReadWriteByte(0xFF, Rxh, Rxh+1, Rxh+2);SPI_ReadWriteByte(0xFF, Rxl, Rxl+1, Rxl+2);ADS8688_CS = 1;ADC1_Data[i] = (Rxh[0] << 8) | Rxl[0];ADC2_Data[i] = (Rxh[1] << 8) | Rxl[1];ADC3_Data[i] = (Rxh[2] << 8) | Rxl[0];}
}
/*===============================================================
函数名称:Data_Transfer函数功能:排序输入通道输入参数:无返 回 值:无
================================================================*/
void Data_Transfer(void)
{ Transfer_Data[0] = ADC1_Data[5]; //通道1 ADC转换数据Transfer_Data[1] = ADC1_Data[4]; //通道2 ADC转换数据Transfer_Data[2] = ADC1_Data[3]; //通道3 ADC转换数据Transfer_Data[3] = ADC1_Data[2]; //通道4 ADC转换数据Transfer_Data[4] = ADC1_Data[1]; //通道5 ADC转换数据Transfer_Data[5] = ADC1_Data[0]; //通道6 ADC转换数据Transfer_Data[6] = ADC1_Data[6]; //通道7 ADC转换数据Transfer_Data[7] = ADC2_Data[5]; //通道8 ADC转换数据Transfer_Data[8] = ADC2_Data[4]; //通道9 ADC转换数据Transfer_Data[9] = ADC2_Data[3]; //通道10 ADC转换数据Transfer_Data[10] = ADC2_Data[2]; //通道11 ADC转换数据Transfer_Data[11] = ADC2_Data[1]; //通道12 ADC转换数据Transfer_Data[12] = ADC2_Data[0]; //通道13 ADC转换数据Transfer_Data[13] = ADC2_Data[6]; //通道14 ADC转换数据Transfer_Data[14] = ADC3_Data[5]; //通道15 ADC转换数据Transfer_Data[15] = ADC3_Data[4]; //通道16 ADC转换数据Transfer_Data[16] = ADC3_Data[3]; //通道17 ADC转换数据Transfer_Data[17] = ADC3_Data[2]; //通道18 ADC转换数据Transfer_Data[18] = ADC3_Data[1]; //通道19 ADC转换数据Transfer_Data[19] = ADC3_Data[0]; //通道20 ADC转换数据Transfer_Data[20] = ADC3_Data[6]; //通道21 ADC转换数据
}
软件SPI ADS8684/ADS8688驱动程序相关推荐
- 【51单片机快速入门指南】5:软件SPI
目录 硬知识 SPI协议简介 SPI接口介绍 SPI接口连接图 SPI数据传输方向 SPI传输模式 软件SPI程序源码 Soft_SPI.c Soft_SPI.h 普中51-单核-A2 STC89C5 ...
- STM-32:SPI通信协议/W25Q64简介—软件SPI读写W25Q64
目录 一.SPI简介 1.1电路模式 1.2通信原理 1.3SPI时序基本单元 1.3.1起始和终止 1.3.2交换字节 二.W25Q64 2.1W25Q64简介 2.2W25Q64硬件电路 2.3W ...
- GD32F303调试小记(二)之SPI(软件SPI、硬件SPI、硬件SPI+DMA)
前言 目前有一个项目中用到了TFT-LCD,其驱动芯片为ILI9341.为更好的达到显示效果,在最终的代码中我们会使用单片机自带的硬件SPI+DMA模块(由于调试过程中SPI+DMA输出的波形没能驱屏 ...
- STM32L475 硬件SPI+软件SPI驱动ST7789V2
前言 最近购买了IoT Board 潘多拉开发板来研究,学习使用STM32CubeMX工具配置SPI,然后驱动了TFTLCD.潘多拉开发板的TFTLCD驱动IC是ST7789V2,结合原子哥的TFTL ...
- 联盛德 HLK-W806 (十一): 软件SPI和硬件SPI驱动ST7567液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- 联盛德 HLK-W806 (九): 软件SPI和硬件SPI驱动ST7789V液晶LCD
目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...
- [学习笔记]STM32F1软件SPI读写W25Qx(寄存器、标准库、HAL库)
目录 9. 软件SPI读写W25Qx 0. 博主调侃: 1. 实验内容及步骤: 2. 硬件说明 3. 步骤详细讲解 3.1 配置GPIO 3.2 软件SPI读写Byte(模式0或模式3) 3.3 读取 ...
- 关于 printk() 对 spi slave 内核驱动程序的性能影响
调试 imx6 的 spi slave 内核驱动,前期调试总免不了得要追一下寄存器的设置,过程函数的调用. 采用了 printk() 打印语句. 1.采用的硬件方法是: 分析 imx6 spi sla ...
- 【硬件通讯协议】SIP总线协议以及模拟(软件)SPI
参考资料 NXP 官方网站提供的 SPI 总线规范 S12SPIV4.pdfhttps://www.nxp.com/files-static/microcontrollers/doc/ref_manu ...
最新文章
- UIButton防止按钮和手势的暴力点击
- iOS 使用Instruments优化内存性能
- python画菱形的代码_Python打印“菱形”星号代码方法
- jsp mysql 音乐网站_Maven+JSP+SSM+Mysql实现的音乐网站
- Tomcat、JDK 历史版本下载地址
- 属于python应用领域的有数据可视化_Python数据可视化
- 请求zabbix_快速部署zabbix
- Java基于Redis的分布式锁
- 力扣-389 找不同
- 颜色空间——Gamma与线性颜色空间
- Extjs中EditorGridPanel修改并获取数据的两种方式
- 《第一行代码(第三版)》kotlin开发Android,学习笔记(进行中ing)
- C++标准模板库(STL)(3) 之 vector map容器快速学习 (自学笔记)
- AUTOSAR CDD 模块解析 --- 设计建议
- python画结构图_【实战案例】五分钟!用python绘制系统架构图
- 操作系统(存储管理)
- python win32com Dispatch, DispatchEx 无法打开(启动)excel pywintypes.com_error: (-2146959355, ‘服务器运行失败‘
- HTTP 请求之PostMan 中文乱码分析
- 为什么现在的视频都会加入自动字幕功能?
- Introduction to SPM statistics
热门文章
- 限号判断c语言程序设计,北京理工大学2013级C程序设计非信息类答案part2概要.doc...
- 怎样做需求调研:需求研讨
- 计算机无法复制大文件格式,U盘单个文件过大无法复制怎么办?如何将U盘FAT32转NTFS格式?...
- CentOS Out of Memery问题分析
- PHP论坛实现积分系统的思路
- [02-24] [刺杀肯尼迪][1080p BRRip /MKV/1.7G][2013年美国传记/历史片]
- (good)相位噪声基础及测试原理和方法
- 生于忧患而死于安乐也
- 养生之道--21天改变体质
- 0基础强化学习实践之超级玛丽