STM32单片机PID闭环精确控制直流电机位置(角度)

STM32单片机PID闭环精确控制直流电机位置(角度)

硬件

1、STM32F103VET6开发板

2、树莓派高精度AD/DA拓展板(其实就只用了它的ADS1256芯片)
STM32单片机PID闭环精确控制直流电机位置(角度)_第1张图片
ADS1256基本特性:
https://download.csdn.net/download/Rendezvous1/14945861
1、模拟部分供电5V;
2、SPI数字接口电平:3.3V
3、PGA设置范围: 1、2、4、8、16、32、64、
4、参考电压2.5V (推荐缺省的,外置的)
5、输入电压范围:PGA = 1 时, 可输入正负5V
6. 自动校准 (当设置了PGA,BUF使能、数据采样率时,会启动自校准)
7. 输入的缓冲器可设置启用和关闭(一般选启用)

外部晶振频率 = 7.68MHz,
时钟频率 tCLK = 1/7.68M = 0.13uS
输出数据周期 tDATA = 1 / 30K = 0.033mS (按30Ksps计算)
对SPI的时钟速度要求: (ads1256.pdf page 6)
最快 4个tCLK = 0.52uS
最慢 10个tDATA = 0.3mS (按 30Ksps 计算)

SCL高电平和低电平持续时间最小 200ns

RREG, WREG, RDATA 命令之后,需要延迟 4 * tCLK = 0.52uS;
RDATAC, RESET, SYNC 命令之后,需要延迟 24 * tCLK = 3.12uS;

实际测试,在3.3V上电后, 及时不做任何配置,ADS125的DRDY 口线即开始输出脉冲信号(2.6us高,33.4低,频率30KHz)

3、4WD-L298P驱动板
STM32单片机PID闭环精确控制直流电机位置(角度)_第2张图片
技术规格:
驱动工作电压:4.8 ~ 35V
最大输出电流:单路2A
最大耗散功率:25W(T=75℃)
驱动形式:双路H桥驱动
驱动电源接口:一路外部电源端子 / Arduino-VIN
驱动输出接口:两路电机接线端子 / 排针
Arduino控制端口:数字口10,11,12,13
工作温度:-25℃ ~ 130℃
模块尺寸:56x57mm
L289P资料 https://download.csdn.net/download/Rendezvous1/14945571
4、稳压源
5、直流电机+传感器

电路结构

STM32单片机PID闭环精确控制直流电机位置(角度)_第3张图片

软件

1、与读取ADS1256有关的代码已经上传资源

ADS1256初始化函数

void bsp_InitADS1256(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

#ifdef SOFT_SPI

	/* 打开GPIO时钟 */
	RCC_APB2PeriphClockCmd(RCC_SCK | RCC_DIN | RCC_DOUT | RCC_CS | RCC_DRDY, ENABLE);

	/* 配置几个推完输出IO */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;	/* 设为推挽输出口 */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	/* IO口最大速度 */

	GPIO_InitStructure.GPIO_Pin = PIN_SCK;
	GPIO_Init(PORT_SCK, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_DIN;
	GPIO_Init(PORT_DIN, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_CS;
	GPIO_Init(PORT_CS, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_SYNC;
	GPIO_Init(PORT_SYNC, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = PIN_RST;
	GPIO_Init(PORT_RST, &GPIO_InitStructure);
	/* 配置GPIO为浮动输入模式(实际上CPU复位后就是输入状态) */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	GPIO_InitStructure.GPIO_Pin = PIN_DOUT;
	GPIO_Init(PORT_DOUT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = PIN_DRDY;
	GPIO_Init(PORT_DRDY, &GPIO_InitStructure);
	
	RST_0();
	delay_ms(1);
	SYNC_1();
	RST_1();
	delay_ms(100);

	//
	CS_1();
	SCK_0();		/* SPI总线空闲时,钟线是低电平 */
	DI_1();
	
#endif

	//ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_1000SPS);	/* 配置ADC参数: 增益1:1, 数据输出速率 1KHz */
}

配置ADC参数,增益和数据输出速率的函数

void ADS1256_CfgADC(ADS1256_GAIN_E _gain, ADS1256_DRATE_E _drate)
{
	g_tADS1256.Gain = _gain;
	g_tADS1256.DataRate = _drate;

	ADS1256_StopScan();			/* 暂停CPU中断 */

	ADS1256_ResetHard();		/* 硬件复位 */

	ADS1256_WaitDRDY();

	{
		uint8_t buf[4];		/* 暂存ADS1256 寄存器配置参数,之后连续写4个寄存器 */

		/* 状态寄存器定义
			Bits 7-4 ID3, ID2, ID1, ID0  Factory Programmed Identification Bits (Read Only)

			Bit 3 ORDER: Data Output Bit Order
				0 = Most Significant Bit First (default)
				1 = Least Significant Bit First
			Input data  is always shifted in most significant byte and bit first. Output data is always shifted out most significant
			byte first. The ORDER bit only controls the bit order of the output data within the byte.

			Bit 2 ACAL : Auto-Calibration
				0 = Auto-Calibration Disabled (default)
				1 = Auto-Calibration Enabled
			When Auto-Calibration is enabled, self-calibration begins at the completion of the WREG command that changes
			the PGA (bits 0-2 of ADCON register), DR (bits 7-0 in the DRATE register) or BUFEN (bit 1 in the STATUS register)
			values.

			Bit 1 BUFEN: Analog Input Buffer Enable
				0 = Buffer Disabled (default)
				1 = Buffer Enabled

			Bit 0 DRDY :  Data Ready (Read Only)
				This bit duplicates the state of the DRDY pin.

			ACAL=1使能自校准功能。当 PGA,BUFEEN, DRATE改变时会启动自校准
		*/
		buf[0] = (0 << 3) | (1 << 2) | (1 << 1);
		//ADS1256_WriteReg(REG_STATUS, (0 << 3) | (1 << 2) | (1 << 1));

		buf[1] = 0x08;	/* 高四位0表示AINP接 AIN0,  低四位8表示 AINN 固定接 AINCOM */

		/*	ADCON: A/D Control Register (Address 02h)
			Bit 7 Reserved, always 0 (Read Only)
			Bits 6-5 CLK1, CLK0 : D0/CLKOUT Clock Out Rate Setting
				00 = Clock Out OFF
				01 = Clock Out Frequency = fCLKIN (default)
				10 = Clock Out Frequency = fCLKIN/2
				11 = Clock Out Frequency = fCLKIN/4
				When not using CLKOUT, it is recommended that it be turned off. These bits can only be reset using the RESET pin.

			Bits 4-2 SDCS1, SCDS0: Sensor Detect Current Sources
				00 = Sensor Detect OFF (default)
				01 = Sensor Detect Current = 0.5 μ A
				10 = Sensor Detect Current = 2 μ A
				11 = Sensor Detect Current = 10μ A
				The Sensor Detect Current Sources can be activated to verify  the integrity of an external sensor supplying a signal to the
				ADS1255/6. A shorted sensor produces a very small signal while an open-circuit sensor produces a very large signal.

			Bits 2-0 PGA2, PGA1, PGA0: Programmable Gain Amplifier Setting
				000 = 1 (default)
				001 = 2
				010 = 4
				011 = 8
				100 = 16
				101 = 32
				110 = 64
				111 = 64
		*/
		buf[2] = (0 << 5) | (0 << 3) | (_gain << 0);
		//ADS1256_WriteReg(REG_ADCON, (0 << 5) | (0 << 2) | (GAIN_1 << 0));	/* 选择1;1增益, 输入正负5V */

		/* 因为切换通道和读数据耗时 123uS, 因此扫描中断模式工作时,最大速率 = DRATE_1000SPS */
		buf[3] = s_tabDataRate[_drate];	// DRATE_10SPS;	/* 选择数据输出速率 */

		CS_0();	/* SPI片选 = 0 */
		ADS1256_Send8Bit(CMD_WREG | 0);	/* 写寄存器的命令, 并发送寄存器地址 */
		ADS1256_Send8Bit(0x03);			/* 寄存器个数 - 1, 此处3表示写4个寄存器 */

		ADS1256_Send8Bit(buf[0]);	/* 设置状态寄存器 */
		ADS1256_Send8Bit(buf[1]);	/* 设置输入通道参数 */
		ADS1256_Send8Bit(buf[2]);	/* 设置ADCON控制寄存器,增益 */
		ADS1256_Send8Bit(buf[3]);	/* 设置输出数据速率 */

		CS_1();	/* SPI片选 = 1 */
	}

	bsp_DelayUS(50);
}

RESET函数

static void ADS1256_ResetHard(void)
{
	/* ADS1256数据手册第7页 */
	//RESET_0();			/* 复位 */
	//bsp_DelayUS(5);
	//RESET_1();

	//PWDN_0();			/* 进入掉电 同步*/
	//bsp_DelayUS(2);
	//PWDN_1();			/* 退出掉电 */

	bsp_DelayUS(5);

	//ADS1256_WaitDRDY();	/* 等待 DRDY变为0, 此过程实测: 630us */
}

SEND函数

static void ADS1256_Send8Bit(uint8_t _data)
{
	uint8_t i;

	/* 连续发送多个字节时,需要延迟一下 */
	ADS1256_DelaySCLK();
	ADS1256_DelaySCLK();

	/* ADS1256 要求 SCL高电平和低电平持续时间最小 200ns  */
	for(i = 0; i < 8; i++)
	{
		if (_data & 0x80)
		{
			DI_1();
		}
		else
		{
			DI_0();
		}
		SCK_1();
		ADS1256_DelaySCLK();
		_data <<= 1;
		SCK_0();			/* <----  ADS1256 是在SCK下降沿采样DIN数据, 数据必须维持 50nS */
		ADS1256_DelaySCLK();
	}
}

RECEIVE函数

static uint8_t ADS1256_Recive8Bit(void)
{
	uint8_t i;
	uint8_t read = 0;

	ADS1256_DelaySCLK();
	/* ADS1256 要求 SCL高电平和低电平持续时间最小 200ns  */
	for (i = 0; i < 8; i++)
	{
		SCK_1();
		ADS1256_DelaySCLK();
		read = read<<1;
		SCK_0();
		if (DO_IS_HIGH())
		{
			read++;
		}
		ADS1256_DelaySCLK();
	}
	return read;
}

太多了,现将ADS1256相关的资料打包上传资源。自取。https://download.csdn.net/download/Rendezvous1/14945861
2、PID闭环控制可以控制电机正反转,及速度。

资源已上传自取

3、还可以增加通信模块,以发送让电机运动的指令。

你可能感兴趣的:(笔记,单片机,stm32,传感器,嵌入式,pid)