51单片机控制步进电机
将自己大学做的为数不多的编程学习进行记录,选修嵌入式之前,师兄提醒我这作业量大,还是选了,因为对编程有一种向往。差点挂掉这门课,每周要交作业,学习一到两个硬件知识,真的比想象中吃力,到最后还是顺利交完作业,通过了课程。这个课程正逢《流浪地球》热播,老师第一节课说了其中电影中有一点很真实:“没有硬件支撑和配合,程序不管用。”通过这个课程,确实了解到了硬件的重要性,以前看到的黑客电影一下子分为严谨和糊弄观众两种了。
- 使用Keil 4编写C语言程序,编译生成.hex文件,使用Proteus7.8进行仿真
-
- 使用了51单片机,按键,电机等一系列硬件
-
#include <reg52.h> #include <intrins.h> #include <string.h> #define uint unsigned int #define uchar unsigned char sbit IN1 = P1^0; sbit IN2 = P1^1; sbit ENA = P1^2; sbit RS = P2^5; sbit RW = P2^6; sbit EN = P2^7; sbit k1 = P2^0; //正转 sbit k2 = P2^1; //反转 sbit k3 = P2^2; //加速 sbit k4 = P2^3; //减速 sbit k5 = P2^4; //暂停 sbit inter0 =P3^2; int g,s,b,q,t,e; //定义转速各位 int m,n,num,PWM=100,PWMH=50; int ZS=0,PWMH_1,PWMH_2,PWMH_3; //转速 uchar LCD_DSY_BUFFER1[]={"ZS 040 PWM 050%"}; // buffer缓冲器 /******************************************************************************* * 函 数 名 : Timer0Init * 函数功能 : 定时器0初始化 *******************************************************************************/ void Timer0Init() { TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。 TH0=0XFC; //给定时器赋初值,定时1ms TL0=0X18; TR0=1;//打开定时器 ET0=1;//打开定时器1中断允许 EA=1; //打开总中断 } /******************************************************************************* * 函 数 名 : Int1Init() * 函数功能 : 设置外部中断1 *******************************************************************************/ void Int0Init() //设置INT0 { IT0=1;//1-跳变沿出发方式(下降沿)0-低电平触发 EX0=1;//打开INT0的中断允许。 EA=1;//打开总中断 } /*================测量转速,利用外部中断INT0和定时器T0,每1s计算一次============*/ /*============定时器0 PWM输出,调节转速 ============*/ void X0_time() interrupt 0 //外部中断0部分 { inter0=0; m++; //计算脉冲 inter0=1; } //定时器T0中断部分 void T0_time() interrupt 1 // interrupt 1 为定时器中断0; 0-外部中断0; 2-外部中断1;3-定时器1;4-串口 { TH0 = 0XFC; // TH0=(65536-1000)/256; 定时1ms TL0 = 0x18; num++; //这是计算溢出次数(脉冲宽度) t++; if(num>=100) //周期100ms,num=1 表示1ms num=0; if(num<=PWMH) ENA=1; //置高电平 else ENA=0; if(t==970) //1s时间到,计算转速 1000ms { ZS=m*60/24; //一转2脉冲 b=ZS%1000/100; s=ZS%100/10; g=ZS%10; ZS=m*60/2; m=0; t=0; } } void delay(uchar z) //延时0.5MS { uchar y; for(z;z>0;z--) for(y=243;y>0;y--); } void keyscan() { if(k1==0) //正转 { e=1; while(!k1); } if(k2==0) //反转 { e=2; while(!k2); } if(k3==0) //加速 { PWMH=PWMH+10; if(PWMH>=110) { PWMH=30; } while(!k3); } if(k4==0) //减速 { PWMH=PWMH-10; if(PWMH<=-10) { PWMH=30; } while(!k4); } if(k5==0) //暂停、启动 { e=0; while(!k5); } PWMH_1=PWMH/100; PWMH_2 = PWMH %100/10; PWMH_3 =PWMH%10; } /****************LCD显示部分********************/ uchar Read_LCD_State() // 6 1602 { uchar state; RS=0;RW=1;EN=1;delay(1); state=P0; EN = 0;delay(1); return state; } void LCD_Busy_Wait() // 7 { while((Read_LCD_State()&0x80)==0x80); //当最高位为1时,延时5秒 delay(5); } void Write_LCD_Data(uchar dat) // 8 { LCD_Busy_Wait(); RS=1;RW=0;EN=0;P0=dat;EN=1;delay(1);EN=0; //dat为 } void Write_LCD_Command(uchar cmd) // 9 command命令 控制 { LCD_Busy_Wait(); RS=0;RW=0;EN=0;P0=cmd;EN=1;delay(1);EN=0; //cmd为地址 } void Init_LCD() // 10 初始化 { Write_LCD_Command(0x38); //显示16*2显示,5*7点阵,8位数据接口 delay(1); Write_LCD_Command(0x01); //显示清零,数据指针清零 delay(1); Write_LCD_Command(0x06); //写一个字符后地址指针加一 delay(1); Write_LCD_Command(0x0c); //设置开显示,不显示光标 delay(1); } void Set_LCD_POS(uchar p) // 11 { Write_LCD_Command(p|0x80); // } void Display_LCD_String(uchar p,uchar *s) //12 在LCD显示 Display_LCD_String(0x00,LCD_DSY_BUFFER1); { uchar i; Set_LCD_POS(p); //p为液晶屏地址0x00 for(i=0;i<25;i++) { Write_LCD_Data(s[i]); delay(1); } } void Display_LCD_String2(uchar p,uchar *s) //12 在LCD显示 { uchar i; Set_LCD_POS(p); //p为液晶屏地址0x00 for(i=0;i<16;i++) { Write_LCD_Data(s[i]); delay(1); } } void Format_Date(uchar d,uchar *a) // 13 { a[1]=d+'0'; //0’的ASCII值为48 } void main() { Timer0Init(); //初始化T0 Int0Init(); //初始化外部中断 Init_LCD(); while(1) { keyscan(); Format_Date(b,LCD_DSY_BUFFER1+2); // Format_Date(s,LCD_DSY_BUFFER1+3); // Format_Date(g,LCD_DSY_BUFFER1+4); // Format_Date(PWMH_1,LCD_DSY_BUFFER1+10); Format_Date(PWMH_2,LCD_DSY_BUFFER1+11); Format_Date(PWMH_3,LCD_DSY_BUFFER1+12); Display_LCD_String(0x00,LCD_DSY_BUFFER1); if(e==0) {IN1=1;IN2=1;ENA=1;} if(e==1) {IN1=0;IN2=1;ENA=1;} if(e==2) {IN1=1;IN2=0;ENA=1;} } }
- 难点是按键控制电机转速时使用PWM,将电机转速传递到液晶显示屏并显示
-
- 每一次接触新的硬件,就要查它的相关信息,才能顺利编程,真是很宝贵的自己学习经历