电机转速调节课设

第二章 设计方案
2.1方案简介
方案为基于红外传感器和51单片机的直流电机调速系统的设计,使用C++进行编程,系统一共含有6个模块,输入模块,显示模块,测速模块,51单片机,电机驱动模块,电源。系统的结构框图如下图2.1。

第三章 硬件模块介绍
3.1 STC12C5A60S2单片机
STC12C5A60S2/AD/PWM系列单片机是宏晶科技生产的单时钟/机器周期(1T)的单片机,是高速/低功耗/超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换(250K/S),针对电机控制,强干扰场合。为增强型8051 CPU,1T,单时钟/机器周期,指令代码完全兼容传统8051。有EEPROM功能(STC12C5A62S2/AD/PWM无内部EEPROM)。 2个时钟输出口,可由T0的溢出在P3.4/T0输出时钟,可由T1的溢出在P3.5/T1输出时钟。具有PWM(2路)/PCA(可编程计数器阵列,2路),可实现八位PWM输出。

3.2 矩阵键盘
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。

3.3 L298N电机驱动
L298N是ST公司生产的一种高电压、大电流电机驱动芯片。该芯片采用15脚封装。主要特点是:工作电压高,最高工作电压可达46V;输出电流大,瞬间峰值电流可达3A,持续工作电流为2A;额定功率25W。内含两个H桥的高电压大电流全桥式驱动器,可以用来驱动直流电动机和步进电动机、继电器线圈等感性负载;采用标准逻辑电平信号控制;具有两个使能控制端,在不受输入信号影响的情况下允许或禁止器件工作有一个逻辑电源输入端,使内部逻辑电路部分在低电压下工作;可以外接检测电阻,将变化量反馈给控制电路。使用L298N芯片驱动电机,该芯片可以驱动一台两相步进电机或四相步进电机,也可以驱动两台直流电机。

3.4 RS385直流电机
RS385直流电机具有,升温慢,寿命长,效率高,抗干扰,耐损耗的特点。可用于家用电器,通信,教育等领域。是一个标准的小型直流电机。

3.5 红外对射槽型测速传感器模块
红外对射槽型测速传感器模块广泛用于电机转速检测,脉冲计数,位置限位等。
该模块使用进口槽型光耦传感器,槽宽度10mm,有输出状态指示灯,输出高电平灯灭,输出低电平灯亮,使用宽电压LM393 比较器输出,信号干净,波形好,驱动能力强,超过15mA,设有固定螺栓孔,方便安装。

3.6 LCD1602显示模块
LCD1602工业字符型液晶,能够同时显示16x02即32个字符。(16列2行)它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。

3.7 220v转12V直流开关电源
开关电源是一种高频化电能转换装置,是电源供应器的一种。其功能是将一个位准的电压,透过不同形式的架构转换为用户端所需求的电压或电流。开关电源的输入多半是交流电源(例如市电)或是直流电源,而输出多半是需要直流电源的设备,而开关电源就进行两者之间电压及电流的转换。
开关电源产品广泛应用于工业自动化控制、军工设备、科研设备、LED照明、工控设备、通讯设备、电力设备、仪器仪表、医疗设备、半导体制冷制热、空气净化器,电子冰箱,液晶显示器,LED灯具,通讯设备,视听产品,安防监控,LED灯带,电脑机箱,数码产品和仪器类等领域。

第四章 软件设计
4.1 系统流程
单片机一开机,进行PWM,定时器,显示初始。当进入T0定时器中断时,重新赋值T0,。进行中断处理。先检测键盘输入,若检测到输入,则修改设定值。若没有,则执行下一步。设定值与输出值相减,得到余差del,余差再进行增量式PI运算,得到输出值。将余差赋值给上一个余差del_old。最后进行LCD显示。跳出中断。

4.2 定时器与计数器
STC12系列定时器与51系列一样。先对定时器,计数器进行初始化。初始化代码如图4.2所示。

进行初始化后,每进行1ms,单片机将进入一次中断。每进入中断,tt加1,当tt等于500时,也就是当进行了0.5s的定时后,执行中断里的程序。程序包括键盘检测,PI运算,PWM输出,LCD显示。代码如图4.3所示。

4.3 键盘检测
键盘检测使用矩阵键盘常见的扫描法。先行后列行线为输出线,列线为输入线。一开始单片机将行线全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。代码如图4.4所示。

4.4 PI运算
PI运算采用增量式PID运算。增量式PID是指数字控制器的输出只是控制量的增量Δu(k)。采用增量式算法时,计算机输出的控制量Δu(k)对应的是本次执行机构位置的增量,而不是对应执行机构的实际位置,因此要求执行机构必须具有对控制量增量的累积功能,才能完成对被控对象的控制操作。
采用增量式是因为算式中不需要累加。控制增量Δu(k)的确定仅与最近3次的采样值有关,容易通过加权处理获得比较好的控制效果;计算机每次只输出控制增量,即对应执行机构位置的变化量,故机器发生故障时影响范围小、不会严重影响生产过程。代码如图4.5.

4.5 PWM输出
STC12系列有PCA模块PWM输出。PCA模块包含两个捕获/比较匹配 模块,可以实现上升沿/下降沿捕获,及捕获中断,或者比较匹配中断,或者PWM,或者最普通的定时/计数器。在这里我们采用的是8位PWM输出。PCA模块的工作模式如图4.6所示。PWM模式的频率选择如图4.7所示。

利用PCA模块,进行输出8位PWM输出的代码如图4.8所示。

4.6 LCD显示
LCD1602通常为14引脚,16引脚多了两根背光正负极,正极A(15脚)与负极K(16脚)。16引脚的引脚图如图4.9。

LCD1602的初始化为设置显示模式,光标与闪烁的开关与位置设置,清屏操作。初始化后可进行代码送入或字符送入。当初始化未完成时,是无法进行代码如字符送入的。需等待初始化完成后才可执行。代码如图4.10所示。

#include <stdio.h>
#include <string.h>
#include <STC12C5A60S2.h>
#define uchar unsigned char
#define uint unsigned int

sbit RS=P0^6;
sbit RW=P0^5;
sbit EN=P0^4;
sbit R2=P1^4;
sbit R1=P1^5;
sbit C1=P1^6;
sbit C2=P1^7;
sbit GS=P0^0;
sbit PWMS=P1^2;

int set_speed,act_speed;
int tt=0;
int tho,hun,ten,unit,tho2,hun2,ten2,unit2;
int i;
float KI =0.007;
float KP = 0.005;
int delta=0;
int pwm_now=256;

char set_str[4],act_str[4],PWM[4];
char info_1[]=“set:”;
char info_2[]=“act:”;
char info_3[]=“PWM:”;

void LCD1602_WriteCMD(char cmd);
void LCD1602_WriteDATA(char Data);
void LCD1602_init();
int pi(int del);
int setpwm(int pwm);
void control();

void delay(int k) //延时k ms
{
int m,n;
for(m=0;m<k;m++)
{
for(n = 0;n<120;n++);
}
}

int scan(int spe) //
{
//1.4 r1 1.5 r2 1.6 c1 1.7 c2
int kten,khun,speout; //定义百位,十位,输出转速
khun = spe/100; //把百位提取出来
kten = (spe%100)/10; //把十位提取出来

	C1=1;    //初始化
	C2=1;		
	R1=0;     
	R2=0;    
	if(C1==0)  //当第一行有按键
	{
		delay(5);   //延时
		if(C1==0)    //进入列检测
		{
			R1=1;	//列检测
			R2=1;	
			C1=0;
			C2=0;
			delay(5);	//延时			
			if(R1==0)   //第一列有按键
				khun++;		//加100
			if(R2==0)   //第二列有按键
				khun--;  //减100
		}
	}
	if(C2==0)//第二行有按键
	{
		delay(5);//延时
		if(C2==0)//进入列判断
		{
			R1=1;	//列判断
			R2=1;	
			C1=0;
			C2=0;
			delay(5);//延时				
			if(R1==0)//第一列按键
				kten++;	//加10
			if(R2==0)//第二列按键
				kten--;//减10
		}
	}
speout = khun*100+kten*10;//得到输出转速
return  speout;

}

void SCON_T0_init() //定时器,计数器初始化
{
TMOD = 0x51; //T0T1工作模式,T0为16位定时器模式,T1为16位计数器模式

TH0 = 0xFC;     //对T0进行1ms定时
TL0 = 0x18;
ET0 = 1;     //允许T0中断

TH1 = 0x00;     //T1计数器数值初始化
TL1 = 0x00;
ET1 =1;     //允许T1中断

EA =1;	//运行中断
TR0 =1;     	//T0开始工作
TR1 = 1;    //T1开始工作

}

void spe_to_arr(int spe,char *arr)
{
arr[0] = 0x30+spe/1000;
arr[1] = ‘0’+spe%1000/100;
arr[2] =‘0’+spe%100/10;
arr[3] =‘0’+spe%10;
}

void LCD_display()
{
LCD1602_WriteCMD(0x80); // 第一行显示
for(i=0;i<strlen(info_1);i++)
LCD1602_WriteDATA(info_1[i]);
for(i=0;i<4;i++)
LCD1602_WriteDATA(set_str[i]);
LCD1602_WriteCMD(0x8A);
for(i=0;i<4;i++)
LCD1602_WriteDATA(PWM[i]);

	 LCD1602_WriteCMD(0xC0); //  第二行显示
	for(i=0;i<strlen(info_2);i++)
		LCD1602_WriteDATA(info_2[i]);  
	for(i=0;i<4;i++)
		LCD1602_WriteDATA(act_str[i]);

}

void T0_us(void) interrupt 1 //T0定时器中断
{
TH0 = 0xFC; //重新赋值T0定时
TL0 = 0x18;

if(tt<500)    //延长定时时间,当定时0.5s时,执行一次中断程序。
	tt++;
else 
{
	tt = 0;    //给tt重新赋值
	
	set_speed =scan(set_speed);   //键盘检测程序
	act_speed =(TH1*256+TL1)*10;   //将T1计数器的数值进行换算,得到现在的转速
	
spe_to_arr(set_speed,set_str);  //将设定转速转化为数组
spe_to_arr(act_speed,act_str);  //将现在的转速转化为数组
spe_to_arr(pwm_now,PWM);        //将PWM输出转化为数组

 LCD_display();        //LCD1602显示程序
	
	TH1 = 0x00;     
	TL1 = 0x00;    // 将T1计数器的数值重新赋值,为下一次计数做准备
	control();       //PI运算与PWM输出程序
}

}

void PWM_init() //PWM初始化
{
//占空比= (1-CCAPnH/256)*100%
//CCAPnH = (1 - 占空比)*256
// (1-0.875)*256 = 32 = 20H
//PWM频率=系统时钟频率/12/256 = 22118400/12/256 =7.2K
CMOD=0x80; //频率 = 系统时钟/12
CCAPM0=0x42; //8位PWM工作模式

CCAP0H = 0xFF;  //赋值占空比
CCAP0L = 0xFF;  
    CR=1;               //开启PCA   

}

void PWM_output(int k) //PWM输出
{
CCAP0H=k;//赋值占空比
CCAP0L=k;
}

void LCD1602_WriteCMD(char cmd) //往LCD1602送入代码
{
EN = 0;
P2=cmd; //送入代码
RS=0;
RW=0; //设置为代码输入
EN=1;
delay(50);
EN=0; //上跳沿使能
delay(50);
}

void LCD1602_WriteDATA(char Data)//往LCD1602送字符
{
EN = 0;
P2=Data; //送入字符
RS=1;
RW=0; //设置为数字输入
EN=1;
delay(50);
EN=0; //上跳沿使能
delay(50);
}

void LCD1602_init()//LCD1602初始化
{
LCD1602_WriteCMD(0x38); // 置功能,4位总线,双行显示,显示5X7的点阵字符
LCD1602_WriteCMD(0x0F); // 显示开关控制,开显示, 有光标,闪烁
LCD1602_WriteCMD(0x06); // 光标和显示位置设置, 光标移动方向右移,屏幕上所有文字不动
LCD1602_WriteCMD(0x01); // 清显示,指令码01H,光标复位到地址00H位置
}

void control() //PI运算
{
delta= set_speed - act_speed; //余差
pwm_now = pi(delta); //增量式PI计算
pwm_now=setpwm(pwm_now);//PWM约束
PWM_output(pwm_now);//PWM输出
}

int pi(int del)//增量式PI计算
{
static int delta_old=0;
EA=0;

pwm_now=pwm_now-KI*del+KP*(del-delta_old);//增量式PID计算

delta_old=del;//将余差赋值到旧余差
EA=1;
return pwm_now;

}

int setpwm(int pwm)//PWM约束
{
if(pwm < 150)//最小值
pwm = 150;
if(pwm >230)//最大值
pwm = 230;
return pwm;
}

void main(void)
{
PWMS=0;
set_speed =2000;
act_speed =0000;

LCD1602_init();	
SCON_T0_init();
PWM_init();	
PWMS=1;
while(1);		

}

  • 3
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MOOLE_ustdo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值