课程设计分析

题目:风力摆控制系统

一、 题目要求

1.基本要求

采用MPU6050和空心杯电机以及任意一款单片机,设计一风力摆控制系统(系统模型图见图1),能够在竖直平面(平面与杆1垂直。下文无特殊说明,所说的竖直平面均与此平面重合)内控制角β的值,即控制摆杆使摆杆的当前位置与初始位置之间的夹角(在竖直平面内)可控。
图1 风力摆控制系统
图1 风力摆控制系统

2.设计要求

(1) 模块必须有总开关,能够控制整个电路是否通电
(2) 主控部分具有复位电路,可采用学院发主控板,也可采用stc15f2k60s2、stm32、k60、plc等主控(要求必须为最小系统板,即除主控必要功能外不得有其他与本设计有关的功能)
(3) 显示部分,要求能够显示自己队伍队长的学号(如采用数码管进行显示,可显示学号后三位),能够显示设定的角度数值和当前角度数值,显示P、I、D的参数数值,其他功能可自行发挥
(4) 系统角度设置要求,基本要求:角度可自定义,最终效果,有一个稳定的摆动角度。设计要求:角度可通过外部输入设备任意给定,并在可容许时间内达到设定角度值。其他要求:其他实现功能可自行发挥
(4)电路板要求自制(可用AD软件自行绘制,如自己绘制需在电路板上注明日期队员姓名队长学号,或者用洞洞板面包板自行搭建),电源模块可用成品
(5)能够清楚知道PID系统中各个参数的意义,并能够实际调试PID参数
(6)如自己绘制电路板、采用高级单片机、或具有创新部分可根据实际情况加分

二.设计难点

(1)机械结构的设计与传感器放置位置选择
(2)角度传感器的数据读取与处理
(3)PID算法的代码实现与参数调试

三.控制方案示意

角度控制可通过角度传感器(MPU6050)反馈角度信息,使用PID算法实现系统的闭环控制。
动力系统可选用空心杯电机提供风力,吹动摆杆在竖直平面内运动,下图为摆杆实现方案示意。
图2 风力摆实现方案示意
图2 风力摆实现方案示意

思路分析

从“测”、“控”的角度分析,首先是“测”,即使用MPU6050进行角度的测量,然后是“控”,采用闭环控制系统,系统的输入量是预设的角度,输出量是控制电机速度的pwm波,控制器采用pid控制器。基本的工作流程为,设定角度,作为系统的目标值也即系统的参比变量、设定值、系统输入,PID控制器的输入为当前值测量值与设定值的差,将此数据给控制器即可输出pwm数值用于执行器——电机的调速作用,由于两侧电机的转速不同则产生的吹力不同,即可使白干产生倾斜,使用测量元件反馈当前角度,从而形成一个单回路闭环控制系统。

设定值
求差
PID控制器
PWM
电机执行器
被控对象角度
检测元件imu

硬件选择

一、主控

1.选择一 STC15W408AS

详细参数请参照此链接
相关资料请参照此链接
STC15W408AS

2.选择二 STM32F103C8T6

相关资料请参照此链接,提取码:a7w5
STM32F103C8T6

二、显示模块

1.选择一 LCD1602(含iic转接板)

相关资料请参照此链接
为了减少单片机I/O口的浪费,所以使用含有转接板的显示屏,该显示屏只需要两个I/O口以及一个VCC一个GND即可驱动,,由于材料历程为Arduino程序,所以在下文会给出stc15单片机程序及注释。
LCD1602

2.选择二 0.96寸OLED显示屏

相关资料请参照此链接,提取码:cvux
0.96寸OLED显示屏

三、GY-521 MPU6050

相关资料请参照此链接,提取码:es9t
该模块采用iic与主控进行通讯,下文会给予程序和相关注释
GY-521 MPU6050

四、2路直流电机驱动板模块

其驱动方式可参照L298N的驱动方式,相关资料请参照此链接,下问亦会给出相关代码与注释
2路直流电机驱动板模块

五、716空心杯

716空心杯

机械结构

一、碳纤维管

选用8×6×1规格的碳纤维管,以配合轴承使用,也可作为摆杆使用
碳纤维管

二、深沟球微型小轴承

采用8×22×7mm规格的轴承,可替代于摆杆顶部的万向节使用
深沟球微型小轴承

程序部分(软件)

程序设计思路(个人看法),首先测试每个模块是否可以正常工作,确定模块没有问题,将所有模块组合为一个系统,进行整体功能的测试,实现基本功能后搭建机械结构,进行参数调节,接下来介绍每个模块的程序及测试过程。此处仅针对部分函数进行解释,工程文件见文章末尾网盘链接。

一、LCD1602(含iic转接板)程序

以下代码均位于PCF8574.c文件中

void delay()  //延时函数,iic延时使用
{ ;; }
void init()//IIC初始化
{
	sda=1;
	delay();
	scl=1;
	delay();
}
void start()  //IIC起始信号
{	
	sda=1;
	delay();
	scl=1;
	delay();
	sda=0;
	delay();
}

以下为信号的时序图:
时序图

void stop()   //IIC终止信号
{
	sda=0;
	delay();
	scl=1;
	delay();
	sda=1;
	delay();
}

以下为信号的时序图:
终止信号
起始和终止信号:
起始和终止信号

void respons()  //等待IIC应答
{
	uchar i;
	scl=1;
	delay();
	while((sda==1)&&(i<250))i++;
	scl=0;
	delay();
}

以下为信号的时序图:
应答信号
字节传送与应答:
字节传送与应答

void write_byte(uchar date)//IIC写数据zaixie
{
	uchar i,temp;
	temp=date;


	for(i=0;i<8;i++)  //一位一位的写入
	{
		temp=temp<<1;  //左移一位,末位补零,高位溢出到CY寄存器
		scl=0;
	  	delay();
		sda=CY;
		delay();
		scl=1;
		delay();
	}
	scl=0;
	delay();
	sda=1;
	delay();
}

uchar read_byte()//IIC读数据
{
	uchar i,k;
	scl=0;
	delay();
	sda=1;
	delay();
	for(i=0;i<8;i++)
	{
		scl=1;
		delay();	
		k=(k<<1)|sda;  //现将k左移一位,然后一位一位的进行赋值
		scl=0;
		delay();	
	}
	return k;
}

I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
信号时序
jike

void write_add(uchar date1)//写入数据到I/O
{
	start();
	write_byte(0x4e);   //写地址,此处A0 A1 A2 均为1
	respons();
	write_byte(date1);  //写入的数据
	respons();
	stop();
}

PCF8574写模式时序图,看前两行即可,下面的没研究!!!
写模式

uchar read_add()//读数据,从I/O口
{
	uchar date1;
	start();
	write_byte(0x4f);   //读地址,此处A0 A1 A2 均为1
	respons();
	date1=read_byte();
	respons();
	stop();
	return date1;
}zaixie

同样前两行,后面看不懂!!!
读模式
下表为从机地址表,当iic总线上挂载多个设备时,每个设备都有自己的一个地址,方便主机进行分辨。有关iic总线的从机地址问题可以参考这个博客。
地址表
***LCD1602.c***文件中的函数都是对芯片寄存器地址的操作,没必要看的很明白,会用最后一个函数“ShowString”即可。

二、PWM波产生程序

以下程序片段均来自C51-6050-UART.C

sbit left_moto_pwm = P3^2;
sbit right_moto_pwm = P3^3;// i/o定义

unsigned char pwm_val_right = 0;      //电机pwm周期
unsigned char push_val_right = 0;     //电机pwm占空比

unsigned char pwm_val_left = 0;      //电机pwm周期
unsigned char push_val_left = 0;     //电机pwm占空比

/*********************定时器初始化************************/
void TimerInit()
{
        TMOD=0X11;                    //设置定时器工作方式
        TH0=(65536-100)/256;          //100US定时
        TL0=(65536-100)%256;
        TR0= 1;                       //打开定时器1
        ET0= 1;                       //打开定时器1中断
        EA = 1;                       //开总中断
}
/*********************左电机pwm输出***********************/
void pwm_out_lift_moto()
{

		if(pwm_val_left <= push_val_left)
			left_moto_pwm = 1;
		else
			left_moto_pwm = 0;
		
		if(pwm_val_left > 100)
			pwm_val_left = 0;
		
}

/*********************右电机pwm输出***********************/
void pwm_out_right_moto()
{

		if(pwm_val_right <= push_val_right)
			right_moto_pwm = 1;
		else
			right_moto_pwm = 0;
		
		if(pwm_val_right > 100)
			pwm_val_right = 0;

}

/***************定时器中断*************/
void time0() interrupt 1   using 3
{
	
	TH0=(65536-10)/256;          //装初值
  	TL0=(65536-10)%256;
	
	pwm_val_left++;               //电机pwm周期
  	pwm_val_right++;              //电机pwm周期
	
	pwm_out_lift_moto();          //左电机pwm输出
	pwm_out_right_moto();         //右电机pwm输出
	
}

程序就类似于下面这个坐标系,横轴是pwm_val_left,忘写了!!!
在一个周期内高电平占比越大,电机转的也就越快,这就是pwm的意思了!!!!
pwm
就先到这吧,剩下的imu的应用及补充pid等开学在写!!!!

声明:部分图片资料链接来自于淘宝店铺,如有侵权请告知修改!!!

发布了5 篇原创文章 · 获赞 2 · 访问量 79

猜你喜欢

转载自blog.csdn.net/qq_41990294/article/details/104851135