完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
第一部分 :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 /* ----------------------- System incldues ----------------------------------*/ #include “stm32f1xx_hal.h” /* ----------------------- 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.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*/ //定义片选管脚 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引脚 } else { 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口接收到的高或低电平保存至ReadData。 } /*---------------------------------------内循环结束-----------------------------------------------------*/ *(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; } 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引脚初始化 AD7192SoftwareReset();//软复位 } /*--------------------------------------------------------------------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|0x080; //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|0x080; //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。 } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
2000 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1782 浏览 1 评论
1248 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
825 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1800 浏览 2 评论
2031浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
942浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
338浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
682浏览 3评论
668浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-3-6 21:21 , Processed in 0.659513 second(s), Total 44, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191