27,508
社区成员




#include <reg51.h>
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
// ?????????P2.3-P2.7
#define LCD1602_DATA P2
unsigned int speed = 0; // Speed (0-3000 r/min)
unsigned int angle = 0; // Angle (2-9999 deg)
void delay(unsigned int ms) {
unsigned int i, j;
for (i = 0; i < ms; i++)
for (j = 0; j < 123; j++);
}
void lcd_command(unsigned char cmd) {
LCD1602_DATA = cmd;
RS = 0;
RW = 0;
EN = 1;
delay(1);
EN = 0;
}
void LCD1602_check_busy(void) {
EA = 0;
LCD1602_DATA = 0xff; // Set data port as input
RS = 0;
RW = 1;
EN = 1;
while (LCD1602_DATA & 0x80); // Wait until busy flag is cleared
EN = 0;
EA = 1;
}
void lcd_init() {
delay(15); // Initial delay to ensure power stabilization
lcd_command(0x38); // 8-bit mode, 2 lines, 5x7 dots
delay(5);
lcd_command(0x38); // Ensure correct initialization
delay(1);
lcd_command(0x38); // Final initialization command
delay(1);
lcd_command(0x0C); // Display on, cursor off, blink off
delay(1);
lcd_command(0x06); // Increment cursor, no shift
delay(1);
lcd_command(0x01); // Clear display, move cursor to home
delay(2);
}
void lcd_char(unsigned char dat) {
LCD1602_DATA = dat;
RS = 1;
RW = 0;
EN = 1;
delay(1);
EN = 0;
}
void lcd_string(char *str) {
while (*str) {
lcd_char(*str++);
}
}
void lcd_set_cursor(unsigned char row, unsigned char col) {
unsigned char addr;
if (row == 0)
addr = 0x80 + col;
else
addr = 0xC0 + col;
lcd_command(addr);
}
void step_motor(unsigned char pattern) {
P1 = pattern;
delay(speed / 10); // Control the speed by adjusting the delay
}
char key_scan() {
unsigned char rows[] = {0xF7, 0xFB, 0xFD, 0xFE};
unsigned char cols[] = {0xEF, 0xDF, 0xBF, 0x7F};
unsigned char key_matrix[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
unsigned char row, col;
for (row = 0; row < 4; row++) {
P3 = rows[row];
for (col = 0; col < 4; col++) {
if (!(P3 & cols[col])) {
return key_matrix[row][col];
}
}
}
return '\0'; // No key pressed
}
void update_display() {
lcd_set_cursor(0, 0);
lcd_string("Speed:");
lcd_char((speed / 1000) + '0');
lcd_char(((speed % 1000) / 100) + '0');
lcd_char(((speed % 100) / 10) + '0');
lcd_char((speed % 10) + '0');
lcd_string(" RPM");
lcd_set_cursor(1, 0);
lcd_string("Angle:");
lcd_char((angle / 1000) + '0');
lcd_char(((angle % 1000) / 100) + '0');
lcd_char(((angle % 100) / 10) + '0');
lcd_char((angle % 10) + '0');
lcd_string(" DEG");
}
void main() {
unsigned char patterns[] = {0x06, 0x0E, 0x1E, 0x3E, 0x3F, 0x2F};
unsigned char key_pressed;
unsigned char i;
lcd_init();
lcd_string("Init OK"); // Test message to check if LCD is working
while (1) {
key_pressed = key_scan();
switch (key_pressed) {
case '1':
speed += 100;
if (speed > 3000) speed = 3000;
break;
case '2':
speed -= 100;
if (speed < 0) speed = 0;
break;
case '3':
angle += 10;
if (angle > 9999) angle = 9999;
break;
case '4':
angle -= 10;
if (angle < 2) angle = 2;
break;
default:
break;
}
update_display();
for (i = 0; i < 6; i++) {
step_motor(patterns[i]);
}
}
}