标题:
单片机控制直流电机启动和正反转程序,按键的时候要按键好几次才启动
[打印本页]
作者:
mekio韩
时间:
2019-4-24 18:38
标题:
单片机控制直流电机启动和正反转程序,按键的时候要按键好几次才启动
这段程序是控制直流电机启动和正反转的,电路图我也放上了,程序不太对,按键的时候要按键好几次才启动,正反转按钮也不好使,有没有大佬给改改。
QQ截图20190424183145.png
(49.39 KB, 下载次数: 67)
下载附件
proteus图
2019-4-24 18:38 上传
单片机源程序如下:
#include"reg51.h"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
void delay1(uint ms);
sbit k1=P1^0; //启停按键K1
sbit k2=P1^1; //正反转按键K2
sbit up=P1^2; //加速按键up
sbit down=P1^3; //减速按键down
sbit in1=P1^5; //正反转输入口
sbit in2=P1^6;
sbit ENA=P1^7; //PWM信号输入口
sbit LED1=P2^3; //绿灯正转
sbit LED2=P2^4; //红灯反转
uchar a=1;
uchar count=40; //速度上限
uchar t=0;
char speed=20; //初始速度
/*-----------------------端口命名------------------------*/
sbit rs=P2^0; //LCD的数据/命令选择端
sbit rw=P2^1; //LCD的读写选择端
sbit e=P2^2; //LCD的使能信号端
/*-------------------------------------------------------*/
/*-----------------------定义参数------------------------*/
uint i,z,cou,zhuan,msec; //定义参数
uchar display[]={"speed= r/min "}; //定义显示参数
/*-------------------------------------------------------*/
/*-----------------------正反转延时函数------------------*/
void delay(void)
{
uchar i,j,k;
for(i=50;i>0;i--)
{
for(j=100;j>0;j--)
for(k=230;k>0;k--);
}
}
/*------------------------------------------------------*/
/*-----------------------启停函数------------------------*/
void qiting() //b为启停标志
{
if(k1==0)
{
delay1(20);
if(k1==0){
LED1=1;
LED2=0;
ENA=1;
}}
else
{
LED1=0;
LED2=0;
ENA=0;
}
}
/*-------------------------------------------------------*/
/*-----------------------正反转函数----------------------*/
void zhengfan()
{ if(k1==1)
{
ENA=0;
}
else if(k2==1) //正转
{
LED1=1;
LED2=0;
delay();
ENA=1;
in1=1;
in2=0;
}
else if(k2==0) //开关按下反转
{
LED1=0;
LED2=1;
delay();
ENA=1;
in1=0;
in2=1;
}
}
/*--------------------------------------------------------*/
/*-----------------------增减速函数-----------------------*/
void speed_control()
{
if(up==0) //增速
{
speed++;
while(up==0) //即时对计满数的speed值控制在设定范围之内
if(speed>count)speed=count;
}
if(down==0) //减速
{
speed--;
while(down==0)
if(speed<0)speed=0;
}
}
/*----------------------------------------------------------------------------*/
/*-------输出PWM的定时器中断(与增减函数配合输出PWM信号)---------------------*/
void timer0_PWM() interrupt 3 //计满1ms跳一次,有speed个之后PWM跳变
{
if(k1==0)
{
if(t<speed) ENA=1;
else ENA=0;
t++;
if(t>=count)t=0;
}
}
/*-------------------------------------------------------*/
/*-----------------------毫秒延时------------------------*/
void delay1(uint ms)
{
uint i,j; //为延时引入i,j两参数
for (j=0;j<ms;j++) //延时第一循环
for (i=0;i<120;i++); //延时第二循环
}
/*-------------------------------------------------------*/
/*--------------------向LCD1602写命令--------------------*/
void write_command(uchar command)
{
rs=0; //数据、命令选择端0为命令
rw=0; //读、写选择端0为写
P0=command; //向LCD写命令
delay1(5); //稍做延迟,代替检测忙状态
e=1; //信号使能端高电平
delay1(5); //稍做延迟,代替检测忙状态
e=0; //信号使能端低电平
}
/*-------------------------------------------------------*/
/*--------------------向LCD1602写数据--------------------*/
void write_data(uchar data0)
{
rs=1; //数据、命令选择端 1为数据
rw=0; //读、写选择端0为写
P0=data0; //向LCD写数据
delay1(5); //稍做延迟,代替检测忙状态
e=1; //信号使能端高电平
delay1(5); //稍做延迟,代替检测忙状态
e=0; //信号使能端低电平
}
/*-------------------------------------------------------*/
/*-------------------外部中断1计数程序-------------------*/
void counter(void) interrupt 2
{
cou++;
if(cou==2) //2次循环为发动机转一圈
{
cou=0; //初始化计数
z++; //转圈计数加1
}
}
/*-------------------------------------------------------*/
/*------------------------LCD显示------------------------*/
void displaytolcd()
{
write_command(0x80); //向LCD1602写命令80H
for (i=0;i<sizeof(display)-1;i++) //循环要传输的字符个数次,每一次传一个字符
{
write_data(display[i]);
delay1(5);
}
}
/*-------------------------------------------------------*/
/*-----------------内部中断0计时计数程序-----------------*/
void Timer_0(void) interrupt 1
{
TH0=0x3c; //50ms定时
TL0=0xb0;
msec++;
if(msec==20) //50*20=1S
{
msec=0;
zhuan=60*z; //每分钟转速
displaytolcd();
z=0;
}
}
/*-------------------------------------------------------*/
/*-----------------------数据处理------------------------*/
void disp_count()
{
display[7]=(zhuan/1000+'0'); //转换转速的千位
display[8]=(zhuan/100%10+'0'); //转换转速的百位
display[9]=(zhuan/10%10+'0'); //转换转速的十位
display[10]=(zhuan%10+'0'); //转换转速的个位
}
/*-------------------------------------------------------*/
/*----------------------端口初始化-----------------------*/
void int_all()
{
in1=1; //下面五行为启停、正反转初始化
in2=0; //2
LED1=0; //3
LED2=0; //4
ENA=0; //5
z=0; //初始化z的值
cou=0; //初始化co的值
zhuan=0; //初始化转的值
rw=0; //选择LCD写数据指令
delay1(15); //延时15ms
write_command(0x38); //向LCD1602写命令38H
delay1(5); //延时5ms
write_command(0x0e); //向LCD1602写命令0EH
delay1(5); //延时5ms
write_command(0x06); //向LCD1602写命令06H
TMOD=0x21; //内部中断定时器选择;定时器0工作在方式1,定时器1工作在方式2
TH0=0x3C; //50ms定时
TL0=0xb0;
TR0=1; //定时器0工作,用于测速
TH1=0xA3; //1ms定时
TL1=0xA3;
TR1=1; //定时器1工作,用于调速
EA=1; //开中断总开关
IT1=1; //外部中断1为下降沿触发
ET1=1; //T1允许中断
ET0=1; //T0允许中断
EX1=1; //外部中断1允许中断
}
void main()
{
int_all();
ENA=0;
while(1)
{
qiting();
zhengfan();
if(k1==0)
{
speed_control();
}
disp_count(); //数据处理
displaytolcd(); //LCD显示
}
}
复制代码
作者:
ccczx
时间:
2019-4-30 13:55
好好学习一下
作者:
ccczx
时间:
2019-4-30 14:01
参考一下,谢谢楼主
作者:
1255230
时间:
2019-4-30 15:26
可以在按键那里加一个上拉电阻,使单片机引脚不用时处于高电平,然后把销抖的延时时间变短一点,五毫秒左右就行了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1