今天的实验需要用到的材料有:51单片机最小系统,4X4的矩阵键盘,DC直流6V-12V带编码器电机,L298N模块,一个led小灯。下面把产品截图展示一下:


单片机就不展示了,都一样,下面是接线图:



下面是电机的脉冲信号接法:4个脉冲1圈,图中单片机处接到51单片机的P3.2口,外部中断0


接下来就是我组装完了的一张图片了。

下面介绍一下程序的大体流程:按A键正转,按B键反转,0停止,1到9设置脉冲的高电平占用的百分比,10%到90%,也就是1最慢,9最快了。还能再快,没有写,到100%就是最快了,不管什么情况下,转够十圈都会停止转动。
下面就是整个程序,有注释,程序测试没有问题,特此记录:
- #include
- 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();
- }
- }