基于51单片机的步进电机控制(电机正转、电机反转、电机停止、电机正转加速、电机正转减速,电机反转加速、电机反转减速、汉字显示12864)原理图、流程图、物料清单、仿真图、源代码

基于51单片机的步进电机控制(电机正转、电机反转、电机停止、电机正转加速、电机正转减速,电机反转加速、电机反转减速、汉字显示12864)原理图、流程图、物料清单、仿真图、源代码

基于51单片机的步进电机控制(12864)

单片机控制步进电机
使用LCD显示汉字,不同工作模式对应不同内容:电机正转、电机反转、电机停止、电机正转加速、电机正转减速,电机反转加速、电机反转减速。

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit AA=P3^4;//电机
sbit BB=P3^5;
sbit CC=P3^6;
sbit DD=P3^7;
sbit k1=P1^0;//按钮
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
sbit k5=P1^4;

sbit RS	=P0^5;//显示器引脚
sbit RW	=P0^6;
sbit EN	=P0^7;
sbit CS1=P0^3;
sbit CS2=P0^4;
uchar start=0;//开启
uchar speed=10,time=0;//速度
uchar fang=0,flag=0;//方向

 uchar code str0[] =
{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0xFF,0x88,0x88,0x88,0x88,0xF8,0x00,0x00,0x00,
0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x7F,0x88,0x88,0x88,0x88,0x9F,0x80,0xF0,0x00};/*"电",3*/
 uchar code str1[] =
{0x10,0x10,0xD0,0xFF,0x90,0x10,0x00,0xFE,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,
0x04,0x03,0x00,0xFF,0x00,0x83,0x60,0x1F,0x00,0x00,0x00,0x3F,0x40,0x40,0x78,0x00};/*"机",4*/
 uchar code str2[] =
{0x00,0x02,0x02,0xC2,0x02,0x02,0x02,0xFE,0x82,0x82,0x82,0x82,0x82,0x02,0x00,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00};/*"正",5*/
 uchar code str3[] =
{0x00,0x00,0xFC,0x24,0x24,0xE4,0x24,0x24,0x22,0x22,0x22,0xA3,0x62,0x00,0x00,0x00,
0x40,0x30,0x8F,0x80,0x40,0x40,0x23,0x14,0x08,0x14,0x22,0x41,0x40,0x80,0x80,0x00};/*"反",6*/
 uchar code str4[] =
{0xC8,0xB8,0x8F,0xE8,0x88,0x88,0x40,0x48,0x48,0xE8,0x5F,0x48,0x48,0x48,0x40,0x00,
0x08,0x18,0x08,0xFF,0x04,0x04,0x00,0x02,0x0B,0x12,0x22,0xD2,0x0A,0x06,0x00,0x00};/*"转",7*/
 uchar code str5[] =
{0x10,0x10,0x10,0xFF,0x10,0x10,0xF0,0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00,
0x80,0x40,0x30,0x0F,0x40,0x80,0x7F,0x00,0x00,0x7F,0x20,0x20,0x20,0x7F,0x00,0x00};/*"加",8*/
 uchar code str6[] =
{0x00,0x02,0x0C,0xC0,0x00,0xF8,0x08,0x48,0x48,0x48,0x08,0xFF,0x08,0x09,0x8A,0x00,
0x02,0x02,0x7F,0x80,0x40,0x3F,0x00,0x1E,0x92,0x5E,0x20,0x17,0x38,0x46,0xF1,0x00};/*"减",9*/
 uchar code str7[] =
{0x40,0x40,0x42,0xCC,0x00,0x04,0xF4,0x94,0x94,0xFF,0x94,0x94,0xF4,0x04,0x00,0x00,
0x00,0x40,0x20,0x1F,0x20,0x48,0x44,0x42,0x41,0x5F,0x41,0x42,0x44,0x48,0x40,0x00};/*"速",10*/
 uchar code str8[] =
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//空
 uchar code str9[] =
{0x80,0x60,0xF8,0x07,0x00,0x04,0x74,0x54,0x55,0x56,0x54,0x54,0x74,0x04,0x00,0x00,
0x00,0x00,0xFF,0x00,0x03,0x01,0x05,0x45,0x85,0x7D,0x05,0x05,0x05,0x01,0x03,0x00};/*"停",0*/
 uchar code str10[] =
{0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0xFF,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,
0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x7F,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00};/*"止",1*/
/************** 判忙函数 **************/ 
void lcd_r_busy()
{
    P2 = 0x00;
    RS = 0;
    RW = 1;
    EN = 1;
    while (P2 & 0x80);  // 最高位DB7==1,则busy
    EN = 0;
}
  
/************* LCD写命令函数 *************/
void lcd_w_cmd(uchar value)
{
    lcd_r_busy();    // 每次读写操作前都要忙判断
    RS = 0;
    RW = 0;
    P2 = value;
    EN = 1;       // 下降沿锁存写入的数据/命令
    _nop_();
    _nop_();
    EN = 0;
} 
 
/************* LCD写数据  **************/
void lcd_w_data(uchar value)
{
    lcd_r_busy();
    RS = 1;
    RW = 0;
    P2 = value;
    EN = 1;        // 下降沿锁存写入的数据/命令
    _nop_();
    _nop_();
    EN = 0;
}
 
/***************页设置:显示在哪一页******************/
/*************共8页,一页是8行像素点*****************/
void lcd_set_page(uchar page)
{
    page = 0xb8 | page;   // 页的首地址为0xb8:page或上0xb8=选择page页
    lcd_w_cmd(page);
}
  
/************行设置:起始在哪一行********************/
/**********每页共8行,一般从0行开始******************/
void lcd_set_line(uchar sline)
{
    sline = 0xc0 | sline;  // 起始行地址为0xc0:sline或上0xc0=选择行
    lcd_w_cmd(sline);
}
  
/*************起始列设置+像素点选择********************/
/***********每半片共64列,列值不得大于63***************/
void lcd_set_column(uchar column)
{
    column = 0x3f & column;  // 与上列的最大值63:0x3f 可得所选列值<63
    column = 0x40 | column;  // 得列的首地址
    lcd_w_cmd(column);
}
 
/*************设置显示的开关********************/
/**********0为关闭显示;1为 开启显示************/
void lcd_on_off(uchar set)
{
    set = 0x3e | set;    // =0011 111x----0x3e为关闭显示;0x3f为开启显示
    lcd_w_cmd(set);
}
 
 
/*************选择左右半屏显示********************/
/********0-全屏显示;1-左;2-右********************/
/************cs片选端低电平有效********************/
void lcd_cs(uchar sel)
{
    switch (sel)
    {
    case 0:CS1 = 0; CS2 = 0; break;   // 全屏显示
    case 1:CS1 = 0; CS2 = 1; break;   // 左显示
    case 2:CS1 = 1; CS2 = 0; break;   // 右显示
    default:break;
    }
}
 
 
/*************清屏:选择半屏********************/
/********0-清全屏;1-清左;2-清右***************/
void lcd_clear(uchar sel)
{
    uchar i, j;
    lcd_cs(sel);
    for (i = 0; i < 8; i++)
    {
        lcd_set_page(i);
        lcd_set_column(0);
        for (j = 0; j < 64; j++)
        {
            lcd_w_data(0x00);  // 每列全部写0,列地址指针自动+1
        }
    }
}

/****************LCD的初始化********************/
void lcd_init()
{
    lcd_r_busy();
    lcd_cs(0);
    lcd_on_off(0);     // 关显示
    lcd_cs(0);
    lcd_on_off(1);     // 开显示
    lcd_cs(0);
    lcd_clear(0);      // 清全屏
    lcd_set_line(0);  // 起始行设为0
}
 
/****************16*16像素的汉字显示程序********************/
//CS左右半屏1,2
//page 页
void display(uchar cs, uchar page, uchar column, uchar* p)
{
    uchar i;
    lcd_cs(cs);
    lcd_set_page(page);       // 要在本页写上半个汉字8*16
    lcd_set_column(column);     // 选择起始列
    for (i = 0; i < 16; i++)
    {
        lcd_w_data(p[i]);      // 按列输入上半个汉字的编码8*16
    }
    lcd_set_page(page + 1);     // 要在下一页写下半个汉字8*16
    lcd_set_column(column);     // 选择起始列
    for (i = 0; i < 16; i++)
    {
        lcd_w_data(p[i + 16]);   // 按列输入下半个汉字的编码8*16 
    }
}
void state1()//状态1,电机正转
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str8); 
	display(1, 2, 2 * 16, str0);   
    display(1, 2, 3 * 16, str1);  
    display(2, 2, 4 * 16, str2);   
	display(2, 2, 5 * 16, str4);
	display(2, 2, 6 * 16, str8);
}
void state2()//状态2,电机反转
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str8); 
	display(1, 2, 2 * 16, str0);   
    display(1, 2, 3 * 16, str1);  
    display(2, 2, 4 * 16, str3);   
	display(2, 2, 5 * 16, str4);
	display(2, 2, 6 * 16, str8);
}
void state3()//状态3,电机停止
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str8); 
	display(1, 2, 2 * 16, str0);   
    display(1, 2, 3 * 16, str1);  
    display(2, 2, 4 * 16, str9);   
	display(2, 2, 5 * 16, str10);
	display(2, 2, 6 * 16, str8);
}
void state4()//状态4,电机正转加速
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str0); 
	display(1, 2, 2 * 16, str1);   
    display(1, 2, 3 * 16, str2);  
    display(2, 2, 4 * 16, str4);   
	display(2, 2, 5 * 16, str5);
	display(2, 2, 6 * 16, str7);
}
void state5()//状态5,电机反转加速
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str0); 
	display(1, 2, 2 * 16, str1);   
    display(1, 2, 3 * 16, str3);  
    display(2, 2, 4 * 16, str4);   
	display(2, 2, 5 * 16, str5);
	display(2, 2, 6 * 16, str7);
}
void state6()//状态6,电机正转减速
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str0); 
	display(1, 2, 2 * 16, str1);   
    display(1, 2, 3 * 16, str2);  
    display(2, 2, 4 * 16, str4);   
	display(2, 2, 5 * 16, str6);
	display(2, 2, 6 * 16, str7);
}
void state7()//状态7,电机反转减速
{
	lcd_set_line(0);             // 设置起始行为0
    display(1, 2, 1 * 16, str0); 
	display(1, 2, 2 * 16, str1);   
    display(1, 2, 3 * 16, str3);  
    display(2, 2, 4 * 16, str4);   
	display(2, 2, 5 * 16, str6);
	display(2, 2, 6 * 16, str7);
}

void main()
{
    //设置INT1
	IT1=1;//跳变沿出发方式(下降沿)
	EX1=1;//打开INT1的中断允许。
	TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
	TH0=0XD8;	//10ms
	TL0=0XF0;	
	ET0=1;//打开定时器0中断允许
	EA=1;//打开总中断
	TR0=1;//打开定时器
	P0=0xfe;
	lcd_init();                 // 初始化
    lcd_clear(0);               // 清屏
    lcd_set_line(0);             // 设置起始行为0
 	state3();
    while (1)
	{
		
	}
}
void Timer0() interrupt 1//定时器中断
{
	if(start)//开始
	{
		if(time<speed)
			time++;
		else
		{
			time=0;
			if(fang==0)//正转
			{
				 switch(flag)
				 {
				 	case 0:BB=1;break;
					case 1:AA=0;break;
					case 2:CC=1;break;
					case 3:BB=0;break;
					case 4:DD=1;break;
					case 5:CC=0;break;
					case 6:AA=1;break;
					case 7:DD=0;
				 }
				 if(flag<7)
				 	flag++;
				else
					flag=0;
			}
			else//反转
			{
				 switch(flag)
				 {
				 	case 0:DD=1;break;
					case 1:AA=0;break;
					case 2:CC=1;break;
					case 3:DD=0;break;
					case 4:BB=1;break;
					case 5:CC=0;break;
					case 6:AA=1;break;
					case 7:BB=0;
				 }
				 if(flag<7)
				 	flag++;
				else
					flag=0;
			}
		}
	}
	TH0=0XD8;	//10ms
	TL0=0XF0;
}
void Int1()	interrupt 2	//外部中断1的中断函数
{
	TR0=0;
	if(!k1)//正转
	{
		start=1;
		fang=0;
		state1();//显示状态
	}
	if(!k2)//停止
	{
		start=0;
		state3();//显示状态
	}
	if(!k3)//反转
	{
		start=1;
		fang=1;
		state2();//显示状态
	}
	if(!k4)//加速
	{
		start=1;
		if(speed>5)
			speed--;
		if(fang)
			state5();//显示状态
		else
			state4();//显示状态
	}
	if(!k5)//减速
	{
		start=1;
		if(speed<40)
			speed++;
		if(fang)
			state7();//显示状态
		else
			state6();//显示状态
	}
	TR0=1;
}
  • 12
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqtianxingkeji

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值