智能小车之测速小车原理和开发

这篇具有很好参考价值的文章主要介绍了智能小车之测速小车原理和开发。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 测速模块介绍

2. 测试原理和单位换算

3. 定时器和中断实现测速开发和调试代码

4. 小车速度显示在OLED屏


1. 测速模块介绍

智能小车之测速小车原理和开发,51跟32单片机,单片机,stm32,嵌入式硬件

  • 用途:广泛用于电机转速检测,脉冲计数,位置限位等。
  • 有遮挡,输出高电平;无遮挡,输出低电平
  • 接线 :VCC 接电源正极3.3-5V
  • GND 接电源负极 DO TTL开关信号输出
  • AO 此模块不起作用

2. 测试原理和单位换算

  • 轮子走一圈,经过一个周长,C = 2x3.14x半径= 3.14 x 直径(6.5cm)
  • 对应的码盘也转了一圈,码盘有20个格子,每经过一个格子,会遮挡(高电平)和不遮挡(低电平), 那么一个脉冲就是走了 3.14 * 6.5 cm /20 = 1.0205CM
  • 定时器可以设计成一秒,统计脉冲数,一个脉冲就是1cm
  • 假设一秒有80脉冲,那么就是80cm/s

3. 定时器和中断实现测速开发和调试代码

定时器介绍:

  • C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器 或者计数器使用。
  • 确切的说,定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使 用时,每经过1个机器周期,计数存储器的值就加1。而当配置为计数器时,每来一个负跳变信号 (信号从P3.4 或者P3.5引脚输入),就加1,以此达到计数的目的。
  • 标准C51有2个定时器/计数器:T0和T1。他们的使用方法一致。C52相比C51多了一个T2

中断寄存器介绍:

智能小车之测速小车原理和开发,51跟32单片机,单片机,stm32,嵌入式硬件

CPU能响应定时器0中断的条件:需要配置IE寄存器的bit1: ET0 bit7:EA

  • 1. ET0中断允许要置一 ET0 = 1
  • 2. EA总中断要置一 EA = 1

测试数据通过串口发送到上位机

//main.c
#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "reg52.h"
#include "time.h"
#include "stdio.h"

sbit speedIO = P3^2;//外部中断0
unsigned int speedCnt = 0; //统计格子,脉冲次数
extern unsigned int speed;//速度
extern char signal; //主程序发速度数据的通知
char speedMes[24];  //主程序发送速度数据的字符串缓冲区

void Ex0Init()
{
	EX0 = 1;//允许中断
	//EA = 1;在串口初始化函数中已经打开了总中断
	IT0 = 1;//外部中断的下降沿触发
}

void main()
{
	Time0Init();//定时器0初始化
	UartInit();//串口相关初始化
	//外部中断初始化
	Ex0Init();
	
	while(1){
		if(signal){//定时器1s到点,把signal置一,主程序发送速度
			sprintf(speedMes,"speed:%d cm/s",speed);//串口数据的字符串拼装,speed是格子,每个格子1cm
			SendString(speedMes);//速度发出去
			signal = 0;//清0speed,下次由定时器1s后的中断处理中再置一
		}
	}
}

void speedHandler() interrupt 0 //外部中断处理函数
{
	speedCnt++;//码盘转动了一个格子
}

//uart.c
#include "reg52.h"
#include "motor.h"
#include "string.h"
sbit D5 = P3^7;
#define SIZE 12

sfr AUXR = 0x8E;
char buffer[SIZE];

void UartInit(void)		//9600bps@11.0592MHz
{
	AUXR = 0x01;
	SCON = 0x50; //配置串口工作方式1,REN使能接收
	TMOD &= 0x0F;
	TMOD |= 0x20;//定时器1工作方式位8位自动重装
	
	TH1 = 0xFD;
	TL1 = 0xFD;//9600波特率的初值
	TR1 = 1;//启动定时器
	
	EA = 1;//开启总中断
	ES = 1;//开启串口中断
}


void SendByte(char mydata)
{
	SBUF = mydata;
	while(!TI);
	TI = 0;
}

void SendString(char *str)
{
	while(*str != '\0'){
		SendByte(*str);
		str++;
	}
}


//M1qian  M2 hou M3 zuo  M4 you
void Uart_Handler() interrupt 4
{
	static int i = 0;//静态变量,被初始化一次
	char tmp;

	if(RI)//中断处理函数中,对于接收中断的响应
	{
			RI = 0;//清除接收中断标志位
			tmp = SBUF;
			if(tmp == 'M'){
				i = 0;
			}
			buffer[i++] = tmp;
		
			//灯控指令
			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;
			}
	}
		
}

//motor.c
#include "reg52.h"

sbit RightCon1A = P3^7;
sbit RightCon1B = P3^3;

sbit LeftCon1A = P3^4;
sbit LeftCon1B = P3^5;

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

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


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

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

void stop()
{
	LeftCon1A = 0;
	LeftCon1B = 0;
	
	RightCon1A = 0;
	RightCon1B = 0;
}

//time.c
#include "motor.h"
#include "reg52.h"

extern unsigned int speedCnt;
unsigned int speed;
char signal = 0;
unsigned int cnt = 0;

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 Time0Handler() interrupt 1
{
	cnt++;  //统计爆表的次数. cnt=1的时候,报表了1
	//重新给初值
	TL0=0x33;
	TH0=0xFE;
	
	if(cnt == 2000){//爆表2000次,经过了1s
		signal = 1;
		cnt = 0;  //当100次表示1s,重新让cnt从0开始,计算下一次的1s
		//计算小车的速度,也就是拿到speedCnt的值
		speed = speedCnt;
		speedCnt = 0;//1秒后拿到speedCnt个格子,就能算出这1s的速度,格子清零
	}
		
}

4. 小车速度显示在OLED屏

使用oled模块,oled写命令

智能小车之测速小车原理和开发,51跟32单片机,单片机,stm32,嵌入式硬件

写命令/数据的代码分析:

  • /* 1. start()
  • 2. 写入 b0111 1000 0x78
  • 3. ACK
  • 4. cotrol byte: (0)(0)000000 写入命令 (0)(1)000000写入数据
  • 5. ACK
  • 6. 写入指令/数据
  • 7. ACK
  • 8. STOP */

最终小车代码整合:文章来源地址https://www.toymoban.com/news/detail-702397.html

//main.c
#include "reg52.h"
#include "intrins.h"
#include "Oled.h"

void main()
{
		//1. OLED初始化
		Oled_Init();
		Oled_Clear();
		Oled_Show_Str(2,2,"speed:35cm/s");
	
		while(1);
}

//oled.c
#include "reg52.h"
#include "intrins.h"
#include "Oledfont.h"


sbit scl = P1^2;
sbit sda = P1^3;

void IIC_Start()
{
	scl = 0;
	sda = 1;
	scl = 1;
	_nop_();
	sda = 0;
	_nop_();
}

void IIC_Stop()
{
	scl = 0;
	sda = 0;
	scl = 1;
	_nop_();
	sda = 1;
	_nop_();
}

char IIC_ACK()
{
	char flag;
	sda = 1;//就在时钟脉冲9期间释放数据线
	_nop_();
	scl = 1;
	_nop_();
	flag = sda;
	_nop_();
	scl = 0;
	_nop_();
	
	return flag;
}

void IIC_Send_Byte(char dataSend)
{
	int i;
	
	for(i = 0;i<8;i++){
		scl = 0;//scl拉低,让sda做好数据准备
		sda = dataSend & 0x80;//1000 0000获得dataSend的最高位,给sda
		_nop_();//发送数据建立时间
		scl = 1;//scl拉高开始发送
		_nop_();//数据发送时间
		scl = 0;//发送完毕拉低
		_nop_();//
		dataSend = dataSend << 1;
	}
}

void Oled_Write_Cmd(char dataCmd)
{
	//	1. start()
	IIC_Start();
	//		
	//	2. 写入从机地址  b0111 1000 0x78
	IIC_Send_Byte(0x78);
	//	3. ACK
	IIC_ACK();
	//	4. cotrol byte: (0)(0)000000 写入命令   (0)(1)000000写入数据
	IIC_Send_Byte(0x00);
	//	5. ACK
	IIC_ACK();
	//6. 写入指令/数据
	IIC_Send_Byte(dataCmd);
	//7. ACK
	IIC_ACK();
	//8. STOP
	IIC_Stop();
}

void Oled_Write_Data(char dataData)
{
	//	1. start()
	IIC_Start();
	//		
	//	2. 写入从机地址  b0111 1000 0x78
	IIC_Send_Byte(0x78);
	//	3. ACK
	IIC_ACK();
	//	4. cotrol byte: (0)(0)000000 写入命令   (0)(1)000000写入数据
	IIC_Send_Byte(0x40);
	//	5. ACK
	IIC_ACK();
	///6. 写入指令/数据
	IIC_Send_Byte(dataData);
	//7. ACK
	IIC_ACK();
	//8. STOP
	IIC_Stop();
}


void Oled_Init(void){
	Oled_Write_Cmd(0xAE);//--display off
	Oled_Write_Cmd(0x00);//---set low column address
	Oled_Write_Cmd(0x10);//---set high column address
	Oled_Write_Cmd(0x40);//--set start line address  
	Oled_Write_Cmd(0xB0);//--set page address
	Oled_Write_Cmd(0x81); // contract control
	Oled_Write_Cmd(0xFF);//--128   
	Oled_Write_Cmd(0xA1);//set segment remap 
	Oled_Write_Cmd(0xA6);//--normal / reverse
	Oled_Write_Cmd(0xA8);//--set multiplex ratio(1 to 64)
	Oled_Write_Cmd(0x3F);//--1/32 duty
	Oled_Write_Cmd(0xC8);//Com scan direction
	Oled_Write_Cmd(0xD3);//-set display offset
	Oled_Write_Cmd(0x00);//
	
	Oled_Write_Cmd(0xD5);//set osc division
	Oled_Write_Cmd(0x80);//
	
	Oled_Write_Cmd(0xD8);//set area color mode off
	Oled_Write_Cmd(0x05);//
	
	Oled_Write_Cmd(0xD9);//Set Pre-Charge Period
	Oled_Write_Cmd(0xF1);//
	
	Oled_Write_Cmd(0xDA);//set com pin configuartion
	Oled_Write_Cmd(0x12);//
	
	Oled_Write_Cmd(0xDB);//set Vcomh
	Oled_Write_Cmd(0x30);//
	
	Oled_Write_Cmd(0x8D);//set charge pump enable
	Oled_Write_Cmd(0x14);//
	
	Oled_Write_Cmd(0xAF);//--turn on oled panel		
}

void Oled_Clear()
{
	unsigned char i,j; //-128 --- 127
	
	for(i=0;i<8;i++){
		Oled_Write_Cmd(0xB0 + i);//page0--page7
		//每个page从0列
		Oled_Write_Cmd(0x00);
		Oled_Write_Cmd(0x10);
		//0到127列,依次写入0,每写入数据,列地址自动偏移
		for(j = 0;j<128;j++){
			Oled_Write_Data(0);
		}
	}
}

void Oled_Show_Char(char row,char col,char oledChar){ //row*2-2
	unsigned int  i;
	Oled_Write_Cmd(0xb0+(row*2-2));                           //page 0
	Oled_Write_Cmd(0x00+(col&0x0f));                          //low
	Oled_Write_Cmd(0x10+(col>>4));                            //high	
	for(i=((oledChar-32)*16);i<((oledChar-32)*16+8);i++){
		Oled_Write_Data(F8X16[i]);                            //写数据oledTable1
	}

	Oled_Write_Cmd(0xb0+(row*2-1));                           //page 1
	Oled_Write_Cmd(0x00+(col&0x0f));                          //low
	Oled_Write_Cmd(0x10+(col>>4));                            //high
	for(i=((oledChar-32)*16+8);i<((oledChar-32)*16+8+8);i++){
		Oled_Write_Data(F8X16[i]);                            //写数据oledTable1
	}		
}


/******************************************************************************/
// 函数名称:Oled_Show_Char 
// 输入参数:oledChar 
// 输出参数:无 
// 函数功能:OLED显示单个字符
/******************************************************************************/
void Oled_Show_Str(char row,char col,char *str){
	while(*str!=0){
		Oled_Show_Char(row,col,*str);
		str++;
		col += 8;	
	}		
}

到了这里,关于智能小车之测速小车原理和开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 35、基于51单片机自动灭火避障智能小车 消防灭火小车系统设计

    智能作为现代的新发明,是以后的发展方向,他可以按照预先设定的模式在一个环境里自动的运作,不需要人为的管理,可应用于科学勘探等等的用途。智能小车就是其中的一个体现,本次设计的多功能智能灭火避障小车, 以 STC89C 52单片机作为微控制器,设计出一种 可以寻

    2024年02月03日
    浏览(52)
  • “无限交互,全新驾驶体验!智能语音小车,与您共同开创未来出行。”#51单片机最终项目《智能语音小车》【中】

      本篇博文介绍的是用51单片机的最终项目《智能语音小车》【中】,包含循迹小车基本原理和方案,根据循迹原理实现循迹功能代码编写,解决冲出赛道不转弯问题,优化转弯平滑。加入电机调速,跟随小车,摇头测距小车01_舵机和超声波封装,摇头测距小车02_实现疯狂

    2024年02月21日
    浏览(55)
  • 51单片机-PWM调速(直流电机,智能小车的电机调速)

    这次来对PWM做一个总结 最近学习时,发现PWM控制在很多地方都会用到,比如使用PWM来控制电机的速度,使用PWM来生成想要的波形。 那么到底什么是PWM呢? PWM即 脉冲宽度调制 ,在具有惯性的系统中,可以通过对 一系列脉冲的宽度进行调制 ,来等效的获得所需要的模拟参量。

    2024年02月02日
    浏览(46)
  • 基于51单片机的多功能智能语音循迹避障小车

    目录 一.功能介绍及硬件准备 二.电机控制及调速 三.小车循迹方案 四.跟随功能实现 五.测速功能实现 六.OLED显示车速 七.摇头避障功能实现 八.SU-03T语音模块介绍 九.语音切换小车模式+OLED显示模式 这是一款基于51单片机开发的智能小车,通过这篇文章我会记录下来开发这款小

    2024年02月03日
    浏览(46)
  • STM32单片机智能小车一PWM方式实现小车调速和转向

    目录 1. 电机模块开发 2. 让小车动起来 3. 串口控制小车方向 4. 如何进行小车PWM调速 5. PWM方式实现小车转向 L9110s概述 接通VCC,GND 模块电源指示灯亮, 以下资料来源官方,具体根据实际调试 IA1输入高电平,IA1输入低电平,【OA1 OB1】电机正转; IA1输入低电平,IA1输入高电平,

    2024年02月07日
    浏览(56)
  • 毕设开源 基于stm32的智能平衡小车 - 单片机 物联网嵌入式

    文章目录 0 前言 1 项目背景 2 设计思路 3 硬件设计 4 软件设计 4.2 直立控制程序设计 4.3 速度控制程序设计 4.4 方向控制程序设计 4.5 关键代码 5 最后 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这

    2024年02月22日
    浏览(60)
  • 68、基于51单片机语音识别控制小车行走系统设计(程序+原理图+PCB源文件+参考论文+开题报告+任务书+元器件清单等)

    随着电子工业的发展,具有语音控制功能的小车越来越受到人们的青睐,在人们的日常消费生活中起着不可忽视的作用。目前,声控技术已在很多领域得到使用。 本文对语音控制功能的小车概况做了阐述。在硬件设计方面,本论文以凌阳公司的STC89C52单片机为控制核心,以语

    2024年02月11日
    浏览(48)
  • 基于51单片机的智能温控风扇(程序+仿真+原理图)

    基于51单片机的智能温控风扇,通过DS180温度传感器采集温度,并通过数码管显示温度,当温度高于20°时,开启风扇降温,当温度低于20°时风扇关闭。 基于51单片机的智能温控风扇 方案验证仿真软件使用的是Proteus仿真文件,Proteus软件版本为8.8;如需下载软件,可以在公众号

    2024年02月11日
    浏览(63)
  • 32、基于51单片机红外智能垃圾桶系统设计

    随着现代化进程的日益推进,科技越来越发达,人们的生活水平也提高了,城市化程度越来越高,与此同时也带了许多问题,生活垃圾越来越多垃圾设施却不够完善。无论是在公共场合还是家庭厨房的垃圾大都是没有盖或者有盖但需要人用手打开的,比如夏天的家庭厨房没有

    2023年04月14日
    浏览(52)
  • 新定义51单片机(RD8G37)实现测距测速仪

    本文描述用新定义51单片机(RD8G37)+超声波一体测距传感器实现简单的测距测速仪。   测距仪演示效果   新定义RD8G37Q48RJ开发板 超声波测距模块:  8位并口屏   1、main.c 2、传感器驱动 HC_SR04.c HC_SR04.h 3、初始化和中断 SC_Init.c, 初始化8位并口屏GPIO,TIMER0。 TIMER0设置为10us中

    2024年01月18日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包