较Version 1.0, 增加了对针臂步进电机、针臂停留底部时间的控制模块, 可通过给定参数以定量方式控制针臂抬起落下的速度或控制针臂在底部停留的时间.
硬件搭建:
8051单片机(STC89C52RC) + 若干杜邦线 + 虚拟接口卡 + 虚拟接口卡专用USB线 + 8051专用USB线.
连线对接:
P1.0 -> P20
P1.1 -> P21
P1.2 -> P22
P1.3 -> P03
P0.0 -> P00
P0.1 -> P01
P0.2 -> P02
注: 左侧为虚拟接口卡接口, 右侧为STC89C52RC接口.
在此补充一下驱动系统的命令:
1. Start.E命令: 启动系统.
2. Stop.E命令: 在一个周期序列动作完成后, 停止系统.
3. Rotate 0/1.E命令: 命令主转盘以顺时针/逆时针方向转动.
4. Main motor runs X(0 ~ 9).E命令: 在一个周期序列动作完成后, 停止系统, 以给定参数决定的速度, 转动X步主转盘.(这里借用针臂步进电机的时延函数来驱动主步进电机).
5. Main motor runs XX(10 ~ 99).E命令: 和4功能一致, 在给定的步数为两位数时使用.
6. Reset.E: 命令: 系统未进入到Start命令模式下且针臂未在该模式下进入到上下移位过程中, 针臂抬至上限位, 主转盘转至0号瓶位置, 之后停止工作.
7. Arm speeds XX, XX.E命令: 命令针臂以XX XX决定的参数上下移动.
8. Arm delays XXX, XXX.E命令: 命令针臂在底部停留的时间.
#include char tcount = 0; char step = 0;//记录主电机走过的步数(走过的步数=step/2) char buf[30];//存放命令 int en = 0;//en = 1 -> 系统工作, en = 0 -> 系统停止 int k = 0; int len = 0; int re = 0;//复位信号, 1 -> 复位, 0 -> 不复位 int direction = 0;//0 -> 顺时针, 1 -> 逆时针 int step_B = 0;//命令要求主电机转的步数 int motorRun = 0;// 1 -> 按命令转相应步数, 0 -> 无动作 int S1 = 300;//针臂在底部停留时间参数1 int S2 = 400;//针臂在底部停留时间参数2 int A1 = 40;//针臂电机参数1 int A2 = 40; //针臂电机参数2 void delay(int A1, int A2) { int i,j; for(i = 0; i < A1; i++) for(j = 0; j < A2 ; j++) { ;//为针臂步进电机提供时延 } } void delay2(int S1, int S2)//针臂在底部停留时延 { int i,j; for(i=0;i ; } } void motor_Control(int steps)//控制主转盘电机转动指定步数 { int i; for(i = 0; i < steps; i++) { P20 = 0; delay(A1, A2); P20 = 1; delay(A1, A2); } } void timer0() interrupt 1 { int i = 0; if(step == 0) { if(direction == 0) { P21 = 0;//顺时针 } else if(direction == 1) { P21 = 1;//逆时针 } } TR0 = 0;//关闭定时器0 TH0 = 0x3c; TL0 = 0xB0;//50ms if(re == 1)//复位信号起作用 { re = 0; //针臂移至上限位, 转盘转回0号瓶 P03 = 0;//往上转 while(P01 == 1)//若未到上限位置,P0.1接单片机P01 { P22 = 0; delay(A1, A2); P22 = 1; delay(A1, A2); } while(P00 == 1)//若未到0号瓶位置 { P20 = 0; delay(A1, A2); P20 = 1; delay(A1, A2); } //霍尔传感器有误差, 还差2.5格左右, 再发20个脉冲 if(P21 == 1)//转盘逆时针转过来 { while(i++ < 20) { P20 = 0; delay(A1, A2); P20 = 1; delay(A1, A2); } } else if(P21 == 0)//转盘顺时针转过来 { while(i++ < 22) { P20 = 0; delay(A1, A2); P20 = 1; delay(A1, A2); } } tcount = 0; en = 0; step = 0; goto END; } if(motorRun == 1)//电机按要求转命令起作用 { motorRun = 0; step = 0; tcount = 0; en = 0; motor_Control(step_B); step_B = 0; goto END; } tcount++; if(tcount == 2)//100ms = 0.1s { P20 = ~P20;//P20翻转,相当于发送脉冲 tcount = 0; step ++; if(step / 2 == 8)//电机走了8步(经历了8次高低电平的转换) { step = 0;//将步数归零 //P1.3=1代表向下,P1.3=0代表向上 P03 = 1;//往下转,P13接单片机P03 while(P02 == 1)//若未到下限位置,P0.2接单片机P02 { P22 = 0; delay(A1, A2); P22 = 1; delay(A1 ,A2); } delay2(S1, S2);//针臂在底部停留片刻 P03 = 0;//往上转 while(P01 == 1)//若未到上限位置,P0.1接单片机P01 { P22 = 0; delay(A1, A2); P22 = 1; delay(A1, A2); } } }//1000ms = 1s 发送一个完整的脉冲 END: ; TR0 = 1;//开启定时器0 } void UART_INT() interrupt 4//串行通信中断处理程序 { int len = 0; int j = 0; if(RI == 1)//如果收到数据 { if(k == 30) { k = 0;//防止越界访问 } RI = 0; buf[k++] = SBUF;//将数据接收下来 if(buf[k - 1] == 'E')//到达结尾 { len = k - 1;//记录数据长度 k = 0; if(len == 6) { if(buf[0] == 'S' && buf[1] == 't' && buf[2] == 'a' && buf[3] == 'r' && buf[4] == 't' && buf[5] == '.') { //Start命令(开机) en = 1; P27 = 0;//D8亮 P26 = 1; P25 = 1; P24 = 1; //再将en的值传回去 SBUF = en + 48; } else if(buf[0] == 'R' && buf[1] == 'e' && buf[2] == 's' && buf[3] == 'e' && buf[4] == 't' && buf[5] == '.')//主转盘回到原始位置,针臂抬到最高位置 { //Reset命令(复位命令) en = 1; P27 = 1; P26 = 0;//D7亮 P25 = 1; P24 = 1; SBUF = en + 48; re = 1;//复位信号 } } else if(len == 5)//停机命令 { if(buf[0] == 'S' && buf[1] == 't' && buf[2] == 'o' && buf[3] == 'p' && buf[4] == '.') { //Stop命令(停机命令) en = 0; P27 = 1; P26 = 1;
上一篇:8051单片机串行通信参数设置(8位UART+timer1 8位自动重装)
下一篇:8051单片机(STC89C52)八灯从中间往两边亮
推荐阅读最新更新时间:2024-11-20 10:42