软件SPI驱动PGA113程控增益放大器

    这段时间项目中正好要做一个双通道电压放大电路,因为去年底才开始学习单片机的缘故对协议还不是很熟练,这里正好用到了PGA113这款可控增益放大芯片。使用stm32G030K6T6编写程序(主频率64MHz),因为对控制速度没有要求,所以不使用硬件SPI。

电路如上图所示,仪表放大器INA826放大100倍  隔直 再偏置1.65v后输入PGA113的CH1通道,同时给PGA113的VREF端提供1.65v(使用一个运放作为跟随器,反馈电阻10k偏大会产生震荡,实际减少至100Ω)以满足参考电位需求。

下面是软件SPI代码,基于模式0的写操作,另外这里用不到读操作,读操作是AI生成,我没有验证不确定有没有问题。

 

#ifndef INC_PGA113_H_
#define INC_PGA113_H_

#include "main.h"

/****************寄存器操作********************/
// 定义引脚
#define CS1_PIN GPIO_PIN_8
#define CS2_PIN GPIO_PIN_2
#define DIO_PIN GPIO_PIN_1
#define SCLK_PIN GPIO_PIN_0
//
 定义端口
#define CS1_GPIO_PORT GPIOA
#define CS2_GPIO_PORT GPIOB
#define DIO_GPIO_PORT GPIOB
#define SCLK_GPIO_PORT GPIOB
//
 GPIO操作宏
#define PGA_CS1_HIGH (CS1_GPIO_PORT->BSRR = CS1_PIN)
#define PGA_CS1_LOW  (CS1_GPIO_PORT->BSRR = (uint32_t)CS1_PIN << 16U)
#define PGA_CS2_HIGH (CS2_GPIO_PORT->BSRR = CS2_PIN)
#define PGA_CS2_LOW  (CS2_GPIO_PORT->BSRR = (uint32_t)CS2_PIN << 16U)
#define PGA_DIO_HIGH (DIO_GPIO_PORT->BSRR = DIO_PIN)
#define PGA_DIO_LOW  (DIO_GPIO_PORT->BSRR = (uint32_t)DIO_PIN << 16U)
#define PGA_CLK_HIGH (SCLK_GPIO_PORT->BSRR = SCLK_PIN)
#define PGA_CLK_LOW  (SCLK_GPIO_PORT->BSRR = (uint32_t)SCLK_PIN << 16U)

/****************HAL_IO操作********************/
//#define PGA_CS1_HIGH HAL_GPIO_WritePin(GPIOA, CS1_Pin, GPIO_PIN_SET)
//#define PGA_CS1_LOW  HAL_GPIO_WritePin(GPIOA, CS1_Pin, GPIO_PIN_RESET)
//#define PGA_CS2_HIGH HAL_GPIO_WritePin(GPIOB, CS2_Pin, GPIO_PIN_SET)
//#define PGA_CS2_LOW  HAL_GPIO_WritePin(GPIOB, CS2_Pin, GPIO_PIN_RESET)
//#define PGA_DIO_HIGH HAL_GPIO_WritePin(GPIOB, DIO_Pin, GPIO_PIN_SET)
//#define PGA_DIO_LOW  HAL_GPIO_WritePin(GPIOB, DIO_Pin, GPIO_PIN_RESET)
//#define PGA_CLK_HIGH HAL_GPIO_WritePin(GPIOB, SCLK_Pin, GPIO_PIN_SET)
//#define PGA_CLK_LOW  HAL_GPIO_WritePin(GPIOB, SCLK_Pin, GPIO_PIN_RESET)


void Delay_us(uint8_t cycles);
void SetGain(uint8_t ch,uint8_t gain);

#endif /* INC_PGA113_H_ */


这里由于我一个板子有2个PGA113,所以在 函数上做了一个选择,chip对应拉低某个cs引脚

#include "PGA113.h"

uint16_t gainBuffer[8]={ 0x2a01,0x2a11,0x2a21,0x2a31,0x2a41,0x2a51,0x2a61,0x2a71 };//定义增益数组

void SPI_Transmit16(uint8_t chip, uint16_t data) {/* 发送一个16位的数据 */

	PGA_CS1_HIGH;
	PGA_CS2_HIGH;
	PGA_CLK_LOW;

	if (chip == 1) {
		PGA_CS1_LOW;
		PGA_CS2_HIGH;
	}else {
		PGA_CS1_HIGH;
		PGA_CS2_LOW;
	}

    for (uint16_t i = 0; i < 16; i++) {//发送16位数据

		if (data & 0x8000) {//检查最高位
			PGA_CLK_LOW;
			PGA_DIO_HIGH;
		}else{
			PGA_CLK_LOW;
			PGA_DIO_LOW;
		}
			data <<= 1;  //数据左移一位
			Delay_us(5);
			PGA_CLK_HIGH;//上升沿捕获数据
			Delay_us(5);
    }

			PGA_DIO_LOW; //通信结束,释放所有引脚
			PGA_CLK_LOW;
			Delay_us(10);
			PGA_CS1_HIGH;
			PGA_CS2_HIGH;

}

uint16_t SPI_Receive16(void) {/*接收一个16位的数据*/

    uint16_t received_data = 0;

    for (uint16_t i = 0; i < 16; i++) {
        received_data <<= 1;//为下一位腾出空间


        PGA_CLK_LOW;//确保数据线稳定时拉低时钟
        Delay_us(64);//确保时钟低电平持续足够时间,准备接收数据
        PGA_CLK_HIGH;//时钟上升沿,数据被设备输出至DIO
        Delay_us(64);//确保时钟高电平持续足够时间,数据稳定

        if (HAL_GPIO_ReadPin(GPIOB, DIO_Pin) == GPIO_PIN_SET) {//读取DIO引脚的状态
            received_data |= 0x01;  //如果DIO为高,将当前最低位设为1
        }
    }

    return received_data;

}

void SetGain(uint8_t ch,uint8_t gain){

    uint8_t gtemp=0;

        switch(gain)
        {
            case 1:
                gtemp=0;
                break;
            case 2:
                gtemp=1;
                break;
            case 5:
                gtemp=2;
                break;
            case 10:
                gtemp=3;
                break;
            case 20:
                gtemp=4;
                break;
            case 50:
                gtemp=5;
                break;
            case 100:
                gtemp=6;
                break;
            case 200:
                gtemp=7;
                break;
            default:

                return;
        }

        SPI_Transmit16(ch,gainBuffer[gtemp]);

}

void Delay_us(uint8_t cycles) {/*短延时*/
    while (cycles--) {
        __asm volatile("NOP");
    }
}

 

 SetGain(1,10);//芯片1放大10倍

这里记录一下调试过程中出现的马虎问题,因为要配置CH1通道,下意识写了一个0x2ax2,实际上应该是0x2ax1,因为描述通道选择的表格还在下面没有看到,这导致直接浪费了3天时间,外加2片芯片(以为坏了,重新买了2片)

如上图所示选择CH1应该是01,而非02,如果写02则无输出。

最后记录一下逻辑分析仪结果 D3为cs,D1为clk,D0为DIO 

STM32单片机(STM32F429)读写(8通道带PGA的24位ADC)ADS1256软件例程源码,可以做为你的学习设计参考。 int main(void) { uint8_t i; bsp_Init(); PrintfLogo(); /* 打印例程Logo到串口1 */ bsp_DelayMS(100); /* 等待上电稳定,等基准电压电路稳定, bsp_InitADS1256() 内部会进行自校准 */ bsp_InitADS1256(); /* 初始化配置ADS1256. PGA=1, DRATE=30KSPS, BUFEN=1, 输入正负5V */ /* 打印芯片ID (通过读ID可以判断硬件接口是否正常) , 正常时状态寄存器的高4bit = 3 */ #if 0 { uint8_t id; id = ADS1256_ReadChipID(); if (id != 3) { printf("Error, ASD1256 Chip ID = 0x%X\r\n", id); } else { printf("Ok, ASD1256 Chip ID = 0x%X\r\n", id); } } #endif ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_30SPS); /* 配置ADC参数: 增益1:1, 数据输出速率 1KHz */ ADS1256_StartScan(); /* 启动中断扫描模式, 轮流采集8个通道的ADC数据. 通过 ADS1256_GetAdc() 函数来读取这些数据 */ while (1) { bsp_Idle(); /* 空闲时执行的函数,比如喂狗. 在bsp.c中 */ /* 打印采集数据 */ for (i = 0; i < 8; i++) { int32_t iTemp; iTemp = ((int64_t)g_tADS1256.AdcNow[i] * 2500000) / 4194303; /* 计算实际电压值(近似估算的),如需准确,请进行校准 */ if (iTemp < 0) { iTemp = -iTemp; printf("%d=%6d,(-%d.%03d %03d V) ", i, g_tADS1256.AdcNow[i], iTemp /1000000, (iTemp%1000000)/1000, iTemp%1000); } else { printf("%d=%6d,( %d.%03d %03d V) ", i, g_tADS1256.AdcNow[i], iTemp/1000000, (iTemp%1000000)/1000, iTemp%1000); } } printf("\r\n"); bsp_DelayMS(500); /* 每隔500ms 输出一次数据 */ } }
<think>好的,我现在需要回答用户关于程控放大器及其IT应用的问题。首先,我需要了解程控放大器的基本概念和工作原理。程控放大器,全称是程控增益放大器PGA),是一种可以通过数字信号或软件控制来调整增益放大器。它的核心在于能够根据不同的输入信号动态调整放大倍数,这对于处理变化范围较大的信号非常有用。 接下来,我要考虑程控放大器的组成部分。通常,它由运算放大器、模拟开关和电阻网络构成。用户可能想知道这些部分如何协同工作,比如模拟开关如何切换不同的反馈电阻来改变增益。此外,数字接口如SPI、I2C或并行接口的作用也很重要,因为这些接口允许微控制器或处理器发送控制信号来调整增益。 然后,关于IT应用,我需要列举几个主要的应用领域。自动测试系统(ATE)是一个明显的例子,程控放大器在这里用于适应不同传感器的输出范围。医疗电子设备也是一个关键领域,比如心电图机需要放大微弱的生物电信号,程控放大器可以根据信号强弱自动调整增益。通信系统中,信号强度可能变化很大,程控放大器能动态调整增益以保持信号质量。此外,物联网(IoT)和工业自动化中的传感器网络也需要程控放大器来处理各种传感器信号,确保数据采集的准确性。 用户提供的引用中提到了AIoT和5G的重要性,所以我要将程控放大器与这些技术联系起来。例如,在AIoT中,程控放大器可以预处理传感器数据,提高后续AI分析的准确性。5G的高带宽和低时延特性使得程控放大器在实时数据处理中更加高效,比如智能工厂中的实时监控系统。 在结构上,我需要按照用户的要求,分点回答,使用中文,并正确应用LaTeX格式。同时,生成的相关问题需要覆盖程控放大器的工作原理、优势、应用案例以及与新兴技术的结合等方面,确保问题有针对性且能帮助用户进一步学习。 最后,检查是否有遗漏的信息,比如是否需要提到具体的芯片型号或更详细的应用案例。根据用户的问题,可能不需要过于深入的技术细节,而是更关注基本原理和应用场景。确保引用正确,将提供的引用自然地融入回答中,特别是在讨论AIoT和5G时引用邬贺铨的观点。</think>### 程控放大器及其IT应用 #### 1. 程控放大器基础 程控放大器(Programmable Gain Amplifier, PGA)是一种可通过数字信号控制增益放大器,其核心公式为: $$ G = 1 + \frac{R_f}{R_{in}} $$ 通过改变反馈电阻$R_f$或输入电阻$R_{in}$的阻值(通常使用模拟开关切换电阻网络),实现增益的动态调整。 #### 2. 关键组成部分 - **运算放大器**:核心放大单元 - **模拟开关与电阻网络**:通过数字信号切换不同阻值组合 - **数字接口**:如SPI、I2C或并行接口,接收外部控制信号[^1] #### 3. IT应用场景 1. **自动测试系统(ATE)** 在半导体测试、传感器校准中,自动适应不同量程的输入信号,例如处理$0.1\text{mV}$至$10\text{V}$范围的传感器输出。 2. **医疗电子设备** 用于心电图(ECG)、脑电图(EEG)等生物电信号采集,动态调整增益以匹配$0.5\text{mV}-5\text{mV}$的微弱信号。 3. **通信系统** 在5G基站中处理动态范围达$60\text{dB}$的射频信号,通过实时增益控制优化信号质量[^1]。 4. **物联网(IoT)与工业4.0** 在智能传感器节点中,配合MCU实现自适应信号调理,例如: ```python # 伪代码示例:根据ADC读数自动调整增益 adc_value = read_adc() if adc_value < 100: set_gain(1000) else: set_gain(100) ``` 5. **AIoT边缘计算** 结合AI算法实现智能增益控制,例如在噪声环境中自动选择最优增益参数,提升后续AI处理的准确性[^1]。 #### 4. 技术优势 - **动态范围扩展**:可处理$\mu V$级至$V$级信号 - **系统集成度提升**:减少外部元件数量 - **自适应能力**:支持软件定义硬件的灵活性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值