标题:
51单片机+编码器+42步进电机的源程序
[打印本页]
作者:
mxk569364343
时间:
2018-5-15 10:05
标题:
51单片机+编码器+42步进电机的源程序
前几天帮别做一个51的小东西需要编码器,结果发现网上编码器的程序比较不好找,自己根据别人一个巧妙的思路写了一个读编码器读数的程序,用LCD1602显示出来。里边还有使用L298N驱动42步进电机部分,可以参考一下。
单片机源程序如下:
#include <reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//LCD1602定义
#define LCD1602_DB P0 //LCD1602数据总线
sbit LCD1602_RS = P2^7; //RS端
sbit LCD1602_RW = P2^6; //RW端
sbit LCD1602_EN = P2^5; //EN端
uchar code digit[ ]={"0123456789"}; //定义字符数组显示数字
uchar idata TEST[]="TEST";
//电机正反转二维数组 0为逆时针,1为顺时针
uchar code MotorCode[2][8]={{0x04,0x06,0x02,0x0a,0x08,0x09,0x01,0x05},{0x05,0x01,0x09,0x08,0x0a,0x02,0x06,0x04}};
uchar MotorStatus;//电机正反转标志位
sbit EncoderA=P3^2; //编码器A相
sbit EncoderB=P3^4; //编码器B相
uint EncoderCount=0 ;
/* 毫秒软件延时函数*/
void delay_ms(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=114;b>0;b--);
}
/*=================================================
*函数名称:Read_Busy
*函数功能:判断1602液晶忙,并等待
=================================================*/
void Read_Busy()
{
uchar busy;
LCD1602_DB = 0xff;//复位数据总线
LCD1602_RS = 0; //拉低RS
LCD1602_RW = 1; //拉高RW读
do
{
LCD1602_EN = 1;//使能EN
busy = LCD1602_DB;//读回数据
LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿
}while(busy & 0x80); //判断状态字BIT7位是否为1,为1则表示忙,程序等待
}
/*=================================================
*函数名称:LCD1602_Write_Cmd
*函数功能:写LCD1602命令
*调用:Read_Busy();
*输入:cmd:要写的命令
=================================================*/
void LCD1602_Write_Cmd(uchar cmd)
{
Read_Busy(); //判断忙,忙则等待
LCD1602_RS = 0;
LCD1602_RW = 0; //拉低RS、RW操作时序情况1602课件下中文使用说明基本操作时序章节
LCD1602_DB = cmd;//写入命令
LCD1602_EN = 1; //拉高使能端 数据被传输到LCD1602内
LCD1602_EN = 0; //拉低使能以便于下一次产生上升沿
}
/*=================================================
*函数名称:LCD1602_Write_Dat
*函数功能:写LCD1602数据
*调用:Read_Busy();
*输入:dat:需要写入的数据
=================================================*/
void LCD1602_Write_Dat(uchar dat)
{
Read_Busy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_EN = 1;
LCD1602_EN = 0;
}
/*=================================================
*函数名称:LCD1602_Clear
*函数功能:LCD1602清屏
=================================================*/
void LCD1602_Clear()
{
Read_Busy();
LCD1602_Write_Cmd(0x01); //清屏
}
/*=================================================
*函数名称:LCD1602_Dis_OneChar
*函数功能:在指定位置显示一个字符
*调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
*输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
dat:需要显示的数据以ASCLL形式显示
=================================================*/
void LCD1602_Dis_OneChar(uchar x, uchar y,uchar dat)
{
if(y) x |= 0x40;
x |= 0x80;
LCD1602_Write_Cmd(x);
LCD1602_Write_Dat(dat);
}
/*=================================================
*函数名称:LCD1602_Dis_Str
*函数功能:在指定位置显示字符串
*调用:LCD1602_Write_Cmd(); LCD1602_Write_Dat();
*输入:x:要显示的横坐标取值0-40,y:要显示的行坐标取值0-1(0为第一行,1为第二行)
*str:需要显示的字符串
=================================================*/
void LCD1602_Dis_Str(uchar x, uchar y, uchar *str)
{
if(y) x |= 0x40;
x |= 0x80;
LCD1602_Write_Cmd(x);
while(*str != '\0')
{
LCD1602_Write_Dat(*str++);
}
}
/*=================================================
*函数名称:Init_LCD1602
*函数功能:1602初始化
*调用: LCD1602_Write_Cmd();
=================================================*/
void Init_LCD1602()
{
LCD1602_Write_Cmd(0x38); // 设置16*2显示,5*7点阵,8位数据接口
LCD1602_Write_Cmd(0x0c); //打开显示屏,不显示光标,光标所在位置的字符不闪烁。
LCD1602_Write_Cmd(0x06); //读写一字节后地址指针加1
LCD1602_Write_Cmd(0x01); //清除显示
}
void Motor_Forward() //电机正转
{
TMOD=0x01;
TH0=(65535-2000)/256;
TL0=(65535-2000)%256;
EA=1;
ET0=1;
TR0=1;
MotorStatus=0;
}
void Motor_Reversal() //电机反转
{
TMOD=0x01;
TH0=(65535-2000)/256;
TL0=(65535-2000)%256;
EA=1;
ET0=1;
TR0=1;
MotorStatus=1;
}
void Motor_Stop() //停止电机
{
ET0=0;
TR0=0;
P1=P1&0xF0;
}
uchar index = 0; //定义节拍输出索引
void time0() interrupt 1
{
uchar tmp; //定义一个临时变量
TH0=(65535-1000)/256;
TL0=(65535-1000)%256;
tmp = P1; //用 tmp 把 P1 口当前值暂存
tmp = tmp & 0xF0; //用&操作清零低4位
//用|操作把节拍代码写到低4位
tmp = tmp | MotorCode[MotorStatus][index];
//把低4位的节拍代码和高4位的原值送回 P1
P1 = tmp;
index++; //节拍输出索引递增
index = index & 0x07; //用&操作实现到8归零
}
Init_Encoder ()
{
EA = 1; //开总中断
EX0 = 1;//开外部中断1
IT0 = 1;//外部中断1下降沿触发
}
void main()
{
Init_Encoder ();
Init_LCD1602();
Motor_Reversal();
LCD1602_Dis_Str(0, 0, &TEST[0]); //提示第一行MENU1
while (1)
{
LCD1602_Dis_OneChar(0,1,digit[EncoderCount/10000]);
LCD1602_Dis_OneChar(1,1,digit[EncoderCount%10000/1000]);
LCD1602_Dis_OneChar(2,1,digit[EncoderCount%1000/100]);
LCD1602_Dis_OneChar(3,1,digit[EncoderCount%100/10]);
LCD1602_Dis_OneChar(4,1,digit[EncoderCount%10/1]);
delay_ms(100);
// delay_ms(500); //延时 2 ms,即 2 ms 执行一拍
// Motor_Reversal(); //电机反转
// delay_ms(500); //延时 2 ms,即 2 ms 执行一拍
// Motor_Stop();
// delay_ms(500); //延时 2 ms,即 2 ms 执行一拍
}
}
//外部中断1中断服务程序
void int0() interrupt 0
{
if (EncoderB)
{
EncoderCount++; //正转
}else
{
EncoderCount--; //反转
}
if (EncoderCount==360)
Motor_Stop();
}
复制代码
所有资料51hei提供下载:
42步进电机 编码器.rar
(32.23 KB, 下载次数: 489)
2018-5-15 10:03 上传
点击文件名下载附件
51单片机+增量式编码器+42步进电机
下载积分: 黑币 -5
作者:
7454679
时间:
2018-7-29 00:29
好东西
作者:
15942379927
时间:
2018-10-21 20:26
好贴 顶上去
作者:
lindeijun1
时间:
2018-10-22 15:36
好东西,顶一顶!!
作者:
liliqun
时间:
2018-11-25 11:39
学习学习
作者:
hongaa
时间:
2018-11-25 12:08
好东西,顶一顶!!
作者:
letter1996
时间:
2018-11-26 18:58
谢谢大佬
作者:
letter1996
时间:
2018-11-26 19:01
谢谢大佬的分享
作者:
梦园心田
时间:
2019-1-22 01:34
太强了。。
作者:
gdatgb
时间:
2019-1-24 14:34
谢谢大佬的分享,学习 学习!!
作者:
gdatgb
时间:
2019-1-24 14:35
有没有电路图啊????
作者:
电子123456
时间:
2019-5-4 16:30
楼主用的是八拍的吗?
作者:
钻研旋律
时间:
2019-5-21 22:16
顶上去,学习了
作者:
肖蠢蠢
时间:
2019-6-10 17:03
大哥,没图?
作者:
1606050540011
时间:
2019-6-10 19:14
很给力!
作者:
鹏博士PBs
时间:
2019-6-10 21:43
42步进电机用的是多少拍的啊
作者:
Tars
时间:
2019-6-18 12:01
感谢大佬!!!!!!!!!!!!!
作者:
ttaniscy
时间:
2019-8-5 10:22
这个是好东西,谢谢分享
作者:
lizhidi100
时间:
2019-10-30 19:04
谢谢分享
作者:
hulilanyua
时间:
2019-11-8 23:58
有没有电路图啊????
作者:
wdliming
时间:
2019-11-14 13:06
谢谢分享
作者:
xyllovezuu
时间:
2020-5-18 12:42
学习了,感谢楼主
作者:
xllin
时间:
2020-5-20 10:39
谢谢分享
作者:
yyzf998
时间:
2020-7-2 06:39
宝贝不错,好好学习了,谢谢楼主!
作者:
lilei12306
时间:
2021-4-14 23:10
有仿真没?
作者:
中国红
时间:
2021-12-27 14:32
不完全,是不是要下载压缩包?
作者:
快乐眼泪
时间:
2023-8-30 21:59
谢谢楼主!有没有电路图?
作者:
kevintang
时间:
2024-1-16 19:32
这个是好东西,谢谢分享。
作者:
35462
时间:
2024-10-24 13:09
有图吗,要怎么接线
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1