直流电机控制电路仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- ///*************************************************************************************************************
- ///直流电机的pwm控制程序
- ///功能:直流电机的速度控制,速度测试,速度显示。
- ///作者:廖维斌,郭留涛
- ///*************************************************************************************************************
- #include<reg51.h> ///包含头文件
- #include<absacc.h>
- #define gew DBYTE[0X40] ///定义显示缓冲区 个位
- #define shiw DBYTE[0X41] //////////////////十位
- #define baiw DBYTE[0X42] //////////////////百位
- #define qianw DBYTE[0X43] //////////////////千位
- #define unint unsigned int ///自定义变量
- #define uchar unsigned char
- sbit in1=P3^0; ///控制位定义
- sbit in2=P3^1;
- sbit ena=P3^7;
- uchar code zm[12]={0Xc0,0Xf9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0x73,0x71};///在程序存储区定义字型码表
- uchar code wm[4]={0xfe,0xfd,0xfb,0xf7};///在程序存储区定义字位控制码表***选位
- uchar a=8; ///占空比控制字
- uchar n=1; ///速度增减量一
- uchar m=2; ///速度增减量二
- unint speedbuf=0; ///速度值
- uchar zc=0;
- unint ys=0;
- key(); ///子函数声明
- display();
- control();
- delays();
- speedcan();
- ///*************************************************************************************************************
- ///主函数
- ///*************************************************************************************************************
- main()
- {
- gew=shiw=baiw=qianw=0; ///显示初始化
- P0=0xc0;
- P2=0;
- in1=0; ///电机控制的初始化
- in2=0;
- ena=1;
- TMOD=0X15; ///定时器1为定时模式,使用方式2;定时器0为计数模式,使用方式2
- TH1=0Xfa; ///装定时器初值
- TL1=0X24;
- TH0=0; ///装计数器初值
- TL0=0;
- EA=1; ///开总中断
- ET0=1; ///允许定时器0中断
- ET1=1; ///允许定时器1中断
- TR0=1; ///开计数器
- TR1=1; ///开定时器
- while(1) ///无限循环
- {
- key(); ///调用按键扫描程序
- control(); ///调用电机控制程序
- display(); ///调用显示程序
- speedcan(); ///调用速度处理程序
- }
- }
- ///*************************************************************************************************************
- ///中断处理程序,实现输出方波占空比控制
- ///*************************************************************************************************************
- timer_1() interrupt 3 using 1 ///定时器1中断,使用寄存器组1
- {
- TR1=0; ///停止定时
- zc++; ///中断次数加1
- ys++;
- control();
- speedcan();
- TH1=0Xfa; ///重装定时初值
- TL1=0X24;
- TR1=1;
- }
- ///************************************************************************************************************
- ///脉宽控制程序,实现PWM的输出
- ///***********************************************************************************************************
- control()
- {
- if(zc==a)
- {
- ena=0;
- }
- if(zc==15)
- {
- zc=0;
- ena=1;
- }
- }
- ///*****************************************************************************************************************
- ///显示子函数,显示当前电机的速度
- ///****************************************************************************************************************
- display()
- {
- uchar i;
- gew=speedbuf%10; ///求速度个位值送各位显示缓冲
- shiw=(speedbuf/10)%10; ///求速度十位值送十位显示缓冲
- baiw=(speedbuf/100)%10; ///求速度百位值送百位显示缓冲
- qianw=speedbuf/1000; ///求速度千位值送千位显示缓冲
- for(i=0;i<4;) ///循环选中数码管的每一位
- {
- P2=wm[i];
- if(i==0) ///显示个位
- {
- P0=zm[gew];
- delays();
- }
- else if(i==1) ///显示十位
- {
- P0=zm[shiw];
- delays();
- }
- else if(i==2) ///显示百位
- {
- P0=zm[baiw];
- delays();
- }
- else if(i==3) ///显示千位
- {
- P0=zm[qianw];
- delays();
- }
- i++;
- }
- }
- ///**********************************************************************************************************
- ///读速度值子函数,从计数器0中读计数值,经过计算,求出当前速度值
- ///*************************************************************************************************************
- speedcan()
- {
- if(ys==500)
- {
- TR0=0; ///停止计数
- speedbuf=((TH0*256+TL0)*8)/3;///读计数器
- ys=0;
- TH0=0; ///重装计数初值
- TL0=0;
- TR0=1; ///开计数器
- }
- }
- ///*********************************************************************************************************
- ///延时子函数
- ///***********************************************************************************************************
- delays()
- {
- uchar i;
- for(i=80;i>0;i--);
- }
- ///************************************************************************************************************
- ///键盘扫描子函数,实现电机的方向 速度的控制
- ///*********************************************************************************************************
- key()
- {
- uchar i;
- P1=0xff; ///拉高P1口的电平
- i=P1; ///读P1口
- if(i==0xfe) ///第一个键按下
- { delays(); ///延时去抖动
- if(i==0xfe) ///再判断按键是否按下
- {
- in1=0; ///电机顺时针转动
- in2=1;
- }
- }
- if(i==0xfd) ///第二个键是否按下
- {
- delays(); ///延时去抖动
- if(i==0xfd) ///再判断按键是否按下
- {
- in1=1; ///电机逆时针转动
- in2=0;
- }
- }
- if(i==0xfb) ///第三个键是否按下
- {
- delays();
- if(i==0xfb)
- {
- a=a+n; ///速度加((慢速)
- if(a>=15)
- a=15;
- }
- }
- if(i==0xf7)
- {
- delays();
- if(i==0xf7)
- {
- if(a>3) ///速度减(慢速)
- a=a-n;
- else
- a=3;
- }
- }
- if(i==0xef)
- {
- delays();
- if(i==0xef)
- {
- a=a+m; ///速度加,(快速)
- if(a>=15)
- a=15;
- }
- }
- if(i==0xdf)
- {
- delays();
- if(i==0xdf)
- if(a>3) ///速度减,(快速)
- a=a-m;
- else
- a=3;
- }
- if(i==0xbf)
- {
- delays();
- if(i==0xbf)
- {
- in1=0; ///停止转动
- in2=0;
- }
- }
- if(i==0x7f)
- {
- delays();
- if(i==0x7f)
- a=5; ///回到中间速度
- }
- while(P1!=0xff); ///等待按键放下
- }
复制代码
所有资料51hei提供下载:
直流电机的pwm控制.rar
(162.44 KB, 下载次数: 158)
|