完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
用单片机设计一个步进电机控制器。要求能对步进电机实现正、反转及速度控制,同时能对步进电机进行位置控制,即能控制步进电机从一个位置精确地运行到另一个位置。步进电机为四相反应式,软件生成脉冲序列,可设置参数和运行状态参数实时显示。威廉希尔官方网站
要求 1. 转速:0—3000r/m,误差1‰;2. 角位移控制:2º—9999º;3. 方向:可逆;4. 可设置参数和运行状态参数实时显示。
下面是我写的一个简单的程序,但是我不知道该怎么修改才能满足题目的要求以及转速和角位移的显示程序,麻烦各位帮我看看,说说你们的想法,现在这谢了啊 #include #include #define uchar unsigned char #define uint unsigned int uchar i,j,k; uchar code zhengcode[8]={0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09}; //四相八拍正转编码 uchar code fancode[8]={0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01}; ////四相八拍反转编码 ***it K1 = P3^2; //正转 ***it K2 = P3^3; //反转 ***it K3 = P3^4; //停止 void main() { TMOD=0X01; TH0=0xff; TL0=0xf6; //定时0.01ms EA=1; ET0=1; TR0=1; i=0; j=0; k=100; if(K1==0) { while(1) { P1=zhengcode[i]; if(K3==0) {break;} } } else if(K2==0) { while(1) { P1=fancode[j]; if(K3==0) {break;} } } else P1=0xf0; } void intt0() interrupt 1 { k--; TH0=0xff; TL1=0xf6; if(k==0) { k=100; i++; j++;} if(i==7) {i=0;} if(j==7) {j=0;} }
|
|
相关推荐
10个回答
|
|
你现在能控制电机正反转动了吗?我也没有做过,一步一步的做吧,先让电机转起来,再来调速, 精度之类的功能
|
|
|
|
|
|
不知道你显示部分电路有了没有,是用液晶显示,还是用LED,请先说明一下,对应的外部电路有,才好对应进行编程...
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这个问题是要能够设定步进电机的转速啊,通过键盘设定。你会编写这个程序吗?
下面是我的完整程序,就是我调节的转速好没有与实际的转速一一对应。你能帮我改写吗? #include #include void delayNOP() {_nop_();_nop_();_nop_();_nop_();} #define uchar unsigned char #define uint unsigned int ***it LCD_RS = P2^0; ***it LCD_RW = P2^1; ***it LCD_EN = P2^2; uchar keycode,scan1,scan2; uchar chuzhi; uchar shedingzhuansu[4]={0x00,0x01,0x00,0x00}; //存储转速 uchar shedingjiaodu[4]={0x03,0x00,0x00,0x00}; //存储角度 uint zhuanguojiaodu=0,number;//计算转过的角度和脉冲计数 uchar code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //反转码 uchar code REV[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1}; //正传码 uchar m,v=0,q=0; uint zhuansu,jiaodu; //设置的转速和角度 bit zhengrunflag=0,fanrunflag=0,stopflag=0,zhuansushezhiflag=1,jiaodushezhiflag=0,shuzi; //区分控制键和数字键标志 bit on_off=0; //运行与停止标志 bit direction; //正反标志 uint data_temp,data_temP1,data_temp2,data_temp3,data_temp4; void delay(uint t) //延时函数 { uchar k; while(t--) { for(k=0; k<125; k++) { } } } bit lcd_busy() // 检查LCD忙不忙 { bit result; LCD_RS = 0; LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); LCD_EN = 0; return(result); } void lcd_wcmd(uchar cmd) // LCD写指令 { while(lcd_busy()); LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } void lcd_wdat(uchar dat) //LCD写数据 { while(lcd_busy()); LCD_RS = 1; LCD_RW = 0; LCD_EN = 0; P0 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } void lcd_clr() // LCD清屏 { lcd_wcmd(0x01); delay(5); } void lcd_init() // LCD初始化 { delay(30); lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay(5); lcd_wcmd(0x38); delay(5); lcd_wcmd(0x38); delay(5); lcd_wcmd(0x0c); //显示开,关光标 delay(5); lcd_wcmd(0x06); //移动光标 delay(5); lcd_wcmd(0x01); //清除LCD的显示内容 delay(5); } uchar keyscan()//矩阵键盘线反转法扫描程序 { uchar i=0; P3=0xf0; scan1=P3; if(scan1!=0xf0) { delay(8); if(scan1!=0xf0) { P3=0x0f; scan2=P3; keycode=(scan1|scan2); switch(keycode) { case 0xee: zhengrunflag=1;shuzi=0;break; case 0xde: fanrunflag=1;shuzi=0;break; case 0xbe: stopflag=1;shuzi=0;break; case 0xed: zhuansushezhiflag=1;shuzi=0;break; case 0xdd: jiaodushezhiflag=1;shuzi=0;break; case 0xbd: chuzhi=0;shuzi=1;break; case 0x7d: chuzhi=1;shuzi=1;break; case 0xeb: chuzhi=2; shuzi=1;break; case 0xdb: chuzhi=3;shuzi=1;break; case 0xbb: chuzhi=4;shuzi=1;break; case 0x7b: chuzhi=5;shuzi=1;break; case 0xe7: chuzhi=6;shuzi=1;break; case 0xd7: chuzhi=7;shuzi=1;break; case 0xb7: chuzhi=8;shuzi=1;break; case 0x77: chuzhi=9;shuzi=1;break; } } else shuzi=0; } else shuzi=0; return shuzi; } void zhuansutiaojie() // 转速调节程序 { uint i, j=0; for(i=0;i<4;i++) { while(!keyscan()) {;} shedingzhuansu[j]=chuzhi; lcd_wcmd(j|0x80); lcd_wdat(shedingzhuansu[j]+0x30); j++; delay(500); } zhuansushezhiflag=0; zhuansu=shedingzhuansu[0]*1000; zhuansu=zhuansu+shedingzhuansu[1]*100; zhuansu=zhuansu+shedingzhuansu[2]*10; zhuansu=zhuansu+shedingzhuansu[3];//设定的转速 } void jiaodutiaojie() // 角度调节 { uint i,j=0; for(i=0;i<4;i++) { while(! keyscan()); {;} shedingjiaodu[j]=chuzhi; lcd_wcmd((0x40+j)|0x80); lcd_wdat(shedingjiaodu[j]+0x30); j++; delay(500); } jiaodushezhiflag=0; jiaodu=shedingjiaodu[0]*1000; jiaodu=jiaodu+shedingjiaodu[1]*100; jiaodu=jiaodu+shedingjiaodu[2]*10; jiaodu=jiaodu+shedingjiaodu[3]; //设置的角度 } void data_conv() // 数据转化函数 { data_temP1=data_temp/1000; data_temP1=data_temP1+0x30; data_temp2=data_temp%1000/100; data_temp2=data_temp2+0x30; data_temp3=data_temp%1000%100/10; data_temp3=data_temp3+0x30; data_temp4=data_temp%10; data_temp4=data_temp4+0x30; } void data_dis() //步进电机显示函数 { data_temp = zhuanguojiaodu; //显示转过角度 data_conv(); lcd_wcmd(0x48|0x80); lcd_wdat(data_temP1); lcd_wcmd(0x49|0x80); lcd_wdat(data_temp2); lcd_wcmd(0x4a|0x80); lcd_wdat(data_temp3); lcd_wcmd(0x4b|0x80); lcd_wdat(data_temp4); } void motor_DR() { if(direction==1) {lcd_wcmd(0x47|0x80); lcd_wdat(0x2b); } else { lcd_wcmd(0x47|0x80); lcd_wdat(0x2d); } } void motor_RUN() // 步进电机运转子程序 { if(on_off==1) { TR0=1; motor_DR(); } else { TR0=0; P1 =0x0f; } } void main() //主程序 { delay(10); lcd_init(); lcd_clr(); lcd_wcmd(0x00|0x80); lcd_wdat(shedingzhuansu[0]+0x30); lcd_wdat(shedingzhuansu[1]+0x30); lcd_wdat(shedingzhuansu[2]+0x30); lcd_wdat(shedingzhuansu[3]+0x30); lcd_wcmd(0x40|0x80); lcd_wdat(shedingjiaodu[0]+0x30); lcd_wdat(shedingjiaodu[1]+0x30); lcd_wdat(shedingjiaodu[2]+0x30); lcd_wdat(shedingjiaodu[3]+0x30); TMOD = 0x01; //T0定时方式1 TL0 = 0x9c; //定时时间为0.1ms TH0 = 0xff; EA = 1; ET0 = 1; P1 = 0x0f; while(1) { keyscan(); if(zhuansushezhiflag==1) // 开始调节速度 { zhuansutiaojie();} if(jiaodushezhiflag==1) //开始调节角度 { jiaodutiaojie();} if(zhengrunflag==1) //正转键 { zhuanguojiaodu=0; number=0; on_off=1; direction=1; motor_RUN(); zhengrunflag=0; } if(fanrunflag==1) // 反转键 { zhuanguojiaodu=0; number=0; on_off=1; direction=0; motor_RUN(); fanrunflag=0; } if(stopflag==1) // 停止键 { on_off=0; motor_RUN(); stopflag=0; } if(zhuanguojiaodu==jiaodu) //判断是否达到了设置角度 { zhuanguojiaodu=0; P1=0x0f; on_off=0; motor_RUN(); } data_dis(); //显示函数 } } void motor_onoff() interrupt 1 //定时器0中断服务程序 { TL0 = 0x9c; TH0 = 0xff; q++; if(q else { q=0; number++; //脉冲计数 zhuanguojiaodu=number*2; //转过角度 if(direction==1) //方向标志 { if(v<8) {P1 = FFW[v];v++; } //取数据,正转 if(v==8) { v=0; } } else { if(v<8) {P1 = REV[v];v++; } //取数据,反转 if(v==8) { v=0; } } //电机转动角度 } } |
|
|
|
|
|
这么好的东西
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-本地仓库管理之分支间的操作
561 浏览 0 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】3D 图形显示
498 浏览 0 评论
630 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】SPI点亮16级灰阶OLED显示屏
503 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第四十二章 录音机实验
1122 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12206 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-23 12:00 , Processed in 0.770911 second(s), Total 94, Slave 75 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号