pwm控制电机C程序

合集下载

PWM调速的C语言程序编写(非常简单)

PWM调速的C语言程序编写(非常简单)

PWM调速的C语言程序编写关于PWM的原理在上一篇文章中已经说的很详细了,现在就细说一下pwm C语言程序的编写。

C语言中PWM的编写有这么几种方法;一、用普通的I/O 口输出的PWM ,二、使用定时计数器编写,三、就是使用片内PWM了。

1 先说使用普通的I\O口编写PWM程序了。

使用I/O口输出PWM波形你必须首先明白PWM他的实质是:调制占空比,占空比就是波形中高电平的长度与整个波长的比值。

我们写C语言的目的是写PWM波形的一个周期。

在这个周期内高低电平的比值是可以改变的。

这也就符合了PWM的原意脉宽调制。

即高电平的宽度的调制。

当然了PWM他也可用于改变频率,我们这里只先说他改变脉宽。

一旦我们的C语言程序写完那么他产生的PWM波形的频率就一定了。

(也可写频率变化的PWM,难度有点大)一般我们控制使用1K到10K的PWM波进行控制。

当然了你也可在要求不是很高的地方使用频率更低的PWM波。

比如在飞思卡尔智能车比赛中我们学校使用的PWM波频率只有600HZ.我们要改变一个PWM波周期内的高电平的宽度显然需要将一个PWM波的周期分成单片机可以控制的N个小的周期,N的取值越大你的调速等级越高,但产生的PWM频率就越低。

我们下面以实现100级调速为例编写PWM程序。

先写出程序再慢慢给大家分析void pwm (uchar x,uint y) //X 为占空比 Y为函数使用时间{ uint i,j,a,b;for(i=y;i>0;i--)//定时外函数{for(j=7;j>0;j--)//定时内函数{for(a=y;a>0;a--) / /PWM波高电平宽度{PORTA=0X01;}for(b=100-y;b>0;b--) //PWM低电平宽度{PORTA=0X00;}}}}这个程序够简单吧轻松的实现AVR单片机的PA.0口输出7KHZ左右的PWM脉冲你可以将PORTA=0X01;改为P1.0=0X01;就可以移植到51单片机上了为什么使用参数Y定时是因为用普通I/O口控制它的开关没有使用定时器编写的灵活。

C语言中的运动控制与机器人编程

C语言中的运动控制与机器人编程

C语言中的运动控制与机器人编程C语言是一种广泛应用于嵌入式系统和机器人领域的编程语言,它为开发人员提供了强大的运动控制能力。

本文将介绍C语言中的运动控制和机器人编程相关的概念和技术。

一、机器人编程简介机器人编程是指使用计算机编程语言来控制机器人完成特定任务的过程。

在机器人编程中,我们可以使用各种编程语言,包括C语言,来实现机器人的运动控制、感知与决策等功能。

C语言被广泛应用于机器人编程中,因为它可以提供高效、灵活的底层控制能力。

二、C语言中的运动控制C语言中的运动控制主要通过操作机器人的执行器(例如电机、伺服驱动器等)来实现。

以下是一些常用的C语言运动控制技术:1. 脉冲宽度调制(PWM)脉冲宽度调制是一种常用的控制执行器(如电机)转速和角度的技术。

在C语言中,我们可以使用定时器来生成PWM信号,并通过调节脉冲宽度来控制执行器的位置和速度。

2. 位置反馈控制在一些机器人应用中,需要对执行器的位置进行精确控制。

C语言中,我们可以使用编码器等位置传感器来获取执行器的位置信息,并通过PID控制算法来控制执行器的位置。

3. 轨迹规划对于一些需要执行复杂运动的机器人,如机械臂,我们需要对其运动轨迹进行规划。

C语言中,我们可以使用插补算法来实现机器人的轨迹规划,从而实现平滑和高效的运动控制。

三、C语言在机器人编程中的应用除了基本的运动控制技术外,C语言还可以用于实现机器人的感知和决策功能。

以下是一些C语言在机器人编程中的应用领域:1. 传感器数据处理机器人需要通过各种传感器来感知周围环境,包括距离传感器、摄像头、惯性测量单元等。

C语言可以用于处理和解析传感器数据,从而实现机器人的环境感知功能。

2. 智能决策C语言的灵活性和高效性使其成为机器人智能决策算法的理想选择。

例如,我们可以使用C语言实现路径规划算法、目标跟踪算法等,使机器人能够智能地决策行动。

3. 通信与控制机器人通常需要与其他设备或系统进行通信和控制。

三相异步电动机 foc 控制 pwm 变频调速工作原理

三相异步电动机 foc 控制 pwm 变频调速工作原理

三相异步电动机的FOC控制是一种利用变频器控制三相交流马达的技术,它通过调整变频器的输出频率、输出电压的大小及角度,来控制马达的输出。

具体来说,FOC控制通过调整PWM(脉冲宽度调制)信号的占空比,来控制变频器的输出电压,从而控制马达的转速。

PWM信号是一种方波信号,其占空比是指在一个周期内高电平时间与整个周期时间的比值。

当占空比变化时,变频器输出的平均电压也会变化,从而改变马达的转速。

在FOC控制中,首先需要将三相输出电流及电压以矢量来表示,这个过程称为矢量控制或磁场定向控制。

通过调整变频器的输出频率和电压大小,可以控制马达的磁场强度和转速。

对于有传感器FOC,由于电机的传感器(一般为编码器)能反馈电机转子的位置信息,因此在控制中可以不使用位置估算算法,控制起来相对无传感器FOC简单。

然而,对于无传感器FOC,由于没有传感器来反馈电机转子的位置信息,因此需要使用位置估算算法来控制马达的转速。

总之,三相异步电动机的FOC控制利用PWM信号来控制变频器的输出电压,从而控制马达的转速。

它是一种高效、精确的电机控制方法,被广泛应用于各种工业场合。

电动车控制器C语言源代码讲解

电动车控制器C语言源代码讲解
*主函数
******************************************************************************/
void main(void)
{
Init(); //初始化
Init_IO(); //初始化端口
H_Sample(); //霍尔信号采样
{
Speed_Buffer[i]=0;
}
for (i=0;i<16;i++)
{
Voltage_Buffer[i]=0;
}
Current_P=0;
Speed_P=0;
Voltage_P=0;;
Speed_SUM=0;
// PWM_MAX=0;
Current_SUM=0;
Voltage_SUM=0;
H_State=0;
KS_Finish();
}
}
//***Function Set***//
if(AH_Count >= 100)
{
AutoHelp(); //自助力
AH_Count = 0;
}
if(KS_CNT >= 3000)
{
KS_CNT = 0;
Keep_Speed(); //巡航定速
}
Volt_Low(); //欠压保护
*/
while(1)
{
_nop_();
//AutoHelpEN(0,0x1AA,100);
//Keep_SpeedEN(1,0x20,6);
//Current_Lim(0xB50);
//LowVoltage_Lim(0x9B0);
//EABS_Set(0,0);

PWM控制输出代码

PWM控制输出代码

PWM控制输出代码#ifndef INCLUDE_H#define INCLUDE_H#include"AT89X51.h"#include"intrins.h"#define uchar unsigned char#define uint unsigned int#define _BV(x) (1<<(x))#define GET_BIT(x,y) (((x)&(1<<(y)))==0?0:1) /*取x变量y位的数据*/ #define SET_BIT(x,y) ((x)|=(0x0001<<(y))) /*置位x变量y位*/#define CLR_BIT(x,y) ((x)&=~(0x0001<<(y))) /*清零x变量y位*/#define LET_BIT(x,y,z) ((x)=(x)&(~(0x0001<<(y)))|(z)<<(y)) /*置位或清零x变量y位*/#define F_CPU 12000000UL /*cpu震荡周期*/#define sei() (EA=1) /*开总中断*/#define cli() (EA=0) /*关总中断*/#endif-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------#define KEY_GLOBAL 1#include"Key.h"static uchar keyValueBuff; /*读取键值的缓冲区*/static uchar keyValueOld; /*前一次的键值*/static uchar keyValueTemp; /*键值中间交换变量*/static uint stillTimes; /*键按下保持次数*/static uint stillTimesMax;static uchar get_data_1_count(uchar number);static void read_all_key(uchar *buff);/********************************************函数名称:key_init(void)*函数功能:初始化按键扫描*函数入口:无*函数出口:无*******************************************/void key_init(void){keyValueBuff = 0x00;keyValueOld = 0x00;keyValueTemp = 0x00;stillTimes = 0;stillTimesMax = FIRST_TIMES;}/****************************************************** *函数名称:read_all_key(uchar *buff)*函数功能:扫描按键下的键,将按下的键的位置存入变量buff *函数入口:buff*函数出口:无*******************************************************/ void read_all_key(uchar *buff){if(IN_PRESS_UP==KEY_FORCE_VALUE) //检测按下的键READ_KEY(1,KEY_UP,*buff);elseREAD_KEY(0,KEY_UP,*buff);if(IN_PRESS_DOWN==KEY_FORCE_VALUE)READ_KEY(1,KEY_DOWN,*buff);elseREAD_KEY(0,KEY_DOWN,*buff);}/****************************************************** *函数名称:get_key_value(void)*函数功能:读取键值*函数入口:无*函数出口:返回按下的有效键值*******************************************************/ uchar get_key_value(void){keyValueBuff = 0x00;read_all_key(&keyValueBuff);keyValueTemp = keyValueBuff;delay_us(KEY_DELAY_TIME);read_all_key(&keyValueBuff);#if REPEAT_MODEif(FIRST_TIMES == stillTimesMax){stillTimesMax = OTHER_TIMES;}#endifreturn keyValueTemp;}#elsestillTimes = 0;return 0;#endif}}else{stillTimes = 0;return 0;}return 0;}/********************************************************** *函数名称:get_data_1_count(uchar number)*函数功能:计算uchar类型变量中的数量,用于检测是否多键按下*函数入口:number,需要检测数量的变量*函数出口:返回变量bumber中的数量***********************************************************/ uchar get_data_1_count(uchar number){register uchar i,j = 0;for(i = 0; i < 8; i ++){if( (number&_BV(i)) ){j ++;}}return j;}/********************************************************** *函数名称:delay_us(uint us)*函数功能:毫秒级延时*函数入口:延时计数变量us*函数出口:无***********************************************************/void delay_us(uint us){uchar delayi;while(--us){for(delayi=0;delayi<10;delayi++);}}#include"Include.h"#ifndef KEY_H#define KEY_H 1#ifndef KEY_GLOBAL#define KEY_EXT extern#else#define KEY_EXT#endif#define READ_KEY(x,name,b) ((x)?(b|=name):(b&=~name) )//--------------------------------用户设置区------------------------------------------#define CAN_MORE_PRESS 0 /* 是否允许多键都按: 允许为;不允许为*/#define CAN_REPEAT 1 /* 是否允许重复按键: 允许为;不允许为*/#define REPEAT_MODE 1 /* 重复模式: 先长后短为;相同间隔为*/#define FIRST_TIMES 200 /* 重复按下时,第一次间隔时间*/#define OTHER_TIMES 25 /* 第二次后间隔时间(如果重复模式为时此值无效) */ #define KEY_DELAY_TIME 20 /* 键盘扫描时间间隔XXXus */#define KEY_FORCE_VALUE 0 /*键盘有效电平,为高电平,为低电平*/#define IN_PRESS_UP P1_0 /*1设置键端口*/#define IN_PRESS_DOWN P1_1 /*2设置键端口*//* 键盘重映射注:当前结构下最大按键数为:8; 以进制中的相应位来标识*/enum KEY_VALUE{KEY_UP= 0x01,KEY_DOWN= 0x02,KEY_NULL = 0x00};//------------------------------------------------------------------------------------ KEY_EXT void key_init(void); //键盘扫描初始化KEY_EXT uchar get_key_value(void); //读取有效键值变量KEY_EXT void delay_us(uint us); //us级延时函数#endif#define LED_GLOBAL 1#include"led.h"extern void delay_us(uint us); /*声明微秒级延时函数*/ /*****************************************************函数名称:led_init(void)*函数功能:数码管初始化*函数入口:无*函数出口:无****************************************************/void led_init(void){//数码管显示pwm初始化值,/100ledWrite('1',0x01,DIGITAL);ledWrite('0',0x02,DIGITAL);ledWrite('0',0x03,DIGITAL);}/*********************************************************** *函数名称:ledWrite(uchar c,uchar n,uchar mod)*函数功能:向第n个数码管写mod模式的内容c*函数入口:c为要显示的内容,显示数字时,调用入口应输入数字字符; n为要显示的数码管编号;mod为要显示的模式*函数出口:无*************************************************************/ void ledWrite(uchar c,uchar n,uchar mod){if(CHARACTER==mod) //为任意字段显示LED=c;else if(DIGITAL==mod)LED=segLedCode[c-'0'];switch(n){case 0x01:{LED_CS1=CS_FORCE_VALUE;delay_us(10);LED_CS1=0; //~CS_FORCE_VALUEbreak;}case 0x02:{LED_CS2=CS_FORCE_VALUE;delay_us(10);LED_CS2=0;break;}case 0x03:{LED_CS3=CS_FORCE_VALUE;delay_us(10);LED_CS3=0;break;}default:break;}}/********************************************************* *驱动名称:七段LED数码管驱动*功能:适用于带个锁存器LS373的段数码管显示*修改:修改驱动使其适用于三个数码管显示*版本:V0.0.1*作者:kxm*时间:.06.11*********************************************************/ #ifndef LED_H#define LED_H 1#include"Include.h"#ifndef LED_GLOBAL#define LED_EXT extern#else#define LED_EXT#endif#define CS_FORCE_VALUE 1 /*74LS373片选有效电平*///***************数码管端口定义**************************** #define LED P0 /*定义LED数据端口*/#define LED_CS1 P2_0 /*74LS373锁存器片选端口*/ #define LED_CS2 P2_1 /*74LS373锁存器片选端口*/ #define LED_CS3 P2_2 /*74LS373锁存器片选端口*/ //*********************************************************enum SEG_DISPLAY_MOD{DIGITAL=0x00,CHARACTER=0x01}; /*数码管输出模式,数字或任意字段显示*/ /*高电平驱动*/#ifdef LED_GLOBALuchar segLedCode[10]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x73};/*数码管数码译码数组,led6~led0==a~g,code1~10==0~9*/#endifLED_EXT void led_init(void); /*数码管初始化*/LED_EXT void ledWrite(uchar c,uchar n,uchar mod); /*向第n个数码管写mod模式的内容c*/#endif#define PWM_GLOBAL 1#include"pwm.h"/******************************************************函数名称:pwm_init(void)*函数功能:PWM初始化,设置定时器*函数入口:无*函数出口:无*****************************************************/void pwm_init(void) // 12M{TMOD=0x20; // 定时器模式TL1 = 255-10; // 1msTH1 = 255-10;ET1 = 1; //定时器边沿触发TR1 = 1; //开定时器中断pwmPeriodCont =0x00;pwmH=0x01;}/******************************************************函数名称:void pwm_set(const uchar NewPwmValue)*函数功能:PWM占空比设置*函数入口:无*函数出口:无*****************************************************/void pwm_set(uchar NewPwmValue){if ((NewPwmValue >= 1)&&(NewPwmValue <= 99)) //一个周期里{pwmH = NewPwmValue;}else//若占空比不在...99范围内则输出一个尖脉冲{pwmH =0x01;}}/******************************************************函数名称:pwmProduce(void)*函数功能:定时器溢出中断设置*函数入口:无*函数出口:无*****************************************************/void pwmProduce(void) interrupt 3{pwmPeriodCont++; //PWM定时周期计数加if(pwmPeriodCont<=pwmH)PWM_OUT =1; // 高电平从到...PWM_Helse// 剩下的为低电平时间{PWM_OUT =0;if (pwmPeriodCont >= PWM_Period)// 一个频率周期结束{pwmPeriodCont=0;}}}/************************************************驱动功能:产生pwm,12MHZ晶振下,总周期为*1ms*版本:.0.1*作者:lhw*时间:.06.11***********************************************/#ifndef PWM_H#define PWM_H#include"Include.h"#ifndef PWM_GLOBAL#define PWM_EXT extern#else#define PWM_EXT#endif#define PWM_Period 100 //100%占空比时标数//*******************端口定义**********************sbit PWM_OUT=P1^2; /*pwm输出端口映射*///*************************************************PWM_EXT uchar pwmPeriodCont; // PWM 占空比计数器PWM_EXT uchar pwmH;PWM_EXT void pwm_init(void); /*PWM初始化,设置定时器*/ PWM_EXT void pwm_set(const uchar NewPwmValue); /*PWM占空比设置*/#endif#include"led.h"#include"key.h"#include"pwm.h"static uchar pwmScale; //pwm占空比,1~99 void main(){uchar keyValue;pwm_init(); //初始化pwm,pwm高电平默认值为 key_init();led_init();pwmScale=0x01; //初始化占空比变量,初始值为 sei();while(1){keyValue=get_key_value();if(keyValue!=KEY_NULL){if(keyValue==KEY_UP){if(pwmScale<99)pwmScale++;}if(keyValue==KEY_DOWN){if(pwmScale>1)pwmScale--;}pwm_set(pwmScale);ledWrite(pwmScale%10+'0',0x01,DIGITAL); //显示占空比个位 ledWrite(pwmScale/10+'0',0x02,DIGITAL); //显示占空比十位}}}。

STC系列PWM方式控制两相步进电机

STC系列PWM方式控制两相步进电机

单片机课程设计步进电机控专业班级:姓名:学号:指导教师:目录一.课程设计要求二.课程设计目的三.所用仪器及相关说明1.5 7步进电机23HS66202. DM524 型细分型两相混合式步进电机驱动器3.STC12C5A60S2系列单片机四.调试程序【程序一、二】五.程序功能【程序一、二】六.误差说明七.心得体会八.课设说明一.课程设计要求通过计算机对单片机芯片的编程,将单片机与驱动器相连,从而实现对步进电机的各种方式控制。

二.课程设计目的1.根据所期望的结果编写程序,并在实验仪器上调试和验证。

2.使用步近电机的工作原理与步进电机驱动器。

3.学习控制步进电机转角、速度、方向的实时软件设计三.所用仪器及相关说明1.57步进电机23HS66202.DM524型细分型两相混合式步进电机驱动器,采用直流18~50V 供电,适合驱动电压24V~50V,电流小于 4.0V ,外径42~86毫米的两相混合式步进电机。

此驱动器采用交流伺服驱动器的电流环进行细分控制,电机的转矩波动很小,低速运行很平稳,几乎没有振动和噪音。

高速时力矩也大大高于其它二相驱动器,定位精度高。

广泛适用于雕刻机、数控机床、包装机械等分辩率要求较高的设备上。

电气参数输入电流小于4安培输出电流 1.0A ~4.2A功耗功耗:80W ;内部保险:6A温度工作温度-10~45℃;存放温度-40℃~70℃湿度不能结露,不能有水珠气体禁止有可燃气体和导电灰尘重量200克主要特点1)平均电流控制,两相正弦电流驱动输出(2)直流24~50V 供电3)光电隔离信号输入/输出(4)有过压、欠压、过流、相间短路保护功能5)十五档细分和自动半流功能(6)八档输出相电流设置(7)具有脱机命令输人端子(8)高启动转速(9)高速力矩大(10)电机的扭矩与它的转速有关,而与电机每转的步数无关控制信号接口控制信号定义PLS/CW+:步进脉冲信号输入正端或正向步进脉冲信号输入正端PLS/CW-:步进脉冲信号输入负端或正向步进脉冲信号输入负端DIR/CCW+ :步进方向信号输入正端或反向步进脉冲信号输入正端DIR/CCW- :步进方向信号输入负端或反向步进脉冲信号输入负端ENA+ :脱机使能复位信号输入正端ENA- :脱机使能复位信号输入负端脱机使能信号有效时复位驱动器故障,禁止任何有效的脉冲,驱动器的输出功率元件被关闭,电机无保持扭矩。

通过PWM 控制直流电机的转动(C语言)

通过PWM 控制直流电机的转动(C语言)

通过PWM 控制直流电机的转动(C语言)脉冲宽度调制(PWM)是英文“Pulse Width Modulation”的缩写,简称脉宽调制。

void PWM(uchar u1){uchar t=0X29; //设置周期cap=0; //使能端置0,电机转while(t--){if(u1= =0)cap=1;u1--;}}例:#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit cap=P1.5; //电机pwm输入端sbit d=P1.7; //电机方向控制端,1为正向void PWM(uchar u1){uchar t=0XFF; //设置周期cap=0; //使能端置0,电机转while(t--){if(u1= =0)cap=1;u1--;}}void STOP( ) //停止{cap=1; //使能端置1 电机停止转动}void FRONT( ) //电机正转{d=1; //方向端置1 电机正转PWM(150); // 以150/255倍的全速正转}void BACK( ) //电机反转{d=0;PWM(100);}void main( ){FRONT( );BACK( );STOP( );}使用的平台是keil c51编译器,直流电机两端分别接使能端和方向端,电机转动的前提是使能端为0。

方向端为1则电机正转,为0则反转(电路实现)。

三电平svpwm的c语言代码

三电平svpwm的c语言代码

三电平svpwm的c语言代码三电平SVPWM(Space Vector Pulse Width Modulation)是一种常用的电力电子调制技术,广泛应用于交流电机驱动系统中。

在这篇文章中,我们将介绍三电平SVPWM的原理和C语言代码实现。

让我们来了解一下SVPWM的原理。

SVPWM是一种通过改变电压矢量的占空比来控制交流电机的技术。

它基于矢量控制理论,将电压矢量分解为两个方向的矢量,通过改变其占空比来实现对电机的控制。

SVPWM的基本原理是将三相电压分解为两个相互垂直的矢量,即一个旋转矢量和一个静止矢量。

旋转矢量用来控制电机转子的速度和位置,静止矢量用来控制电机的功率输出。

通过改变这两个矢量的占空比,可以实现对电机的精确控制。

接下来,让我们来看看如何用C语言实现三电平SVPWM。

首先,我们需要定义一些变量来存储电压矢量和占空比信息。

然后,我们可以使用循环语句来生成PWM信号。

在C语言代码中,我们可以使用if-else语句来根据电压矢量的位置来确定占空比的值。

根据三电平SVPWM的原理,我们可以将电压矢量分为六个扇区,每个扇区对应于不同的占空比设置。

根据电压矢量的位置,我们可以选择相应的占空比值,并将其赋值给PWM信号。

除了生成PWM信号,我们还需要考虑其他一些因素,如死区时间和频率设置。

死区时间是为了避免PWM信号的两个开关同时导通而引起的故障。

频率设置决定了PWM信号的切换速度,影响了电机的响应时间和效率。

在实际应用中,我们还需要考虑一些其他因素,如过流保护、过压保护和过热保护等。

这些保护机制可以有效地保护电机和电力电子器件的安全运行。

在最后,让我们来总结一下三电平SVPWM的优点和应用。

三电平SVPWM具有高精度、高效率和低谐波失真的特点,适用于各种交流电机驱动系统,如电动汽车、工业自动化和再生能源等。

三电平SVPWM是一种常用的电力电子调制技术,通过改变电压矢量的占空比来实现对交流电机的精确控制。

bldc六步换相法 c代码

bldc六步换相法 c代码

bldc六步换相法 c代码
BLDC六步换相法的C代码实现需要经过以下几个步骤:
1. 定义引脚和变量:首先,需要将接受PWM信号的引脚,以及电机运行和状态的变量进行定义。

2. 设置PWM: PWM信号控制电机线圈上的电流,因此需要在代码中对其进行设置。

3. 编写换向程序:在BLDC六步换相中,电流需要在不同的线圈之间交替流动,以推动电机旋转。

4. 代码循环:在主循环中,电机状态需要被读取并执行相应的代码。

使用BLDC六步换相法的电机驱动需要编写精细的代码来确保电机以正确的速度和方向运行。

该代码应考虑到电机运行的各种状态和控制逻辑。

请注意,具体的代码实现会根据硬件和应用场景有所不同,建议你提供更具体的需求,以便我提供更有针对性的帮助。

pwm电机调速程序

pwm电机调速程序

PWM电机调速程序*******************************************************************/ /* 程序名:PWM直流电机调速 *//* 晶振:11.00592 MHz CPU型号:AT89C51 *//* 直流电机的PWM波控制,可以直接的调速从0到20级的调速 *//*****************************************************************/ #include<reg51.h>#define TH0_TL0 (65536-1000)//设定中断的间隔时长unsigned char count0 = 50;//低电平的占空比unsigned char count1 = 0;//高电平的占空比bit Flag = 1;//电机正反转标志位,1正转,0反转sbit Key_add=P2 ^ 0; //电机减速sbit Key_dec=P2 ^ 1; //电机加速sbit Key_turn=P2 ^ 2; //电机换向sbit PWM1=P2^6;//PWM 通道 1,反转脉冲sbit PWM2=P2^7;//PWM 通道 2,正转脉冲unsigned char Time_delay;/************函数声明**************/void Delay(unsigned char x);void Motor_speed_high(void);void Motor_speed_low(void);void Motor_turn(void);void Timer0_init(void);/****************延时处理**********************/void Delay(unsigned char x){Time_delay = x;while(Time_delay != 0);//等待中断,可减少PWM输出时间间隔}/*******按键处理加pwm占空比,电机加速**********/void Motor_speed_high(void)//{if(Key_add==0)Delay(10);if(Key_add==0){count0 += 5;if(count0 >= 100){count0 = 100;}}while(!Key_add);//等待键松开}}/******按键处理减pwm占空比,电机减速*****/ void Motor_speed_low(void){if(Key_dec==0){Delay(10);if(Key_dec==0){count0 -= 5;if(count0 <= 0){count0 = 0;}}while(!Key_dec );}}/************电机正反向控制**************/ void Motor_turn(void){if(Key_turn == 0){Delay(10);if(Key_turn == 0){Flag = ~Flag;}while(!Key_turn);}/***********定时器0初始化***********/void Timer0_init(void){TMOD=0x01; //定时器0工作于方式1TH0=TH0_TL0/256;TL0=TH0_TL0%256;TR0=1;ET0=1;EA=1;}/*********主函数********************/void main(void){Timer0_init();while(1){Motor_turn();Motor_speed_high();Motor_speed_low();}}/**************定时0中断处理******************/ void Timer0_int(void) interrupt 1 using 1{TR0 = 0;//设置定时器初值期间,关闭定时器TL0 = TH0_TL0 % 256;TH0 = TH0_TL0 / 256 ;//定时器装初值TR0 = 1;if(Time_delay != 0)//延时函数用{Time_delay--;}if(Flag == 1)//电机正转{PWM1 = 0;if(++count1 < count0)PWM2 = 1;}elsePWM2 = 0;if(count1 >= 100){count1=0;}}else //电机反转{PWM2 = 0;if(++count1 < count0){PWM1 = 1;}elsePWM1 = 0;if(count1 >= 100){count1=0;}}}//-----------------------------------------------------------------------------#include <c8051f330.h> // SFR declarations#include <math.h>// Function Prototypes//-----------------------------------------------------------------------------#define CMD_RESET 0xA4 //HD7279复位#define DECODE1 0xc8 //方式0译码sbit cs=P1^3;sbit clk=P1^2;sbit dat=P1^1;sbit key=P1^0;sbit led_D1003=P0^7;sbit sw1=P1^7;sbit sw2=P1^6;sbit sw3=P1^5;sbit sw4=P1^4;void long_delay(void); //延时函数void short_delay(void);void delay10ms(unsigned char);void write7279(unsigned char,unsigned char); //HD7279写指令void send_byte(unsigned char);void delay(unsigned char);void disp1(unsigned int);void OSCILLATOR_Init (void);void PORT_Init (void);void PCA0_Init (void);void Timer0_Init(void);void Ext_Interrupt_Init (void);//-----------------------------------------------------------------------------// Global Variables//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// main() Routine//-----------------------------------------------------------------------------unsigned int CEX0_Compare_Value; // Holds current PCA compare valueunsigned int tmr,Speed_evaluate;unsigned char num,num1,num2,num3,a;unsigned int Speed,pi,Speed2;unsigned int Speed1[10];typedef struct {double SetPoint; /* 设定目标Desired Value */double Proportion; /* 比例常数Proportional Const */double Integral; /* 积分常数Integral Const */double Derivative; /* 微分常数Derivative Const */double LastError; /* 前一项误差*/double PrevError; /* 前第二项误差*/double SumError; /* 误差和*/} PID;double PIDCalc( PID *pp, double NextPoint ){double dError,Error,Pout;Error = pp->SetPoint - NextPoint; /* */pp->SumError += Error; /* /dError = pp->LastError - pp->PrevError; /* */pp->PrevError = pp->LastError;pp->LastError = Error; /* */Pout= pp->Proportion * Error + pp->Integral * pp->SumError +pp->Derivative * dError ;if(Pout>1100)Pout=1000;if(Pout<100)Pout=100;return (Pout);}PID sPID; //定义PID结构体变量double rOut; //PID响应输出unsigned char rIn; //设置PID反馈值double x;double sumout;unsigned char dd;//设置PID输出void main (void){sPID.Proportion = 0.44; //设置PsPID.Integral = 0.70; //设置IsPID.Derivative = 0.0; //设置D//sPID.SetPoint = CEX0_Compare_Value;//sPID.SetPoint = CEX0_Compare_Value; //设置PID输出PCA0MD = 0x00; // Disable watchdog timerled_D1003=0;PORT_Init (); // Initialize crossbar and GPIOOSCILLATOR_Init (); // Initialize oscillatorPCA0_Init (); // Initialize PCA0IP=0x82; //定时器中断0高于外部中断0Timer0_Init();Ext_Interrupt_Init ();for (tmr=0;tmr<0x2000;tmr++);send_byte(CMD_RESET);//HD7279复位// Globally enable interruptsEA = 1;sPID.SetPoint=70;while (1){delay10ms(100);//键盘程序 -------------------------------------------------------------if(sw1==0) //按键1是否按下{if(sw1==0)//再次检查按键{num++; //若按键按下,num加1if(num==1) //到9归0{num=0;}while(sw1==0);//按键释放}// delay10ms(100);}write7279(DECODE1+4,num); //将num写入HD7279第1位 delay10ms(1);if(sw2==0){if(sw2==0){num1++;if(num1==2){num1=0;}while(!sw2);}// delay10ms(100);}write7279(DECODE1+5,num1);//将num1写入HD7279第2位delay10ms(1);if(sw3==0){if(sw3==0){num2++;if(num2==10){num2=0;}while(!sw3);}// delay10ms(100);}write7279(DECODE1+6,num2);//将num1写入HD7279第2位delay10ms(1);if(sw4==0){if(sw4==0){num3++;if(num3==10){num3=0;}while(!sw4);}// delay10ms(100);}write7279(DECODE1+7,num3);//将num1写入HD7279第2位delay10ms(1);Speed_evaluate=num*1000+num1*100+num2*10+num3;sPID.SetPoint=Speed_evaluate;//控制程序-----------------------------------------------------------------//---------------------------------------------------------------------------}}void OSCILLATOR_Init (void){OSCICN = 0x83; // Set internal oscillator torun// at its maximum frequencyCLKSEL = 0x00;}void PORT_Init (void){XBR0 = 0x00;XBR1 = 0x41;// Enable crossbar and weak pull-upsP0MDOUT |= 0x10; // Set CEX0 (P0.4) to push-pull P0SKIP |=0x0F; //P1SKIP = 0x00;P1MDOUT= 0x0f;}void PCA0_Init (void){PCA0CN = 0x00; // Stop counter; clear allflagsPCA0MD = 0x01; // Use Ettern ime basePCA0CPM0 = 0xCB; // Module 0 = 16-bit PWM modeand// enable Module 0 Match and Interrupt// Flags// Configure initial PWM duty cycle = 50%CEX0_Compare_Value = 65536 - (65536 * 0.15);PCA0CPL0 = (CEX0_Compare_Value & 0x00FF);PCA0CPH0 = (CEX0_Compare_Value & 0xFF00)>>8;EIE1 |= 0x10; // Enable PCA interrupts// Start PCA counterCR = 1;}void Ext_Interrupt_Init (void){TCON |= 0x05; // /INT 0 and /INT 1 are edge triggeredIT01CF = 0x10; // /INT0 active low; /INT0 on P0.0;// /INT1 active low; /INT1 on P0.1EX0 = 1; // Enable /INT0 interrupts}void Timer0_Init(void){TH0 = 0 ; // Init Timer0 High registerTL0 = 0 ; // Init Timer0 Low registerTMOD |= 0x01; // Timer0 in 16-bit mode方式1CKCON |= 0x02; // Timer0 uses a 1:48 prescalerET0 = 1; // Timer0 interrupt enabledTCON|=0x10;// Timer0 ON}// PCA0_ISR//-----------------------------------------------------------------------------void PCA0_ISR (void) interrupt 11{CCF0 = 0; // Clear module 0 interrupt flag.PCA0CPL0 = (CEX0_Compare_Value & 0x00FF);PCA0CPH0 = (CEX0_Compare_Value & 0xFF00)>>8;}void Timer0_ISR (void) interrupt 1{int j,sum;TF0=0;// Clear interrupt flag.a++;if (a==4){Speed1[pi]=Speed;if(pi>=3){ EX0 = 0;for(j=0;j<=3;j++){sum=sum+Speed1[j];Speed2=sum/4;disp1(Speed2);Speed=0;pi=0;EX0 = 1;}a=0;sum=0;if(pi>=3)pi=0;elsepi++;TH0 = 0; // Reinit Timer0 High register TL0 = 0; // Reinit Timer0 Low registerif(abs( sPID.SetPoint-Speed2)<=5) {CEX0_Compare_Value=CEX0_Compare_Value;}else{rIn =Speed2;for(dd=0;dd<50;dd++)x=rIn;//x = 5.0 * (double)rIn / 256.0;rOut = PIDCalc ( &sPID,x );// sumout=rOut*256/5;if(rOut==100)sumout=0;elsesumout= (0.85/1000.0)*rOut;//CEX0_Compare_Value=CEX0_Compare_Value-sumout;CEX0_Compare_Value = 65536 - (65536 * ( sumout+0.15));}}else{TH0 = 0; // Reinit Timer0 High registerTL0 = 0; // Reinit Timer0 Low register}}void INT0_ISR (void) interrupt 0{IE0=0; // // Clear interrupt flag.Speed++;}void write7279(unsigned char cmd, unsigned char dta) {send_byte(cmd);send_byte(dta);}void send_byte( unsigned char out_byte){unsigned char i;cs=0;long_delay();for (i=0;i<8;i++){if (out_byte&0x80){dat=1;}else{dat=0;}clk=1;short_delay();clk=0;short_delay();out_byte=out_byte*2; }dat=0;}void long_delay(void){unsigned char i;for (i=0;i<0x30;i++);}void short_delay(void){unsigned char i;for (i=0;i<8;i++);}void delay10ms(unsigned char time) {unsigned char i;unsigned int j;for (i=0;i<time;i++){for (j=0;j<0x390;j++);}}void disp1(unsigned int date){unsigned char d0, d1, d2 , d3; d0=date / 1000;d1=(date-d0*1000)/100;d2=(date-d0*1000-d1*100)/10 ;d3= date-d0*1000-d1*100-d2*10;write7279(DECODE1,d0);delay10ms(1);write7279(DECODE1+1,d1);delay10ms(1);write7279(DECODE1+2,d2);delay10ms(1);write7279(DECODE1+3,d3);delay10ms(1);}。

PID控制步进电机转速仿真及c程序

PID控制步进电机转速仿真及c程序

PID控制步进电机转速仿真及c程序#include<reg52.h>#include"lcd1602.h"sfr T2MOD = 0x0c9;#define uchar unsigned char#define uint unsigned intsbit Q0 = P2^4;sbit Q1 = P2^5;sbit Q2 = P2^6;sbit Q3 = P2^7;sbit PWM= P1^7;sbit UP= P1^0;sbit DOWM= P1^1;sbit GORB= P2^3; //换相sbit ADDSPEED = P1^2;sbit SUBSPEED= P1^3;uint tuint = 65535;uint tpwm = 1;//pwm周期为10000us tpwm变量表示pwm高电平时间,也相当于占空比(仿真时,频率高时,电机反应慢。

在实物上要加大频率)uchar t1_flag = 0;uint pulse = 0;uint t0_flag = 0;uchar t2_flag = 0;bit t2_over = 0;bit Just_Get = 1;#define ZZ { Q0 = 0;Q1 = 0;Q2 = 1;Q3 = 1;}//正转#define FZ { Q0 = 1;Q1 = 1;Q2 = 0;Q3 = 0;}//反转#define STOP{ Q0 = 1;Q1 = 0;Q2 = 1;Q3 = 0;}//停止//禁止出现Q0 = 0;Q1 = 1;Q2 = 0;Q3 = 1; 不然会烧掉mos管//************************ PID ************************************* float now = 0,bef = 0,bbef = 0; //本次采样值,上次采样值,上上次采样值float err_now,err_bef,err_bbef;//当前偏差,上次偏差,上上次偏差float error_add = 0;//所有偏差之和float set = 25;//设定值float kp = 25;float ki = 25;float kd = 0;//*****************************************************************void delayms(uint ms)//延时?个ms{uchar a,b,c;while(ms--){for(c=1;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}}void timer_init(){EA = 1;ET0 = 1;ET1 = 1;ET2 = 1;TMOD = 0x15; //定时器0 计数模式定时器1模式1T2MOD = 0x01;TH0 = TL0 = 255;TH2 = 0x3C;TL2 = 0xB0;//50MS}void timer1() interrupt 3{if(t1_flag == 0){t1_flag = 1;PWM = 1;TH1 = (tuint - tpwm + 1)/256;TL1 = (tuint - tpwm + 1)%256;}else{t1_flag = 0;PWM = 0;TH1 = (tuint - 10000 + tpwm + 1)/256;TL1 = (tuint - 10000 + tpwm + 1)%256;}}void timer0() interrupt 1{TH0 = TL0 = 255;t0_flag++;}void timer2() interrupt 5{TF2 = 0;TH2 = 0x3C;TL2 = 0xB0;//50MSt2_flag++;if(t2_flag == 2){TR0 = 0;TR2 = 0;t2_flag = 0;t2_over = 1;//表示100ms时间到}}void GetPulse(){t0_flag = 0;t2_flag = 0;TH0 = TL0 = 255;TH2 = 0x3C;TL2 = 0xB0;//50MSTR0 = 1;TR2 = 1;}int PID()//增量式PID{int change;err_now = set - now;err_bef = set - bef;err_bbef = set - bbef;change = kp*(err_now - err_bef) + ki*err_now + kd*(err_now - 2*err_bef + err_bbef);/*if(set >= now){if(set - now > 1)change = kp*(err_now -err_bef) + ki*err_now + kd*(err_now -2*err_bef + err_bbef);elsechange = 0.2*kp*(err_now - err_bef) + 0.5*ki*err_now + kd*(err_now - 2*err_bef + err_bbef);}else if(now > set){if(now - set > 1)change = kp*(err_now -err_bef) + ki*err_now + kd*(err_now -2*err_bef + err_bbef);elsechange = 0.2*kp*(err_now - err_bef) + 0.5*ki*err_now + kd*(err_now - 2*err_bef + err_bbef);}*///change = (kp + ki + kd)*(set - now) + (-kp - 2*kd)*(set - bef) + kd*(set - bbef);//change = kp*(set - now) + ki*(set - bef) + kd*(set - bbef);if(change > 0){printchar(1,10,'+');printuint(1,11,4,change);}else if(change < 0){printchar(1,10,'-');printuint(1,11,4,-change);}else if(change == 0){printchar(1,10,' ');printword(1,11," 0 ");}return(change);}int PID2()//位置式PID{int num = 0;static num_bef = 0;err_now = set - now;err_bef = set - bef;error_add = error_add + err_now; //误差累加。

电动车控制器C语言源代码

电动车控制器C语言源代码

电动车控制器C语言源代码.#define _E_BIKE_W79E83X_C_ #include "intrins.h"#include "E_BIKE_W79E83X.H" #include"W79E834.h"/****************************************************************************** 主函数******************************************************************************/void main(void){Init(); // 初始化Init_IO(); // 初始化端口H_Sample(); // 霍尔信号采样Phase_Change(); // 相位变换AutoHelpEN(1,0x1AA,200);/*第一个参数设定助力功能允许不否,1为允许,0为禁止第二个参数设定助力力量(PWM占空比),数值围:0~0x355,数值越大,力量越大第三个参数设定助力时间,数值越大,时间越长*/Keep_SpeedEN(1,0x20,6);/*第一个参数设定定速巡航功能允许不否,1为允许,0为禁止第二个参数设定定速巡航最低速设置..第三个参数设定在巡航点保持多长时间后才进入巡航*/Current_Lim(0xB48);/*过流保护上限值设定0xB00对应限电流最大大约为2.6A0xB80对应限流值最大大约为3.8A*/LowVoltage_Lim(0x9B0);/*欠压保护下限值设定电池电压为47.9V时ADC采样值为0xB6 ==> 0xB60推算电池电压为41V时的采样值为0x9B ==> 0x9B0推算电池电压为40V时的采样值为0x98 ==> 0x980*/EABS_Set(1,1);/*第一个参数为滑行充电功能使能,1为允许,0为禁止第二个参数为电刹车功能使能,1为允许,0为禁止*/Speed_LimHW(0,0,0,1);/*硬件控制最大速度参数只能有一个为1。

PWM直流电机调速系统设计

PWM直流电机调速系统设计

PWM直流电机调速系统设计PWM(脉宽调制)直流电机调速系统设计是通过改变电机输入电压的有效值和频率,以控制电机转速的一种方法。

本文将介绍PWM直流电机调速系统的原理、设计过程和实施步骤。

一、PWM直流电机调速系统原理1.电机:PWM直流电机调速系统使用的电机一般是带有永磁励磁的直流电机,其转速与输入电压成正比。

2.传感器:传感器主要用于检测电机转速和转速反馈。

常用的传感器有霍尔传感器和编码器。

3.控制器:控制器通过接收传感器反馈信号,并与用户输入信号进行比较来调整电机输入电压。

控制器一般包括比较器、计数器、时钟和PWM 发生器。

4.功率电源:功率电源负责提供PWM信号的电源。

PWM直流电机调速系统的工作原理是:先将用户输入转速转化为电压信号,然后通过比较器将输入信号与传感器反馈信号进行比较,再将比较结果输入给计数器,由计数器根据输入信号的边沿通过时钟控制PWM发生器,最后通过功率电源提供PWM信号给电机。

二、PWM直流电机调速系统设计过程1.确定电机类型和参数:根据实际需要确定使用的直流电机类型和技术参数,包括额定电压、额定转速、功率等。

2.选择传感器:根据调速要求选择合适的传感器,常用的有霍尔传感器和编码器。

3.设计控制器:根据电机类型和传感器选择合适的控制器,设计比较器、计数器、时钟和PWM发生器电路,并进行连线连接。

4.设计功率电源:根据控制器和电机的电压和电流要求设计适当的功率电源电路。

5.总结设计参数:总结所选器件和电路的技术参数,确保设计完整。

三、PWM直流电机调速系统实施步骤1.进行电路连线:根据设计图将所选器件和电路进行连线连接,包括控制器、传感器、电机和功率电源。

2.进行参数调整:根据需要进行控制器参数的调整,如比较器的阈值、计数器的初始值等。

3.进行调速测试:连接电源后,通过用户输入信号和传感器反馈信号进行调速测试。

根据测试结果进行参数调整。

4.优化系统性能:根据测试结果优化系统性能,如改进控制器参数、调整电机参数等。

单片机控制PWM的直流电机调速系统的设计

单片机控制PWM的直流电机调速系统的设计

单片机控制PWM的直流电机调速系统的设计PWM(脉宽调制)是一种常用的电压调节技术,可以用来控制直流电机的转速。

在单片机控制PWM的直流电机调速系统中,主要包括硬件设计和软件设计两个方面。

硬件设计方面,需要考虑的主要内容有:电机的选择与驱动、电源电压与电流的设计、速度反馈电路的设计。

首先,需要选择合适的直流电机和驱动器。

选择直流电机时需考虑其功率、转速、扭矩等参数,根据实际需求选择合适的电机。

驱动器可以选择采用集成驱动芯片或者离散元件进行设计,通过PWM信号控制电机的速度。

其次,需要设计合适的电源电压与电流供应。

直流电机通常需要较大的电流来实现工作,因此需要设计合适的电源电流,以及保护电路来防止电流过大烧坏电机和电路。

最后,需要设计速度反馈电路来实现闭环控制。

速度反馈电路可以选择采用编码器等传感器来获得转速信息,然后通过反馈控制实现精确的速度调节。

软件设计方面,需要考虑的主要内容有:PWM输出的控制、速度闭环控制算法的实现。

首先,需要编写代码实现PWM输出的控制。

根据具体的单片机型号和开发环境,使用相关的库函数或者寄存器级的编程来实现PWM信号的频率和占空比调节。

其次,需要实现速度闭环控制算法。

根据速度反馈电路获取的速度信息,通过比较目标速度与实际速度之间的差异,调整PWM信号的占空比来实现精确的速度调节。

常用的速度闭环控制算法有PID控制算法等。

最后,需要优化程序的鲁棒性和稳定性。

通过合理的调节PID参数以及增加滤波、抗干扰等功能,提升系统的性能和稳定性。

在实际的设计过程中,需要根据具体的应用需求和单片机性能等因素,进行合理的选择和调整。

同时,还需要通过实验和调试来验证系统的可靠性和稳定性,不断进行优化和改进,以获得较好的调速效果。

STM8的C语言编程(14) PWM

STM8的C语言编程(14)   PWM
TIM2_CCMR2 = TIM2_CCMR2 | 0x70;// Output mode PWM2. // 通道 2 被设置成比较输出方式 // OC2M = 111,为 PWM 模式 2, // 向上计数时,若计数器小于比较值,为无效电平 // 即当计数器在 0 到比较值时,输出为 1,否则为 0
// 程序描述:用 PWM 输出驱动 LED
#include "STM8S207C_S.h"
void CLK_Init(void); void TIM_Init(void);
// 函数功能:延时函数 // 输入参数:ms -- 要延时的毫秒数,这里假设 CPU 的主频为 2MHZ // 输出参数:无 // 返 回 值:无 // 备 注:无 void DelayMS(unsigned int ms)
DelayMS(5);
}
// 下面的循环将占空比逐渐从 50%递减到 0
for(i=128;i>0;i--) {
TIM2_CCR2H = 0; TIM2_CCR2L = i; DelayMS(5); } } }
TIM2_ARRH = 0; TIM2_ARRL = 0xFF;
//初始化比较寄存器,决定 PWM 方波的占空比 TIM2_CCR2H = 0; TIM2_CCR2L = 0;
// 初始化时钟分频器为 1,即计数器的时钟频率为 Fmaster=4MHZ TIM2_PSCR = 0;
// 启动计数 TIM2_CR1 = TIM2_CR1 | 0x01;
{
CLK_CKDIVR = 0x11;
// 10: fHSI = fHSI RC output/ 4
//
= 16MHZ / 4 =4MHZ

单片机输出PWM温控程序C语言代码

单片机输出PWM温控程序C语言代码

单片机PWM温控C语言程序部分代码#include <reg52.h>#include <at89x52.h>#include <keyscan.h>extern void scan_full(void);extern unsigned char key_scan(void);extern bit key_ok;unsigned char pwm_set,key_value;unsigned char count;sbit PWM=P3^6; //将PWM定义为P3口的第六位?bit up,down,set_flag;unsigned char code BCD[]={0x3f,0x06,0x5b,0x4f, //此处是将0-F转换成0x66,0x6d,0x7d,0x07, //相应的BCD码0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};void delay1(unsigned char t){while(t--);}void pwm(void) interrupt 5//定时器2产生PWM波形{TF2=0; //定时器2的溢出标志要软件清除,//但当RCLK或TCLK为1时由硬件清除if((count>=pwm_set)&amt;&amt;(count<10))PWM=1;elsePWM=0;count++;if(count==10)count=0x00;}void key_pwm(unsigned char x)//把键值转化为PWM设置值{switch(x) //把矩阵键盘转化为独立键盘{case 1:up=1;break;case 2:down=1;break;case 3:set_flag=!set_flag;break;default:break;}//设置PWM参数:pwm_setif(up&amt;&amt;set_flag){pwm_set++;up=0;if(pwm_set>=10)pwm_set=0x00;}if(down&amt;&amt;set_flag){pwm_set--;down=0;if(pwm_set==0xff) //减到-1?pwm_set=9;}if(!set_flag){up=0;down=0;}}void main(void){TH2=0xb1; //定时20MSTL2=0xe0;RCAP2H=0xb1;//定时器2溢出会把该单元内容送到TH2和TL2 RCAP2L=0xe0;EA=1;ET2=1;TR2=1;while(1){scan_full(); //看是否有键按下if(key_ok) //有键按下,则判断到底是哪个键按下{key_value=key_scan();//键值送key_value暂存P0=~BCD[key_value]; /*此三句是将键值显示出来*/P2=0xfe;delay1(200);key_pwm(key_value); //调用键值转PWM设置参数函数key_value=0x00; //清除键值,以免一次按下,多次响应}P0=~BCD[pwm_set]; /***此三句是将pwm_set值显示出来*/P2=0xfd;delay1(200);}}#include <reg52.h>//#include <at89x52.h>//unsigned char code BCD[]={0x3f,0x06,0x5b,0x4f, //此处是将0-F转换成//相应的BCD码 :// 0x66,0x6d,0x7d,0x07,// 0x7f,0x6f,0x77,0x7c,// 0x39,0x5e,0x79,0x71};//unsigned char code KEY[]={0x00,0x00,0x01,0x02,0x03,//此处是为使程序通用,当键值不是按// 0x04,0x05,0x06,0x07,//这个排列时,把此表更改即可// 0x08,0x09,0x0a,0x0b,//最前面的那个0x00是为了查表方便,// 0x0c,0x0d,0x0e,0x0f};//因为键值是从1开始的sfr key_port=0x90; //定义P1口为键盘扫描口bit key_ok=0; //有键按下的标志/*************延时子程序*****************调用一次用时18微秒,t每加1,用时增加6微秒*/void delay(unsigned char t){while(t--);}unsigned char r_left(unsigned char x)//循环左移一位{x<<=1;x++;return(x);}/*************粗判有无键按下**************有键按下则将key_ok置1************/void scan_full(void){unsigned char temp;key_port=0xf0; //低半字节为行线,高半字节为列线temp=P1;if(temp!=0xf0)key_ok=1;elsekey_ok=0;}/************键盘扫描程序*****************************功能:返回键值,当无键按下时,返回0*************/unsigned char key_scan(void){unsigned char temp,count=0x01,key_value;//按键返回值unsigned char x_scan=0xfe,y_scan=0xef;//行、列扫描码unsigned char i,j,y; //行数和列数while(1){scan_full(); //粗判是否有键按下if(key_ok==1){key_ok=0;delay(200); //延时去抖动scan_full(); //再次粗判是否有键按下if(key_ok==1){for(i=0;i<4;i++) //扫描4行{key_port=x_scan;for(j=0;j<4;j++) //每行4列{temp=key_port;temp=temp&amt;0xf0;y=y_scan&amt;0xf0;if(temp==y){while(key_ok!=0)//等待按键松开{scan_full();}key_value=count;return(key_value);//找到键值,马上返回}else{count++;y_scan=r_left(y_scan);}}y_scan=0xef; //扫描完一列,重新对列扫描量赋初值x_scan=r_left(x_scan);//行扫描码左移一位,扫描下一行}}}return(key_value);//没键按下,返回0}}//unsigned char key(void)//{// unsigned char x;// unsigned char y;// x=key_scan();// return(x);// y=KEY[x];// return y;//}。

第三章无刷直流电动机PWM控制方案

第三章无刷直流电动机PWM控制方案

第三章无刷直流电动机PWM控制方案无刷直流电动机是目前应用广泛的电动机之一,其具有高效率、高功率密度和长寿命的特点。

PWM(Pulse Width Modulation)是一种常用的控制技术,可以实现对无刷直流电动机的精确控制。

本文将详细介绍PWM 控制方案在无刷直流电动机中的应用。

1.PWM控制原理PWM控制是通过调整开关器件的开通时间来控制电压的有效值,从而实现对无刷直流电动机的控制。

PWM控制的主要原理是将直流供电通过开关器件进行快速切换,使得电机得到一个等效的可调的直流电,从而实现对电动机的控制。

(1)基于单脉冲宽度调制(SPWM)的控制方案SPWM是一种常见的PWM调制技术,其基本思想是将待调制的模拟信号与一个高频的三角波进行对比,通过比较得到一个等效的PWM信号。

在无刷直流电动机中的应用,SPWM控制方案可以实现对电机的速度和转矩的控制。

(2)基于矢量控制的控制方案矢量控制是一种高级的PWM控制技术,可以实现对无刷直流电动机的精确控制。

它通过对电流矢量的调整来实现对电机的转速和转向的控制。

矢量控制具有较高的动态性能和响应速度,能够实现电机的高效运行。

(3)基于空间矢量调制(SVM)的控制方案SVM是一种高级的PWM调制技术,可以实现对无刷直流电动机的高精度控制。

它通过对电流矢量的调整来实现对电机的速度和转矩的控制。

SVM控制具有较高的输出电流质量,让电机运行更加稳定和高效。

3.PWM控制的优势(1)高效率:PWM控制可以实现对电机的高效率控制,可以根据需要调整输出电压和电流,从而使电机运行在最佳点。

(2)高精度:PWM控制可以实现对电机的精确控制,可以根据需要调整输出电压和电流的波形,从而实现对电机速度和转矩的精确控制。

(3)稳定性好:PWM控制可以减小电机的振动和噪声,从而使电机运行更加平稳和稳定。

4.PWM控制的应用(1)工业应用:PWM控制广泛应用于各类工业设备中,如机械加工、自动化生产线等,可以实现对电机的高精度控制,提高生产效率。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
else
{
PWM=1;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
}
}
}
void Timer1() interrupt 3
{
TH1=0x4c;
TL1=0x00;
Tcount++;
if(Tcount==20)
{
Tcount=0;
now=a;
i++;
if(i==10)
key_scan();
change();
}
}
基于89C51的pwm
#include "reg52.h"
#include "intrins.h"
#define uc unsigned char
uc deasil;//顺时针
uc widdershins;//逆时针
uc start,up; //停止
uc key_value,a,Tcount,temp;
samp=a;
if(i>100)
i=90;
a=0;
}
}
void exter() interrupt 0
{
a++;
}
//***********键盘扫描****************************
//函数名称:void Timer0() interrupt 1 using 1
//函数功能:计时
{
P2=temp;//送列扫描码
if((P2&0xf0)!=00xf0;//得出行编码
line=i-1;//计算出列值
break;
}
temp=(temp<<1)|0x01;//进行下一列扫描
}
switch(key_code)//根据行编码得出行值
{
case 0xe0: row=3;break;
pwm=pwm-500;
if(pwm<0)
pwm=0;
}
}
void init()
{
TMOD=0x11;
TR0=1;
ET0=1;
TH1=0x4c;
TL1=0x00;
TR1=1;
ET1=1;
IT0=1;
EX0=1;
EA=1;
PWM=1;
}
void main()
{
init();
while(1)
{
display();
//参数说明:
//***********************************************
void key_scan(void)
{
unsigned char key_code;//键盘行编码
unsigned char row=0;//行值
unsigned char line=0;//列值
////////////////延时子程序//////////////////////
void delay(unsigned int delay_time)
{
uc i;
while(delay_time--)
{
for(i=0;i<125;i++)
;
}
//延时8+6*delay_time us
}
void display()
{
uc i,temp;
temp=0xfe;
buf[0]=now%1000%100%10;
buf[1]=now%1000%100/10;
buf[2]=now%1000/100;
buf[3]=now/1000;
for(i=0;i<4;i++)
{
P0=seg[buf[i]];
P1=temp;
temp=_crol_(temp,1);
{
PWM=0;
TH0=(65536-40000)/256;
TL0=(65536-40000)%256;
}
}
if(deasil==1)//shun时针转
{
if(PWM==1)
{
PWM=0;text=1;text1=1;
TH0=(65536-10000-pwm)/256;
TL0=(65536-10000-pwm)%256;
unsigned char temp=0xfe;//列扫描码
unsigned char i;
P2=0xf0;//P2口赋初值,准备进行行,列扫描
if((P2&0xf0)!=0xf0)//表示有键按下
{
delay(10);//
if((P2&0xf0)!=0xf0)//表明确实有键按下,进行键盘扫描
{
for(i=4;i>0;i--)//列扫描
case 0xd0: row=2;break;
case 0xb0: row=1;break;
case 0x70: row=0;break;
default: break;
}
key_value=row*4+line;//根据行,列值计算出键值
}
deasil=key_value;
widdershins=key_value;
uc ge,shi,bai,qian,i,samp,now;
uc code seg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
int pwm;
uc buf[10];
sbit PWM=P3^7;
sbit text=P3^6;
sbit text1=P3^5;
start=key_value;
while((P2&0xf0)!=0xf0){//等待按键释放
display();
}
}
}
void change()
{
if(samp>now)
{
text=0;
pwm=pwm+500;
if(pwm>57500)
pwm=57500;
}
if((now-3)>samp)
{
text1=0;
}
else
{
PWM=1;
TH0=(65536-40000)/256;
TL0=(65536-40000)%256;
}
}
if(start==3)//
{
if(PWM==1)
{
PWM=0; text=1;text1=1;
TH0=(65536-40000)/256;
TL0=(65536-40000)%256;
delay(4);
}
}
void Timer0() interrupt 1
{
if(widdershins==2)//逆时针转
{
if(PWM==0)
{
PWM=1;text=1; text1=1;
TH0=(65536-10000-pwm)/256;
TL0=(65536-10000-pwm)%256;
}
else
相关文档
最新文档