pwm实现调速
1、原理:利用定时器溢出自动循环,0.5ms为一个节点,循环40次20ms为一个周期,全速为40次循环皆做功,半速为20个循环做功,stop为0循环做功
2、实现:
①将2个车轮前进分别进行定义
②用定时器0控制左轮做功次数,用定时器1控制右轮做工次数
③将两个轮子通过pwm来调节平衡
④也可实现小车的平缓转弯
直接代码演示:
1、main.c
#include "reg52.h"//代码里边没有,sbit i/o口,可以不要声明 //#include "intrins.h"//代码里边没有_nop_();可以不要该声明 #include "motor.h" #include "dalay.h" #include "uart.h" #include "esp.h" #include "pwm.h" extern char speed; void main() { Delay1000ms(); time0init(); UartInit(); // init_esp(); while(1){ Delay1000ms(); Delay1000ms(); speed=10; Delay1000ms(); Delay1000ms(); speed=20; Delay1000ms(); Delay1000ms(); speed=40; } while(1); }
2、motor.c
#include "reg52.h" sbit right1=P3^2; sbit right2=P3^3; sbit left1=P3^4; sbit left2=P3^5; void goback() { left1=1; left2=0; right1=1; right2=0; } void goforward() { left1=0; left2=1; right1=0; right2=1; } void goleft() { left1=0; left2=0; right1=0; right2=1; } void goright() { left1=0; left2=1; right1=0; right2=0; } void stop() { left1=0; left2=0; right1=0; right2=0; }
motor.h
void goback(); void goforward(); void goleft(); void goright(); void stop();
3、uart.c
#include "reg52.h" #include "motor.h" #include "string.h" #include "dalay.h" #include "esp.h" #define SIZE 12 sfr AUXR=0x8E;//不认识AUXR,报错需要声明 char buffer[SIZE]; extern char AT_ok_flag; void UartInit(void) //9600bps@11.0592MHz { AUXR=0x01; SCON=0x50;//配置串口工作方式1,ren能接收01000000 TMOD&=0x0F; TMOD|=0x20;//定时器1的工作方式8位自动重装配置 TH1=0xFD; TL1=0xFD;//9600波特率的初值 TR1=1;//启动定时器 EA=1;//打开总中断 ES=1;//允许串口中断 } void uart_toutine()interrupt 4 { static int i = 0; char tmp; if(RI) { RI = 0; tmp = SBUF; if(tmp=='M'||tmp=='W'||tmp=='O'||tmp=='L'){//WIFI GOT IP中既包含W、又包含F,底下条件满足FI,D5亮 i = 0; } buffer[i++] = tmp; if(buffer[0] == 'O' && buffer[1] == 'K'){ AT_ok_flag = 1; memset(buffer, '\0', SIZE); } if(buffer[0] == 'L' && buffer[1] == '0'){ D5 = 0; memset(buffer, '\0', SIZE); } if(buffer[0] == 'L' && buffer[1] == '1'){ D5 = 1; memset(buffer, '\0', SIZE); } if(buffer[0] == 'M'){ switch(buffer[1]){ case '1': goforward(); Delay10ms(); break; case '2': goleft(); Delay10ms(); break; case '3': goright(); Delay10ms(); break; case '4': goback(); Delay10ms(); break; default: stop(); break; } } } if(i == 12){ memset(buffer, '\0', SIZE); i = 0; } }
uart.h
void UartInit(); //9600bps@11.0592MHz
4、pwm.c
#include "reg52.h" #include "motor.h" char t=0; char speed; void time0init() { TMOD=0x01;//定义模式为16位寄存器 TL0=0x33;//定义开始时间,赋初值 TH0=0xFE; TR0=1;//计时开始,直到计时结束TF0才为1 TF0=0; ET0=1;//打开定时器0中断 EA=1;//打开总中断 } void time0hander()interrupt 1//定时器寄存器溢出,此时TF0=1,中断发生,TF0置0,重新循环 { t++;//用来计数 TL0=0x33;//重新赋初值 TH0=0xFE; if(t<speed){ goforward(); } else{ stop(); } if(t==40){ t=0;//循环100次为1s,重新循环 } }
pwm.h
void time0init();
5、dalay.c
#include "intrins.h" void Delay1000ms() //@11.0592MHz { unsigned char i, j, k; _nop_(); i = 8; j = 1; k = 243; do { do { while (--k); } while (--j); } while (--i); } void Delay10ms() //@11.0592MHz { unsigned char i, j; i = 18; j = 235; do { while (--j); } while (--i); }
dalay.h
void Delay1000ms(); void Delay10ms();
以下代码为wifi控制,可添加也可不添加:
esp.c
#include "reg52.h" #include "dalay.h" #include "uart.h" code char LJWL[]="AT+CWJAP=\"Xiaomi_7EC3\",\"xiaomi123\"\r\n"; code char LJFWQ[]="AT+CIPSTART=\"TCP\",\"192.168.31.152\",8880\r\n"; char KQTC[]="AT+CIPMODE=1\r\n"; char KQFS[]="AT+CIPSEND\r\n"; sbit D6=P3^6; sbit D5=P3^7; char AT_ok_flag; void senddata(char c) { SBUF=c; while(!TI); TI=0; } void sendstring(char*str) { while(*str!='\0'){ senddata(*str); str++; } } void init_esp() { Delay1000ms(); sendstring(LJWL); while(!AT_ok_flag); D6=0; AT_ok_flag=0; D6=1; sendstring(LJFWQ); D5=1; while(!AT_ok_flag); AT_ok_flag=0; sendstring(KQTC); D6=0; while(!AT_ok_flag); AT_ok_flag=0; sendstring(KQFS); D6=1; while(!AT_ok_flag); if(AT_ok_flag){ D6=0; D5=0; } }
esp.h
sbit D6=P3^6; sbit D5=P3^7; void init_esp();