PWM直流电机调速仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
Altium Designer画的PWM直流电机调速原理图和PCB图如下:(51hei附件中可下载工程文件)
里面包含PCB封装库文件:
PWM直流电机调速单片机程序如下
- #include <reg51.h>
- #include <intrins.h>
- #include "LCD1602.h"
- #define uchar unsigned char
- #define uint unsigned int
- /**********端口分配*******************************/
- sbit add_key=P1^0; //占空比加
- sbit dec_key=P1^1; //占空比减
- sbit z_key=P1^2; //正转键
- sbit f_key=P1^3; //反转键
- sbit run_key=P1^4; //启动/停止键
-
- sbit beep=P3^2;
- //电机驱动相关
- sbit ENA=P3^5;
- sbit IN1=P3^7;
- sbit IN2=P3^4;
- /**********变量定义*******************************/
- //电机相关定义
- bit Rotation_f=0; //步进电机旋转状态标志 为0正转 1反转
- bit power_flag=0; //总开关标志
- #define PWM_cnt_LEN 100 //计数全长
- #define PWM_ON 1 //开
- #define PWM_OFF 0 //关
- uint PWM_cnt; //PWM计数
- uchar PWM_duty; //PWM占空比
- uint speed_cnt=0; //转速
- uint speed_value;
- bit dis_speed_flag=0;
- uint delay_cnt;
- uchar dis_buf[6];
- uchar dis_cnt;
- uchar dis_buf1[4];
- uchar dis_cnt1;
- /*********定义延时1ms子程序************************/
- void delay1ms(uint t)//1ms延时子程序
- {
- uint k,j;
- for(k=0;k<t;k++)
- for(j=0;j<120;j++);
- }
- /**************************************************/
- /**********蜂鸣器报警**********************/
- void beep_alarm()
- {
- beep=0;
- delay1ms(100);
- beep=1;
- }
- /*******************************************/
- /**********电机停止********************/
- void motor_stop()
- {
- IN1=1;
- IN2=1;
- }
- /***************************************/
- /*******电机正转********************/
- void motor_foreward()
- {
- IN1=1;
- IN2=0;
- }
- /************************************/
- /********电机反转**********************/
- void motor_reversal()
- {
- IN1=0;
- IN2=1;
- }
- /*****************************************/
- /************显示转速*********************/
- void dis_speed()
- {
- dis_cnt=0;
- if(speed_value/10000!=0)
- {
- dis_buf[dis_cnt]=speed_value/10000+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10000/1000+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%1000/100+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%100/10+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10+0x30;
- dis_cnt++;
- }
- else if(speed_value%10000/1000!=0)
- {
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10000/1000+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%1000/100+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%100/10+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10+0x30;
- dis_cnt++;
- }
- else if(speed_value%1000/100!=0)
- {
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%1000/100+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%100/10+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10+0x30;
- dis_cnt++;
- }
- else if(speed_value%100/10!=0)
- {
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%100/10+0x30;
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10+0x30;
- dis_cnt++;
- }
- else
- {
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=' ';
- dis_cnt++;
- dis_buf[dis_cnt]=speed_value%10+0x30;
- dis_cnt++;
- }
- dis_buf[dis_cnt]='\0';
- LCD1602_Print(2,0,dis_buf); //显示转速
- }
- /*****************************************/
- /**********显示占空比*********************/
- void dis_duty()
- {
- dis_cnt1=0;
- if(PWM_duty/100!=0)
- {
- dis_buf1[dis_cnt1]=PWM_duty/100+0x30;
- dis_cnt1++;
- dis_buf1[dis_cnt1]=PWM_duty%100/10+0x30;
- dis_cnt1++;
- dis_buf1[dis_cnt1]=PWM_duty%10+0x30;
- dis_cnt1++;
- }
- else if(PWM_duty%100/10!=0)
- {
- dis_buf1[dis_cnt1]=' ';
- dis_cnt1++;
- dis_buf1[dis_cnt1]=PWM_duty%100/10+0x30;
- dis_cnt1++;
- dis_buf1[dis_cnt1]=PWM_duty%10+0x30;
- dis_cnt1++;
- }
- else
- {
- dis_buf1[dis_cnt1]=' ';
- dis_cnt1++;
- dis_buf1[dis_cnt1]=' ';
- dis_cnt1++;
- dis_buf1[dis_cnt1]=PWM_duty%10+0x30;
- dis_cnt1++;
- }
- dis_buf1[dis_cnt1]='\0';
- LCD1602_Print(9,1,dis_buf1); //显示占空比
- }
- /*****************************************/
- /*************定时器初始化程序*******************/
- void timer_init(void)
- {
- TMOD=0x11; //设置定时器0,1为16位模式
- TH0=0xD8; //10ms定时初值 10ms D8F0
- TL0=0xF0;
- ET0=1; //定时器0中断开
- TR0=1; //开定时器0
- TH1=0xFF; //100us定时初值
- TL1=0x9C;
- ET1=1; //定时器1中断开
- TR1=1; //开定时器1
- EA=1; //总中断开
- }
- /*************************************************/
- /***********定时器0中断服务程序*******************/
- void timer0(void) interrupt 1
- {
- TH0=0xD8; //10ms定时初值 10ms D8F0
- TL0=0xF0;
- delay_cnt++;
- if(delay_cnt>=200) //2S计时
- {
- delay_cnt=0;
- speed_value=speed_cnt*30; //30 将两秒内的计数乘以30得到转每分 (还要除2 因为有两片磁铁) 30/2=15
- speed_cnt=0;
- dis_speed_flag=1;
- }
- }
- /*************************************************/
- /**********外部中断1服务程序**************/
- void int1() interrupt 2
- {
- speed_cnt++; //转速
- }
- /*****************************************/
- /***********定时器1中断服务程序*******************/
- void timer1(void) interrupt 3
- {
- TH1=0xFF; //100us定时初值
- TL1=0x9C;
- if(++PWM_cnt==PWM_cnt_LEN)
- {
- PWM_cnt=0;
- if(power_flag==1)
- ENA=PWM_ON;
- else ENA=PWM_OFF;
- }
- if(PWM_cnt==PWM_duty)
- {
- ENA=PWM_OFF;
- }
- }
- /*************************************************/
- /*******按键处理程序******************************/
- void key_check()
- {
- if(add_key==0) //占空比加
- {
- delay1ms(50);
- if(add_key==0)
- {
- beep_alarm(); //蜂鸣器报警
- PWM_duty++;
- if(PWM_duty>100)
- PWM_duty=100;
- dis_duty(); //显示占空比
- }
- }
- if(dec_key==0) //占空比减
- {
- delay1ms(50);
- if(dec_key==0)
- {
- beep_alarm(); //蜂鸣器报警
- PWM_duty--;
- if(PWM_duty>100)
- PWM_duty=0;
- dis_duty(); //显示占空比
- }
- }
- if(z_key==0) //正转键
- {
- delay1ms(50);
- if(z_key==0)
- {
- beep_alarm(); //蜂鸣器报警
- Rotation_f=0; //步进电机旋转状态标志 为0正转 1反转
- LCD1602_Print(12,0,"pros");
- motor_stop();//电机停止
- delay1ms(1);
- motor_foreward(); //电机正转
- }
- }
- if(f_key==0) //反转键
- {
- delay1ms(50);
- if(f_key==0)
- {
- beep_alarm(); //蜂鸣器报警
- Rotation_f=1; //步进电机旋转状态标志 为0正转 1反转
- LCD1602_Print(12,0,"cons");
- motor_stop();//电机停止
- delay1ms(1);
- motor_reversal(); //电机反转
- }
- }
- if(run_key==0) //启动/停止键
- {
- delay1ms(50);
- if(run_key==0)
- {
- beep_alarm(); //蜂鸣器报警
- power_flag=~power_flag; //总开关标志
- if(power_flag==1)
- {
- if(Rotation_f==0) //步进电机旋转状态标志 为0正转 1反转
- {
- motor_stop();//电机停止
- delay1ms(1);
- motor_foreward(); //电机正转
- }
- else
- {
- motor_stop();//电机停止
- delay1ms(1);
- motor_reversal(); //电机反转
- }
- }
- else motor_stop(); //电机停止
- while(!run_key);//等待按键释放
- }
- }
- }
- /*************************************************/
- /**********************主函数*********************/
- void main()
- {
- PWM_duty=50; //PWM占空比
- timer_init(); //定时器初始化程序
- EX1=1;
- IT1=1;
- LCD1602_init(); //LCD1602液晶初始化
- LCD1602_Print(0,0,"V: 0rpm pros");
- LCD1602_Print(0,1,"PWM_duty: 0 ");
- dis_duty(); //显示占空比
- while(1)
- {
- key_check(); //按键处理程序
- if(dis_speed_flag==1)
- {
- dis_speed(); //显示转速
- dis_speed_flag=0;
- }
- }
- }
- /**************************************************/
复制代码
全部资料51hei下载地址:
PWM直流电机调速显示转速.7z
(11.63 MB, 下载次数: 462)
|