📄 xin.c
字号:
#include<reg51.h> //包含单片机寄存器的头文件
#include<intrins.h> //包含_nop_()函数定义的头文件
//x5045引脚定义
sbit SCK=P2^2; //将SCK位定义为P3.4引脚
sbit SI=P2^3; //将SI位定义为P3.5引脚
sbit SO=P2^1; //将SO位定义为P3.6引脚
sbit CS=P2^0; //将SCK位定义为P3.7引脚
//功能变量定义
#define WREN 0x06 //写使能锁存器允许
#define WRDI 0x04 //写使能锁存器禁止
#define WRSR 0x01 //写状态寄存器
#define READ 0x03 //读出
#define WRITE 0x02 //写入
#define uchar unsigned char
#define uint unsigned int
/***************电动机控制定义*******************/
sbit powder1L=P0^0;//普通电机1低电平正转
sbit powder1R=P0^1;//普通电机1低电平反转
sbit powder2L=P0^2;//步进电机2低电平正转
sbit powder2R=P0^3;//步进电机2低电平反转
sbit powder3L=P0^4;//步进电机3低电平正转
sbit powder3R=P0^5;//步进电机3低电平反转
sbit powder4L=P0^6;//步进电机4低电平正转
sbit powder4R=P0^7;//步进电机4低电平反转
sbit powder5L=P3^2;//步进电机5低电平正转
sbit powder5R=P3^3;//步进电机5低电平反转
/*****************步进电机脉冲信号**************/
sbit P25=P2^5;
sbit P26=P2^6;
sbit P27=P2^7;
/********************行程开关定义**************/
sbit K1=P1^0;
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;
sbit K5=P1^4;
sbit K6=P1^5;
sbit K7=P1^6;
sbit K8=P1^7;
sbit K9=P3^0;
sbit K10=P3^1;
sbit P24=P2^4;
/******************LED定义*////
sbit LED1=P3^4;
sbit LED2=P3^5;
/*****************************************************
函数功能:延时1ms
(3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒
***************************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++);
}
/*****************************************************
函数功能:延时若干毫秒
入口参数:n
***************************************************/
void delayms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
void delay4s()
{
unsigned char h,i,j,k;
for(h=20;h>0;h--)
for(i=4;i>0;i--)
for(j=116;j>0;j--)
for(k=214;k>0;k--);
}
/*****************************************************
函数功能:从X5045的当前地址读出数据
出口参数:x
***************************************************/
unsigned char ReadCurrent(void)
{
unsigned char i;
unsigned char x=0x00; //储存从X5045中读出的数据
SCK=1; //将SCK置于已知的高电平状态
for(i=0;i<8;i++)
{
SCK=1; //拉高SCK
SCK=0; //在SCK的下降沿输出数据
x<<=1; //将x中的各二进位向左移一位,因为首先读出的是字节的最高位数据
x|=(unsigned char)SO; //将SO上的数据通过按位"或"运算存入 x
}
return(x); //将读取的数据返回
}
/*****************************************************
函数功能:写数据到X5045的当前地址
入口参数:dat
***************************************************/
void WriteCurrent(unsigned char dat)
{
unsigned char i;
SCK=0; //将SCK置于已知的低电平状态
for(i=0;i<8;i++) // 循环移入8个位
{
SI=(bit)(dat&0x80); //通过按位"与"运算将最高位数据送到S
//因为传送时高位在前,低位在后
SCK=0;
SCK=1; //在SCK上升沿写入数据
dat<<=1; //将y中的各二进位向左移一位,因为首先写入的是字节的最高位
}
}
/*****************************************************
函数功能:写状态寄存器 ,可以设置看门狗的溢出时间及数据保护
入口参数:rs; //储存寄存器状态值
***************************************************/
void WriteSR(unsigned char rs)
{
CS=0; //拉低CS,选中X5045
WriteCurrent(WREN); //写使能锁存器允许
CS=1; //拉高CS
CS=0; //重新拉低CS,否则下面的写寄存器状态指令将被丢弃
WriteCurrent(WRSR); //写状态寄存器
WriteCurrent(rs); //写入新设定的寄存器状态值
CS=1; //拉高CS
}
/*****************************************************
函数功能:写数据到X5045的指定地址
入口参数:addr
***************************************************/
void WriteSet(unsigned char dat,unsigned char addr)
{
SCK=0; //将SCK置于已知状态
CS=0; //拉低CS,选中X5045
WriteCurrent(WREN); //写使能锁存器允许
CS=1; //拉高CS
CS=0; //重新拉低CS,否则下面的写入指令将被丢弃
WriteCurrent(WRITE); //写入指令
WriteCurrent(addr); //写入指定地址
WriteCurrent(dat); //写入数据
CS=1; //拉高CS
SCK=0; //将SCK置于已知状态
}
/*****************************************************
函数功能:从X5045的指定地址读出数据
入口参数:addr
出口参数:dat
***************************************************/
unsigned char ReadSet(unsigned char addr)
{
unsigned char dat;
SCK=0; //将SCK置于已知状态
CS=0; //拉低CS,选中X5045
WriteCurrent(READ); //开始读
WriteCurrent(addr); //写入指定地址
dat=ReadCurrent(); //读出数据
CS=1; //拉高CS
SCK=0; //将SCK置于已知状态
return dat; //返回读出的数据
}
/*****************************************************
函数功能:看门狗复位程序
***************************************************/
void WatchDog(void)
{
CS=1; //拉高CS
CS=0; //CS引脚的一个下降沿复位看门狗定时器
CS=1; //拉高CS
}
/*****************************************************
函数功能:主程序
***************************************************/
void main(void)
{ uchar V;
V=ReadSet(0x10);
delayms(10);
WriteSR(0x12); //写状态寄存器
delayms(10);
TMOD=0x21 ;
TH0=0xfe ;
TL0=0xe8 ; //280微秒
TH1=0x88 ; //120微秒
TL1=0x88 ;
EA=1;
ET0=1;
ET1=1;
TR0=1 ;
if(V==1)
{ powder1L=0;
delay4s();
}
if(V==2)
{
if(K1==1)
{
powder1L=1;
delayms(200);
powder2L=0;//第2台电机正转
delay4s();//未定的数值移动若干距离
powder2L=1;
delayms(200);
powder3L=0;//步时电机3正转触发单片机板进行控制
delayms(100);
powder3L=1;
delayms(200);
powder4L=0;//旋转后开始上升
}
}
if(V==3)
{ powder1L=1;
delayms(200);
powder2L=0;//第2台电机正转
delay4s();//未定的数值移动若干距离
powder2L=1;
delayms(200);
powder3L=0;//步时电机3正转触发单片机板进行控制
delayms(100);
powder3L=1;
delayms(200);
powder4L=0;//旋转后开始上升
}
if(V==4)
{ powder4L=1;
delayms(200);
powder2L=0;//电步进电机2开始工作
}
if(V==5)//遇行程开关K6电机2停止工作
{
powder2L=1;
delayms(200);
powder5L=0;//电机1第二次正转
}
if(V==6)//遇行程开关K8,电机1停止工作
{
powder5L=1;
delay4s();//电机1延时4秒后反转
powder5R=0;
//遇K7电机1停止工作
delay4s();
powder5R=1;
delayms(200);
powder2L=0;//第2台电机反转
powder2R=0;
delay4s();//未知数值
powder2L=1;
powder2R=1;
delayms(200);
powder4R=0;//第4台电机反转
powder4L=0;
}
if(V==7)
{ powder4R=1;
powder4L=1;
delayms(200);
powder3R=0;//第三台电动机反旋转
powder3L=0;
delayms(100);
powder3L=1;
delay4s();//延时4秒后停止
powder3R=1;
powder2R=0;//第2台电动机第二次反转
powder2L=0;
}
if(V==8)//遇行程开关K4停止
{
powder2R=1;
powder2L=1;
delayms(200);
powder1R=0;
}//第一台电机反转
if(V==9)
{
powder1R=1;
}
/* if(V==5)
{powder4L=1;
delayms(200);
powder5L=0;}
if(V==6)
{ powder5L=1;
LED2=0;
delay4s();
powder5R=0;//第5台电机反转
LED2=1;}
if(V==7)
{ powder5R=1;
delayms(200);
powder4R=0;//第4台电机反转
powder4L=0;}
if(V==8)
{ powder4R=1;
powder4L=1;
delayms(200);
powder3R=0;//第3台电机反转
powder3L=0;
LED1=0;}
if(V==9)
{
powder3R=1;
powder3L=1;
LED1=1;
delayms(200);
powder2R=0;//第2台电机反转
powder2L=0;
}
if(V==10)
{powder2R=1;
powder2L=1;
delayms(200);
powder1R=0;//第1台电机反转
}
if(V==11)
{ powder1R=1;
delay4s();
powder1L=0;
}*/
//X5045的写入周期约为10ms
while(1)
{
if(K1&K2==0)
{ WriteSet(0x01,0x10);
delayms(10);
delay4s();//延时4S启动
powder1L=0;//电机1开始工作
if(K3==0)//遇行程开关电机1停
{ WriteSet(0x02,0x10);
delayms(10);
if(K1==1)
{ WriteSet(0x03,0x10);
delayms(10);
powder1L=1;
delayms(200);
powder2L=0;//第2台电机正转
delay4s();//未定的数值移动若干距离
powder2L=1;
delayms(200);
powder3L=0;//步时电机3正转触发单片机板进行控制
delayms(100);
powder3L=1;
delayms(200);
powder4L=0;//旋转后开始上升
}
}
}
if(K5==0)//遇行程开关5,电机4停止工作
{
WriteSet(0x04,0x10);
delayms(10);
powder4L=1;
delayms(200);
powder2L=0;//电步进电机2开始工作
if(K6==0)//遇行程开关K6电机2停止工作
{ WriteSet(0x05,0x10);
delayms(10);
powder2L=1;
delayms(200);
powder5L=0;//电机1第二次正转
}
if(K7==0)//遇行程开关K8,电机1停止工作
{ WriteSet(0x06,0x10);
delayms(10);
powder5L=1;
delay4s();//电机1延时4秒后反转
powder5R=0;
//遇K7电机1停止工作
delay4s();
powder5R=1;
delayms(200);
powder2L=0;//第2台电机反转
powder2R=0;
delay4s();//未知数值
powder2L=1;
powder2R=1;
delayms(200);
powder4R=0;//第4台电机反转
powder4L=0;}
}
if(K2==0)
{ WriteSet(0x07,0x10);
delayms(10);
powder4R=1;
powder4L=1;
delayms(200);
powder3R=0;//第三台电动机反旋转
powder3L=0;
delayms(100);
powder3L=1;
delay4s();//延时4秒后停止
powder3R=1;
powder2R=0;//第2台电动机第二次反转
powder2L=0;
if(K4==0)//遇行程开关K4停止
{WriteSet(0x08,0x10);
delayms(10);
powder2R=1;
powder2L=1;
delayms(200);
powder1R=0;}//第一台电机反转
if(K1==0)
{ WriteSet(0x09,0x10);
delayms(10);
powder1R=1;
}
}
/*if(K4==0)
{ WriteSet(0x05,0x10);
delayms(10);
powder4L=1;
delayms(200);
powder5L=0;//第5台电机正转
}
if(K5==0)
{ WriteSet(0x06,0x10);
delayms(10);
powder5L=1;
LED2=0;
delay4s();
powder5R=0;//第5台电机反转
LED2=1;
}
if(K6==0)
{WriteSet(0x07,0x10);
delayms(10);
powder5R=1;
delayms(200);
powder4R=0;//第4台电机反转
powder4L=0;
}
if(K7==0)
{WriteSet(0x08,0x10);
delayms(10);
powder4R=1;
powder4L=1;
delayms(200);
powder3R=0;//第3台电机反转
powder3L=0;
LED1=0;
}
if(K8==0)
{ WriteSet(0x09,0x10);
delayms(10);
powder3R=1;
powder3L=1;
LED1=1;
delayms(200);
powder2R=0;//第2台电机反转
powder2L=0;
}
if(K9==0)
{ WriteSet(0x0A,0x10);
delayms(10);
powder2R=1;
powder2L=1;
delayms(200);
powder1R=0;//第1台电机反转
}
if(K10==0)
{ WriteSet(0x0B,0x10);
delayms(10); ;
powder1R=1;
delay4s();
powder1L=0;
}
*/
//将数据读出送P1口显示
WatchDog(); //复位看门狗
}
}
/*********************************************************/
// 定时器0 中断服务程序.
/*********************************************************/
void timer0() interrupt 1
{
TR1=0 ;
TH0=0xfe ;
TL0=0xe8 ; //280微秒
TH1=0x88 ; //120微秒
TL1=0x88;
TR1=1 ;
P25=0 ; //启动输出
P26=0;
P27=0;
}
/*********************************************************/
// 定时器1 中断服务程序
/*********************************************************/
void timer1() interrupt 3
{
TR1=0 ;
P25=1 ; //结束输出
P26=1;
P27=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -