简单测速程序
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/*实现功能:电机测速
使用芯片:AT89S52 或者STC89C52 或AT89S51 STC89C51
晶振:12MHZ
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
//==============LCD1602接口连接方法=====================
/*-----------------------------------------------------
|DB0-----P0.0 | DB4-----P0.4 | RW-------P2.3 |
|DB1-----P0.1 | DB5-----P0.5 | RS-------P2.4 |
|DB2-----P0.2 | DB6-----P0.6 | E--------P2.2 |
|DB3-----P0.3 | DB7-----P0.7 |
---------------------------------------------------*/
//================================================*/
#define LCM_Data P0 //LCD1602数据接口
#define Busy 0x80 //用于检测LCM状态字中的Busy标识
sbit LCM_RW = P2^3; //读写控制输入端,LCD1602的第五脚
sbit LCM_RS = P2^4; //寄存器选择输入端,LCD1602的第四脚
sbit LCM_E = P2^2; //使能信号输入端,LCD1602的第6脚
//=================计数传感模块连接=====================
/*-----------------------------------------------------
|VCC-----VCC | GND-----GND | OUT-------P3.2
---------------------------------------------------*/
sbit OUT=P3^2;
//**************函数声明***************************************
void WriteDataLCM (uchar WDLCM);//LCD模块写数据
void WriteCommandLCM (uchar WCLCM,BuysC); //LCD模块写指令
uchar ReadStatusLCM(void);//读LCD模块的忙标
void DisplayOneChar(uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符void LCMInit(void);//LCD初始
void DelayMs(uint Ms);//1MS基准延时程序
uint total,zhuansu;
uchar t0_count;
#define canshu=2;//参数,如果电机转一圈,计数器检测到几次,这里的参数就要相应修改//***********************主程序******************************
main()
{
TMOD=0x01;//定时器T0为定时器工作方式1
TCON=01;//设定外部中断0为边沿触发方式
TH0=0X3C;
TL0=0XB0;//设定定时器TO为50MS
TR0=1;//启动定时器T0
ET0=1;
EA=1;//开启外部中断
LCMInit();//LCD初始
total=20;
t0_count=0;
OUT=1;
DisplayOneChar(0, 0,'T');//显示:T
DisplayOneChar(0, 1,':');//显示::
DisplayOneChar(0, 2, zhuansu/1000+0x30);//显示十位数据
DisplayOneChar(0, 3, zhuansu/100%10+0x30);//显示个位数据
DisplayOneChar(0, 4,zhuansu/10%10+0x30);//
DisplayOneChar(0, 5, zhuansu%10+0x30); //显示百位数据
EX0=1;//允许外部中断0
while(1)
{
DisplayOneChar(0, 0,'T');//显示:T
DisplayOneChar(0, 1,':');//显示::
DisplayOneChar(0, 2, zhuansu/1000+0x30);//显示十位数据
DisplayOneChar(0, 3, zhuansu/100%10+0x30);//显示个位数据
DisplayOneChar(0, 4,zhuansu/10%10+0x30);//
DisplayOneChar(0, 5, zhuansu%10+0x30); //显示百位数据
DisplayOneChar(1, 0,'C');//显示:T
DisplayOneChar(1, 1,':');//显示::
DisplayOneChar(1, 2, total/1000+0x30);//显示十位数据
DisplayOneChar(1, 3, total/100%10+0x30);//显示个位数据
DisplayOneChar(1, 4,total/10%10+0x30);//
DisplayOneChar(1, 5, total%10+0x30); //显示百位数据}
}
//****外部中0中断入口
void ex0_in() interrupt 0
{
total++;
}
//***************定时器T0中断
void t0_int() interrupt 1
{
TH0=0X3C;
TL0=0XB0;//重新装载定时T0
t0_count++;
if(t0_count==20)//中断20次为1秒
{
t0_count=0;
zhuansu=total/canshu;
total=0;
}
}
/*======================================================================
LCM初始化
======================================================================*/
void LCMInit(void)
{
LCM_Data = 0;
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
DelayMs(5);
WriteCommandLCM(0x38,0);
DelayMs(5);
WriteCommandLCM(0x38,0);
DelayMs(5);
WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示
WriteCommandLCM(0x01,1); //显示清屏
WriteCommandLCM(0x06,1); // 显示光标移动设置
WriteCommandLCM(0x0C,1); // 显示开及光标设置[;.
DelayMs(100);
}
//==============================LCD1602显示子程序================================================
// 写数据函数: E =高脉冲RS=1 RW=0
//======================================================================*/
void WriteDataLCM(uchar WDLCM)
{
ReadStatusLCM(); //检测忙
LCM_Data = WDLCM;
LCM_RS = 1;
LCM_RW = 0;
LCM_E = 0; //若晶振速度太高可以在这后加小的延时
LCM_E = 0; //延时
LCM_E = 1;
}
/*====================================================================
写指令函数: E=高脉冲RS=0 RW=0
======================================================================*/
void WriteCommandLCM(uchar WCLCM,BuysC) //BuysC为0时忽略忙检测
{
if (BuysC) ReadStatusLCM(); //根据需要检测忙
LCM_Data = WCLCM;
LCM_RS = 0;
LCM_RW = 0;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
}
/*==================================================================== 正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;
DB7: 0 LCD控制器空闲,1 LCD控制器忙。
读状态
======================================================================*/ uchar ReadStatusLCM(void)
{
LCM_Data = 0xFF;
LCM_RS = 0;
LCM_RW = 1;
LCM_E = 0;
LCM_E = 0;
LCM_E = 1;
while (LCM_Data & Busy); //检测忙信号
return(LCM_Data);
}
/*====================================================================== 功能: 在1602 指定位置显示一个字符:第一行位置0~15,第二行16~31
说明: 第X 行,第y 列注意:字符串不能长于16个字符
======================================================================*/ void DisplayOneChar( uchar X, uchar Y, uchar ASCII)
{
X &= 0x1;
Y &= 0xF; //限制Y不能大于15,X不能大于1
if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;
Y |= 0x80; // 算出指令码
WriteCommandLCM(Y, 0); //这里不检测忙信号,发送地址码
WriteDataLCM(ASCII);
}
/*==================================================================== 设定延时时间:x*1ms
====================================================================*/ void DelayMs(uint Ms)
{
uint i,TempCyc;
for(i=0;i<Ms;i++)
{
TempCyc = 250;
while(TempCyc--);
} }。