测量下你仿真图左下角的那个U4(A:A)有没有波形。你的电机是在中断中运行的,受到P3.3脚控制。显示是都没显示还是无法显示转速?你在两个地方都调用了displaytolcd()。这可能会导致显示混乱。如果是没显示转速有P3.2接霍尔了没有? |
哎哟喂,懂了! 发表于 2017-6-3 20:52 你上面那个程序还是不能用啊 |
连上传感器就能测实时转速吗?要是连光电传感器呢?怎么改啊 |
哎哟喂,懂了! 发表于 2017-5-16 12:54 仿真里面没有L298n啊 |
#include"reg51.h" #include <intrins.h> #define uchar unsigned char #define uint unsigned int 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 c=0; uchar count=48; //速度上限 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) { if(c<=0) { LED1=1; LED2=0; } ENA=1; c++; if(c >= 3) { c = 2; } } else { LED1=0; LED2=0; ENA=0; c=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显示 } } 终于调试成功了,上传到这上面共后来者参考。 |
对,出了什么问题呢? |
学习了,想知道问题到底出在哪? |
cjjcjj1 发表于 2017-5-16 10:03 运用51单片机输出pwm信号,再运用电机驱动芯片L298驱动直流电机转动,用按键控制启停、正反转、运用PWM占空比多少调速;运用霍尔元件测电机转速,在通过LCD显示转速。 |
呆萌侠 发表于 2017-5-16 10:00 直流电机,用单片机输出PWM信号,再用L298驱动电机 |
用示波器看下PWM出来的波形是否正常。电机是什么电机,用的什么驱动呢? |