51单片机+L298驱动步进电机+L297测速+LCD1602显示+按键调试+Proteus仿真
51单片机+L298驱动步进电机+L297测速+LCD1602显示+按键调试+Proteus仿真
*Proteus仿真

- L298N是双H桥式驱动器。
- L297是步进电机控制集成芯片(包括环形分配器),可产生四相驱动信号,应用于微处理机控制两相双极性和四相单极性步进电机。电动机可由半阶梯、正常和斩波驱动模式驱动,同时设于晶片内的PWM斩波线路容许以开关形式控制线路的电流。此器件只需要时钟、方向和模式输入信号。相位是由内部产生的,因此可减轻微处理机和程序设计的负担。
实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
| /\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* 51单片机+L298驱动步进电机+L297测速+LCD1602显示+按键调试+Proteus仿真 \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
#include <reg51.h> #include <stdio.h>
//宏定义 #define uchar unsigned char #define uint unsigned int //定义提供脉冲的管脚 sbit CLOCK = P0^1; sbit CW = P0^0;//控制电机方向
//LCD显示用 sbit RS=P2^0; sbit RW=P2^1; sbit E=P2^2;
sbit s_add = P3^2; //速度加 sbit s_mus = P3^3; //速度减 sbit forward = P3^4; //正转 sbit reversal = P3^5; //反转
uchar SpeedChar[]="SPEED(n/min):"; uchar StateChar[]="RUN STATE:"; uchar STATE_CW[]="CW "; uchar STATE_CCW[]="CCW";
//当前速度 uint speed = 0; //设置速度标志位 uint set_speed = 30;
void lcd\_int(); void lcd\_w\_cmd(unsigned char com); void lcd\_w\_dat(unsigned char dat); unsigned char lcd\_r\_start(); void display(); void display\_speed(); void dis\_state(); void delay(uint j) { uint x; for(x=0;x<j;x++); }
void key\_scan() { if(forward==0) { delay(1000); if(forward==0) { CW=1; dis\_state(); } while(!forward); } if(reversal==0) { delay(1000); if(reversal==0) { CW=0; dis\_state(); } while(!reversal); } if(s_add==0) { delay(1000); if(s_add==0) { if(set_speed>10) set_speed -=2; speed=(60000/(8\*set_speed)); display\_speed(); while(!s_add); } } if(s_mus==0) { delay(1000); if(s_mus==0) { if(set_speed<50) set_speed +=2; speed=(60000/(8\*set_speed)); display\_speed(); while(!s_mus); } }
}
void main() { EA=1;//打开总中断 TMOD=0x01; //定时器工作方式 TH0=(65535-1000)/256; //初值约1ms TL0=(65535-1000)%256; ET0=1; //打开定时器中断 TR0=1; //打开定时器 lcd\_int(); display(); //计算示初始速度 speed=(60000/(8\*set_speed)); display\_speed(); dis\_state(); while(1){ key\_scan(); }
}
void display() { uchar i=0; lcd\_w\_cmd(0x80); //设置显示地址(第一行) for(i=0;SpeedChar[i]!='\0';i++) //此处显示SpeedChar[]字符串,字符串结束符为‘0’ { lcd\_w\_dat(SpeedChar[i]); } lcd\_w\_cmd(0xC0); //更改显示位置用 for(i=0;StateChar[i]!='\0';i++) //此处显示SpeedChar[]字符串,字符串结束符为‘0’ { lcd\_w\_dat(StateChar[i]); } }
void dis\_state() { uchar i; lcd\_w\_cmd(0xCB); if(CW==0) { for(i=0;STATE_CW[i]!='\0';i++) //此处显示Current\_Time[]字符串,字符串结束符为‘0’ { lcd\_w\_dat(STATE_CW[i]); } } if(CW==1) { for(i=0;STATE_CCW[i]!='\0';i++) //此处显示Current\_Time[]字符串,字符串结束符为‘0’ { lcd\_w\_dat(STATE_CCW[i]); } } } void display\_speed() { uchar str[3]={""}; uchar i; lcd\_w\_cmd(0x8d); sprintf(str,"%u ",speed); for(i=0;str[i]!='\0';i++) //此处显示Current\_Time[]字符串,字符串结束符为‘0’ { lcd\_w\_dat(str[i]); } }
//函数名:lcd\_int //函数功能:lcd初始化 void lcd\_int() { lcd\_w\_cmd(0x3c); //设置工作方式 lcd\_w\_cmd(0x0c); //设置显示状态 lcd\_w\_cmd(0x01); //清屏 lcd\_w\_cmd(0x06); //设置输入方式 lcd\_w\_cmd(0x80); //设置初始显示位置 } //函数名:lcd\_w\_cmd //函数功能:写命令 //形式参数:命令字已经存入com单元中 void lcd\_w\_cmd(unsigned char com) { unsigned char i; do { //查lcd忙状态 i=lcd\_r\_start(); //调用读状态字函数 i&=0x80; //“与”操作屏蔽掉低7位 delay(2); }while(i!=0); //lcd忙,继续查询,否则退出循环 RW=0; delay(1); RS=0; //RW=0,RS=0,写lcd命令字 delay(1); E=1; //E端时序以0或1高低波动 delay(1); P1=com; //将com中的命令字写入lcd数据口 delay(1); E=0; delay(1); RW=1; delay(2); } //函数名:lcd\_w\_dat //函数功能:写数据 void lcd\_w\_dat(unsigned char dat) { unsigned char i; do { //查忙操作 i=lcd\_r\_start(); //调用读状态字函数 i&=0x80; //“与”操作屏蔽掉低7位 delay(2); }while(i!=0); //lcd忙,继续查询,否则退出循环 RW=0; delay(1); RS=1; //RW=0,RS=1,写lcd命令字 delay(1); E=1; //E端时序以0或1高低波动 delay(1); P1=dat; //将dat中的显示数据写入lcd数据口 delay(1); E=0; delay(1); RW=1; delay(2); } //函数名:lcd\_r\_start //函数功能:读状态字 unsigned char lcd\_r\_start() { unsigned char s; RW=1; //RW=1,RS=0,读lcd状态 delay(1); RS=0; delay(1); E=1; //E端时序以0或1高低波动 delay(1); s=P1; //从lcd的数据口读状态 delay(1); E=0; delay(1); RW=0; delay(1); return(s); //返回值s读取状态忙或空闲 } void Time() interrupt 1 { static unsigned int count=0; TH0=(65535-1000)/256; //重装初值 TL0=(65535-1000)%256; //重装初值 count++; //8个脉冲转一圈 if(count>=set_speed) { count = 0; CLOCK = ~CLOCK; }
}
|
仿真资源和程序源码
1 2 3
| 链接:https://pan.baidu.com/s/1-kkMKdzKIv5N6rZl3_tBzg 提取码:cmix
|
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!