完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
#include"STC_NEW_8051.H" #include"delay.h" #include"INTRINS.H" #define uchar unsigned char #define uint unsigned int #define ON 0 #define OFF 1 #define LOW 0 #define HIGH 1 #define M_tiME 100//定义不进电机频率为75 /*-----------inductor-----------*/ //感应器端口定义 ***it G=P0^0; //用做步进电机原点感应器 ***it L = P0^4; //标志步进电机终点感应器 ***it zhengzhuan=P0^1; //手动 正转 ***it fanzhuan=P0^2; //手动 反转 ***it zidong=P0^3; //自动 /*----------motor_GPIO()---------*/ //马达输出口定义 ***it M_Z = P2^0 ; //脉冲正极, ***it M_F = P2^1; //脉冲负极, unsigned char date ,CHZT; #define BUFSIZE 80//定义串口字节数组长度保存变量 uchar idata Rec_Buff[BUFSIZE]; //接收字符数组BUFSIZE长度 uchar Rec_cnt = 0; bit Rec_ok; uint Rec_timeout; uchar stop_cnt = 0; void zz_key_press(); void zd_key_press(); void fz_key_press(); void init_m(); void Send_Buf(uchar *p,uchar len) ; void init_com() ; void clear_rec(); void zd(); uint i , j = 300; void main() { zhengzhuan = 1; fanzhuan = 1; G = 1; L = 1; M_Z = 0; M_F = 0; init_m(); // 初始化步进电机归初始状态 init_com(); Send_Buf("*******rn",9); while(1) { if(Rec_ok == 1) { if(Rec_Buff[0]=='s') //start { Send_Buf("**srn",5); //测试是否进入 if(Rec_Buff[1]=='t') { if(Rec_Buff[2]=='a') { if(Rec_Buff[3]=='r') { if(Rec_Buff[4]=='t') { zd(); Send_Buf("start_okn",9); } } } } } if(Rec_Buff[0]=='l') //left { Send_Buf("lrn",3); //测试是否进入 if(Rec_Buff[1]=='e') { Send_Buf("ern",3); //测试是否进入 if(Rec_Buff[2]=='f') { Send_Buf("frn",3); //测试是否进入 if(Rec_Buff[3]=='t') { Send_Buf("trn",3); //测试是否进入 M_F = 0; for(i=0;i<=j && L == 1;i++) { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } Send_Buf("left_okn",9); } } } } if(Rec_Buff[0]=='r') //right { Send_Buf("rrn",3); //测试是否进入 if(Rec_Buff[1]=='i') { if(Rec_Buff[2]=='g') { if(Rec_Buff[3]=='h') { if(Rec_Buff[4]=='t') { M_F = 1; for(i=0;i<=j && G == 1;i++) { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } Send_Buf("right_okn",10); } } } } } Rec_ok = 0; clear_rec(); Rec_cnt = 0; } zz_key_press(); fz_key_press(); zd_key_press(); } } /**************初始化串口通讯函数********************/ void init_com() //COM初始化 { AUXR=0x20; SCON=0x50; PCON=0x00; TMOD=0x21; TH1=0xfa; TL1=0xfa; PS=1; EA=1; ES=1; TR1=1; } void send_byte(char date) { ES=0; REN=0; //TI = 0; SBUF=date; while(!TI); TI = 0; //串口发送完毕后,将在标志位TI置0 REN=1; ES=1; } void Send_Buf(uchar *p,uchar len) //发送函数 *P(字符串) len(字符串的长度) { while(len>0) { send_byte(*p); p++; len--; } } void clear_rec() //清空 Rec_Buff[BUFSIZE]里面的数据 { uchar i; for(i=0;i Rec_Buff[i] = 0; } } //******************检测串行中断********************// void RX_com() interrupt 4 { //Send_Buf("testrn",6); if(TI) { TI = 0; } if(RI) { RI=0; Rec_timeout = 0;//超时函数 Rec_Buff[Rec_cnt] = SBUF; //循环把SBUF(串口接收的字符串)保存在数组 Rec_Buff[]里面 数组长度 BUFSIZE Send_Buf("test_RIrn",9); //测试是否进入 if((Rec_Buff[0]=='s')) { stop_cnt = 5;//假如是s开头,默认为start ,stop_cnt = 5; Send_Buf("srn",3); //测试是否进入 if((Rec_Buff[1]=='t')) { Send_Buf("trn",3); //测试是否进入 } }else if((Rec_Buff[0]=='l')) { stop_cnt = 4; //假如是l开头,默认为left ,stop_cnt = 4; Send_Buf("l**rn",5); //测试是否进入 }else if((Rec_Buff[0]=='r')) { stop_cnt = 5; //假如是r开头,默认为right ,stop_cnt = 5; Send_Buf("rrn",3); //测试是否进入 } Rec_cnt++; if(Rec_cnt>=BUFSIZE) { Rec_cnt = 0; ES =0 ; } if(BUFSIZE>=stop_cnt) { Rec_ok = 1; Send_Buf("test_rec_okrn",13); //测试是否进入 } }else{ Rec_ok = 0; ES =0 ; //关中断,回复完了再ES=1; } } void zd() { M_F = 0; while(L == 1 ) { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } M_F=1; while( G == 1)//当原点感应器不在初始状态下,步进电机回原点 { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } } /**************自动按钮控制函数********************/ void zd_key_press() { if(CHZT = 1)//只有在步进电机在初始位置,自动按钮才生效 { if(zidong == 0 ) { delay_us(20); if(zidong == 0 || G == 0 ) { zd(); } CHZT = 1;//标志步进电机在初始位置 } } } /**************手动反转按钮控制函数********************/ void fz_key_press() { if(fanzhuan == 0) { delay_us(20); if(fanzhuan == 0 ) { M_F = 1; /*while(fanzhuan == 0 ) //反转按钮按下,而且初始状态感应器断开,才可以转。 { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } */ if(G == 1) { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } CHZT = 1;//标志步进电机在初始位置 } } } /**************手动正转按钮控制函数********************/ void zz_key_press() { if(zhengzhuan == 0) { delay_us(20); if(zhengzhuan == 0) { M_F = 0; /*while(zhengzhuan == 0 || L == 1) //正转按钮按下,而且初始状态感应器断开,才可以转。 { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); }*/ if(L == 1) { M_Z = 1; delay_us(M_TIME); M_Z = 0; delay_us(M_TIME); } CHZT = 1;//标志步进电机在初始位置 } } } /**************初始化不进电机位置控制函数********************/ void init_m() { M_F = 1; while(G == 1) //当原点感应器不在初始状态下,步进电机回原点 { M_Z=1; delay_us(M_TIME); M_Z=0; delay_us(M_TIME); } CHZT = 1;//标志 步进电机在初始位置 }
|
|
相关推荐
7个回答
|
|
代码真心好长,大概看了下。首先你得把串口接收中断中的代码缩短,太长了,可能会在上位机发数据的时候你上一次的中断还没退出来,导致接收数据有误。中断执行时间要短!!!!给你个参考
数据接收到缓冲区后拿到中断外面去处理。还要做好错误帧的识别,假如数据接收数大于你设置的stop_cnt了,但是不是你要的指令怎么办?后续的数组要接收满了才能清零从0开始? 还有一帧数据和一帧数据要有个间隔时间,后续还有很多可以完善的地方。代码嵌套的也好多,你不头晕吗? |
|
|
|
HARRY007 发表于 2016-10-12 22:11 就是头晕,现在不知道哪里出了错误。 |
|
|
|
HARRY007 发表于 2016-10-12 22:11 大哥,可以把你给的代码注释一下吗?我不怎么懂 |
|
|
|
自己先看看测试结果和程序之间 的对于关系
|
|
|
|
恩,我觉得自己的逻辑没有错,就是代码不知道哪里错了。弄成这样的结果 |
|
|
|
跟你说了不要在串口中断中处理那么多数据,尤其是还要发数据出去,假如都是波特率都是9600,接收一个数据后第二个数据来了你还在中断里发送你的那些啥“测试是否进入”之类的东西,都删掉 |
|
|
|
我给你的代码本来有注释的,复制过来是乱码我就删除了。 cntRxd_RS485跟你设置的Rec_cnt一个意思,缓冲数据最大128字节。 USART_ReceiveData(UART4);就是等同于51里的SBUF,表示进来一个字节的数据。 Rs485_Buf[cntRxd_RS485++]表示每接收一个数据就放入buf里,cntRxd_RS485加1,以便接收下一个数据。 cntRxd_RS485的清零都在中断外部处理的,buf里的数据识别也都是在中断外面。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
203 浏览 0 评论
761 浏览 0 评论
806 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
743 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
1195 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11811 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-28 05:36 , Processed in 0.607233 second(s), Total 53, Slave 46 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号