51单片机+编码器+42步进电机的源程序

2019-11-09来源: 51hei关键字:51单片机  编码器  步进电机

前几天帮别做一个51的小东西需要编码器,结果发现网上编码器的程序比较不好找,自己根据别人一个巧妙的思路写了一个读编码器读数的程序,用LCD1602显示出来。里边还有使用L298N驱动42步进电机部分,可以参考一下。

单片机源程序如下:

#include


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 != '')

        {

                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] [2]
关键字:51单片机  编码器  步进电机 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic479497.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:单片机测速与1602显示程序与电路
下一篇:单片机点阵时钟原理图和源码

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

AVR单片机跑马灯的仿真设计
简易的跑马灯设计。基于AVR单片机仿真原理图如下:单片机源程序如下:/********************************************************************                            汇诚科技*********************************************************************/#include <iom16v.h>
发表于 2019-11-11
AVR单片机跑马灯的仿真设计
电池容量测试仪电路与源码(PIC16F1938单片机+AD623实现)
分享一个由PIC16F1938单片机芯片和AD623构成的电池容量测试仪.电路原理图如下:电池容量测试仪的pic单片机源码:#include    "main.h" //------------------------32MHZ---------------------------------------------- __CONFIG(FOSC_INTOSC & CLKOUTEN_OFF & BOREN_ON & PWRTE_ON & CPD_OFF          &CP_ON
发表于 2019-11-11
电池容量测试仪电路与源码(PIC16F1938单片机+AD623实现)
基于51单片机的DS18B20温控系统设计
单片机相对应的51汇编语言和结构化程序设计方法进行软件编程。程序设计语言有三种:机器语言、汇编语言和高级语言。机器语言是机器唯一能“懂”的语言,用汇编语言或高级语言编写的程序(称为源程序)最终都必须翻译成机器语言的程序(成为目标程序),计算机才能“看懂”,然后逐一执行。高级语言是面向问题和计算过程的语言,它可通过于各种不同的计算机,用户编程时不必仔细了解所用的计算机的具体性能与指令系统,而且语句的功能强,常常一个语句已相当于很多条计算机指令,于是用高级语言编制程序的速度比较快,也便于学习和交流,但是本系统却选用了汇编语言。原因在于,本系统是编制程序工作量不大、规模较小的单片机微控制系统,使用汇编语言可以不用像高级语言那样占用较多
发表于 2019-11-11
基于51单片机的DS18B20温控系统设计
BWT901CL的单片机和Arduino程序(蓝牙9轴)
//51单片机读取串口MPU6050模块的实例程序//测试平台://51单片机开发板YL-39,芯片STC89C52//注意://    1.51单片机的下载串口只有一个,同时又需要接MPU6050,因此在下载的时候需要拔下MPU6050的TX线,等程序下载成功以后再插上。//接线方法://     51单片机                  JY901模块//                +5V  
发表于 2019-11-11
单片机MQ-2烟雾检测+ADC0809 AD转换+lcd1602显示程序
单片机源程序如下:/*============================================================////程序编写:刘先生接线:D0--D7接P0.0-P0.7      ST---P2.3          EOC--P2.2          OE---P2.1          CLK--P2.0本程序源码只供学习参考,不得应用于商业用途,如有需要请联系作者。[注:使用12M或11.0592M晶振,实测
发表于 2019-11-11
单片机MQ-2烟雾检测+ADC0809 AD转换+lcd1602显示程序
STC15w4k58s4单片机4串口同时收发例程
STC15w4k58s4 芯片的4串口同时收发例程单片机源程序如下:#include "intrins.H"#include "uart.H"#define uchar unsigned  char#define uint  unsigned   intuchar uart1buf[6]={0xa5,0x5a,0x4a,0xf8,0xff,0xff};uchar uart2buf[6]={0xa5,0x5a,0x4a,0xf8,0xff,0xff};uchar uart3buf[6]={0xa5,0x5a,0x4a,0xf8,0xff,0xff};uchar
发表于 2019-11-11
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved