STM32GPIO模拟SPI操作AD7192
STM32 GPIO模拟SPI操作AD7192
第⼀部分:STM32 GPIO模拟SPI
本篇内容参考了⽹上很多⽂章和官⽅源码,经过⾃⼰学习和修改,拿出来给⼤家参考参考,希望有所帮助。
下⾯直接贴源码,上⼲货,有什么意见和建议直接留⾔。
头⽂件AD7192Driver.h
/* ----------------------- Defines ------------------------------------------*/
#define AD7192_CS_Pin GPIO_PIN_15 //⽚选引脚,低电平有效
#define AD7192_CS_GPIO_Port GPIOA
#define AD7192_SCLK_Pin GPIO_PIN_10 //串⾏时钟
#define AD7192_SCLK_GPIO_Port GPIOC
#define AD7192_DOUT_Pin GPIO_PIN_11 //AD7192输出引脚
#define AD7192_DOUT_GPIO_Port GPIOC
#define AD7192_DIN_Pin GPIO_PIN_12 //AD7192输⼊引脚
#define AD7192_DIN_GPIO_Port GPIOC
/* AD7192_CS 低电平有效*/
#define AD7192_CS_ENABLE() HAL_GPIO_WritePin(AD7192_CS_GPIO_Port, AD7192_CS_Pin, GPIO_PIN_RESET)
#define AD7192_CS_DISABLE() HAL_GPIO_WritePin(AD7192_CS_GPIO_Port, AD7192_CS_Pin, GPIO_PIN_SET)
/* AD7192_SCL ⾼电平空闲*/
#define AD7192_SCLK_H HAL_GPIO_WritePin(AD7192_SCLK_GPIO_Port, AD7192_SCLK_Pin, GPIO_PIN_SET)
#define AD7192_SCLK_L HAL_GPIO_WritePin(AD7192_SCLK_GPIO_Port, AD7192_SCLK_Pin, GPIO_PIN_RESET)
/* AD7192_RDY_STATE ⾼电平空闲*/
#define AD7192_RDY_STATE HAL_GPIO_ReadPin(AD7192_DOUT_GPIO_Port,AD7192_DOUT_Pin)堪萨斯州立大学
/* AD7192驱动函数声明*/
void STM32_AD7192_Config(void);//GPIO初始化
void STM32SpiOperation(unsigned char* WriteBuffer,unsigned char*ReadBuffer,unsigned char NumberOfByte);//GPIO模拟SPI操作AD unsigned short Get_ADTemprate(void);//AD芯⽚温度采集
void AD7192_Unipolar_Multichannel_Config(void);//多路单端输⼊AD采集配置
源⽂件AD7192Driver.c
promoted/* ----------------------- System incldues ----------------------------------*/
#include"stm32f1xx_hal.h"fek
/* ----------------------- AD7192 incldues-----------------------------------*/
#include"AD7192.h"
#include"AD7192Driver.h"
/* ----------------------- Defines ------------------------------------------*/
/* ----------------------- Variables ----------------------------------------*/
/*STM32与AD7192通讯管脚配置函数*/
void STM32_AD7192_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct ={0};/*定义⼀个GPIO_InitTypeDef类型的结构体*/
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
//定义输⼊管脚
GPIO_InitStruct.Pin = AD7192_DOUT_Pin;/*选择要控制的GPIO引脚,即PC11,对7192来说是数据输出端,对STM32就应是输⼊*/
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;/*设置引脚模式为输⼊模式*/
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;/*设置引脚模式为输⼊模式*/
GPIO_InitStruct.Pull = GPIO_NOPULL;/*设置引脚模式为浮空输⼊*/
HAL_GPIO_Init(AD7192_DOUT_GPIO_Port,&GPIO_InitStruct);/*调⽤库函数,初始化GPIO*/
//定义输出管脚
GPIO_InitStruct.Pin = AD7192_DIN_Pin;/*选择要控制的GPIO引脚,即PC12,对7192来说是数据输⼊端,对STM32就应是输出。*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;/*设置引脚模式为通⽤推挽输出*/
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;/*设置引脚速率为50MHz */
HAL_GPIO_Init(AD7192_DIN_GPIO_Port,&GPIO_InitStruct);/*调⽤库函数,初始化GPIO*/
despicable伯明翰大学官网//定义⽚选管脚
GPIO_InitStruct.Pin = AD7192_CS_Pin;/*选择要控制的GPIO引脚,即PA15*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;/*设置引脚模式为通⽤开漏输出*/
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;;/*设置引脚速率为50MHz */
HAL_GPIO_Init(AD7192_CS_GPIO_Port,&GPIO_InitStruct);/*调⽤库函数,初始化GPIO*/
AD7192_CS_DISABLE();//将⽚选信号拉⾼
//定义时钟管脚
GPIO_InitStruct.Pin = AD7192_SCLK_Pin;/*选择要控制的GPIO引脚,即PC10*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;/*设置引脚模式为通⽤推挽输出*/
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;/*设置引脚速率为50MHz */
HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);/*调⽤库函数,初始化GPIO*/
AD7192_SCLK_H;//将时钟信号拉⾼
}
/*STM32实现GPIO⼝模拟SPI与AD7192通讯函数*/
void STM32SpiOperation(unsigned char*WriteBuffer,unsigned char*ReadBuffer,unsigned char NumberOfByte)
{
unsigned char WriteData, ReadData;//分别定义⼀个要写出数据的中间变量和⼀个要读⼊数据的中间变量
unsigned char i, j;
AD7192_SCLK_H;//时钟拉⾼
/*-------------------------------------外循环执⾏判断是否达到要发送的字节数------------------------------------*/
for(i =0; i < NumberOfByte; i++)
{
WriteData =*(WriteBuffer + i);//写缓冲器⾥⾯的数据赋给中间变量WriteData
ReadData =0;
/*---------------------------------内循环执⾏完毕发送和接收8位数据----------------------------------------*/
for(j =0; j <8; j++)
{
AD7192_SCLK_H;//时钟拉⾼,写⼊数据
if(0x80==(WriteData &0x80))
{
HAL_GPIO_WritePin(AD7192_DIN_GPIO_Port, AD7192_DIN_Pin, GPIO_PIN_SET);//Send one to SDI pin 发送1⾄DIN引脚
}
el
{
HAL_GPIO_WritePin(AD7192_DIN_GPIO_Port, AD7192_DIN_Pin, GPIO_PIN_RESET);//Send zero to SDI pin 发送0⾄DIN引脚
}
WriteData = WriteData <<1;
英文整句翻译AD7192_SCLK_L;//时钟拉低,读取数据
ReadData =(ReadData <<1)|HAL_GPIO_ReadPin(AD7192_DOUT_GPIO_Port, AD7192_DOUT_Pin)
;//将IO⼝接收到的⾼或低电平保存⾄ReadDa ta。
}
/*---------------------------------------内循环结束-----------------------------------------------------*/
*(ReadBuffer + i)= ReadData;
}//读写操作完成,将WriteBuffer⾥的值通过中间变量WriteData发送出去。
/*-----------------------------------------------------------外循环结束-------------------------------------------------------------*/
AD7192_SCLK_H;//时钟拉⾼
}//GPIO⼝模拟SPI程序到此为⽌
/*========================================================================================================================= ====================================================*/
unsigned short Get_ADTemprate(void)//获取AD7192芯⽚温度
{
{
unsigned short result;
unsigned long int AD7192Data;
float AD7192Temperature=0.0;
AD7192InternalZeroScaleCalibration(TEMP);//校准时只能使能⼀个通道
AD7192InternalFullScaleCalibration(TEMP);//校准时只能使能⼀个通道
AD7192Data =AD7192ReadTemperature();
AD7192Temperature =RealTemperature(AD7192Data);
result=AD7192Temperature*=100;//扩⼤100倍.
return result;
fbl是什么意思}
void AD7192_Unipolar_Multichannel_Config(void)//多路单独输⼊配置
{
/* 斩波使能,消除失调及失调漂移*/
/* 内部增益gain=1,即正负5V*/
/*校准时只能使能⼀个通道*/
/* Calibrates channel AIN1(+) - AINCOM(-)*/
AD7192InternalZeroScaleCalibration(AIN1_COM);
AD7192InternalFullScaleCalibration(AIN1_COM);
/* Calibrates channel AIN2(+) - AINCOM(-)*/
AD7192InternalZeroScaleCalibration(AIN2_COM);
AD7192InternalFullScaleCalibration(AIN2_COM);
/* Calibrates channel AIN3(+) - AINCOM(-)*/
AD7192InternalZeroScaleCalibration(AIN3_COM);
党员发言稿
AD7192InternalFullScaleCalibration(AIN3_COM);
/* Calibrates channel AIN4(+) - AINCOM(-)*/
AD7192InternalZeroScaleCalibration(AIN4_COM);
AD7192InternalFullScaleCalibration(AIN4_COM);
/* 使能4个通道,启动连续转换模式*/
AD7192StartContinuousConvertion(AIN1_COM | AIN2_COM | AIN3_COM | AIN4_COM);
/* 启动连续读函数*/
AD7192StartContinuousRead();
}
第⼆部分 AD7192源码
第⼆部分就很简单了,官⽅源码,相信⼤家也都会下载的。
下⾯只贴出我⾃⼰修改的⼀部分。
1、头⽂件中校准函数增加通道形参。
void AD7192InternalZeroScaleCalibration(unsigned long int Channels);//增加形参unsigned char Channel void AD7192InternalFullScaleCalibration(unsigned long int Channels);//增加形参unsigned char Channel 2、源⽂件中修改部分如下:
/*-------------------------AD7192初始化函数------------------------------------*/
void AD7192Initialization()
{
STM32_AD7192_Config();//GPIO引脚初始化
AD7192SoftwareRet();//软复位
}
/*--------------------------------------------------------------------AD7192内部零电平校准-------------------------------------------------------------------------------------------------------------------*/
void AD7192InternalZeroScaleCalibration(unsigned long int Channels)
{
AD7192Registers[REG_MODE]=0;//实际上就是AD7192Registers[0x01],即AD7192Registers[1]
AD7192Registers[REG_CONF]=0;//实际上就是AD7192Registers[0x02],即AD7192Registers[2]
//斩波禁⽤|IN1参考电压|使能通道|禁⽤激励电流|禁⽤基准电压检测|禁⽤缓冲器|双极性|增益±5 V
AD7192Registers[REG_CONF]= CHOP_DIS|REF_IN1|Channels|BURN_DIS|REFDET_DIS|BUF_DIS|UB_UNI|GAIN_1;// Gain = 1
//AD7192Registers[REG_CONF] =0x00001000
WriteToAD7192ViaSPI(REG_CONF,1, AD7192Registers, REG_CONF);//写⼊配置寄存器
AD7192Registers[REG_MODE]= MODE_INZCL|DAT_STA_EN|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_DIS|SINGLECYCLE_DIS|REJ60_DIS|0x 080;
//AD7192Registers[REG_MODE] =0x009C2080
WriteToAD7192ViaSPI(REG_MODE,1, AD7192Registers, REG_MODE);//写⼊模式寄存器
AD7192_CS_ENABLE();//⽚选信号使能,选通AD7192。
while(HAL_GPIO_ReadPin(AD7192_DOUT_GPIO_Port, AD7192_DOUT_Pin)==1){;}// wait until RDY = 0;⽬的是为了等待AD7192内部零电平校准完成。AD7192_CS_DISABLE();//⽚选信号拉⾼,禁⽤AD7192。
}
/*--------------------------------------------------------------------AD7192内部满量程校准-------------------------------------------------------------------------------------------------------------------*/
void AD7192InternalFullScaleCalibration(unsigned long int Channels)
{
AD7192Registers[REG_MODE]=0;
AD7192Registers[REG_CONF]=0;
好看的英剧AD7192Registers[REG_CONF]= CHOP_DIS|REF_IN1|Channels|BURN_DIS|REFDET_DIS|BUF_DIS|UB_UNI|GAIN_1;// Gain = 1;和内部零电平校准⼀样//AD7192Registers[REG_CONF] =0x00000100
WriteToAD7192ViaSPI(REG_CONF,1, AD7192Registers, REG_CONF);//写⼊配置寄存器
AD7192Registers[REG_MODE]=0;
AD7192Registers[REG_MODE]= MODE_INFCL|DAT_STA_EN|INCLK_MCLK2EN|SINC_4|ENPAR_EN|CLK_DIV_2|SINGLECYCLE_DIS|REJ60_DIS|0x08 0;
//AD7192Registers[REG_MODE] =0x00BC3080
WriteToAD7192ViaSPI(REG_MODE,1, AD7192Registers, REG_MODE);//写⼊模式寄存器
AD7192_CS_ENABLE();//⽚选信号使能,选通AD7192。
while(HAL_GPIO_ReadPin(AD7192_DOUT_GPIO_Port, AD7192_DOUT_Pin)==1){;}// wait until RDY = 0;⽬的是为了等待AD7192内部全量程校准完成。AD7192_CS_DISABLE();//⽚选信号拉⾼,禁⽤AD7192。
uma}