在BST-V51 Ver3.3全新升级版的51单片机开发板上实现使用矩阵键盘控制电机开关,同时实现使用矩阵键盘控制电机按不同速率转动,按1~5数字键则电机按5档速率转动,使用定时器实现电机的PWM调速,频率为10kHz,同时使用该PWM点亮LED1,使其亮度同步变化。(由于开发板供电限制,占空比不要低于50%,否则电机不转,可分别取60%、70%、80%、90%和99%五个档位进行实验。)同时在LCD1602上实时显示电机状态(LCD1602显示初始状态为: State:OFF Speed:0 )的简单的示例代码。
时间: 2024-02-25 10:54:13 浏览: 193
基于51单片机的步进电机控制(电机正转、电机反转、电机停止、电机正转加速、电机正转减速,电机反转加速、电机反转减速、汉字显示12
5星 · 资源好评率100%
以下是简单的示例代码:
```c
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
// 矩阵键盘输入
sbit key_port_1 = P2^0;
sbit key_port_2 = P2^1;
sbit key_port_3 = P2^2;
sbit key_port_4 = P2^3;
sbit key_port_5 = P2^4;
sbit key_port_6 = P2^5;
sbit key_port_7 = P2^6;
sbit key_port_8 = P2^7;
// LCD1602显示
sbit rs = P0^0;
sbit rw = P0^1;
sbit e = P0^2;
// 电机输出
sbit motor_out = P1^0;
// 定时器中断计数器
uint count;
// PWM占空比(0~100)
uchar duty_cycle;
// 当前电机状态(0: OFF, 1: ON)
uchar motor_state;
// 当前电机速度(0~5)
uchar motor_speed;
// 矩阵键盘扫描函数
uchar key_scan() {
if (key_port_1 == 0) {
return 1;
} else if (key_port_2 == 0) {
return 2;
} else if (key_port_3 == 0) {
return 3;
} else if (key_port_4 == 0) {
return 4;
} else if (key_port_5 == 0) {
return 5;
} else if (key_port_6 == 0) {
return 6;
} else if (key_port_7 == 0) {
return 7;
} else if (key_port_8 == 0) {
return 8;
} else {
return 0;
}
}
// 定时器0中断服务函数
void timer0_isr() interrupt 1 {
count++;
// PWM调速
if (count >= duty_cycle) {
motor_out = 0;
} else {
motor_out = 1;
}
// 重置计数器
if (count >= 100) {
count = 0;
}
}
// 初始化定时器0
void init_timer0() {
TMOD |= 0x01; // 16位定时器
TH0 = 0xFF; // 计时初值
TL0 = 0xFF;
ET0 = 1; // 打开定时器0中断
EA = 1; // 打开总中断
TR0 = 1; // 启动定时器0
}
// 初始化LCD1602
void init_lcd() {
delay(20);
lcd_write_cmd(0x38); // 设置16x2显示,5x7点阵,8位数据线
delay(5);
lcd_write_cmd(0x0C); // 开显示,光标不闪烁
delay(5);
lcd_write_cmd(0x06); // 光标右移,不移动屏幕
delay(5);
lcd_write_cmd(0x01); // 清屏幕
delay(5);
}
// LCD1602写入命令
void lcd_write_cmd(uchar cmd) {
rs = 0;
rw = 0;
e = 0;
P0 = cmd;
e = 1;
delay(5);
e = 0;
}
// LCD1602写入数据
void lcd_write_data(uchar dat) {
rs = 1;
rw = 0;
e = 0;
P0 = dat;
e = 1;
delay(5);
e = 0;
}
// LCD1602写入字符串
void lcd_write_str(uchar *str) {
while (*str != '\0') {
lcd_write_data(*str++);
}
}
// 延时函数
void delay(uint n) {
uint i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < 110; j++);
}
}
void main() {
uchar key_val;
// 初始化
count = 0;
duty_cycle = 99;
motor_state = 0;
motor_speed = 0;
init_timer0();
init_lcd();
// 初始状态显示
lcd_write_cmd(0x80);
lcd_write_str("State:OFF Speed:0");
while (1) {
key_val = key_scan();
switch (key_val) {
case 1:
// 开关电机
if (motor_state == 0) {
motor_state = 1;
motor_out = 1;
lcd_write_cmd(0x80);
lcd_write_str("State:ON Speed:");
lcd_write_data(motor_speed + 0x30);
} else {
motor_state = 0;
motor_out = 0;
lcd_write_cmd(0x80);
lcd_write_str("State:OFF Speed:0");
}
break;
case 2:
// 降低速度
if (motor_speed > 0) {
motor_speed--;
duty_cycle = (motor_speed + 1) * 20;
lcd_write_cmd(0x8C);
lcd_write_data(motor_speed + 0x30);
}
break;
case 3:
// 提高速度
if (motor_speed < 5) {
motor_speed++;
duty_cycle = (motor_speed + 1) * 20;
lcd_write_cmd(0x8C);
lcd_write_data(motor_speed + 0x30);
}
break;
default:
break;
}
}
}
```
以上代码仅供参考,具体实现可能需要根据具体的硬件和需求进行调整。
阅读全文