求测速直流电机的c程序

求测速直流电机的c程序,第1张

"测速直流电机的c程序"这是什么意思?直流电机测速还需要c程序?直流电机通电就转c程序可以通过PWM对其调速,但这与测速好像木有太大关系,下面是51单片机I/O模拟PWM程序:

/

声明: 在网上找的

Title: 模拟PWM输出

Description: 51单片机模拟PWM输出控制灯的100个档级

/

#include <reg51h>

#define uInt unsigned int

#define uchar unsigned char

uchar PWM_T = 0; //占空比控制变量

//////////////////主程序入口//////////////////////

void main(void)

{

bit flag = 1; //控制灯渐亮渐熄方式

uInt n;

TMOD=0x02; //定时器0,工作模式2,8位定时模式

TH0=210; //写入预置初值(取值1-255,数越大PWM频率越高)

TL0=210; //写入预置值 (取值1-255,数越大PWM频率越高)

TR0=1; //启动定时器

ET0=1; //允许定时器0中断

EA=1; //允许总中断

P1=0xff; //初始化P1

while(1)

{

for(n=0;n<600;n++); //延时,将响应定时器中断,灯会自动加/减一个档次的亮度

//取值0-65535,数字越大变化越慢

if(flag==1) //灯渐亮

PWM_T++;

else //灯渐熄

PWM_T--;

if(PWM_T>=100) //设置灯亮度级别为10

flag=0;

if(PWM_T==0) //限定最低亮度级别为0

flag = 1;

}

}

///////////////////定时器0中断模拟PWM////////////////////

timer0() interrupt 1 using 2

{

static uchar t ; //PWM计数

t++; //每次定时器溢出加1

if(t==100) //PWM周期

{

t=0; //使t=0,开始新的PWM周期

P1=0x00; //使LED灯亮

}

if(PWM_T==t) //按照当前占空比切换输出为高电平

P1=0xff; //使LED灯灭

}

#include<reg51h>

#define Tpwm 0xfc18//PWM周期对应的计数值1ms,基于12MHz晶振

unsigned int duty[]={0,/0/

0xff9c/100us/,0xff38/200us/,0xfed4/300us/,\

0xfe70/400us/,0xfe0c/500us/,0xfda8/600us/,\

0xfd44/700us/,0xfce0/800us/,0xfc7c/900us/,\

0xfc18/1000us/};//PWM高电平时间

unsigned char i=0;

sbit P32 = P3^2;

sbit P33 = P3^3;

sbit PWMOUT = P2^0;

sbit PWMIN1 = P2^1;

sbit PWMIN2 = P2^2;

bit flag = 1;//PWM输出电平状态,1为输出高电平时间,0为输出低电平时间

void delay10ms(int n);

void  main(void)

{

PWMOUT = 0;//初始化L293D ,停止电机

PWMIN1 = 0;

PWMIN2 = 1;

EA = 1;  //开总中断

IT0 = 1;  //中断方式为跳变

IT1 = 1;

EX0 = 1;  //打开外部中断0

EX1 = 1;  //打开外部中断1

ET0 = 1;  //开定时器0中断允许

TMOD = 0x01; //设置定时方式

while(1)  //等待中断

{

/在此可以实现其它任务/

}

}

//10ms延时函数

void delay10ms(int n)

{

int i=0,j;

while(n--)

{

for(i=0;i<10;i++)

{

for(j = 0; j < 125; j++);

}

}

}

void keySpeeddownISR() interrupt 0 //按键中断服务程序

{

EA = 0;   //关中断

delay10ms(2);  //延时消抖

if (!P32)    //确认按键按下,滤除键盘抖动干扰

{//减少PWM高电平时间

if(i>0)

i--;

if((TR0=1) && (i == 0))

{

TR0 = 0;

PWMOUT = 0;

}

}

EA = 1;

}

void keySpeedupISR() interrupt 2 //按键中断服务程序

{

EA = 0;   //关中断

delay10ms(2);  //延时消抖

if (!P33)    //确认按键按下,滤除键盘抖动干扰

{//增加PWM高电平时间

if(i<=10)

i++;

if((TR0 == 0) && (i > 0))

{//启动PWM,电机顺时针旋转

PWMIN1 = 0;

PWMIN2 = 1;

PWMOUT = 1;

TH0 = duty[i]>>8;

TL0 = duty[i]&0xff;

TR0 = 1;

flag = 1;

}

}

EA = 1;

}

void T0ISR() interrupt 1 //定时器0中断服务程序

{

EA = 0;   //关中断

if(flag)

{//高电平时间结束,输出低电平补齐PWM周期

PWMOUT = 0;

TH0 = (65535-(duty[i]-Tpwm))>>8;

TL0 = (65535-(duty[i]-Tpwm))&0xff;

flag = 0;

}else

{//周期结束

PWMOUT = 1;

TH0 = duty[i]>>8;

TL0 = duty[i]&0xff;

flag = 1;

}

EA = 1;

}

仅供参考。学单片机还需自己多多思考和练习

这个我经常用,电机调速控制,严格说这不是PWM,是可控硅移相触发。

电路很简单,一个可控硅触发电路,一个过零检测电路,配合一段中断服务程序就能完成。

不知道你应用的一些详情,简单说一下思路。

可控硅触发一般使用MOC3021,相关手册上有典型电路,CPU端接一个GPIO就可以。

闭环控制时过零检测不需要很精确,一般用一个双向光耦就足够,光耦输入接交流电输入,输出接CPU中断,用史密特整形一下输出信号最好。

中断程序的结构分成两部分,过零中断与延时中断。

过零中断做两件事,输出复位,开始延时。如果定时器有外部管脚复位启动功能,可以不要这段。

延时中断做一件事,触发输出。如果定时器有触发输出功能,可以没有这段中断程序。

具体的延时时间,由主程序控制,一般是根据PID的计算结果进行设置。注意,延时时间越长,输出电压越小。

P4SEL=0X0E; P4DIR=0xFF; P4OUT=0xFF;

TBCCTL1 = OUTMOD_7; // CCR1 reset/set

TBCCTL2 = OUTMOD_7; // CCR2 reset/set

TBCCTL3 = OUTMOD_7; // CCR3 reset/set

TBCCR0=5000;

TBCCR1=pwm1d1;

TBCCR2=pwm2d1;

TBCCR3=pwm3d1;

TBCTL = TBSSEL_2 + TBCLR + MC_1;//MCLK,UP

改变TBCCR1,TBCCR2,TBCCR3便改变占空比。TA的你自已改吧。单片机要选TA可以输出7路PWM的。

/

模块名称:PWMc

功 能:可调PWM波

说 明:按键AN1增加占空比,按键AN2减小占空比,P0^2口输出PWM波

/

#include < reg52h >

#define uchar unsigned char

#define uint unsigned int

uint T_1 = 10000; //定时器1初值变量

uchar flag; //按键返回变量

sbit PWM = P0^2; //PWM输出口

sbit AN1 = P0^0; //增加占空比

sbit AN2 = P0^1; //减小占空比

//调节占空比函数

/

函 数 名:timer_init()

功 能:定时器初始化函数

说 明:无

入口参数:无

返 回 值:无

/

void timer_init()

{

TMOD = 0x11; //定时器0、定时器1工作于模式1

EA = 1; //开总中断

ET0 = 1; //定时中断0允许

ET1 = 1; //定时中断1允许

TH0 = (65536-20000)/256; //定时器0装初值:20ms

TL0 = (65536-20000)%256;

TH1 = (65536-T_1)/256; //定时器1装初值:10ms

TL1 = (65536-T_1)%256;

TR0 = 1; //开启定时中断0

}

/

函 数 名:timer0()

功 能:定时中断0中断服务函数

说 明:产生高电平,中断固定时间20ms,频率50HZ

入口参数:无

返 回 值:无

/

void timer0() interrupt 1

{

TR0 = 0; //关闭定时中断0

PWM = 1; //脉冲高电平

TH0 = (65536-20000)/256; //定时器0装初值:20ms

TL0 = (65536-20000)%256;

TR1 = 1; //开启定时中断1

TR0 = 1; //开启定时中断0

}

/

函 数 名:timer1()

功 能:定时中断1中断服务函数

说 明:产生低电平,中断时间可变

入口参数:无

返 回 值:无

/

void timer1() interrupt 3

{

TR1 = 0; //关闭定时中断1

PWM = 0; //脉冲低电平

TH1 = (65536-T_1)/256; //定时器1装初值:10ms

TL1 = (65536-T_1)%256;

}

/

函 数 名:keyscan()

功 能:键盘扫描函数

说 明:无

入口参数:无

返 回 值:无

/

uchar keyscan(void)

{

if(AN1==0) //AN1按下

{

while(AN1==0); //AN1松开

return 1; //返回 1

}

if(AN2==0) //AN2按下

{

while(AN2==0); //AN2松开

return 2; //返回 2

}

else return 0; //返回 0

}

/

函 数 名:change()

功 能:调节占空比函数

说 明:无

入口参数:无

返 回 值:无

/

void change(void)

{

flag = keyscan(); //按键返回值保存

if(flag==1) //按键返回值为1,即AN1按下

{

if(T_1>=65435) //定时器初值变量大于等于65525

{

T_1 = 65530; //定时器初值变量等于65535

}

if(T_1<65525) //定时器初值变量小于65525

{

T_1 = T_1+100; //定时器初值变量加10

}

}

if(flag==2) //按键返回值为2,即AN2按下

{

if(T_1<=100) //定时器初值变量小于等于10

{

T_1 = 5; //定时器初值变量等于0

}

if(T_1>100) //定时器初值变量大于10

{

T_1 = T_1-100; //定时器初值变量减10

}

}

}

/

函 数 名:main()

功 能:主函数

说 明:无

入口参数:无

返 回 值:无

/

void main()

{

timer_init(); //定时器初始化

while(1)

{

change(); //改变占空比

}

}

你用Protues软件的示波器按照程序引脚图连一下,就是一个PWM波了,且占空比可调

首先弄清楚PID是一种控制算法!!!

1,“如果用单片机恒温可以使温度到达预定值就停止加热,低了就加热,用一个温度传感器反馈,这样算是一个自动控制吗”你这是控制系统,但是效果会非常差,尤其是对于温度控制这种大惯性系统,达到预定值就停止加热,但是由于惯性,温度肯定会继续上升,电炉烧水的时候,水开了,断电之后水还要沸腾一定时间的(沸腾是很消耗能量的,由此可见如果是加热的话温度上升更严重,你也可以自己用温度计试试看);“低了就加热”是同样的道理。如果系统对控制精度有要求,你这样做肯定达不到要求。PID是一种控制算法,相对于其他控制算法来说算是最简单的了。PID能够做到在温度快要达到设定值的时候降低加热功率,让温度上升速度变慢,最终稳定在设定值。如果用你的直接控制,温度会在设定值上下振荡,永远不会停在设定值。

2,一般的控制系统都需要加反馈,以构成闭环控制系统,相对的还有开环控制系统。开环控制系统,举个例子,就是你加热的时候事先计算好大约需要多少热量,然后考虑一下环境影响,计算出加热时间,然后控制加热系统按照你这个时间加热。你觉得这样的系统能够稳定工作吗?环境稍稍有变动就挂了!开环控制系统的特点就是很容易受到环境的影响;闭环控制系统就稳定很多,你用1L水可用,2L水也行,500W电能用,1000W电炉也能用,这就是闭环的优点。

因此,大多数的控制系统都是闭环的,开环很少单独使用,即使用到了也是有闭环的。开环其实也是有优点的,开环在控制系统里面叫做前馈(跟反馈对应的),比如你的系统里面电源电压上升了,加热速度肯定会变快,如果你对电源电压采样,将采样的结果输入到闭环里面,对闭环做一个轻微的修正,控制的精度会更好,这就是开环的优势,它是超前的,能够预知结果(根据地源电压提高就能知道需要降低输出功率了)。

说完这些,你应该明白了,反馈是必需的(前馈也可以要,但是不是必需的),PID不能被取代(除非你用其它更复杂的控制算法)。

以上就是关于求测速直流电机的c程序全部的内容,包括:求测速直流电机的c程序、基于Proteus的直流电机调速c程序、单片机控制PWM 要用到双向可控硅 求相关电路图和程序(最好是C语言的) 我把剩下的所有财富都给大家了急等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9481983.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-28
下一篇 2023-04-28

发表评论

登录后才能评论

评论列表(0条)

保存