Functions
The functions realized are as follows.
-
realizing forward and reverse rotation of the motor.
-
realizing motor speed change within a certain range.
-
controlling motor start, stop, forward and reverse rotation, acceleration and deceleration, modification of time and zeroing of speed setting through 2x4 keyboard, and displaying system operation status with LCD screen.
-
Display the current status of motor operation, including (start, stop, forward rotation, reverse rotation, acceleration, deceleration, modification of hours, modification of minutes, etc.).
(5) LCD display Beijing time, adjustable hours and minutes (seconds can not be modified), can be added or subtracted.
(6) equipped with motor operation indicator, when the motor is running, the indicator lights up, when the motor stops, the indicator lights off, used to indicate whether the motor is running.
(7) equipped with reset button, can be manually reset when the operation is wrong.
Proteus hardware circuit schematic drawing
Source code and comments
#include "reg51.h" //header file
#include <string.h> //character manipulation
#define uchar unsigned char //macro definition
#define uint unsigned int
uchar time[] = "23:59:56";//time string
uchar state[] = " hello ";//state string
char code tab[2][4]={{'0','1','2','3'},
{'4','5','6','7'}}; // 8 key plants from 0 to 7
uint num=0;//judge whether to 1 second
uchar speed=100;//used to delay the speed control
bit time_flag=0; //modify the time flag bit, modify the hour or minute
bit turn_flag=0;//the speed direction flag bit
bit turn_stop=0;//Start/stop flag bit
uchar key;//Key value
sbit E=P2^2;//Enable E to send signal in the form of pulse
sbit RS=P2^1;//0: command 1: character
sbit RW=P2^0;//0: write 1: read
sbit led=P2^3;//motor running status light
void keyscan();//used in the interrupt keyboard scan
void key_gn();//key function
void moto();//motor driver
void delay(uint x)//delay
{
uint i;
i=x*100;
while(i--);
}
void LCD_1602_Cmd(uchar cmd)//lcd write instruction
{
RS=0; //timing is RS, RW, E
RW=0;
P1=cmd;
E=1; //one pulse, one enable signal
delay(2);
E=0;
}
void LCD_1602_Data(uchar dat)//lcd write character
{
RS=1;
RW=0;
P1=dat;
E=1;
delay(2);
E=0;
}
void LCD_1602_init()//lcd initialization
{
LCD_1602_Cmd(0X38);//open display: 8-bit line, 5x7 display dot matrix
LCD_1602_Cmd(0X06);//add one to the pointer after each character is written, i.e., the cursor moves one to the right
LCD_1602_Cmd(0X0c);//open display but not display cursor
LCD_1602_Cmd(0X01);//clear the screen
}
void display(uint l,uchar *p)//;cdisplay string
{
uint i;
for(i=0;i<l;i++)
LCD_1602_Data(p[i]);
}
void int0() interrupt 1 using 1 //t0 interrupt update display time, timer
{
unsigned int shi;//hour
unsigned int fen;//minutes
unsigned int miao; //seconds
num++;//num to 20 proves that a second has been reached
TR0 = 0;//Stop timing
TL0=0xB0; //assign initial value, 50ms delay
TH0=0x3C;
if(num == 20)//reached one second
{
shi = (time[0]-48)*10+time[1]-48;//difference between Askew code and number 48,0 Askew code is 48, take out the number of hours in the string
fen = (time[3]-48)*10+time[4]-48;//take out the number of minutes
miao = (time[6]-48)*10+time[7]-48;//take out the number of seconds
num = 0;//return to 0
miao++;//seconds + 1
if(miao == 60)//whether it reaches one minute
{
miao = 0;//clear the number of seconds 0
fen = fen + 1;//fraction + 1
}
if(fen >= 60)//whether to reach one minute
{
fen = 0;//fraction clear 0
shi = shi + 1;//hour + 1
}
if(shi >= 24)//whether it reaches 24 hours
{
shi = 0;//hours clear 0
}
time[0] = shi / 10 + 48;//update the tenth digit of the hour in the time string, +48 is the corresponding Asics code
time[1] = shi % 10 + 48;//update the hour in the time string to the single digit
time[3] = fen / 10 + 48;//update the tenth digit of the minute in the time string
time[4] = fen % 10 + 48;//update the minutes in the time string
time[6] = miao / 10 + 48;//update the tenths of the seconds in the time string
time[7] = miao % 10 + 48;//update the time string to the second digit
}
TR0 = 1;//continue timing
}
void INTERR(void) interrupt 0//Use external interrupt to determine if a key is pressed, no query, save system time
{
keyscan();//judge which key is pressed
}
void start(void) interrupt 2//Use external interrupts to determine if a key is pressed, no need to query, saves system time
{
turn_stop=1;
strcpy(state, "start");//strcpy string copy function, copy 'start' to state, easy to display
led = 0;//the light is on
speed = 100;//prevent the operation when not started, start with the default rotation speed
}
void keyscan()
{
unsigned char hang,lie;//rows and columns
delay(5);//delay for a while
if((P3&0x03)! =0x03)//judge whether the key is pressed
{
switch(P3&0x03)//judge which line's key pressed
{
case 0x01:hang=1;break;//the second line pressed
case 0x02:hang=0;break;//The first line is pressed
}
P3=P3&0xfc;//P3's low two pull low to determine which column
P2=P2|0xf0;//the high four bits of P2 pull high
while((P3&0x03)! =0x00);//P3's low two bits pull low and continue
switch(P2&0xf0)//read P2 high four bits
{
case 0xe0:lie=3;break;//the fourth column
case 0xd0:lie=2;break;//third column
case 0xb0:lie=1;break;//second column
case 0x70:lie=0;break;//first column
}
P2=P2&0x0f;//pull down the high four bits of P2
P3=P3|0x03;//pull up P3 low two
while((P2&0xf0)! =0x00);//pull down the high four bits of P2 and then continue
key=tab[hang][lie];//judge which key is pressed, assign the corresponding value to all variables key, to facilitate further operations
key_gn();//key's function function
}
else
key=0;//default value no key pressed
}
void key_gn() //key's function
{
uint time_temp;//time modified to temporary value
if(key!=0)//if a key is pressed
{
state[0]="\0";//the state display information on the lcd is cleared, because the \0 escape character represents the end, no better way to find
switch(key)//switch branch statement, execute the function of the key
{
case '0'://the first pressed
strcpy(state, "reset");//strcpy string copy function, copy 'reset' to state, easy to display
speed = 100;//default speed
break;
case '1'://second key pressed, stop
strcpy(state, "stop");//same as
turn_stop = 0;//start flag position 0
led = 1;//light off
break;
case '2'://Third key pressed, accelerate
strcpy(state, "speed up");
if((speed >= 50))//the maximum speed set
speed = speed - 20;//speed is the delay time and speed is inversely proportional
break;
case '3'://the fourth key pressed, slow down
strcpy(state, "slow down");
if((speed <= 150))//the minimum speed set
speed = speed + 20;//speed is the delay time and speed is inversely proportional
break;
case '4'://the fifth key pressed, reverse
turn_flag = ~turn_flag;//turn flag bit reversed
if(turn_flag == 1)//flag bit is 0 positive turn
strcpy(state, "left");
else//flag bit is 1 inverse
strcpy(state, "right");
break;
case '5'://the sixth key is pressed, the time adjustment flag bit, modify the hour or minute
time_flag=~time_flag;//reverse
if(time_flag==0)//If the flag bit is 0, adjust the minutes
strcpy(state," minute ");
else//If the flag bit is 0, adjust the hour
strcpy(state," hour ");
break;
case '6'://the seventh key pressed, time +
TR0 = 0; //stop timing
if(time_flag==0)//judge adjust hour or minute
{
strcpy(state, "minute+");//display state
time_temp = (time[3]-48)*10+time[4]-48;//read current minute value
time_temp = time_temp + 1;//minute + 1
if(time_temp >= 60)//If greater than 60, set 0
time_temp = 0;
time[3] = time_temp / 10 + 48;//modify string time
time[4] = time_temp % 10 + 48;
}
else
{
strcpy(state, "hour+");//display state, hour+
time_temp = (time[0]-48)*10 + time[1]-48;//read hour value
time_temp = time_temp + 1;//hour + 1
if(time_temp >= 24)//set 0 if hour is greater than 23
time_temp = 0;
time[0] = time_temp / 10 + 48;//modify string time
time[1] = time_temp % 10 + 48;
}
TR0 = 1;//continue timing
break;
case '7'://eighth key pressed, time -
TR0 = 0;//Stop timing
if(time_flag==0)//the same to determine whether it is hours or minutes
{
strcpy(state, "minute- ");//same reasoning, not in detail
time_temp = (time[3]-48)*10+time[4]-48;
time_temp = time_temp - 1;
if(time_temp > 100)
time_temp = 59;
time[3] = time_temp / 10 + 48;
time[4] = time_temp % 10 + 48;
}
else
{
strcpy(state, "hour-");
time_temp = (time[0]-48)*10 + time[1]-48;
time_temp = time_temp - 1;
if(time_temp > 100)
time_temp = 23;
time[0] = time_temp / 10 + 48;
time[1] = time_temp % 10 + 48;
}
TR0 = 1;
break;
}
}
}
void moto()//stepper motor drive
{
uchar code fan[] = {0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};//positive rotation
uchar code zheng[] = {0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//reverse
uchar i;
if(turn_stop==1)//If it is start state
{
if (turn_flag==0)//judge forward and reverse
{
for(i=0;i<8;i++)
{
P0 = zheng[i];//positive rotation
delay(speed); //delay, adjust speed
}
}
else
{
for(i=0;i<8;i++)
{
P0 = fan[i];//reverse rotation
delay(speed);//delay, adjust speed
}
}
}
}
void main()//main function part
{
TMOD=0x01;//Timer 0, mode 1
TL0=0xB0; //assign initial value
TH0=0x3C;
ET0=1;//allow t0 interrupt
TR0=1;//Start timing
IT0=1; //IT0=1 for lower edge trigger
EX0=1; //Open external interrupt 0
IT1=1; //IT0=1 for lower edge trigger
EX1=1; //Open external interrupt 0
EA=1;//open total interrupt
LCD_1602_init();//lcd initialization
led = 1;//default light off
key = 0;//key is 0
P2=P2&0x0f;//pull down P2 high four bits
while(1)
{
moto();//motor drive
LCD_1602_Cmd(0X80); //first line display time
display(8,time);//display time
LCD_1602_Cmd(0X80+0X40); //The second line shows the state
display(9,state);//display state
}
}
1 post - 1 participant