直流电机控制Keil c51源代码
51单片机C源代码直流电机
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Time1Config()
*******************************************************************************/
void Time1(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号 0 外部中断1 2 外部中断2 4 串口中断
{
TH1 = 0xFE; //重新赋初值
TL1 = 0x0C;
timer1++;
}
#include <reg52.h>
//--定义使用的IO口--//
sbit PWM=P1^0;
//--定义一个全局变量--//
unsigned char timer1;
void Time1Config();
/*******************************************************************************
}
/*******************************************************************************
* 函 数 名 : Time1
* 函数功能 : 定时器1的中断函数
* 输 入 : 无
* 输 出 : 无
{
通过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则反转(电路实现)。
基于单片机的直流电机控制系统程序代码
基于单片机的直流电机控制系统程序代码#include#define unchar unsigned char#define unint unsigned int#define SW1 0x2e#define SW2 0x2d#define SW3 0x2b#define SW4 0x27#define SW5 0x0f#define ZHENGZHUAN 0#define FANZHUAN 1#define TINGZHI 2#define JIASU 3#define JIANSU 4unsigned char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x84,0xff,0xf7};//显示代码unsigned char dispbitcode[]={0x7f,0xbf,0xdf,0xef};//位选口unsigned char dispbuf[4]={0,0,0,0};unsigned char dispbitcnt;unint i;unchar tp=0;unint count=0;unint n=0;unint xs;unint m;unchar keyvalue;sbit p07=P0^7;sbit P30=P3^0;sbit P31=P3^1;sbit P37=P3^7;sbit P10=P1^0;sbit P11=P1^1;sbit P12=P1^2;sbit P13=P1^3;sbit P15=P1^5;void ledshow();unsigned char keyscan();void delay();void zhengzhuan();void fanzhuan();void tingzhi();void jiasu();void jiansu();void t0(void);void INT_0(void);void Timer_1(void);//主程序void main(void){P30=1;P31=0;TMOD=0x12;//内部中断定时器选择TH0=0x66;//50ms定时TL0=0x50;EA=1;//开中断总开关ET0=1;//开内部中断0ET1=1;//开内部中断1TR0=1;//定时器开始工作TR1=1;//计时器开始工作IT0=1;//外部中断0为下降沿触发EX0=1;//开外部中断0while(1){ledshow();//数码管显示keyvalue=keyscan();//键盘扫描switch(keyvalue){case ZHENGZHUAN://正转模块zhengzhuan();break;case FANZHUAN://反转模块fanzhuan();break;case TINGZHI://停止模块tingzhi();break;case JIASU://加速模块jiasu();break;case JIANSU://减速模块jiansu();break;default: break;}}}//延时20ms程序void delay(){unsigned char i,j;for(i=1;i<=125;i++)for(j=1;j<=50;j++) {}}//键盘扫描程序unsigned char keyscan() {unchar temp=0;P1=0xff;if((P1&0x2f)!=0x2f) {delay();if((P1&0x2f)!=0x2f) { temp=P1&0x2f; switch(temp){case SW1:return 0;break;case SW2:return 1;break;case SW3:return 2;break;case SW4:return 3;break;case SW5:return 4;break;default:break; }}}while((P1&0x2f)!=0x2f);}//数码管显示程序void ledshow(){P2|=0xf0;P0=dispcode[dispbuf[0]]; P2=0xef;for(i=0;i<700;i++);P2|=0xf0;P0=dispcode[dispbuf[1]]; P2=0xdf;p07=0;for(i=0;i<700;i++);P2|=0xf0;P0=dispcode[dispbuf[2]]; P2=0xbf;for(i=0;i<700;i++);P2|=0xf0;P0=dispcode[dispbuf[3]]; P2=0x7f;for(i=0;i<700;i++); dispbuf[3]=xs/1000; dispbuf[2]=(xs%1000)/100;dispbuf[1]=(xs%100)/10; dispbuf[0]=xs%10;}//中断服务程序//pWM调速脉冲中断程序void t0(void)interrupt 1 using 0 { if(count>100)count=0;if(count>tp)P37=0;else P37=1;count++;}//外部中断0计数程序void INT_0(void) interrupt 0 { EX1=0;//关外部中断0n++;//转圈计数加1EX1=1;//开外部中断0}//内部中断1计时计数程序void Timer_1(void) interrupt 3 { TH1=0x65;//50ms定时TL1=0xF3;m++;if(m==20)//50*20=1S{xs=(n*10)/4;m=0;n=0;}}//模块程序void zhengzhuan() {P30=1;P31=0;}void fanzhuan() {P30=0;P31=1;}void tingzhi() {P30=0;P31=0;}void jiasu(){if(tp>99)tp=100;else tp=tp+2;}void jiansu(){if(tp<1)tp=0;else tp=tp-2;}。
c51单片机C语言编写的PWM程序
89c51单片机C语言编写的P W M程序(共3页)-本页仅作为预览文档封面,使用时请删除本页-89c51单片机C语言编写的PWM程序PWM, 单片机, C语言, 程序, 编写分享到:新浪微博 QQ空间开心网人人网说明:本程序使用STC89C52RC单片机,晶振,要使用本程序需要自己修改,我是用来控制直流电机的,外接了L298驱动电路,有问题或意见请回复,谢谢^_^#include ""#include ""转;speed<0.反转(-100~100)调用:extern int abs(int val); 取绝对值返回:/******************************************************************/ void motor(char speed1,char speed2){ //==============左边电机============= if (speed1>0) { IN1 =0;IN2 =1;//正转} else if (speed1<0) { IN1 =1;IN2 =0;//反转}//==============右边电机============= if (speed2>0) { IN3 =1;IN4 =0;//正转} else if (speed2<0) { IN3 =0;IN4 =1;//反转}}/******************************************************************名称:motor_PWM();功能:PWM占空比输出参数:无调用:无返回:无/******************************************************************/void motor_PWM (){ uchar PWM_abs1; uchar PWM_abs2;PWM_abs1=MOTO_speed1; PWM_abs2=MOTO_speed2;if (PWM_abs1>PWMAnd) ENA=1; //左边电机占空比输出else ENA=0; if (PWM_abs2>PWMAnd) ENB=1; //右边电机占空比输出else ENB=0; if (PWMAnd>=PWM_COUST) PWMAnd=0; //PWM计数清零else PWMAnd+=1;}/******************************************************************名称:void TIME_Init ();功能:定时器初始化指令:调用:无返回:无/******************************************************************/void TIME_Init (){//=========定时器T2初始化 PWM==================T2CON = 0x00;T2MOD = 0x00;RCAP2H = 0xff; //定时RCAP2L = 0x47; TH2 = 0xff; TL2 = 0x47; ET2 = 1; //定时器2中断开TR2 = 1; //PWM定时器关,PWM周期为10ms }/******************************************************************名称:void PWM_Time2 () interrupt 5功能:T2中断,PWM控制参数:调用:motor_PWM();//PWM占空比输出返回:/******************************************************************/ void PWM_Time2 () interrupt 5{ TR2 = 0; TF2 = 0; ET2 = 0; //定时器0中断禁止motor_PWM();//PWM占空比输出ET2 = 1; //定时中断0开启TR2 = 1;}main(){TIME_Init () ;motor(50,50);//左右电机的转速都是50}。
步进电机和直流电机控制系统C51程序设计(1)
//步进电机控制实验#include <reg51.h>//添加特殊功能寄存器变量定义头文件#include <absacc.h>//添加绝对宏定义头文件#define uchar unsigned char#define uint unsigned int#define D8279 XBYTE[0xE000] //定义8279数据口地址变量#define C8279 XBYTE[0xE001] //定义8279控制口地址变量#define DISPLAY_BUFFER DBYTE [0x70] //定义单片机显示缓冲器首地址变量uchar code TABLE[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, //定义显示码数据表0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x73,0x3E,0x40,0x6E,0x76,0x38,0x00,0x80};uchar code KEY_DA TA[]={0x00,0x08,0x10,0x18,0x01,0x09,0x11,0x19, //定义键值数据表0x02,0x0a,0x12,0x1a,0x03,0x0b,0x13,0x1b};uchar data M_state,M_Code,Timer; //定义电机状态变量、步进电机状态编码变量、软件定时器变量bit Key_in; //定义按键状态变量sbit A_7=ACC^7; //定义8279初始化状态变量void Init_8279();//声明8279初始化函数void Disp();//声明显示函数uchar Get_Key();//声明键盘扫描函数void Timer0_Int();//声明T0中断函数main(){uchar data *ptr=&DISPLAY_BUFFER;//定义显示缓冲区指针变量及其初始化uchar data i,Key_Num;//定义循环计数、键号变量P1=0x03;//初始化P1口M_state=0;//初始化状态变量M_Code=0x33;//初始化电机状态编码变量Init_8279();//调用8279初始化函数TMOD=0x01;TH0=0xEE;TL0=0x00;//定时器T0初始化EA=1;ET0=1;TR0=0;//中断系统初始化for (i=0;i<=7;i++)//显示缓冲区初始化{*ptr=0;ptr++;}Key_in=0;//按键状态变量初始化Disp();//调用显示函数LOOP://主程序循环体do{Key_Num=Get_Key();}while(!Key_in);//如果没有键按下,则不断巡视键是否按下。
8051单片机控制步进电机的C51语言编写的PWM控制程序
8051单片机控制步进电机的C51语言编写的PWM控制程序#include <intrins.h>#include <stdio.h>#include <math.h>#include "UPSD3200.H"#include "upsd_pwm.h"#define uint unsigned int#define uchar unsigned charPSD_REGS PSD8xx_reg _at_ csiop;#define KEYIO (~(PSD8xx_reg.DATAIN_A)) & 0x07sbit CP=P4^7;sbit U_D=P1^1;void init_system(); // 系统初始化uchar keyboard();void uPSD_PWM4_Variable(unsigned char PWM_Period, unsigned char PWM_PulseWidth); uchar Adjust_station=NO;unsigned char data x,flag;unsigned char keyboard() //键盘输入{unsigned char a=0xff,b=0x01,c=0xf8,d;//有按键的位置uint i;do{a=KEYIO|c;}while(a==0xff);if (a == 0xfe){d = '1';}else if (a == 0xfd){d = '2';}else if (a == 0xfb){d = '3';}else {d = '0';}return(d);}void uPSD_PWM4_Init(void)unsigned int PWM_prescaler;P4SFS |= 0x80;PWM_prescaler = (unsigned int)((FREQ_OSC/2)/PWM4_INPUT_freq);//PWM4输入脉冲频率K PSCL1L = PWM_prescaler & 0x00ff;PSCL1H = (PWM_prescaler >> 8);}void StepMotor_GO(bit direction,uint speed) {unsigned char PWM_Period, PWM_PulseWidth;uint temp_uint;U_D = direction;//方向temp_uint = (PWM4_INPUT_freq*1000)/speed;PWM_Period = (unsigned char)temp_uint;PWM_PulseWidth = PWM_Period/2;uPSD_PWM4_Variable(PWM_Period,PWM_PulseWidth);}void StepMotor_STOP(void){P4SFS &= 0x7f;}void uPSD_PWM4_Variable(unsigned char PWM_Period, unsigned char PWM_PulseWidth) {P4SFS |= 0x80;PWMVP = PWM_Period;PWMVPW = PWM_PulseWidth;PWMCON |= 0x20;}void initkey(void){PSD8xx_reg.DATAOUT_A=0xFF;PSD8xx_reg.CONTROL_A=0x00;PSD8xx_reg.DIRECTION_A=0x00;}void init_system() // 系统初始化{WDKEY=0x55;P4SFS = (unsigned char) (0x08 << 3);uPSD_PWM_Channel_8bit(3,243);问题补充:(接着上面的序)void uPSD_PWM_Init_8bit(unsigned char PWM_channel_no, unsigned int PWM_freq8, unsigned char PWMCON_value){unsigned int PWM_prescaler;unsigned char output_polarity_mode;output_polarity_mode = PWMCON_value & 0x8F;PWMCON = (PWMCON & 0x70) | output_polarity_mode;P4SFS = (unsigned char) (0x08 << PWM_channel_no);PWM_prescaler = (unsigned int) ( (((unsigned int) FREQ_OSC) / 2) / PWM_freq8);PSCL0L = PWM_prescaler & 0x00ff;PSCL0H = (PWM_prescaler >> 8);PSCL1L = PWM_prescaler & 0x00ff;PSCL1H = (PWM_prescaler >> 8);}void uPSD_PWM_Disable(void){PWMCON &= 0xDF;}void main(void){x=0;init_system();flag=1;while(flag==1){x=keyboard();if(x=='1') {StepMotor_GO(0,100);}else if(x=='2') {StepMotor_GO(1,500);}else if(x=='3') { StepMotor_STOP();uPSD_PWM_Disable();} else if(x=='0') {uPSD_PWM_Disable();}}}。
C语言控制直流电机步进电机
{
unsigned int i;
for(; t > 0; t--)
{
for(i = 0; i < 125; i++); //1ms
}
}
/*************************************************************************************/
#endif
/***********************************************************************/
/***********************************************************************/
}
//**********************//
//控制驱动芯片函数
//**********************//
void execute_motor()
{
switch(motor_change_mank)
{
case 0: //刹停标志位
{
IN1 = 1;
IN2 = 1;
ENA = 1;
}break;
case 1://正转标志位
{
IN1 = 1;
IN2 = 0;
ENA = 1;
}break;
case 2: //反转标志位
{
IN1 = 0;
IN2 = 1;
ENA = 1;
}break;
default:break;
}
}
//**********************//
51单片机控制直流电机设计
51单片机控制直流电机设计51单片机是一种常用的单片机,广泛应用于嵌入式系统中。
在直流电机控制方面,51单片机可以通过控制IO口输出高低电平来控制电机的转动方向和速度。
本文将介绍如何使用51单片机控制直流电机,并进行详细的设计过程。
一、硬件设计1.电源部分直流电机通常需要较高的电压才能正常运转,因此需要设计一个稳定的电源电路。
可以使用稳压电源模块或者线性稳压电源芯片作为电源模块,并根据电机的额定电压选择合适的电源电压。
2.驱动电路直流电机需要通过驱动电路来控制其转动方向和速度。
驱动电路可以使用电机驱动模块,如L298N驱动模块或者H桥驱动芯片等。
根据电机的额定电流选择合适的驱动模块,并连接正确的引脚。
3.51单片机与驱动模块连接将51单片机的IO口与驱动模块的控制引脚相连,以实现对电机的控制。
通常情况下,驱动模块的使能引脚需要接高电平使能驱动电路,转向引脚控制电机的转向,速度引脚控制电机的转速。
4.电机连接将直流电机的两根引线与驱动模块的输出端相连,确保极性正确。
二、软件设计1.51单片机初始化首先,在主函数中进行51单片机的初始化,包括设置IO口的输入输出方向、初始化定时器等。
2.设置电机转动方向通过控制驱动电路的转向引脚,可以控制电机的正转和反转。
通过设置IO口输出不同的高低电平即可实现。
3.设置电机转动速度通过占空比控制电机的转速,可以使用定时器来设置。
4.电机控制代码我们可以通过编写一些函数来实现电机的控制,例如设置方向的函数、设置速度的函数等。
然后在主函数中调用这些函数来实现电机的控制。
三、实际控制测试在完成硬件设计和软件编写后,可以将51单片机与电源和电机连接起来,并上传软件代码。
然后通过触发相应的输入信号,来控制电机的方向和速度。
通过观察电机的运动情况,可以验证电机控制系统的正确性。
总结本文介绍了51单片机控制直流电机的设计过程,包括硬件设计和软件设计。
通过控制IO口输出高低电平来实现电机的转动方向和速度。
直流电机控制Keil c51源代码
直流电机控制Keil c51源代码直流电机的开环控制Keil c51源代码//-----------------------函数声明,变量定义--------------------------------------------------------#include <reg51.h>#include <intrins.h>#include<ABSACC.H>//-----------------------定义管脚--------------------------------------------------------sbit PWM=P1^0; //PWM波形输出sbit DR=P1^1; //方向控制#define timer_data (256-100) //定时器预置值,12M时钟是,定时0.1ms#define PWM_T 100 //定义PWM的周期T为10msunsigned char PWM_t; //PWM_t为脉冲宽度(0~100)时间为0~10msunsigned char PWM_count; //输出PWM周期计数unsigned char time_count; //定时计数bit direction; //方向标志为//--------------------------------------------------------------------------------------------------// 函数名称:timer_init// 函数功能:初始化设施定时器//--------------------------------------------------------------------------------------------------void timer_init(){TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */ PCON=0x00;TF0=0;TH0=timer_data; //保证定时时长为0.1msTL0=TH0;ET0=1;TR0=1; //开始计数EA=1; //中断允许}//--------------------------------------------------------------------------------------------------// 函数名称:setting_PWM// 函数功能:设置PWM的脉冲宽度和设定方向//--------------------------------------------------------------------------------------------------void setting_PWM(){if(PWM_count==0) //初始设置{PWM_t=20;direction=1;}}//--------------------------------------------------------------------------------------------------// 函数名称:IntTimer0// 函数功能:定时器中断处理程序//--------------------------------------------------------------------------------------------------void IntTimer0() interrupt 1{time_count++;DR=direction;if(time_count>=PWM_T){time_count=0;PWM_count++;setting_PWM(); //每输出一个PWM波调用一次}if(time_count<PWM_t)PWM=1;elsePWM=0;}//--------------------------------------------------------------------------------------------------// 函数名称:main// 用户主函数// 函数功能:主函数//--------------------------------------------------------------------------------------------------void main(){timer_init();setting_PWM();}直流电机闭环控制Keil c51源代码//-----------------------函数声明,变量定义-------------------------------------------------------- #include <reg51.h>sbit INT_0 =P3^2; // 将p3.2外部中断0sbit pulse_A=P1^2; // P1.2为脉冲A输入sbit PWM=P1^0; //PWM波形输出sbit DR=P1^1; //方向控制//-----------------------预定义值--------------------------------------------------------#define PWM_T 1800 //定义PWM的周期T为18ms#define Ts 1000 //定义光电编码器采样时间为10ms#define timer_data (256-10) //定时器预置值,12M时钟是,定时0.01ms//-----------------------预设定值--------------------------------------------------------bit direction; //方向标志位用户设定unsigned char R; //需要得到的直流电机转速用户设定//-----------------------实际运行状态--------------------------------------------------------bit real_direction; //电机实际运行方向unsigned char Rr; //直流电机实际转速//-----------------------计算所得补偿状态------------------------------------------bit compensate_polarity; //补偿极性unsigned char dR; //转速补偿//-----------------------经补偿后得到的脉宽------------------------------------------unsigned char PWM_t; //PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms unsigned char PWM_count; //输出PWM周期计数//-----------------------各中间计数值------------------------------------------unsigned char pulseB_count; //脉冲计数unsigned char time0_count; //定时计数unsigned char time1_count; //定时计数//--------------------------------------------------------------------------------------------------// 函数名称:timer_init// 函数功能:初始化设置定时器//--------------------------------------------------------------------------------------------------void timer_init(){TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */ PCON=0x00;TF0=0;TH0=timer_data; //保证定时时长为0.01msTL0=TH0;TH1=timer_data; //保证定时时长为0.01msTL1=TH0;ET0=1; //定时器0中断允许TR0=1; //定时器0开始计数ET1=1; //定时器1中断允许TR1=1; //定时器1开始计数EA=1; //中断允许}//-------------------------------------------------------------------------------------------------- // 函数名称:INT0_init()// 函数功能:初始化设置// 设定INT0的工作方式//-------------------------------------------------------------------------------------------------- void INT0_init(void ){pulseB_count=0; //脉冲计数器清零IT0=1; //选择INT0为沿触发方式EX0=1; //外部中断允许EA=1; //系统中断允许}//-------------------------------------------------------------------------------------------------- // 函数名称:setting_PWM// 函数功能:设置PWM的脉冲宽度和设定方向//-------------------------------------------------------------------------------------------------- void setting_PWM(){// direction=1; //设定转动方向// R=540; //设定转速// dR=0; //转速补偿为零// calculate_PWM_t(); //重新计算脉宽}//-------------------------------------------------------------------------------------------------- // 函数名称:calculate_PWM_t// 入口参数:R需要得到的直流电机转速,dR转速补偿// 出口参数:PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms// 函数功能:计算脉冲宽度,PWM_t=R/150;//-------------------------------------------------------------------------------------------------- void calculate_PWM_t(){if(compensate_polarity==1) //正补偿PWM_t=(R+dR)/150;elsePWM_t=(R-dR)/150; //负修正}//-------------------------------------------------------------------------------------------------- // 函数名称:calculate_Rr// 入口参数:pulseB_count脉冲计数// 出口参数:Rr直流电机实际转速// 函数功能:计算实际转速//-------------------------------------------------------------------------------------------------- void calculate_Rr(){Rr=pulseB_count/6;}//--------------------------------------------------------------------------------------------------// 函数名称:compensate_dR// 入口参数:Rr直流电机实际转速// R需要得到的直流电机转速// 出口参数:dR转速补偿// 函数功能:计算实际补偿值和补偿极性,根据不同的补偿算法重新设计//-------------------------------------------------------------------------------------------------- void compensate_Rr(){Rr=1;if(Rr>R)compensate_polarity=0; //补偿极性elsecompensate_polarity=1;}//--------------------------------------------------------------------------------------------------// 函数名称:INT0_intrupt// 函数功能:外部中断0处理程序//-------------------------------------------------------------------------------------------------- void INT0_intrupt() interrupt 0 using 1{pulseB_count++;if(pulse_A==0){real_direction=1; //若P1.2为低电平,则电机为正转,计数器N的值加1 }else //若为高电平,则电机为反转,计数器N值减l。
c51直流电机的加减速程序
(基于 L298n 驱动芯片
)
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit k1=P3^0;
sbit k2=P3^1;
sbit k3=P3^2;
sbit k4=P3^3;
//第一个数码管显示正转(1)还是反转(0)
P2=0xfd;
//第二位数码管显示速度标志
P0=table[show_num];
delay(5);
P2=0xfb; P0=table[0]; delay(5);
// 显示 0
P2=0xf7;
//
显示 0
P0=table[0];
delay(5);
}
void dispose()
case 3: show_num=4;
gao_num=4; di_num=0; break; }
void qudong() { uchar x;
} //控制电机程序
if(num1=1)
//正转占空比调节
{if(di_num!=0)
{
for(x=0;x<=di_num; x++)
{ IN1=0;
//PWM 低电平输出
display();
//显示函数延时
}
}
for(x=0;x<=gao_num;x++ )
{ IN1=1; display();
//PWM 高电平输出
}
}
if(num1=0)
//反转占空比调节
{if(di_num!=0)
基于C51单片机的直流电机PWM调速控制(包含原理图及C源代码)
基于C51单片机的直流电机PWM调速控制--SQ这是最近一阶段自己学习所获,现分享与大家。
这里采用A T89C52单片机做主控制芯片,实现两路直流电机的PWM调速控制,另外还可以实现转向、显示运行时间、显示档位等注:考虑小直流电机自身因素,调速范围仅设有四级电路原理图:C语言程序源代码:/******************** 硬件资源分配*********************/数码管:显示电机状态(启停、正反、速度)、运行时间、是否转弯按键:K4 启动/暂停K3 正反转/转弯允许K2 加速/左转/运行时间清零K1 减速/右转/停止定时器:T0 数码管动态显示,输出PWMT1 运行时间记录********************************************************//*******主程序文件PWM.c******/#include <reg52.h>#include "Afx.h"#include "Config.c"#define CIRCLE 5 //脉冲周期//按键定义uchar key,key_tmp=0, _key_tmp=0;//显示定义uchar LedState=0xF0; //LED显示标志,0xF0不显示,Ox00显示uchar code LED_code_d[4]={0xe0,0xd0,0xb0,0x70}; //分别选通1、2、3、4位uchar dispbuf[4]={0,0,0,0}; //待显示数组uchar dispbitcnt=0; //选通、显示的位uchar mstcnt=0;uchar Centi_s=0,Sec=0,Min=0; //分、秒、1%秒//程序运行状态标志bit MotState=0; //电机启停标志bit DirState=0; //方向标志0前,1后uchar State1=-1;uchar State2=-1;uchar State3=0;uchar State4=-1;uchar LSpeed=0;uchar RSpeed=0;//其他uint RunTime=0;uint RTime_cnt=0;uint LWidth;uint RWidth; //脉宽uint Widcnt=1;uint Dispcnt;//函数声明void key_scan(void);void DisBuf(void);void K4(void);void K3(void);void K2(void);void K1(void);void disp( uchar H, uchar n );void main(void){P1|=0xF0;EA=1;ET0=1;ET1=1;TMOD=0x11;TH0=0xFC;TL0=0x66; //T0,1ms定时初值TH1=0xDB;TL1=0xFF; //T1,10ms定时初值TR0=1;Widcnt=1;while(1){key_scan();switch(key){case 0x80: K1(); break;case 0x40: K2(); break;case 0x20: K3(); break;case 0x10: K4(); break;default:break;}key=0;DisBuf();LWidth=LSpeed;RWidth=RSpeed;}}//按键扫描**模拟触发器防抖void key_scan(void){key_tmp=(~P3)&0xf0;if(key_tmp&&!_key_tmp) //有键按下{key=(~P3)&0xf0;}_key_tmp=key_tmp ;}//按键功能处理/逻辑控制void K4(void){if(State4==-1){State4=1;TR1=1;dispbuf[3]=1;LedState=0x00; //打开LEDMotState=1; //打开电机LSpeed=1;RSpeed=1; //初速设为1}else if(State4==1){State4=0;TR1=0;MotState=0; //关闭电机}else if(State4==0){MotState=1;if(State3==0){State4=1;TR1=1;}else if(State3==1){LSpeed=2;RSpeed=2;}}}void K3(void){if(State4==1)DirState=!DirState;if(State4==0){if(State3==0){State3=1; //可以转向标志1可以,0不可以TR1=1;dispbuf[3]=9;MotState=1;LSpeed=2;RSpeed=2;}else if(State3==1){State3=0;TR1=0;dispbuf[3]=0;MotState=0;}}}void K2(void){if(State4==1&&LSpeed<4&&RSpeed<4){LSpeed++;RSpeed++;}else if(State4==0){if(State3==0){//State4=-1;//LedState=0xF0;MotState=0;Sec=0;Min=0;}else if(State3==1&&LSpeed<4&&RSpeed<4){//TurnState=0;LSpeed=2;RSpeed++;}}}void K1(void){if(State4==1&&LSpeed>1&&RSpeed>1){LSpeed--;RSpeed--;}else if(State4==0){if(State3==0){State4=-1;LedState=0xF0;MotState=0;}else if(State3==1&&LSpeed<4&&RSpeed<4){//TurnState=1;LSpeed++;RSpeed=2;}}}//显示预处理void DisBuf(void){if(RTime_cnt==100){Sec++;RTime_cnt=0;}if(Sec==60){Min++;Sec=0;}if(State4==1){dispbuf[0]=Sec%10;dispbuf[1]=Sec/10;dispbuf[2]=Min;if(!DirState) //正转dispbuf[3]=LSpeed;if(DirState) //反转dispbuf[3]=LSpeed+4;}if(State4==0){if(State3==0){dispbuf[0]=Sec%10;dispbuf[1]=Sec/10;dispbuf[2]=Min;dispbuf[3]=0;}if(State3==1){dispbuf[0]=RSpeed;dispbuf[1]=LSpeed;dispbuf[2]=Min;dispbuf[3]=9;}}}//LED驱动void disp( uchar H, uchar n ){P1=n;P1|=LedState ;P1|=LED_code_d[H];}//T0中断**显示/方波输出void Time_0() interrupt 1{TH0=0xFC;TL0=0x66;Widcnt++;Dispcnt++;//电机驱动/方波输出if(Widcnt>CIRCLE){Widcnt=1;}if(Widcnt<=LWidth)LMot_P=!DirState&&MotState;elseLMot_P=DirState&&MotState;LMot_M=DirState&&MotState;if(Widcnt<=RWidth)RMot_P=!DirState&&MotState;elseRMot_P=DirState&&MotState;RMot_M=DirState&&MotState;//显示if(Dispcnt==5){disp(dispbitcnt,dispbuf[dispbitcnt]);dispbitcnt++;if(dispbitcnt==4){dispbitcnt=0;}Dispcnt=0;}}//T1中断**运行时间void Time_1() interrupt 3{TH1=0xDB;TL1=0xFF;RTime_cnt++;}/******配置文件Afx.h******/#ifndef _AFX_#define _AFX_typedef unsigned char uchar;typedef unsigned int uint;typedef unsigned long ulong;#endif/******IO配置文件Config.c******/#ifndef _Config_#define _Config_#include "Afx.h"#include <reg52.h>//显示定义sbit led=P3^2;//电机引脚定义sbit LMot_P=P2^2; sbit LMot_M=P2^3; sbit RMot_P=P2^0; sbit RMot_M=P2^1;#endif。
keil c51中启动代码详细说明
[ 2006-10-27 18:23:00 | By: CHYB_HSH ]让我们先来看看STARTUP.A51文件(默认设置)吧!根据源文件中的说明文字,我们很容易分析出STARTUP.A51文件的工作方式和作用!让我们把它先汉化一下看看!$NOMOD51;Ax51宏汇编器控制命令:禁止预定义的8051;------------------------------------------------------------------------------; This file is part of the C51 Compiler package; Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.;------------------------------------------------------------------------------; STARTUP.A51: This code is executed after processor reset.; STARTUP.A51: STARTUP.A51文件所生成的代码将在单片机复位后被执行!; To translate this file use A51 with the following invocation:; 将按照下面的命令行语句调用A51编译器进行编译产生目标文件; A51 STARTUP.A51;; To link the modified STARTUP.OBJ file to your application use the following; BL51 invocation:; 将按照下面的命令行语句调用BL51连接器把STARTUP.OBJ定位连接到您的程序代码中; BL51 <your object file list>, STARTUP.OBJ <controls>;;;------------------------------------------------------------------------------;; User-defined Power-On Initialization of Memory; 自定义上电后需要初始化的储存区域; With the following EQU statements the initialization of memory; at processor reset can be defined:; 使用下列EQU伪指令定义初始化的存储区域在单片机复位后定义生效; ; the absolute start-address of IDATA memory is always 0IDATALEN EQU 80H ; the length of IDATA memory in bytes.; IDATA(间接寻址区)其起始地址固定为0;IDA TALEN用于指定需要初始化; 的 IDATA区长度(以字节为单位)*XDATASTART EQU 0H ; the absolute start-address of XDATA memoryXDATALEN EQU 0H ; the length of XDA TA memory in bytes.;XDATA (外部直接寻址区)XDA TASTART用于指定需要初始化的XDA TA区起始地;址 XDATALEN 用于指定需要初始化的XDA TA区长度(以字节为单位)*PDATASTART EQU 0H ; the absolute start-address of PDA TA memoryPDATALEN EQU 0H ; the length of PDATA memory in bytes.;PDA TA(页寻址区)PDATASTART用于指定需要初始化的PDA TA区起始地址;PDATALEN 用于指定需要初始化的;PDATA区长度(以字节为单位)*; Notes: The IDA TA space overlaps physically the DATA and BIT areas of the; 8051 CPU. At minimum the memory space occupied from the C51; run-time routines must be set to zero.;注释:8051中 IDATA 区物理上已经包括了DA TA区(直接寻址区)以及 BIT区(位寻址区)。
C51控制直流电机转速
{
if(K0==1&&K1==0&&K2==0&&K3==0&&K4==0)
{
D0832=0x20;
}
else if(K0==0&&K1==1&&K2==0&&K3==0&&K4==0)
{
D0832=0x40;
}
else if(K0==0&&K1==0&&K2==1&&K3==0&&K4==0)
{
D0832=0x60;
}
else if(K0==0&&K1==0&&K2==0&&K3==1&&K4==0)
{
D0832=0x80;
}
else
{
D0832=0x00;
}
}
void main()
{
for( ; ;)
{
check1();
}
}
#include<absacc.h> //
//#include<intrins.h>
sbit K0=P1^1;//可位寻址的变量,连接开关
sbit K1=P1^2;
sbit K2=P1^3;
sbit K3=P1^6;
sbit K4=P1^5;
#define D0832 XBYTE[0x8000] //8000H接收不同的数字信号
我想用电机停转的延时不同来控制转速用p1口的引脚实现
C51控制直流电机转速
C51控制直流电机转速
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
直流电机的开环控制Keil c51源代码//-----------------------函数声明,变量定义--------------------------------------------------------#include <reg51.h>#include <intrins.h>#include<ABSACC.H>//-----------------------定义管脚--------------------------------------------------------sbit PWM=P1^0; //PWM波形输出sbit DR=P1^1; //方向控制#define timer_data (256-100) //定时器预置值,12M时钟是,定时0.1ms#define PWM_T 100 //定义PWM的周期T为10msunsigned char PWM_t; //PWM_t为脉冲宽度(0~100)时间为0~10msunsigned char PWM_count; //输出PWM周期计数unsigned char time_count; //定时计数bit direction; //方向标志为//--------------------------------------------------------------------------------------------------// 函数名称:timer_init// 函数功能:初始化设施定时器//--------------------------------------------------------------------------------------------------void timer_init(){TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */ PCON=0x00;TF0=0;TH0=timer_data; //保证定时时长为0.1msTL0=TH0;ET0=1;TR0=1; //开始计数EA=1; //中断允许}//--------------------------------------------------------------------------------------------------// 函数名称:setting_PWM// 函数功能:设置PWM的脉冲宽度和设定方向//--------------------------------------------------------------------------------------------------void setting_PWM(){if(PWM_count==0) //初始设置{PWM_t=20;direction=1;}}//--------------------------------------------------------------------------------------------------// 函数名称:IntTimer0// 函数功能:定时器中断处理程序//--------------------------------------------------------------------------------------------------void IntTimer0() interrupt 1{time_count++;DR=direction;if(time_count>=PWM_T){time_count=0;PWM_count++;setting_PWM(); //每输出一个PWM波调用一次}if(time_count<PWM_t)PWM=1;elsePWM=0;}//--------------------------------------------------------------------------------------------------// 函数名称:main// 用户主函数// 函数功能:主函数//--------------------------------------------------------------------------------------------------void main(){timer_init();setting_PWM();}直流电机闭环控制Keil c51源代码//-----------------------函数声明,变量定义-------------------------------------------------------- #include <reg51.h>sbit INT_0 =P3^2; // 将p3.2外部中断0sbit pulse_A=P1^2; // P1.2为脉冲A输入sbit PWM=P1^0; //PWM波形输出sbit DR=P1^1; //方向控制//-----------------------预定义值--------------------------------------------------------#define PWM_T 1800 //定义PWM的周期T为18ms#define Ts 1000 //定义光电编码器采样时间为10ms#define timer_data (256-10) //定时器预置值,12M时钟是,定时0.01ms//-----------------------预设定值--------------------------------------------------------bit direction; //方向标志位用户设定unsigned char R; //需要得到的直流电机转速用户设定//-----------------------实际运行状态--------------------------------------------------------bit real_direction; //电机实际运行方向unsigned char Rr; //直流电机实际转速//-----------------------计算所得补偿状态------------------------------------------bit compensate_polarity; //补偿极性unsigned char dR; //转速补偿//-----------------------经补偿后得到的脉宽------------------------------------------unsigned char PWM_t; //PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms unsigned char PWM_count; //输出PWM周期计数//-----------------------各中间计数值------------------------------------------unsigned char pulseB_count; //脉冲计数unsigned char time0_count; //定时计数unsigned char time1_count; //定时计数//--------------------------------------------------------------------------------------------------// 函数名称:timer_init// 函数功能:初始化设置定时器//--------------------------------------------------------------------------------------------------void timer_init(){TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */ PCON=0x00;TF0=0;TH0=timer_data; //保证定时时长为0.01msTL0=TH0;TH1=timer_data; //保证定时时长为0.01msTL1=TH0;ET0=1; //定时器0中断允许TR0=1; //定时器0开始计数ET1=1; //定时器1中断允许TR1=1; //定时器1开始计数EA=1; //中断允许}//-------------------------------------------------------------------------------------------------- // 函数名称:INT0_init()// 函数功能:初始化设置// 设定INT0的工作方式//-------------------------------------------------------------------------------------------------- void INT0_init(void ){pulseB_count=0; //脉冲计数器清零IT0=1; //选择INT0为沿触发方式EX0=1; //外部中断允许EA=1; //系统中断允许}//-------------------------------------------------------------------------------------------------- // 函数名称:setting_PWM// 函数功能:设置PWM的脉冲宽度和设定方向//-------------------------------------------------------------------------------------------------- void setting_PWM(){// direction=1; //设定转动方向// R=540; //设定转速// dR=0; //转速补偿为零// calculate_PWM_t(); //重新计算脉宽}//-------------------------------------------------------------------------------------------------- // 函数名称:calculate_PWM_t// 入口参数:R需要得到的直流电机转速,dR转速补偿// 出口参数:PWM_t为脉冲宽度(320~400)时间为3.2~4.0ms// 函数功能:计算脉冲宽度,PWM_t=R/150;//-------------------------------------------------------------------------------------------------- void calculate_PWM_t(){if(compensate_polarity==1) //正补偿PWM_t=(R+dR)/150;elsePWM_t=(R-dR)/150; //负修正}//-------------------------------------------------------------------------------------------------- // 函数名称:calculate_Rr// 入口参数:pulseB_count脉冲计数// 出口参数:Rr直流电机实际转速// 函数功能:计算实际转速//-------------------------------------------------------------------------------------------------- void calculate_Rr(){Rr=pulseB_count/6;}//--------------------------------------------------------------------------------------------------// 函数名称:compensate_dR// 入口参数:Rr直流电机实际转速// R需要得到的直流电机转速// 出口参数:dR转速补偿// 函数功能:计算实际补偿值和补偿极性,根据不同的补偿算法重新设计//-------------------------------------------------------------------------------------------------- void compensate_Rr(){Rr=1;if(Rr>R)compensate_polarity=0; //补偿极性elsecompensate_polarity=1;}//--------------------------------------------------------------------------------------------------// 函数名称:INT0_intrupt// 函数功能:外部中断0处理程序//-------------------------------------------------------------------------------------------------- void INT0_intrupt() interrupt 0 using 1{pulseB_count++;if(pulse_A==0){real_direction=1; //若P1.2为低电平,则电机为正转,计数器N的值加1 }else //若为高电平,则电机为反转,计数器N值减l。