今天的实验需要用到的材料有:51单片机最小系统,4X4的矩阵键盘,DC直流6V-12V带编码器电机,L298N模块,一个led小灯。下面把产品截图展示一下:
单片机就不展示了,都一样,下面是接线图:
下面是电机的脉冲信号接法:4个脉冲1圈,图中单片机处接到51单片机的P3.2口,外部中断0
接下来就是我组装完了的一张图片了。
下面介绍一下程序的大体流程:按A键正转,按B键反转,0停止,1到9设置脉冲的高电平占用的百分比,10%到90%,也就是1最慢,9最快了。还能再快,没有写,到100%就是最快了,不管什么情况下,转够十圈都会停止转动。
下面就是整个程序,有注释,程序测试没有问题,特此记录:
#include<reg52.h>
sbit IN1=P3^5; //接L298N 7
sbit IN2=P3^6; //接L298N 6
sbit EN1=P3^7; //接L298N 5
sbit LED=P2^7; //接一个小led灯检测信号用
#define uc unsigned char
#define uint unsigned int
uint dat_H[2]; // 定时器初值的高位取值数组
uint dat_L[2]; // 定时器初值的低位取值数组
uint num=1000; // 定时器的定时时间(高电平时间为0.1毫秒)
uc flag=0; //记录按键是否被按下的标志
uc count=0; //用来记录电机转的圈数,4个数为1圈
//电动机停止函数
void motor_stop()
{
IN1=1;
IN2=1;
EN1=1;
EA=0;
}
//电动机正转函数
void motor_zheng()
{
IN1=1;
IN2=0;
EA = 1;
}
//电动机反转函数
void motor_fan()
{
IN1=0;
IN2=1;
EA = 1;
}
//数据初始化
void dat_init()
{
dat_H[0]=(65536-(10000-num))/256;
dat_L[0]=(65536-(10000-num))%256;
dat_H[1]=(65536-num)/256;
dat_L[1]=(65536-num)%256;
}
void key()
{
uc temp=0, temp1=0, temp2=0;
P0 = 0x0F;
if(P0 != 0x0F && flag == 0)
{
flag=1;
}
if(P0 != 0x0F && flag == 1)
{
flag=0; //
temp1 = P0;
}
P0 = 0xF0;
if(P0 != 0xF0 && flag == 0)
{
flag = 1;//temp2 = P0;
}
if(P0 != 0xF0 && flag == 1)
{
flag = 0;//
temp2 = P0;
}
temp = temp1 + temp2;
//按键1按下 修改num值达到修改定时器定时时间的目的
if(temp == 0xEE)
{
num = 1000;
}
//按键2按下
if(temp == 0xDE)
{
num = 2000;
}
//按键3按下
if(temp == 0xBE)
{
num = 3000;
}
//按键A按下
if(temp == 0x7E)
{
motor_zheng(); // 电机正转
}
//按键4按下
if(temp == 0xED)
{
num = 4000;
}
//按键5按下
if(temp == 0xDD)
{
num = 5000;
}
//按键6按下
if(temp == 0xBD)
{
num = 6000;
}
//按键B按下
if(temp == 0x7D)
{
motor_fan(); // 电机反转
}
//按键7按下
if(temp == 0xEB)
{
num = 7000;
}
//按键8按下
if(temp == 0xDB)
{
num = 8000;
}
//按键9按下
if(temp == 0xBB)
{
num = 9000;
}
//按键C按下
// if(temp == 0x7B)
// {
//
// }
//按键*按下
// if(temp == 0xE7)
// {
//
// }
//按键0按下
if(temp == 0xD7)
{
motor_stop(); //停止转动
}
//按键#按下
// if(temp == 0xB7)
// {
//
// }
//
// //按键D按下
// if(temp == 0x77)
// {
//
// }
LED=0;
dat_init(); // 所有按键都检测完了就要重新设置一下初值,好叫按键更改的num值起效
}
//定时器初始化
void time_init()
{
TMOD=0x01;
TH0=dat_H[0];
TL0=dat_L[0];
ET0=1;
EA=1;
TR0=1;
IN1=1;
IN2=0;
EN1=0;
LED=0; //P2的7口接了一个led小灯检测信号有没有用的。
//下面是外部中断初始化
IT0=1; // 外部中断设置成1,边沿触发方式
EX0=1; // 使用INT0的中断
}
// 主函数
int main()
{
time_init(); //初始化定时器
while(1)
{
key(); // 检测按键
}
return 0;
}
// 定时器中断入口函数
void zd() interrupt 1
{
EN1=~EN1; // 电动机转动使能,每次取反, 得1时转动,得0时停止
if(EN1==0) // 如果是停止转动时,就设置初值为(65536-(10000-num))num为定时时间1000为1毫秒
{
TH0=dat_H[0];
TL0=dat_L[0];
}
if(EN1==1) // 如果是转动时,就设置初值为(65536-num),num为定时时间1000为1毫秒
{
TH0=dat_H[1];
TL0=dat_L[1];
}
}
// 外部中断入口函数
void wbzd() interrupt 0
{
count++;
if(count == 40) //记录电机转10圈的时候就停止转动,点亮led灯,圈数置0.
{
LED=1;
count=0;
motor_stop();
}
}