C51小车项目-笔记9

一、小车的拼装

如图所示:

        黑色电池盒正负极和白色电池盒正负极连接,L9110s点击正负极与白色电池盒连接,上官一号正负极与白色电池盒连接,

 

 

 注意:千万不要把电机的正负极接反,接电0.5秒就冒烟

 二、让小车动起来

代码如下:

#include "reg52.h"
#include "intrins.h"

sbit RightCon1A = P3^2;//右轮
sbit RightCon1B = P3^3;

sbit LeftCon1A = P3^4;//左轮
sbit LeftCon1B = P3^5;

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;
 
	_nop_();
	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void goForward(){//前进
	
	LeftCon1A = 0;
	LeftCon1B = 1;
	
	RightCon1A = 0;
	RightCon1B = 1;
}

void goLeft(){//左转
	
	LeftCon1A = 0;
	LeftCon1B = 0;
	
	RightCon1A = 0;
	RightCon1B = 1;
}

void goRight(){//右转
	
	LeftCon1A = 0;
	LeftCon1B = 1;
	
	RightCon1A = 0;
	RightCon1B = 0;
}


void goBack(){//后退
	
	LeftCon1A = 1;
	LeftCon1B = 0;
	
	RightCon1A = 1;
	RightCon1B = 0;
}

void main()
{
	while(1){
		goForward();
		Delay1000ms();
		Delay1000ms();
		Delay1000ms();
		Delay1000ms();
		Delay1000ms();
		goBack();
		Delay1000ms();
		Delay1000ms();
		goLeft();
		Delay1000ms();
		Delay1000ms();
		goRight();
		Delay1000ms();
		Delay1000ms();
	}
	
 } 

 三、实现串口控制小车

代码如下:

#include "reg52.h"
#include "motor.h"
#include <string.h>

#define SIZE 12

sfr AUXR = 0X8E;

char buffer[SIZE];

void UartInit(void){
	AUXR = 0X8E;
	SCON = 0X50;
	EA = 1;
	ES = 1;
	
	TMOD &= 0X0F;
	TMOD |= 0X20;
	TH1 = 0XFD;
	TL1 = 0XFD;
	TR1 = 1;//启动定时器
}
//M1 前,M2后,M3 左,M4 右
void Uart_Handler() interrupt 4  //中断处理函数
{
	static int i = 0;//静态变量,被初始化一次
	char tmp;//定义一个临时的字符变量,用于接收信息
	
	if(RI)//中断处理函数中,对于接收中断的响应
	{
			RI = 0;//清除接收中断标志位
			tmp = SBUF;  //让字符变量接收寄存器传递出来的信息(它是一个字节寻址的寄存器,字节地址为99H,通常用于存储一个字符的数据大小?)
		//tmp只能接收一个字母,SBUF也是一个字节一个字节的输出数据和接收数据
		
			if(tmp == 'M')//注意是M开头的
				{
					i = 0;  //每次接收到信息都让i等于0,用于表示数组的第一位
		    	}
			buffer[i++] = tmp;  //给buffer数组赋值,接下来把temp接收的数据都存到buffer数组中
			
			if(buffer[0] == 'M'){
				switch(buffer[1]){
					case '1':
						goForward();
						break;
					case '2':
						goBack();
						break;
					case '3':
						goLeft();
						break;
					case '4':
						goRight();
						break;
					default:
						stop();
						break;
				}
				
			}
			
			if(i==12){
				
				memset(buffer,'\0',SIZE);//清空内容
				i=0;//越界
			}
}
		
	if(TI);
}

 代码控制小车完成之后,在开发板接上蓝牙模块,就可以实现蓝牙控制小车

四、PWM小车调速

代码如下:

#include "reg52.h"
#include "motor.h"

char speed;
char cnt = 0;

void Time0Init(){
	//1、配置定时器0工作模式位16位计时
	TMOD = 0X01;
	//2、给初值,定一个0.5ms出来
	TL0 = 0X33;
	TH0 = 0XFE;
	//3、开始计时
	TR0 = 1;
	TF0 = 0;//赋初值
	//4、打开定时器0终端
	ET0 = 1;
	//5、打开总终端 
	EA = 1;
}

 void Time0Handler() interrupt 1//定时器0的中中断查询序列是1
 {
	 cnt++;//统计爆表次数,cnt=1的时候,爆表了1次
	 //重新给初值
	 TL0 = 0X33;
	 TH0 = 0XFE;
	 //控制PWM波
	 if(cnt < speed){  //第一次cnt>10,第二次cnt20,第三次cnt>40,执行全速前进函数,剩下的执行停止函数
		 //前进
		 goForward();
	 }else{
		//停止 
		 stop();
	 } 
	 
	 if(cnt == 40){//爆表40次,总共经过了20ms
		 cnt = 0;//当100次表示1s,重新让cnt从1开始,计算下一次的1s
	 }
	 
 }

void main()
{
	Time0Init();
	UartInit();
	Delay1000ms();
	
	while(1){
		speed = 10;//十份全速运行,三十份停止,所以慢,20ms是40份的500us=0.5ms,
		//相当于在20ms里面,有0.5*10=5ms的时间是全速前进,而剩下的15ms的时间是在停止
		Delay1000ms();
		Delay1000ms();
		speed = 20;
		Delay1000ms();
		Delay1000ms();
		speed = 40;
		Delay1000ms();
		Delay1000ms();
	}
	
 } 

五、PWM方式实现小车转向

 原理: 左轮定时器0调速,右轮定时器1调速,那么左转就是右轮速度大于左轮!

 代码如下:

//main.c
void main()
{
 Time0Init(); Time1Init();
 //UartInit();
 
 while(1){
 speedLeft = 10;//10份单位时间全速运行,30份停止,所以慢,20ms是40份的500us
 speedRight = 40;
 Delay1000ms();
 Delay1000ms();
 
 speedLeft = 40;
 speedRight = 10;
 Delay1000ms();
 Delay1000ms();
 }
}
//time.c
#include "motor.h"
#include "reg52.h"
char speedLeft;
char cntLeft = 0;
char speedRight;
char cntRight = 0;
void Time1Init()
{
 //1. 配置定时器1工作模式位16位计时
 TMOD &= 0x0F;
 TMOD |= 0x1 << 4;
 //2. 给初值,定一个0.5出来
 TL1=0x33;
 TH1=0xFE;
 //3. 开始计时
 TR1 = 1;
 TF1 = 0;
 //4. 打开定时器1中断
 ET1 = 1;
 //5. 打开总中断EA
 EA = 1;
}
void Time0Init()
{
 //1. 配置定时器0工作模式位16位计时
 TMOD = 0x01;
 //2. 给初值,定一个0.5出来
 TL0=0x33;
 TH0=0xFE;
 //3. 开始计时
 TR0 = 1;
 TF0 = 0;
 //4. 打开定时器0中断
 ET0 = 1;
 //5. 打开总中断EA
 EA = 1;
}
void Time1Handler() interrupt 3
{
 cntRight++;  //统计爆表的次数. cnt=1的时候,报表了1
 //重新给初值
 TL1=0x33;
 TH1=0xFE;
 
 //控制PWM波
 if(cntRight < speedRight){
 //右前进
 goForwardRight();
 }else{
 //停止
 stopRight();
 }
 
 if(cntRight == 40){//爆表40次,经过了20ms
 cntRight = 0;  //当100次表示1s,重新让cnt从0开始,计算下一次的1s
 }
 
}
void Time0Handler() interrupt 1
{
 cntLeft++;  //统计爆表的次数. cnt=1的时候,报表了1
 //重新给初值
 TL0=0x33;
 TH0=0xFE;
 
 //控制PWM波
 if(cntLeft < speedLeft){
 //左前进
 goForwardLeft();
 }else{
 //停止
 stopLeft();
 }
 
 if(cntLeft == 40){//爆表40次,经过了20ms
 cntLeft = 0;  //当100次表示1s,重新让cnt从0开始,计算下一次的1s
 }
 
}

 

上一篇:使用kubeadm安装k8s v1.31+containerd+外部etcd+haproxy负载均衡


下一篇:【C++】7___运算符重载