标题:
步进电机正反转调速LCD显示实验程序
[打印本页]
作者:
daming
时间:
2014-12-30 01:32
标题:
步进电机正反转调速LCD显示实验程序
#include <reg52.h> //51芯片管脚定义头文件
#include <intrins.h> //内部包含延时函数 _nop_();
#define uchar unsigned char
#define uint unsigned int
uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //正转相序
uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1}; //反转相序
sbit K1 = P3^2; //运行与停止
sbit K2 = P3^3; //速率调整
sbit K3 = P3^4; //方向转换
sbit BEEP = P3^6; //蜂鸣器
sbit RS = P2^0; //液晶管脚定义
sbit RW = P2^1;
sbit E = P2^2;
sbit BF=P0^7; //忙碌标志位
bit on_off=0; //运行与停止标志
bit direction=1; //方向标志
uchar rate=2; //预设定速率
uchar data_temp;
uchar u=0,v=0;
uchar code cdis1[ ] = {" STEPPING MOTOR "};
uchar code cdis2[ ] = {"CONTROL PROCESS"};
uchar code cdis3[ ] = {" STOP "};
uchar code cdis4[ ] = {" RATE: "};
uchar code cdis5[ ] = {" RUNNING "};
/********************************************************/
/*
/* 延时t毫秒
/* 11.0592MHz时钟,延时约1ms
/*
/********************************************************/
void delay(uint t)
{
uchar k;
while(t--)
{
for(k=0; k<125; k++)
{ }
}
}
/********************************************************/
void delayB(uchar x) //x*0.14MS
{
uchar i;
while(x--)
{
for (i=0; i<13; i++)
{ }
}
}
/********************************************************/
void beep()
{
uchar j;
for (j=0;j<100;j++)
{
delayB(4);
BEEP=!BEEP; //BEEP取反
}
BEEP=1; //关闭蜂鸣器
delay(170);
}
/********************************************************/
/*
/*检查LCD忙状态
/*BF为1时,忙,等待。为0时,闲,可写指令与数据。
/*
/********************************************************/
bit BusyTest()
{
bit result;
RS = 0;
RW = 1;
E= 1;
_nop_();
_nop_();
result = BF;
E = 0;
return(result);
}
/*****************************************************
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
***************************************************/
void WriteInstruction (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0; //E置低电平(写指令时,
// 就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空操作两个机器周期,给硬件反应时间
P0=dictate; //将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:指定字符显示的实际地址
入口参数:x
***************************************************/
void WriteAddress(unsigned char x)
{
WriteInstruction(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/*****************************************************
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
***************************************************/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0; //E置低电平(写指令时,,
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=y; //将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空操作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/*****************************************************
函数功能:对LCD的显示模式进行初始化设置
***************************************************/
void LcdInt(void)
{
delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction (0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delay(5); //延时5ms
WriteInstruction (0x38);
delay(5);
WriteInstruction (0x38); //3次写 设置模式
delay(5);
WriteInstruction (0x0c); //显示模式设置:显示开,无
delay(5);
WriteInstruction (0x06); //显示模式设置:光标右移,字符不移
delay(5);
WriteInstruction (0x01); //清屏幕指令,将以前的显示内容清除
delay(5);
}
/********************************************************/
/*
/* LCD1602初始显示子程序
/*
/********************************************************/
void LcdInt_Dis()
{
uchar i=0;
LcdInt();
delay(15);
WriteInstruction(0x01);
delay(5);
WriteAddress(0x00);
delay(5);
while(cdis1[i]!='\0'){
WriteData(cdis1[i]);
delay(5);
i++;
}
WriteAddress(0x40);
delay(5);
i=0;
while(cdis2[i]!='\0'){
WriteData(cdis2[i]);
delay(5);
i++;
}
delay(3000);
WriteInstruction(0x01); //清屏
delay(5);
i=0;
WriteAddress(0x00);
delay(5);
while(cdis3[i]!='\0'){
WriteData(cdis3[i]);
delay(5);
i++;
}
WriteAddress(0x40);
delay(5);
i=0;
while(cdis4[i]!='\0'){
WriteData(cdis4[i]);
delay(5);
i++;
}
WriteAddress(0x0c);
delay(5);
for(i=0;i<2;i++) //显示方向符号
WriteData(0x3e);
}
/********************************************************/
/*
/*数据显示子程序
/*
/********************************************************/
void data_dis()
{
data_temp = rate; //显示速率
WriteAddress(0x4c);
WriteData(data_temp+0x30);
delay(5);
}
/********************************************************
/*
/* 显示运行方向符号
/*
/********************************************************/
void dr_dis()
{
uchar i=0;
WriteAddress(0x0c); //显示方向符号
if(direction==1) //正转方向标
{
for(i=0;i<2;i++){
WriteData(0x3e);
delay(5);
}
}
else
{
for(i=0;i<2;i++){ //反转方向标志
WriteData(0x3c);
delay(5);
}
}
}
/********************************************************
/*
/* 显示运行状态
/*
/********************************************************/
void run_dis()
{
uchar i=0;
if(on_off==1){
WriteAddress(0x00);
delay(5);
for(i=0;cdis5[i]!='\0';i++){
WriteData(cdis5[i]);
delay(5);
}
}
else{
WriteAddress(0x00);
delay(5);
for(i=0;cdis3[i]!='\0';i++){
WriteData(cdis3[i]);
delay(5);
}
}
}
/********************************************************/
/*
/*步进电机正转
/*
/********************************************************/
void motor_ffw()
{
unsigned char i;
unsigned char j;
for (j=0; j<8; j++)
{
for (i=0; i<8; i++) //一个周期转45度
{
P1 = FFW[i]; //取数据
delay(rate); //调节转速
}
}
}
/********************************************************/
/*
/*步进电机反转
/*
/********************************************************/
void motor_rev()
{
unsigned char i=0;
unsigned int j=0;
for (j=0; j<8; j++)
{
for (i=0; i<8; i++) //一个周期转45度
{
P1 = REV[i]; //取数据
delay(rate); //调节转速
}
}
}
/********************************************************
*
* 主程序
*
*********************************************************/
void main()
{
LcdInt_Dis(); //液晶初始化
TMOD=0X01; //定时器T0工作方式1
EA=1; //开总中断
ET0=1; //开T0中断
TH0=(65536-1000)/256;
TL0=(65536-1000)%256; //定时1ms;
TR0=1; //启动T0
P1=0X0F; //关闭电机
while(1){
/**************************************/
if(K1==0){
delay(15); //延时消陡
if(K1==0){
on_off=~on_off; //取反
beep();
while(K1==0); //等待按键释放
}
}
/**************************************/
if(K2==0){
delay(15);
if(K2==0){
rate++;
if(rate==0x0a) //若rate=10,则回到2重新开始
rate=2;
beep();
while(K2==0);
}
}
/**************************************/
if(K3==0){
delay(15);
if(K3==0){
direction=~direction;
beep();
while(K3==0);
}
}
/**************************************/
data_dis();
run_dis();
dr_dis();
};
}
/***************************************
定时器0中断
***************************************/
void t0() interrupt 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
v++;
if(v<rate) //每个脉冲间隔v*1ms
return;
else{
v=0;
if(on_off==1){
if(u==8)
u=0;
if(direction==1) //正转脉冲
P1=FFW[u];
else
P1=REV[u]; //反转脉冲
u++;
}
}
}
复制代码
作者:
jk123
时间:
2015-3-11 20:04
请问大神这段程序void delayB(uchar x) //x*0.14MS{uchar i; while(x--){for (i=0; i<13; i++)有什么作用呢, 还有那个TL0=0X33,TH0=0xf5和你的程序里的TH0=(65536-1000)/256;
TL0=(65536-1000)%256是一样的吗
作者:
木君哥哥
时间:
2017-12-5 15:28
有proteus电路图吗?
作者:
木君哥哥
时间:
2017-12-5 15:33
楼主有proteus电路图吗?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1