独立按键控制步进电机运转C语言程序
单片机控制步进电机系统(C语言源代码)
![单片机控制步进电机系统(C语言源代码)](https://img.taocdn.com/s3/m/e70d21768e9951e79b89277b.png)
题目:单片机控制步进电机系统摘要很多工业控制设备对位移和角度的控制精度要求较高, 一般电机很难实现, 而步进电机可精确实现所设定的角度和转数。
本设计主要是运用51 单片机控制六线4相步进电机系统, 由单片机产生驱动脉冲信号, 控制步进电机以一定的转速向某一方向产生一定的转动角度。
同时能够利用单片机实现电机的正、反转及速度控制,并能在数码管上显示出相应的速度。
本文中给出了该系统设计的硬件电路,软件设计,人机交互等。
并对各个功能模块进行了详细的说明。
主要内容包括以下几个方面:单片机控制步进电机的一般原理。
电机驱动及控制的实现。
控制系统整体设计以及模块划分说明。
原理图。
代码。
关键词:单片机;步进电机;系统;驱动AbstractMany Industrial control equipment have a highly requirement in displacement and angle with control accuracy, the most motor can't carry out .but the step motor can carry out the displacement and angle that you enactmented in accuracy. This design mainly used SCM to control step motor system.The step motor is formed six lines and four phasic.Through SCM generate the drive pulse signal.Control stepper motor through a certain speed in a direction to get a certain degree of rotation angle.At the same time, It can use SCM to realization of the motor is , reverse and speed control. and showed the speed in the digital tube.In this paper, given the design of the system hardware circuit,software design, human-computer interaction and so on.and it given the details description of each functional module.the main contents include the following:(1) The general principles of signal_chip controlling step motor.(2) The realization of motor driving and controlling(3) Control system overall design and description module division(4) Schematic Diagram(5) CodeKey Words:SCM; stepper motor; system; drive目录引言41 单片机控制步进电机的一般原理41.1 步进电机41.1.1 步进电机介绍41.1.2 步进电机分类51.1.3 技术指标51.1.4 步进电机工作原理51.2 单片机72 步进电机驱动实现82.1简介82.2驱动选择83 系统硬件设计93. 1 单片机控制电机93.2 键盘93.3 显示部分10程序流程图11总结12致谢13参考文献13附录13C代码13引言目前,在工业控制生产以及仪器上应用十分广泛。
c语言实现单片机控制步进电机加减速源程序
![c语言实现单片机控制步进电机加减速源程序](https://img.taocdn.com/s3/m/844d90baaff8941ea76e58fafab069dc502247df.png)
C 语言实现单片机控制步进电机加减速源程序1. 引言在现代工业控制系统中,步进电机作为一种常见的执行元件,广泛应用于各种自动化设备中。
而作为一种常见的嵌入式软件开发语言,C 语言在单片机控制步进电机的加减速过程中具有重要的作用。
本文将从单片机控制步进电机的加减速原理入手,结合 C 语言的编程技巧,介绍如何实现单片机控制步进电机的加减速源程序。
2. 单片机控制步进电机的加减速原理步进电机是一种能够精确控制角度的电机,它通过控制每个步骤的脉冲数来实现旋转。
在单片机控制步进电机的加减速过程中,需要考虑步进电机的加速阶段、匀速阶段和减速阶段。
在加速阶段,需要逐渐增加脉冲的频率,使步进电机的转速逐渐增加;在匀速阶段,需要保持恒定的脉冲频率,使步进电机以匀速旋转;在减速阶段,需要逐渐减小脉冲的频率,使步进电机的转速逐渐减小。
这一过程需要通过单片机的定时器和输出控制来实现。
3. C 语言实现步进电机加减速的源程序在 C 语言中,可以通过操作单片机的 GPIO 来控制步进电机的旋转。
在编写源程序时,需要使用单片机的定时器模块来生成脉冲信号,以控制步进电机的旋转角度和速度。
以下是一个简单的 C 语言源程序,用于实现步进电机的加减速控制:```c#include <reg52.h>void main() {// 初始化定时器// 设置脉冲频率,控制步进电机的加减速过程// 控制步进电机的方向// 控制步进电机的启停}```4. 总结与回顾通过本文的介绍,我们了解了单片机控制步进电机的加减速原理和 C 语言实现步进电机加减速源程序的基本思路。
掌握这些知识之后,我们可以更灵活地应用在实际的嵌入式系统开发中。
在实际项目中,我们还可以根据具体的步进电机型号和控制要求,进一步优化 C 语言源程序,实现更加精准和稳定的步进电机控制。
希望本文能为读者在单片机控制步进电机方面的学习和应用提供一定的帮助。
5. 个人观点与理解在我看来,掌握 C 语言实现单片机控制步进电机加减速源程序的技术是非常重要的。
按键单片机控制步进电机加减速C程序
![按键单片机控制步进电机加减速C程序](https://img.taocdn.com/s3/m/2c90d268ddccda38376bafb9.png)
for(f=0;f<8;f++)
{
P1=table1[f];
Hale Waihona Puke //delay(3);//此函数值为 3 频率接近 400HZ
up1();
delay1();
}
if(f==8)
{
f=0;
}
}
//#########################################################
{
P1=table[i];
//
delay(3);//此函数值为 3 频率接近 400HZ
up1();
delay1();
}
if(i==8)
{
i=0;
}
}
//####################################################
void fanzhan()
{
uint f;
P1=0XFF; P3=0XFF; while(1) {
if(cw==0) {
clock(); } else if(ccw==0) {
fanzhan(); }
}
}
//###################################
void clock() //正转
{
uint i;
for(i=0;i<8;i++)
/*========================================= 内容:四相步进电动机驱动程序(四相 8 拍工作方式) 说明:作运行方式:四相八拍运行方式即 A-AB-B-BC-C-CD-D-DA-A 输出:A、B、C、D 四相输出分别对应 P1.0、P1.1、P1.2、P1.3(各相输出为高电平) 输入:开关 1 和开关 2 作加速和减速输入,分别对应 P0.0 和 P0.1(低电平有效) 片:STC89C52 时钟:12MHZ 编译器:KEIL C51 日期:2012/08/16 编译者:许东想 =========================================*/
步进电机控制程序(c语言51单片机)
![步进电机控制程序(c语言51单片机)](https://img.taocdn.com/s3/m/7e586ecfa1c7aa00b52acb22.png)
// pri_dj = Pme );
if( i == set_pwm_width ) { P1 = 0xff; i = 0; one _round_flg = 0; while ( !one_round_flg & key_puse );}
if(!key_puse) { delay(4ms); if(!key_puse) break; }
while ( key_puse & key_clear ); delay ( 8ms );
if ( !key_clear ) { round_num = 0; display(); }
if ( !key_puse ) break; }
while( !key_puse ); delay(8ms);
while( !key_puse ); }
set_display_num(); for(i = 0; i < LEDLen ; i ++){
P0 = 0xf0; P0 = P0 | LEDBuf[i] ; if(i==0) led_1000 = 0; //P0^4 if(i==1) led_100 = 0; //P0^5 if(i==2) led_10 = 0; //P0^6 if(i==3) led_1 = 0; //P0^7
delay ( 1ms ); tmp = (~(P2 | 0xF0)); P2 = 0x7F; // 0111 1111
delay ( 1ms ); tmp = (~(P2 | 0xF0)) * 10 + tmp; set_round_num = set_round_num + tmp * 100; set_round_num = set_round_num * Chilun_Num;
51单片机控制的步进电机C语言程序
![51单片机控制的步进电机C语言程序](https://img.taocdn.com/s3/m/ee340fe576eeaeaad1f330fa.png)
51单片机控制的步进电机C语言程序用的是L298驱动的和ULN2003一样,你把它换成2003就行拉#include <AT89X51.H>unsigned char codetable[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9,0x00,0xf1,0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0x f3,0x00};unsigned char temp,temp_old;unsigned char key;unsigned char i,j,k,m,s;void delay(int i){for(m=i;m>0;m--)for(j=250;j>0;j--)for(k=10;k>0;k--);}void saomiao(){P3=0xff;P3_4=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=4;break;}temp=P3;temp=temp&0x0f;while(temp!=0x0f){temp=P3;temp=temp&0x0f;}}}P3=0xff;P3_5=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}temp=P3;temp=temp&0x0f;while(temp!=0x0f){temp=P3;temp=temp&0x0f;}}}}void main(void){while(1){saomiao();if(key==1){ P1=0;P2=0;saomiao();}if(key==2){temp_old=key;for(s=0;s<8;s++){ P2=table[s];P1_4=0;delay(13);saomiao();if(key!=temp_old){P1_4=1;break;}}}if(key==3){temp_old=key;for(s=0;s<8;s++){ P2=table[s];P1_5=0;delay(5);saomiao();if(key!=temp_old){P1_5=1;break;}}}if(key==4){temp_old=key; for(s=0;s<8;s++){ P2=table[s];P1_6=0;delay(20);saomiao();if(key!=temp_old){P1_6=1;break;}}}if(key==5){temp_old=key;for(s=9;s<17;s++){ P2=table[s];P1_7=0;delay(13);saomiao();if(key!=temp_old){P1_7=1;break;}}}if(key==6){temp_old=key;for(s=9;s<17;s++){ P2=table[s];P1_5=0;delay(5);saomiao();if(key!=temp_old){P1_5=1;break;}}}if(key==7){temp_old=key;for(s=9;s<17;s++){ P2=table[s];P1_6=0;delay(20);saomiao();if(key!=temp_old){P1_6=1;break;}}}}}C语言程序源代码#include <REGX51.H> // 51寄存器定义#include "intrins.h"#define control P1 //P1_0:A相,P1_1:B相,P1_2:C相,P1_3:D相#define discode P0 //显示代码控制端口#define uchar unsigned char //定义无符号型变量#define uint unsigned intsbit en_dm=P3^0; //显示代码锁存控制sbit en_wk=P3^1; //位控锁存控制uchar code corotation[4]= {0x03,0x06,0x0c,0x09};//电机正转uchar code rollback[4]={0x0c,0x06,0x03,0x09}; //电机反转uchar code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示字段uint code Levspeed[5]={500,400,300,200,100};//电机速度等级uchar Hscan,speedcount;//Hscan行扫描,speedcount 速度等级计数uint uu; //频率计数uint step,setstep; //step:电机步伐计数,setstep:手动设置电机步伐uint speed=500; //电机初始速度uchar count;uchar flag[5];uchar butcount; //按键次数//****************************************//flag[0] 正转标志//flag[1] 反转标志//flag[2] 加速标志//flag[3] 减速标志//flag[4] 设置标志//****************************************Delay1mS(unsigned int tt) //延时1ms “Delay1mS”延时子程序,用循环语句延时。
用单片机按键控制步进电机转动的程序怎么写
![用单片机按键控制步进电机转动的程序怎么写](https://img.taocdn.com/s3/m/1f9d58d1760bf78a6529647d27284b73f24236b2.png)
用单片机按键控制步进电机转动的程序怎么写结合按键程序,我们设计这样一个功能程序:按数字键1~9,控制电机转过1~9 圈;配合上下键改变转动方向,按向上键后正向转1~9 圈,向下键则反向转 1~9 圈;左键固定正转 90 度,右键固定反转90;Esc 键终止转动。
通过这个程序,我们也可以进一步体会到如何用按键来控制程序完成复杂的功能,以及控制和执行模块之间如何协调工作,而你的编程水平也可以在这样的实践练习中得到锻炼和提升。
#includesbit KEY_IN_1 = P2^4;sbit KEY_IN_2 = P2^5;sbit KEY_IN_3 = P2^6;sbit KEY_IN_4 = P2^7;sbit KEY_OUT_1 = P2^3;sbit KEY_OUT_2 = P2^2;sbit KEY_OUT_3 = P2^1;sbit KEY_OUT_4 = P2^0;unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表{ 0x31, 0x32, 0x33, 0x26 }, //数字键 1、数字键 2、数字键 3、向上键{ 0x34, 0x35, 0x36, 0x25 }, //数字键 4、数字键 5、数字键 6、向左键{ 0x37, 0x38, 0x39, 0x28 }, //数字键 7、数字键 8、数字键 9、向下键{ 0x30, 0x1B, 0x0D, 0x27 } //数字键 0、ESC 键、回车键、向右键};unsigned char KeySta[4][4] = { //全部矩阵按键的当前状态{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};signed long beats = 0; //电机转动节拍总数void KeyDriver();void main(){EA = 1; //使能总中断TMOD = 0x01; //设置 T0 为模式 1TH0 = 0xFC; //为 T0 赋初值 0xFC67,定时 1msTL0 = 0x67;ET0 = 1; //使能 T0 中断TR0 = 1; //启动 T0while (1){KeyDriver(); //调用按键驱动函数}}/* 步进电机启动函数,angle-需转过的角度 */void StartMotor(signed long angle){//在计算前关闭中断,完成后再打开,以避免中断打断计算过程而造成错误EA = 0;beats = (angle * 4076) / 360; //实测为 4076 拍转动一圈EA = 1;}/* 步进电机停止函数 */void StopMotor(){EA = 0;beats = 0;EA = 1;}/* 按键动作函数,根据键码执行相应的操作,keycode-按键键码*/void KeyAction(unsigned char keycode){static bit dirMotor = 0; //电机转动方向//控制电机转动 1-9 圈if ((keycode>=0x30) && (keycode<=0x39)){if (dirMotor == 0){StartMotor(360*(keycode-0x30));}else{StartMotor(-360*(keycode-0x30));}}else if (keycode == 0x26){ //向上键,控制转动方向为正转dirMotor = 0;}else if (keycode == 0x28){ //向下键,控制转动方向为反转dirMotor = 1;}else if (keycode == 0x25){ //向左键,固定正转 90 度StartMotor(90);}else if (keycode == 0x27){ //向右键,固定反转 90 度StartMotor(-90);}else if (keycode == 0x1B){ //Esc 键,停止转动StopMotor();}}/* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */void KeyDriver(){unsigned char i, j;static unsigned char backup[4][4] = { //按键值备份,保存前一次的值{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};for (i=0; i<4; i++){ //循环检测 4*4 的矩阵按键for (j=0; j<4; j++){if (backup[i][j] != KeySta[i][j]){ //检测按键动作if (backup[i][j] != 0){ //按键按下时执行动作KeyAction(KeyCodeMap[i][j]); //调用按键动作函数}backup[i][j] = KeySta[i][j]; //刷新前一次的备份值}}}}/* 按键扫描函数,需在定时中断中调用,推荐调用间隔 1ms */ void KeyScan(){unsigned char i;static unsigned char keyout = 0; //矩阵按键扫描输出索引static unsigned char keybuf[4][4] = { //矩阵按键扫描缓冲区{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF},{0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF}};//将一行的 4 个按键值移入缓冲区keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;//消抖后更新按键状态for (i=0; i<4; i++){ //每行 4 个按键,所以循环 4 次if ((keybuf[keyout][i] & 0x0F) == 0x00){//连续 4 次扫描值为 0,即 4*4ms 内都是按下状态时,可认为按键已稳定的按下KeySta[keyout][i] = 0;}else if ((keybuf[keyout][i] & 0x0F) == 0x0F){//连续 4 次扫描值为 1,即 4*4ms 内都是弹起状态时,可认为按键已稳定的弹起KeySta[keyout][i] = 1;}}//执行下一次的扫描输出keyout++; //输出索引递增keyout = keyout & 0x03; //索引值加到 4 即归零//根据索引,释放当前输出引脚,拉低下次的输出引脚switch (keyout){case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;default: break;}}/* 电机转动控制函数 */void TurnMotor(){unsigned char tmp; //临时变量static unsigned char index = 0; //节拍输出索引unsigned char code BeatCode[8] = { //步进电机节拍对应的 IO 控制代码0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6};if (beats != 0){ //节拍数不为 0 则产生一个驱动节拍if (beats > 0){ //节拍数大于 0 时正转index++; //正转时节拍输出索引递增index = index & 0x07; //用&操作实现到 8 归零beats--; //正转时节拍计数递减}else{ //节拍数小于 0 时反转index--; //反转时节拍输出索引递减index = index & 0x07; //用&操作同样可以实现到-1 时归 7beats++; //反转时节拍计数递增}tmp = P1; //用 tmp 把 P1 口当前值暂存tmp = tmp & 0xF0; //用&操作清零低 4 位tmp = tmp | BeatCode[index]; //用|操作把节拍代码写到低 4 位P1 = tmp; //把低 4 位的节拍代码和高 4 位的原值送回 P1}else{ //节拍数为 0 则关闭电机所有的相P1 = P1 | 0x0F;}}/* T0 中断服务函数,用于按键扫描与电机转动控制 */void InterruptTimer0() interrupt 1{static bit p = 0;TH0 = 0xFC; //重新加载初值TL0 = 0x67;KeyScan(); //执行按键扫描//用一个静态 bit 变量实现二分频,即 2ms 定时,用于控制电机p = ~p;if (p == 1){TurnMotor();}}这个程序是第 8 章和本章知识的一个综合——用按键控制步进电机转动。
自动门控制的步进电机正反转和加速减速C程序
![自动门控制的步进电机正反转和加速减速C程序](https://img.taocdn.com/s3/m/82e50034ba68a98271fe910ef12d2af90242a809.png)
自动门控制的步进电机正反转和加速减速C程序步进电机的正反转和加速减速是实现自动门控制的关键功能。
通过编写C程序,我们可以实现对步进电机的控制,使其按照设定的方向旋转,并可以进行加速和减速操作。
步进电机正反转步进电机的正反转是通过控制电机的相序来实现的。
下面是一个简单的C程序示例,用于控制步进电机的正反转:include <stdio.h>int main() {// 定义电机的相序int sequence[] = {1, 2, 4, 8};int direction = 1; // 1表示正转,-1表示反转// 正转if (direction == 1) {for (int i = 0; i < 4; i++) {printf("Phase: %d\n", sequence[i]);// 在这里控制步进电机的相序输出}}// 反转else if (direction == -1) {for (int i = 3; i >= 0; i--) {printf("Phase: %d\n", sequence[i]);// 在这里控制步进电机的相序输出}}return 0;}在以上示例代码中,我们通过设置`sequence`数组来表示电机的相序,其中`sequence[0]`表示第一相,`sequence[1]`表示第二相,以此类推。
通过循环遍历数组中的元素,并控制步进电机相序的输出,从而实现步进电机的正反转。
步进电机加速减速步进电机的加速减速是通过逐渐改变电机的驱动信号频率来实现的。
下面是一个简单的C程序示例,用于控制步进电机的加速减速:include <stdio.h>include <unistd.h>int main() {// 定义电机的相序int sequence[] = {1, 2, 4, 8};int delay = 1000; // 初始延时时间,单位为毫秒int minDelay = 100; // 最小延时时间,单位为毫秒// 加速for (int i = 0; i < 4; i++) {printf("Phase: %d\n", sequence[i]);// 在这里控制步进电机的相序输出usleep(delay); // 延时if (delay > minDelay) {delay -= 100; // 减小延时时间,实现加速}}// 延时一段时间// 减速for (int i = 3; i >= 0; i--) {printf("Phase: %d\n", sequence[i]);// 在这里控制步进电机的相序输出usleep(delay); // 延时if (delay < 1000) {delay += 100; // 增加延时时间,实现减速}}return 0;}在以上示例代码中,我们通过循环遍历数组中的元素,并控制步进电机相序的输出,并通过调用`usleep`函数来实现延时,从而控制步进电机的转速。
独立按键控制步进电机调速
![独立按键控制步进电机调速](https://img.taocdn.com/s3/m/e183ab621eb91a37f1115cca.png)
#include "reg52.h"//电机IO#define GPIO_MOTOR P1//sbit F1 = P1^0;//sbit F2 = P1^1;//sbit F3 = P1^2;//sbit F4 = P1^3;//按键IOsbit K1=P3^0;sbit K2=P3^1;sbit K3=P3^2;sbit K4=P3^3;unsigned char code FFW[8]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9}; //反转顺序unsigned char code FFZ[8]={0xf9,0xf8,0xfc,0xf4,0xf6,0xf2,0xf3,0xf1}; //正转顺序unsigned char Direction,Speed;void Delay(unsigned int t);//延时函数声明void Motor(); //步进电机程序函数声明/******************************************************************** ***********主程序********************************************************************* **********/void main(void){unsigned char i;Speed=30;while(1){if(K1==0) //检测按键K1是否按下{Delay(1); //消除抖动if(K1==0){Direction=1;}while((i<200)&&(K1==0)) //检测按键是否松开{Delay(1);i++;}i=0;}if(K2==0) //检测按键K1是否按下{Delay(1); //消除抖动if(K2==0){Direction=2;}while((i<200)&&(K2==0)) //检测按键是否松开{Delay(1);}i=0;}if(K3==0) //检测按键K1是否按下{Delay(1); //消除抖动if(K3==0){Speed=15;}while((i<200)&&(K3==0)) //检测按键是否松开{Delay(1);i++;}i=0;}if(K4==0) //检测按键K1是否按下{Delay(1); //消除抖动if(K4==0){Speed=40;}while((i<200)&&(K4==0)) //检测按键是否松开{Delay(1);}i=0;}Motor();}}/******************************************************************** ***********步进电机控制程序********************************************************************* **********/void Motor(){unsigned char i;for(i=0;i<8;i++){if(Direction==1)GPIO_MOTOR = FFW[i];if(Direction==2)GPIO_MOTOR = FFZ[i];Delay(Speed); //调节转速}}/******************************************************************** ***********延时程序********************************************************************* **********/void Delay(unsigned int t){unsigned int k;while(t--){for(k=0; k<80; k++){ }}}。
片机控制的步进电机C语言程序
![片机控制的步进电机C语言程序](https://img.taocdn.com/s3/m/37ab90c3a6c30c2258019e7f.png)
51单片机控制的步进电机C语言程序用的是L298驱动的和ULN2003一样,你把它换成2003就行拉#include <AT89X51.H>unsigned char codetable[]={0xf1,0xf3,0xf2,0xf6,0xf4,0xfc,0xf8,0xf9,0x00,0xf1,0xf9,0xf8,0xfc,0xf4, 0xf6,0xf2,0xf3,0x00};unsigned char temp,temp_old;unsigned char key;unsigned char i,j,k,m,s;void delay(int i){for(m=i;m>0;m--)for(j=250;j>0;j--)for(k=10;k>0;k--);}void saomiao(){P3=0xff;P3_4=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=4;break;}temp=P3;temp=temp&0x0f; while(temp!=0x0f) {temp=P3;temp=temp&0x0f; }}}P3=0xff;P3_5=0;temp=P3;temp=temp&0x0f;if(temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp&0x0f;if(temp!=0x0f){temp=P3;temp=temp&0x0f;switch(temp){case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}temp=P3;temp=temp&0x0f;while(temp!=0x0f) {temp=P3;temp=temp&0x0f; }}}}void main(void){while(1){saomiao();if(key==1){ P1=0;P2=0;saomiao();}if(key==2){temp_old=key;for(s=0;s<8;s++){ P2=table[s]; P1_4=0;delay(13);saomiao();if(key!=temp_old) {P1_4=1;break;}}}if(key==3){temp_old=key;for(s=0;s<8;s++){ P2=table[s]; P1_5=0;delay(5);saomiao();if(key!=temp_old) {P1_5=1;break;}}}if(key==4){temp_old=key;for(s=0;s<8;s++){ P2=table[s]; P1_6=0;delay(20);saomiao();if(key!=temp_old) {P1_6=1;break;}}}if(key==5){temp_old=key;for(s=9;s<17;s++){ P2=table[s]; P1_7=0;delay(13);saomiao();if(key!=temp_old) {P1_7=1;break;}}}if(key==6){temp_old=key;for(s=9;s<17;s++){ P2=table[s]; P1_5=0;delay(5);saomiao();if(key!=temp_old){P1_5=1;break;}}}if(key==7){temp_old=key; for(s=9;s<17;s++){ P2=table[s]; P1_6=0;delay(20);saomiao();if(key!=temp_old){P1_6=1;break;}}}}}C语言程序源代码#include <REGX51.H> // 51寄存器定义#include "intrins.h"#define control P1 //P1_0:A相,P1_1:B相,P1_2:C相,P1_3:D相#define discode P0 //显示代码控制端口#define uchar unsigned char //定义无符号型变量#define uint unsigned intsbit en_dm=P3^0; //显示代码锁存控制sbit en_wk=P3^1; //位控锁存控制uchar code corotation[4]= {0x03,0x06,0x0c,0x09};//电机正转uchar code rollback[4]={0x0c,0x06,0x03,0x09}; //电机反转uchar code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示字段uint code Levspeed[5]={500,400,300,200,100};//电机速度等级uchar Hscan,speedcount;//Hscan行扫描,speedcount 速度等级计数uint uu; //频率计数uint step,setstep; //step:电机步伐计数,setstep:手动设置电机步伐uint speed=500; //电机初始速度uchar count;uchar flag[5];uchar butcount; //按键次数//****************************************//flag[0] 正转标志//flag[1] 反转标志//flag[2] 加速标志//flag[3] 减速标志//flag[4] 设置标志//****************************************Delay1mS(unsigned int tt) //延时1ms “Delay1mS”延时子程序,用循环语句延时。
独立按键控制步进电机运转C语言程序
![独立按键控制步进电机运转C语言程序](https://img.taocdn.com/s3/m/afddeecf8762caaedd33d49a.png)
/**名称:步进电机**晶振:12MHZ**修改:无**内容:主程序中用3个按键,加速、减速、启动和停止。
定时器做数码* *管动态扫描和步进电机驱动。
***硬件事项:J19的7B,6B,5B,4B依次用杜邦线连接到P27,P26,P25,P24***---------------------------------------------------------------*/#include <REG51.H>#define DataPort P1 //定义数据端口程序中遇到DataPort则用P1替换sbit LATCH1=P2^0;//定义锁存使能端口段锁存sbit LATCH2=P2^1;//位锁存sbit S17=P3^3;//独立按键sbit S18=P3^2;sbit S19=P3^1;sbit S20=P3^0;unsignedcharcodeHEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0x f8,0x80,0x90};//显示段码值89unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码unsignedcharTempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF};//存储显示值的全局变量sbit A1=P2^7; //定义步进电机连接端口sbit B1=P2^6;sbit C1=P2^5;sbit D1=P2^4;#define Coil_AB1 {A1=1;B1=1;C1=0;D1=0;}//AB相通电,其他相断电#define Coil_BC1 {A1=0;B1=1;C1=1;D1=0;}//BC相通电,其他相断电#define Coil_CD1 {A1=0;B1=0;C1=1;D1=1;}//CD相通电,其他相断电#define Coil_DA1 {A1=1;B1=0;C1=0;D1=1;}//D相通电,其他相断电#define Coil_A1 {A1=1;B1=0;C1=0;D1=0;}//A相通电,其他相断电#define Coil_B1 {A1=0;B1=1;C1=0;D1=0;}//B相通电,其他相断电#define Coil_C1 {A1=0;B1=0;C1=1;D1=0;}//C相通电,其他相断电#define Coil_D1 {A1=0;B1=0;C1=0;D1=1;}//D相通电,其他相断电#define Coil_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电unsigned char Speed;bit StopFlag;bit Flag,sb;void Display(unsigned char FirstBit,unsigned char Num);void Init_Timer0(void);unsigned char KeyScan(void);//键盘扫描/*------------------------------------------------uS延时函数,含有输入参数unsigned char t,无返回值unsigned char是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,大致xxxx如下T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/*------------------------------------------------主函数------------------------------------------------*/main(){unsigned int j,i;//旋转一周时间unsigned char num;Init_Timer0();while(1)//正向{Coil_OFFnum=KeyScan();//循环调用按键扫描if(num==1)//第一个按键,速度等级增加{if(Speed<18)Speed++;}else if(num==2)//第二个按键,速度等级减小{if(Speed>1) Speed--;}else if(num==3)//第三个按键,电机停止和启动{switch(j) {case 0:Coil_OFFStopFlag=1;j++;break;case 1: StopFlag=0;j--;break;}}else if(num==4){sb=1;while((1)&&(sb)){Flag=1;i=50;while((i--)&&(Flag))//正向{Coil_A1DelayMs(Speed);Coil_AB1//遇到Coil_AB1{A1=1;B1=1;C1=0;D1=0;}代替力矩越小Coil_B1DelayMs(Speed);Coil_BC1DelayMs(Speed);Coil_C1DelayMs(Speed);Coil_CD1用DelayMs(Speed);Coil_D1DelayMs(Speed);Coil_DA1DelayMs(Speed);num=KeyScan();if(num==3)//第三个按键,电机停止和启动{Flag=0;sb=0;}} Coil_OFFi=50;while((i--)&&(Flag))//反?{// num=KeyScan();Coil_A1DelayMs(Speed);Coil_DA1//遇到Coil_AB1{A1=1;B1=1;C1=0;D1=0;}代替力矩越小Coil_D1DelayMs(Speed);Coil_CD1DelayMs(Speed);Coil_C1DelayMs(Speed);Coil_BC1DelayMs(Speed);Coil_B1DelayMs(Speed);Coil_AB1DelayMs(Speed);num=KeyScan();if(num==3)//第三个按键,电机停止和启动{用Flag=0;sb=0;}}TempData[0]=HEYAO_DuanMa[Speed/10];TempData[1]=HEYAO_DuanMa[Speed%10];}}//分解显示信息,如要显示68,则=668%10=8 TempData[0]=HEYAO_DuanMa[Speed/10];TempData[1]=HEYAO_DuanMa[Speed%10];}}/*------------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit表示需要显示的第一位,如赋值2表示从第三个数码管开始显示如输入0表示从第一个显示。
步进电机c程序
![步进电机c程序](https://img.taocdn.com/s3/m/3a09d8c14028915f804dc232.png)
步进电机控制程序(2008-06-05 19:07:55)转载分类:程序设计标签:it步进电机(键盘控制可调速)#include <reg51.h>#define uchar unsigned charstatic unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢static int spcount; //步进电机转速参数计数void ddelay(void); //键盘扫描延时函数void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒void gorun(); //步进电机控制步进函数sbit P10=P2^0 ; //电机端口定义sbit P11=P2^1 ;sbit P12=P2^2;sbit P13=P2^3 ;void ddelay(void){uchar i;for (i=300;i>0;i--);}uchar keyscan(void){uchar scancode;uchar tmpcode;P1 = 0xf8; // 发全0行扫描码if ((P1&0xf8)!=0xf8) // 若有键按下{ddelay(); // 延时去抖动if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响{scancode = 0xfe;while((scancode&0x08)!=0) // 逐行扫描{P1 = scancode; // 输出行扫描码if ((P1&0xf8)!=0xf8) // 本行有键按下tmpcode = (P1&0xf8)|0x07;return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列 }else scancode = (scancode<<1)|0x01; // 行扫描码左移一位}}}return(0); // 无键按下,返回值为0}void main(void){uchar key;count = 0;step_index = 0;spcount = 0;P10 = 0;P11 = 0;P12 = 0;P13 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFc;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数stop_flag = 0;turn=0;speedlevel = 20;while(1){key = keyscan();switch(key){case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5Sstop_flag=0;turn = 0;speedlevel =10;gorun();delay(1000);break;case 0x0c: //按键*,停止2000*0.5MS=0.5Sstop_flag=1;break;case 0x0a: //按键0,反转以speedlevel = 1的速度转1000*0.5MS=0.5Sstop_flag=0;turn=1;speedlevel =10;gorun();delay(1000);break;case 0x11: // 按键9,以--speedlevel的加速转1000*0.5MS=0.5Sstop_flag=0;if (speedlevel==1){ speedlevel=1;}else { --speedlevel;}gorun();delay(1000);break;case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5Sstop_flag=0;++speedlevel;gorun();delay(1000);break;}}}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFc;TL0=0x18; //设定时每隔1ms中断一次count++;spcount--;if(spcount<=0) //速度调整,SPEEDLEVEL越大,延时越长(延时约为1MS*SPEEDLEVEL),{ // 频率越小,速度越慢spcount = speedlevel;gorun();}}void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒{count=0;do{}while(count<endcount);void gorun(){if (stop_flag==1) {P10 = 0;P11 = 0;P12 = 0;P13 = 0;return;}switch(step_index) {case 0: //0P10 = 1;P11 = 0;P12 = 0;P13 = 0;break;case 1: //0、1P10 = 1;P11 = 1;P12 = 0;P13 = 0;break;case 2: //1P10 = 0;P11 = 1;P12 = 0;P13 = 0;break;case 3: //1、2P10 = 0;P11 = 1;P12 = 1;P13 = 0;break;case 4: //2P10 = 0;P11 = 0;P12 = 1;P13 = 0;break;case 5: //2、3P10 = 0;P11 = 0;P12 = 1;P13 = 1;break;case 6: //3P10 = 0;P11 = 0;P12 = 0;P13 = 1;break;case 7: //3、0P10 = 1;P11 = 0;P12 = 0;P13 = 1;}if (turn==0) //正转{step_index++;if (step_index>7)step_index=0;}else{ //反转step_index--;if (step_index<0)step_index=7;}}步进电机(键盘控制可调速加显示)#include <reg51.h>#define uchar unsigned charstatic unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越大,最小值为1,速度最慢static int spcount; //步进电机转速参数计数void ddelay(void); //键盘扫描延时函数void delay(unsigned int endcount); //延时函数,延时为endcount*1毫秒void gorun(); //步进电机控制步进函数void Delay400Ms(void);void LCMInit(void); //LCM初始化void WriteCommandLCM(unsigned char WCLCM,BuysC); //BuysC为0时忽略忙检测void DisplayOneChar(uchar X, uchar Y, uchar DData);void DisplayListChar(uchar X, uchar Y,uchar ListLength, uchar *DData,uchar n);sbit P10=P3^0 ; //电机端口定义sbit P11=P3^1 ;sbit P12=P3^2;sbit P13=P3^3 ;uchar code speed[]={ 0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30};uchar code stop[] = {"stop"};uchar code go[] = {"go:"};uchar code back[] = {"back:"};uchar code max[] = {"max:8"};void ddelay(void){uchar i;for (i=300;i>0;i--);}uchar keyscan(void){uchar scancode;uchar tmpcode;P1 = 0xf8; // 发全0行扫描码if ((P1&0xf8)!=0xf8) // 若有键按下{ddelay(); // 延时去抖动if ((P1&0xf8)!=0xf8) // 延时后再判断一次,去除抖动影响{scancode = 0xfe;while((scancode&0x08)!=0) // 逐行扫描{P1 = scancode; // 输出行扫描码if ((P1&0xf8)!=0xf8) // 本行有键按下{tmpcode = (P1&0xf8)|0x07;return((~scancode)+(~tmpcode)); // 返回特征字节码,为1的位即对应于行和列 }else scancode = (scancode<<1)|0x01; // 行扫描码左移一位}}}return(0); // 无键按下,返回值为0}void main(void){uchar key;count = 0;step_index = 0;spcount = 0;P10 = 0;P11 = 0;P12 = 0;P13 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFc;TL0 = 0x18; //设定时每隔1ms中断一次TR0 = 1; //开始计数P0=0XFF;P3 &=0XEF; //573片选LCMInit(); //LCM初始化Delay400Ms();stop_flag = 0;turn=0;speedlevel = 5;DisplayListChar(0,0,3,go,1); //每次扫描键盘显示更新一次uchar code go[] DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次while(1){key = keyscan();switch(key){case 0x09: //按键#,正转以speedlevel = 1的速度转1000*0.5MS=0.5S stop_flag=0;turn = 0;speedlevel =5;gorun();WriteCommandLCM(0x01,1);//显示清屏,DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[] DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次delay(1000);break;case 0x0c: //按键*,停止2000*0.5MS=0.5Sstop_flag=1;WriteCommandLCM(0x01,1);//显示清屏,DisplayListChar(0,0,4,stop,0); //每次扫描键盘显示更新一次break;case 0x0a: //按键0,反转以speedlevel = 1的速度转1000*0.5MS=0.5S stop_flag=0;turn=1;speedlevel =5;gorun();WriteCommandLCM(0x01,1);//显示清屏,DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次DisplayOneChar(0,1,0x35); //每次扫描键盘显示更新一次delay(1000);break;case 0x11: // 按键9,以--speedlevel的加速转1000*0.5MS=0.5Sstop_flag=0;if (speedlevel==2){ speedlevel=2;}else { speedlevel--;}gorun();if(speedlevel==2){ DisplayListChar(0,1,5,max,0);}else {DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次 delay(1000);break;case 0x12: // 按键8,以++speedlevel的减速转1000*0.5MS=0.5Sstop_flag=0;speedlevel++;gorun();WriteCommandLCM(0x01,1);//显示清屏,if(turn==0){DisplayListChar(0,0,3,go,0); //每次扫描键盘显示更新一次uchar code go[] DisplayOneChar(0,1, speed[speedlevel]);} //每次扫描键盘显示更新一次else {DisplayListChar(0,0,5,back,0); //每次扫描键盘显示更新一次DisplayOneChar(0,1,speed[speedlevel]);} //每次扫描键盘显示更新一次delay(1000);break;}}}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFc;TL0=0x18; //设定时每隔1ms中断一次count++;spcount--;if(spcount<=0) //速度调整,SPEEDLEVEL越大,延时越长(延时约为1MS*SPEEDLEVEL),{ // 频率越小,速度越慢spcount = speedlevel;gorun();}}void delay(unsigned int endcount)//延时函数,延时为endcount*0.5毫秒{count=0;do{}while(count<endcount);}void gorun(){if (stop_flag==1){P10 = 0;P11 = 0;P12 = 0;P13 = 0;return;}switch(step_index){case 0: //0P10 = 1;P11 = 0;P12 = 0;P13 = 0;break;case 1: //0、1P10 = 1;P11 = 1;P12 = 0;P13 = 0;break;case 2: //1P10 = 0;P11 = 1;P12 = 0;P13 = 0;break;case 3: //1、2P10 = 0;P11 = 1;P12 = 1;P13 = 0;break;case 4: //2P10 = 0;P11 = 0;P12 = 1;P13 = 0;break;case 5: //2、3P10 = 0;P11 = 0;P12 = 1;P13 = 1;break;case 6: //3P10 = 0;P11 = 0;P12 = 0;P13 = 1;break;case 7: //3、0P10 = 1;P11 = 0;P12 = 0;P13 = 1;}if (turn==0) //正转 {step_index++;if (step_index>7)step_index=0; }else{ //反转step_index--;if (step_index<0)step_index=7;}}步进电机(自动循环调速)#include <reg51.h>sbit P00=P2^0 ;sbit P01=P2^1 ;sbit P02=P2^2;sbit P03=P2^3 ;static unsigned int count; //计数static int step_index; //步进索引数,值为0-7static bit turn; //步进电机转动方向static bit stop_flag; //步进电机停止标志static int speedlevel; //步进电机转速参数,数值越大速度越快,最小值为1,速度最慢static int spcount; //步进电机转速参数计数void delay(unsigned int endcount); //延时函数,延时为endcount*0.5毫秒void gorun(); //步进电机控制步进函数void main(void){count = 0;step_index = 0;spcount = 0;stop_flag = 0;P00 = 0;P01 = 0;P02 = 0;P03 = 0;EA = 1; //允许CPU中断TMOD = 0x11; //设定时器0和1为16位模式1ET0 = 1; //定时器0中断允许TH0 = 0xFE;TL0 = 0x0C; //设定时每隔0.5ms中断一次TR0 = 1; //开始计数turn = 0;do{speedlevel =4;delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1Sspeedlevel =4;delay(10000); //以speedlevel = 4的速度转2000*0.5MS=1Sstop_flag=1;delay(6000);//停止,2000*0.5MS=3Sstop_flag=0;}while(1);}//定时器0中断处理void timeint(void) interrupt 1{TH0=0xFE;TL0=0x0C; //设定时每隔0.5ms中断一次count++;spcount--;if(spcount<=0){spcount = speedlevel;gorun();}}void delay(unsigned int endcount){count=0;do{}while(count<endcount);}void gorun(){if (stop_flag==1){P00 = 0;P01 = 0;P02 = 0;P03 = 0;return;}switch(step_index){case 0: //0P00 = 1;P01 = 0;P02 = 0;P03 = 0;break;case 1: //0、1P00 = 1;P01 = 1;P02 = 0;P03 = 0; break;case 2: //1P00 = 0;P01 = 1;P02 = 0;P03 = 0; break;case 3: //1、2P00 = 0;P01 = 1;P02 = 1;P03 = 0; break;case 4: //2P00 = 0;P01 = 0;P02 = 1;P03 = 0; break;case 5: //2、3P00 = 0;P01 = 0;P02 = 1;P03 = 1; break;case 6: //3P00 = 0;P01 = 0;P02 = 0;P03 = 1; break;case 7: //3、0P00 = 1;P01 = 0;P02 = 0;P03 = 1;}if (turn==0){step_index++;if (step_index>7) step_index=0; }else{step_index--;if (step_index<0)step_index=7;}}步进电机控制Link - Thu, 17 Jan 2008 12:41:32 +0800Description:本设计采用的步进电机为35BYJ46型四相八拍电机,电压为DC12V。
步进电机控制设计(C程序设计语言)
![步进电机控制设计(C程序设计语言)](https://img.taocdn.com/s3/m/afe6f610c281e53a5802ffc1.png)
接口课程设计任务书学生姓名专业班级指导老师工作单位计算机学院题目:步进电机控制设计(C程序设计语言)一、内容:在MIFID微机实验台上以双八拍的方式控制步进电机运行,用按钮控制启动和停止。
接口硬件电路图见说明书。
二、要求:1、控制步进电机运行的相序表存储在文件中。
2、按下SW1按钮,从文件中取出一个相序数据,从并行接口8255A的PA口输出,使步进电机运行。
相序数据在CRT上显示。
按下SW2按钮,步进电机运行停止。
3、SW1按钮的数字量由PC1输入,SW2按钮的数字量由PC0输入,4、设计程序运行时的界面友好。
三、进度安排:指导教师签名:年月日系主任(责任教师)签名:年月日一.设计目的和内容目的:通过步进电机控制实验,学习并行接口电路及其控制程序的设计原理与方法。
内容:在MIFID微机实验台上以双八拍的方式控制步进电机运行,用按钮控制启动和停止。
接口硬件电路图见说明书。
要求:1、控制步进电机运行的相序表存储在文件中。
2、按下SW1按钮,从文件中取出一个相序数据,从并行接口8255A的PA口输出,使步进电机运行。
相序数据在CRT上显示。
按下SW2按钮,步进电机运行停止。
3、SW1按钮的数字量由PC1输入,SW2按钮的数字量由PC0输入,4、设计程序运行时的界面友好。
二、实验预备知识可编程并行接口8255是一个具有两个8位(A端口和B端口)和两个4位(C端口)并行I/O端口的芯片。
在与外设进行数据传输时,把A、B、C3个端口分为两组。
A组由A端口和C端口的高4位组成。
B组由B端口和C端口的低4位组成。
为了满足多种数据传输的要求,可以通过对8255的编程用方式控制字设置3种工作方式来实现。
这3种工作方式为:方式0(基本I/O工作方式);方式1(选通I/O工作方式);方式2(双向传送方式)。
8255的控制字有工作方式控制字和C端口的位置位/复位控制字。
工作方式控制字是必须要预先设定的,C端口的位置位/复位控制字可视需要而定。
【精品】步进电机驱动电路+C语言驱动程序
![【精品】步进电机驱动电路+C语言驱动程序](https://img.taocdn.com/s3/m/627b076a65ce0508763213da.png)
/**********************************************/ /*********兰州交通大学电子电工实验中心*********/ /*******************2009-8-2********************/ /*********************************************/ #include"reg51.h"#include"intrins.h"#include"math.h"#include"absacc.h"#definePORTAXBYTE[0x8500]#definePORTBXBYTE[0x8502]#definePORTCXBYTE[0x8504]#definePORTC0XBYTE[0x8506]#definenop_nop_()#defineRight_RUN1#defineLeft_RUN0unsignedlongRunSpeed=76;unsignedcharRUNState=1;sbitRS=P2^0;sbitRW=P2^1;sbitE=P2^2;sbitP17=P1^7;bitflag=0;unsignedcharxx[]="speed(n/min):";unsignedcharSD[]="76";charstate[2][14]={"direction:cw","direction:ccw"}; unsignedcharFLG,INMA=0;unsignedchart,s=0x01; unsignedinta;main(){voidOPJIAN(); unsignedcharJIAN(); unsignedcharJIANZHI(); voidspeed(); voidSHOW_LCD(); voidshow_state(); voidwrite1();voidwrit2(unsignedchari); voiddelay();voidtime();voidbusy(); unsignedchari;i=0x90;PORTC0=i;i=0x01;TMOD=i;t=0x10;a=0x0f;TH0=0x10;TL0=0x0f;FLG=INMA;SHOW_LCD();show_state();EA=1;ET0=1;TR0=1;while(1){i=JIAN();if(i!=0){time();time();}i=JIAN();if(i!=0){INMA=JIANZHI();OPJIAN();time();}if(FLG!=INMA||flag==1){FLG=INMA;SHOW_LCD();show_state();flag=0;}}}voidSHOW_LCD()/*lcd设置程序*/ {P1=0x38;write1();delay();P1=0x38;write1();delay();P1=0x38;write1();delay();P1=0x01;write1();delay();P1=0x0f;write1();delay();write1(); delay(); P1=0x0c;}voidshow_state()/*状态显示程序*/ {unsignedchari=0;P1=0x80;write1();while(xx[i]!='\0'){writ2(xx[i]);i++;delay();}i=0;while(SD[i]!='\0'){writ2(SD[i]);delay();i++;}P1=0xc0;write1();i=0;if(RUNState==Right_RUN)while(state[0][i]!='\0'){writ2(state[0][i]);i++;}elseif(RUNState==Left_RUN)while(state[1][i]!='\0'){writ2(state[1][i]);i++;}}voidwrite1()/*lcd写控制字*/{RS=0;RW=0;E=0;busy();E=1;}voidwrit2(unsignedchari)/*lcd写数据*/ {P1=i;RS=1;E=0;busy();E=1;}voiddelay()/*延时程序*/{unsignedchari;for(i=0;i<100;i++){i=i;}}voidtime(){unsignedchari,j;for(i=0;i<100;i++){for(j=0;j<30;j++){j=j;}}}voidbusy()//判断LCD是否忙{do{P1=0xff;RS=0;RW=1;E=0;nop;E=1;}while(P17==1);}unsignedcharJIAN()/*判断是否有键按下*/ {unsignedchari,j;i=0xff;PORTA=i;time();i=0x00;PORTB=i;j=PORTA;j=~j;returnj;}unsignedcharJIANZHI()/*读键值程序*/{unsignedi,j,d,k,m=1;i=0xfe;k=0x01;do{PORTB=i;j=PORTA;m=j&(0x01);if(m==0)d=k/2;else{m=j&(0x02);if(m==0)d=k/2+4;else{m=j&(0x04);if(m==0)d=k/2+8;else{m=j&(0x08);if(m==0)d=k/2+12;}}}k=k+2;i=i<<1;i=i|(0x01);}while(m!=0);returnd;}voidOPJIAN()/*键值处理程序*/{switch(INMA){case0x08:{RUNState=Right_RUN;s=0xf7;}break; case0x09:{RUNState=Left_RUN;s=0x01;}break; case0x0b:{flag=1;t=t-2;RunSpeed=5000000/(65536-t*256-a);speed();}break;case0x0f:{flag=1;t=t+2;RunSpeed=5000000/(65536-t*256-a);speed();}}}voidspeed()/*速度处理程序*/{unsignedchari=0;SD[0]=RunSpeed/100+48;SD[1]=RunSpeed%100/10+48;SD[2]=RunSpeed%10+48;}voidtime1(void)interrupt1using2{TR0=0;PORTC=s;if(RUNState==0){s=(s<<1);if(s==0x10)s=0x01;}else{s=s>>1;if(s==0x0f)s=0xf7;}TH0=t;TL0=a;TR0=1;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
------------------------------------------------*/ main() {
unsigned int j,i;//旋转一周时间 unsigned char num; Init_Timer0(); while(1) //正向
/*
* 名称:步进电机
*
* 晶振:12MHZ
*
* 修改:无
*
* 内容:主程序中用 3 个按键,加速、减速、启动和停止。定时器做数码*
*
管动态扫描和步进电机驱动。*
*
* 硬件事项:J19 的 7B,6B,5B,4B 依次用杜邦线连接到 P27,P26,P25,P24 *
*
*
---------------------------------------------------------------*/
------------------------------------------------*/ void DelayUs2x(unsigned char t) {
while(--t); } void DelayMs(unsigned char t) {
while(t--) {
//大致延时 1mS DelayUs2x(245); DelayUs2x(245); } }
if(!S18) //如果检测到低电平,说明按键按下 { DelayMs(10); //延时去抖,一般 10-20ms if(!S18) //再次确认按键是否按下,没有按下则退出 { while(!S18);//如果确认按下按键等待按键释放,没有释放则一直等待 { } return 3; } } if(!S17) //如果检测到低电平,说明按键按下 { DelayMs(10); //延时去抖,一般 10-20ms if(!S17) //再次确认按键是否按下,没有按下则退出
//独立按键
unsigned
char
code
HEYAO_DuanMa[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
// 显示段码值 0123456789
unsigned char code HEYAO_WeiMa[]={0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80};
#define Coil_AB1 {A1=1;B1=1;C1=0;D1=0;}//AB 相通电,其他相断电 #define Coil_BC1 {A1=0;B1=1;C1=1;D1=0;}//BC 相通电,其他相断电 #define Coil_CD1 {A1=0;B1=0;C1=1;D1=1;}//CD 相通电,其他相断电 #define Coil_DA1 {A1=1;B1=0;C1=0;D1=1;}//D 相通电,其他相断电 #define Coil_A1 {A1=1;B1=0;C1=0;D1=0;}//A 相通电,其他相断电 #define Coil_B1 {A1=0;B1=1;C1=0;D1=0;}//B 相通电,其他相断电
//分别对应相应的数码管点亮,即位码
unsigned char TempData[8]={0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF,0XFF}; // 存 储 显 示 值
的全局变量
sbit A1=P2^7; //定义步进电机连接端口 sbit B1=P2^6; sbit C1=P2^5; sbit D1=P2^4;
影响
//TH0=0x00;
//给定初值
//TL0=0x00;
EA=1;
//总中断打开
ET0=1;
//时器中断打开
TR0=1;
//定时器开关打开
PT0=1;
//优先级打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
switch(j) {case 0: Coil_OFF StopFlag=1;j++;break; case 1: StopFlag=0;j--;break; } } else if(num==4) { sb=1;
while((1)&&(sb)) {
Flag=1; i=50; while((i--)&&(Flag))
if(!S20) //如果检测到低电平,说明按键按下 { DelayMs(10); //延时去抖,一般 10-20ms if(!S20) //再次确认按键是否按下,没有按下则退出 { while(!S20);//如果确认按下按键等待按键释放,没有释放则一直等待 { } return 1; } }
if(!S19) //如果检测到低电平,说明按键按下 { DelayMs(10); //延时去抖,一般 10-20ms if(!S19) //再次确认按键是否按下,没有按下则退出 { while(!S19);//如果确认按下按键等待按键释放,没有释放则一直等待 { } return 2; } }
// 遇 到 Coil_AB1 用
//改变这个参数可以调整电机转速 , //数字越小,转速越大,力矩越小
Coil_BC1 DelayMs(Speed); Coil_B1 DelayMs(Speed); Coil_AB1 DelayMs(Speed); num=KeyScan();
if(num==3)//第三个按键,电机停止和启动 {
/*-----------------------------------------------显示函数,用于动态扫描数码管 输入参数 FirstBit 表示需要显示的第一位,如赋值 2 表示 从第三个数码管开始显示 如输入 0 表示从第一个显示。 Num 表示需要显示的位数,如需要显示 99 两位数值则该值输入 2
#define Coil_C1 {A1=0;B1=0;C1=1;D1=0;}//C 相通电,其他相断电 #define Coil_D1 {A1=0;B1=0;C1=0;D1=1;}//D 相通电,其他相断电 #define Coil_OFF {A1=0;B1=0;C1=0;D1=0;}//全部断电
i=0;
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式 1,16 位定时器,使用"|"符号可以在使用多个定时器时不受
//清空数据,防止有交替重影 //段锁存
DataPort=HEYAO_WeiMa[i+FirstBit]; //取位码 LATCH2=1; //位锁存 LATCH2=0;
DataPort=TempData[i]; //取显示数据,段码 LATCH1=1; //段锁存 LATCH1=0;
i++; if(i==Num)
{ Coil_OFF
num=KeyScan(); //循环调用按键扫描 if(num==1)//第一个按键,速度等级增加
{ if(Speed<18) Speed++;
} else if(num==2)//第二个按键,速度等级减小
{ if(Speed>1) Speed--;
}
else if(num==3)//第三个按键,电机停止和启动 {
{ Coil_A1 DelayMs(Speed); Coil_AB1
{A1=1;B1=1;C1=0;D1=0;}代替 DelayMs(Speed);
Coil_B1 DelayMs(Speed); Coil_BC1 DelayMs(Speed);
//正向
// 遇 到 Coil_AB1 用 //改变这个参数可以调整电机转速 , //数字越小,转速越大,力矩越小
#include <REG51.H>
#define DataPort P1 //定义数据端口 程序中遇到 DataPort 则用 P1 替换
sbit LATCH1=P2^0;//定义锁存使能端口 段锁存
sbit LATCH2=P2^1;//
位锁存
sbit S17=P3^3; sbit S18=P3^2; sbit S19=P3^1; sbit S20=P3^0;
{
if(times==(20-Speed))//最大值 18,所以最小间隔值 20-18=2
{
times=0;
switch(i)
{
case 0:Coil_A1;i++;break;
case 1:Coil_B1;i++;break;
case 2:Coil_C1;i++;break;
case 3:Coil_D1;i++;break;
unsigned char Speed; bit StopFlag; bit Flag,sb; void Display(unsigned char FirstBit,unsigned char Num); void Init_Timer0(void);
unsigned char KeyScan(void);//键盘扫描
void Timer0_isr(void) interrupt 1
{
static unsigned char times,i;