软件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 

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值