玩转电机驱动——电机编码器

2023-05-16

玩转电机驱动——电机编码器


文章目录

  • 玩转电机驱动——电机编码器
  • 前言
  • 一、旋转编码器
    • 1. 光学编码器
    • 2. 光学旋转编码器与Arduino连接
    • 3. 程序
  • 二、Arduino Encoder.h库相关知识
    • 1.硬件要求
    • 2. 基本用法
    • 3. 了解正交编码信号
    • 4. 示例程序
    • 5. 中断延迟要求
    • 6. 优化中断选项
    • 7. 最大速度和 CPU 使用率
    • 8. 低性能轮询模式
  • 总结


前言

编码器(encoder)是将信号(如比特流)或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号,前者称为码盘,后者称为码尺。(对于电机测速来说应该需要将角位移转变为电信号,所以应该是码盘。)按照信号原理编码器可分为增量式和绝对式两类。

增量式编码器是将位移转换成周期性的电信号,再把这个电信号转变成计数脉冲,用脉冲的个数表示位移的大小。这种类型的编码器提供脉冲作为输出,可以将其视为增量信号。因为它没有任何唯一位置的唯一值,这意味着当该编码器断电时,它失去了位置参考并从零开始。

淘宝上搜“带编码器的电机”大多是这种类型的编码器,增量式编码器有有光电编码器和霍尔编码器两种,两者的主要区别是:
(1)检测方式不同:霍尔编码器是电磁检测位置,光电编码器是光电检测位置;
(2)精度不同:霍尔编码器一般是精度不高,用作粗略的位置反馈,而光电编码器精度高,可以实现高精度的位置检测。
在这里插入图片描述
在这里插入图片描述
绝对式编码器的每一个位置对应一个确定的数字码,因此它的示值只与测量的起始和终止位置有关,而与测量的中间过程无关。这种类型的编码器比增量编码器更为先进。同时它们具有磁盘来代替插槽磁盘,因此它在每个位置都有独特的价值,因此即使在断电后也能记住它的位置。
在这里插入图片描述


一、旋转编码器

旋转编码器是一种光电式或电磁式旋转测量装置,它将被测的角位移直接转换成数字信号(高速脉冲信号)。我们通常用的是增量型编码器,不同型号的旋转编码器,其输出脉冲的相数也不同,有的旋转编码器输出A、B、Z三相脉冲,有的只有A、B相两相,最简单的只有A相。
(1)如单相联接,用于单方向计数,单方向测速。
(2)A.B两相联接,用于正反向计数、判断正反向和测速。
(3)A、B、Z三相联接,用于带参考位修正的位置测量。Z即圈数。

1. 光学编码器

光学旋转编码器是一种机械设备,在圆柱形外壳的内部有一个旋转轴,其结构与电机相同。一个圆形的平盘,上面有两组插槽。光学传感器安装在此光盘的两侧,发射器设置在一侧,接收器设置在一侧。

因此,当开槽光盘在传感器之间旋转时,它会切断光学传感器,并在接收器末端生成信号。

接收器还与微控制器连接以处理生成的信号,这样我们就可以知道旋转了多少轴。

我们还可以通过比较两个输出的信号极性来确定轴的旋转方向。因为两组插槽之间有一定的偏移,光学旋转编码器一般有两个输出“ A”和“ B”。

下图是了解每转400脉冲编码器如何产生脉冲的图像,它使每转总计1600过渡。这意味着它可以提供非常高的精度。
在这里插入图片描述

2. 光学旋转编码器与Arduino连接

白色(OUT A):PIN 3( arduino的中断器引脚)
绿色(OUT B):PIN 2( arduino的中断器引脚)
红色:5V
黑色:GND
在这里,我们必须注意,编码器的A、B相输出必须有一个连接到Aorduino的中断引脚。否则,arduino无法记录来自编码器的脉冲。
在这里插入图片描述

3. 程序

1.	volatile long temp, encoderCounter =0; //这个变量将根据编码器的旋转增加或减少  
2.	int encoderPinA = 2; //interrupt pin 2   
3.	int encoderPinB = 3; //interrrupt pin 3  
4.	  
5.	void setup() {  
6.	Serial.begin (115200);  
7.	pinMode (encoderPinA, INPUT);   
8.	pinMode (encoderPinB, INPUT);   
9.	  
10.	//设者中断函数  
11.	//将中断连接到Arduino的引脚encoderPinA和encoderPinB,  
12.	//当脉冲在CHANGE边缘时,调用函数doEncoderA()/doEncoderB()  
13.	attachInterrupt (digitalPinToInterrupt(encoderPinA), doEncoderA, CHANGE);  
14.	//编码器的A上升沿脉冲触发了中断。  
15.	attachInterrupt (digitalPinToInterrupt(encoderPinB), doEncoderB, CHANGE);  
16.	//编码器的B上升沿脉冲触发了中断。  
17.	  
18.	/*中断函数的使用 
19.	attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); 
20.	pin: 中断引脚号 
21.	ISR: 中断服务程序名 
22.	mode:中断模式 
23.	 
24.	中断模式(mode)有以下几种形式: 
25.	LOW: 当引脚为低电平时触发中断服务程序 
26.	CHANGE: 当引脚电平发生变化时触发中断服务程序 
27.	RISING: 当引脚电平由低电平变为高电平时触发中断服务程序 
28.	FALLING: 当引脚电平由高电平变为低电平时触发中断服务程序 
29.	*/  
30.	}  
31.	  
32.	void loop() {  
33.	  // Send the value of counter  
34.	if ( encoderCounter!= temp){  
35.	  Serial.println (encoderCounter);  
36.	  temp = encoderCounter;  
37.	}  
38.	}  
39.	  
40.	void doEncoderA(){  
41.	  
42.	  // 在A脉冲中寻找上升沿信号,若A编码器引脚为高电平,  
43.	  // 若B编码器引脚为低电平,encoderCounter计数+1,否则-1  
44.	  if (digitalRead(encoderPinA) == HIGH) {   
45.	    // check channel B to see which way encoder is turning  
46.	    if (digitalRead(encoderPinB) == LOW) {    
47.	      encoderCounter = encoderCounter + 1;         // CW  
48.	    }   
49.	    else {  
50.	      encoderCounter = encoderCounter - 1;         // CCW  
51.	    }  
52.	  }  
53.	  else   // 在A脉冲中寻找下降沿信号                                         
54.	  {   
55.	    // check channel B to see which way encoder is turning    
56.	    if (digitalRead(encoderPinB) == HIGH) {     
57.	      encoderCounter = encoderCounter + 1;          // CW  
58.	    }   
59.	    else {  
60.	      encoderCounter = encoderCounter - 1;          // CCW  
61.	    }  
62.	  }  
63.	  //Serial.println (encoder0Pos, DEC);            
64.	  //这段用于调试,记得删去  
65.	}  
66.	  
67.	void doEncoderB(){  
68.	  
69.	  // 在B脉冲中寻找上升沿信号  
70.	  if (digitalRead(encoderPinB) == HIGH) {     
71.	   // check channel A to see which way encoder is turning  
72.	    if (digitalRead(encoderPinA) == HIGH) {    
73.	      encoderCounter = encoderCounter + 1;         // CW  
74.	    }   
75.	    else {  
76.	      encoderCounter = encoderCounter - 1;         // CCW  
77.	    }  
78.	  }  
79.	  // Look for a high-to-low on channel B  
80.	  else {   
81.	    // check channel B to see which way encoder is turning    
82.	    if (digitalRead(encoderPinA) == LOW) {     
83.	      encoderCounter = encoderCounter + 1;          // CW  
84.	    }   
85.	    else {  
86.	      encoderCounter = encoderCounter - 1;          // CCW  
87.	    }  
88.	  }  
89.	} 

将代码上传到arduino后,打开串行监视器

并旋转编码器轴,如果沿顺时针方向旋转编码器,则值会增加;如果沿逆时针方向旋转,则值会减小。

进一步通过,下列函数可以获取电机转动角度。

double angle = encoderCounter*360/172032.0;//ppr=172032  

注:具体使用时,AB相编码器,只需要用一个中断引脚即可,例如:A编码器引脚触发中断后,B相引脚只要接发高低电平即可,无需再进入中断了。

A脉冲为上升沿,B脉冲为高电平,方向为负;
A脉冲为上升沿,B脉冲为低电平,方向为正。

二、Arduino Encoder.h库相关知识

原文:https://www.pjrc.com/teensy/td_libs_Encoder.html

1.硬件要求

编码器有2个信号,必须2个引脚,接法有3种选择:

(1)最佳性能:两个信号都连接到中断引脚。

(2)良好的性能:第一个信号连接到中断引脚,第二个信号连接到非中断引脚。

(3)低性能:两个信号都连接到非中断引脚。

常见Arduino开发板的中断引脚选择如下表所示,记住不要选择13号引脚,13号引脚是自带指示灯引脚。
在这里插入图片描述
低成本编码器仅将其引脚接地,此时编码器将激活片上上拉电阻。如果连接较长的电线,添加 1K 上拉电阻可能会提供更好的信号。

2. 基本用法

(1)Encoder myEnc(pin1, pin2);
使用 2 个引脚创建一个编码器对象。您可以创建多个Encoder对象,每个对象使用自己的 2 个引脚。第一个引脚应该能够中断。如果两个引脚都具有中断功能,则两者都将用于获得最佳性能。如果两个引脚都没有中断,编码器也将在低性能轮询模式下工作。

(2)myEnc.read();
返回累积位置。这个数字可以是正数或负数。

(3)myEnc.write(newPosition);
将累积位置设置为新数字。

3. 了解正交编码信号

编码器可以通过检测孔或标记移动超过2个位置来感知任一方向的移动。下图中的蓝色圆盘顺时针旋转时,首先由引脚 1 检测到变化,然后由引脚 2 检测到变化。当它逆时针旋转时,引脚 2 首先检测到变化。这种方案被称为“正交编码”,因为 2 个引脚检测到的波形相位相差 90 度。

编码器库监视 2 个引脚并更新位置相对变化的计数。库在每次更改时更新其计数,这通常称为 4X 计数,因为编码器硬件中的每个物理标记或孔都有 4 个计数可用。

顺时针转动
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
逆时针转动
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. 示例程序

该示例程序可从以下菜单获得:文件 > 示例 > Encoder> TwoKnobs。

1.	#include <Encoder.h>  
2.	  
3.	// 将这些引脚号更改为连接到编码器的引脚  
4.	// 最佳性能:两个引脚都具有中断能力  
5.	// 良好性能:只有第一个引脚具有中断能力  
6.	// 低性能:两个引脚都没有中断能力  
7.	  
8.	Encoder knobLeft(5, 6);  
9.	Encoder knobRight(7, 8);  
10.	  
11.	// 避免使用带有 LED 的引脚,一般为13号引脚  
12.	  
13.	void setup() {  
14.	  Serial.begin(9600);  
15.	  Serial.println("TwoKnobs Encoder Test:");  
16.	}  
17.	  
18.	long positionLeft  = -999;  
19.	long positionRight = -999;  
20.	  
21.	void loop() {  
22.	  long newLeft, newRight;  
23.	  newLeft = knobLeft.read();  
24.	  newRight = knobRight.read();  
25.	  if (newLeft != positionLeft || newRight != positionRight) {  
26.	    Serial.print("Left = ");  
27.	    Serial.print(newLeft);  
28.	    Serial.print(", Right = ");  
29.	    Serial.print(newRight);  
30.	    Serial.println();  
31.	    positionLeft = newLeft;  
32.	    positionRight = newRight;  
33.	  }  
34.	  // 如果从串行监视器发送一个字符,将两者knobLeft、knobRight都重置为零  
35.	  if (Serial.available()) {  
36.	    Serial.read();  
37.	    Serial.println("Reset both knobs to zero");  
38.	    knobLeft.write(0);  
39.	    knobRight.write(0);  
40.	  }  
41.	} 

5. 中断延迟要求

编码器需要对信号变化的低延迟响应。使用带中断的第一个或两个引脚效果很好。但是,如果中断被您的代码或其他库长时间禁用,编码器可能会错过更改。结果是计数不正确。接下来的 1、2 或 3 次更改可能会产生错误的结果。

SoftwareSerial 和 NewSoftSerial 很可能会导致问题。

6. 优化中断选项

在Arduino种,Encoder 使用以汇编语言编写的非常优化的中断例程。通常,Encoder 使用 attachInterrupt (),它允许将函数动态附加到每个中断。动态函数调用会增加一些开销overhead。要消除此额外开销,您可以使用此选项。

1.	// 此选项可以设置使Encoder使用更优化的代码,  
2.	// 必须放在Encoder.h前定义。 
3.	#define ENCODER_OPTIMIZE_INTERRUPTS  
4.	#include <Encoder.h>  

注:overhead是系统开销,本来直接走路不用花钱,可是浪费时间。有时候,路远了,花点钱坐车还是必要的。在计算机里面,系统开销可能会暂用一些资源,但有时候能提高效率。

编码器将直接定义中断的最小开销。但是如果任何其他代码或您使用的任何库需要 attachInterrupt()函数,将会发生冲突。

7. 最大速度和 CPU 使用率

SpeedTest 示例,在File > Examples > Encoder > SpeedTest中,提供了一种简单的方法来验证 Encoder 消耗了多少 CPU 时间。测量了以下 SpeedTest 结果:
在这里插入图片描述

8. 低性能轮询模式

如果两个引脚都没有中断能力,编码器仍然可以工作。仅在每次使用 read () 函数期间检查信号。只要你的程序继续足够快地调用read (),你就会得到准确的结果。用于仅由人类手指转动的刻度盘或旋钮的低分辨率旋转编码器是低性能轮询模式的良好候选者。连接到电机的高分辨率编码器通常需要中断!

对于 Arduino Uno、Duemilanove 或 Mega,Serial.print() 可能会造成麻烦。Arduino 1.0 提供传输缓冲,比 Arduino 0023 和更早版本的效果要好得多。无论哪种方式,都应使用高速波特率,并且最大限度地减少传输的数据量会有所帮助。


总结

本文介绍了编码器相关的知识,以及ARDUINO Encoder.h库的使用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

玩转电机驱动——电机编码器 的相关文章

  • 将Mircrosoft Store下载的Ubuntu安装到指定位置方法,同时解决“你需要来自System的权限才能对此文件进行更改”问题

    一 概述 最近使用到WIndows的WSL功能 xff0c 需要安装ubuntu这个子系统进行仿真环境搭建 xff0c 但是又不愿意使用虚拟机 xff0c 不太方便 在安装过程中发现本身就岌岌可危的C盘经常突然爆满 xff0c 经过检查发现
  • 本地安装WSL的发行版后,导出到另一台计算机安装的办法

    一 步骤 1 首先你要在你的计算机上安装成功了WSL子系统 xff0c 然后才能导出对应版本的tar文件 xff0c 复制到另一台计算机中进行安装 2 例如我的电脑安装了Ubuntu 20 04 5这个版本 xff0c 如图 xff1a 3
  • Pixhawk基础—认识Pixhawk

    Pixhawk简介 pixhawk是由3DR联合APM小组与PX4小组于2014年推出的飞控PX4的升级版 xff0c 它同时拥有PX4和APM两套固件和相应的地面站软件 该飞控是目前全世界飞控产品中硬件规格最高的产品 Pixhawk基础
  • 关于 adb命令编辑器中无法找到设备:error: device not found 问题的解决办法

    adb命令编辑器中无法找到设备 xff1a error device not found 问题原因解决办法问题来了 解决办法 今天接手一个施乐的设备 xff0c 想要连接到电脑上进行调试 xff0c 调试程序已写好 xff0c 准备用adb
  • LinearLayout中layout_weight属性占比计算方法

    假设一个布局中有三个子布局 xff0c 三个子布局的layout weight属性占比我2 3 4 此时有两种情况 xff1a 1 wrap content比较简单 直接就按比例得了 2 fill content match content
  • 利用POI实现json数据的Excel导出

    首先需要POI jar包 xff0c 相关jar包已经分享到个人网盘 xff0c 有需要可以进行下载 链接 xff1a https pan baidu com s 1N9Cc8UgHuHIMZbWfurmm3w 提取码 xff1a cc6p
  • 基于springboot的简单restful服务demo

    这篇文章主要是本人学习springboot时一个简单的测试demo xff0c 仅供参考 springboot的介绍 xff1a 由Pivotal团队提供的全新框架 xff0c 设计的目的是简化spring新应用搭建的过程 xff0c 使用
  • leetcode刷题 Day23(LRU缓存机制)

    题目 xff1a 思路 xff1a java用LinkHashMap解决 xff0c 在LRUCache中获取缓存容量 xff0c 在put方法中 xff0c 难点在于怎么进行判断最新数据和最不常用的数据 xff0c 这里采取这种办法 xf
  • 野火&洋桃STM32开发版学习指导完整版

    该文章是我历时一个月整理总结而成 xff0c 专门针对想要通过野火 amp 洋桃STM32开发板入门stm32的读者 由于csdn编辑限制 xff0c 该学习指导只包含文字信息 如需查看含图片的完整版可进入我的博客下载页 完整版内容详实 x
  • sumo学习——sumo的路网介绍

    2 sumo路网 这里的记录的内容 xff0c 并不以如何绘制或者如何建立一个路网体系为主 xff0c 而是较为详细的介绍 xff0c 在sumo中是如何定义路网格式的 这里所有的内容都是来自于sumo的软件说明翻译 xff0c 其中部分夹
  • webpack之devtool

    关于Devtool 该选项控制是否以及如何生成源映射 官网上给出的可选值有 xff1a 其中一些值适合开发 xff0c 一些用于生产 对于开发 xff0c 您通常需要快速的Source Maps xff0c 以bundle的大小为代价 xf
  • 汽车UDS诊断详解及Vector相关工具链使用说明——总述

    1 什么是诊断 车辆在运行过程中 xff0c 不可避免地会发生一些故障 xff0c 为了确保行车安全 xff0c 我们要求车上的ECU能够实时监测部件的运行状态 xff0c 一旦发现异常情况 xff0c 能通过点亮报警灯等方式提示驾驶员 但
  • 汽车UDS诊断详解及Vector相关工具链使用说明——2.2.7 动态定义DID(0x2C)

    1 概述 动态定义DID服务允许诊断仪在ECU内部动态定义一个临时的DID 可以通过该DID读取一段内存的数据 也可以通过改DID一次性读取多个原有DID的数据 动态定义DID既可以是支持22服务的DID 也可以是支持2A服务的周期性读取
  • 关于RTOS中信号量、互斥量、邮箱、消息队列的一些理解

    1 信号量 信号量有两种 xff1a 计数性信号量和二值信号量 xff0c 计数性信号量可以被获取多次 xff0c 二值信号量只有0和1两种状态 xff0c 只能被获取一次 信号量可以用来对资源进行保护 xff0c 防止多个任务同时访问某个
  • 英飞凌 AURIX 系列单片机的HSM详解(1)——何为HSM

    本系列的其它几篇文章 xff1a 英飞凌 AURIX 系列单片机的HSM详解 xff08 2 xff09 与HSM相关的UCB和寄存器 英飞凌 AURIX 系列单片机的HSM详解 xff08 3 xff09 开发方法 英飞凌 AURIX 系
  • DoIP(一)——基础概念

    1 DoIP概述 DoIP xff08 Diagnostic communication over Internet Protocol xff09 是基于车载以太网的诊断 xff0c 在OSI 七层模型中属于传输层 xff0c 其传输的诊断
  • DoIP(二)——报文类型

    我们上一篇文章提到 xff0c DoIP报头中有两字节的数据类型 xff08 Payload Type xff09 xff0c 代表DoIP报文类型 xff0c 本文就来详细介绍一下每一种报文类型 标准中对报文类型的定义如下 xff1a 数
  • AUTOSAR —— CAN网络管理(CanNm)

    1 网络状态 AUTOSAR网络管理节点内部有两个状态 xff0c 一个是Requested 被请求状态 xff0c 另一个是Released 被释放状态 xff0c 当节点的应用层需要使用总线进行通讯的时候 xff0c 会调用接口使得节点
  • S32K1XX系列单片机 ——(1)开发环境搭建

    本文介绍一下NXP S32系列单片机开发环境的搭建方法 xff0c 分两种 xff1a S32DS和Keil 1 S32DS S32DS是NXP开发的一款IDE xff0c 编译器是GCC xff0c 支持Lauterbach P amp
  • AUTOSAR —— S32K144 的 Fls 和 Fee 模块配置

    本文来简要介绍一下如何在EB中配置AUTOSAR Fls和Fee模块 Fls模块是Flash的驱动 xff0c 执行具体的Flash擦写读取等操作 Fee模块的全称是FlashEEPROMEmulation xff0c 即Flash模拟EE

随机推荐

  • NXP MCU CAN波特率(位时间)配置详解

    1 概述 本文将会详细讲解如何设置NXP MCU的CAN波特率 位时间 采样点等属性 波特率即CAN总线传输频率 xff0c 位时间是波特率的倒数 xff0c 例如波特率是500K xff0c 那么位时间 61 1 500000 61 0
  • 51单片机之蜂鸣器

    include 34 reg52 h 34 include 34 intrins h 34 typedef unsigned int ui typedef unsigned char uc define led P2 34 34 sbit
  • vnc配置

    centos版本在7 0以上的 一 安装 yum grouplist 查看是否已经安装过 yum groupinstall GNOME Desktop 如没有安装则运行命令安装 以root用户运行以下命令来安装vncserver yum i
  • 【WebAPI 验证】给 webapi加上token 验证(包括上传文件方法)

    需要给网站开发对接EMI 接口 xff0c 因此想通过Webapi 进行传递参数 xff0c 但是由于该方法不太安全 xff0c 因此不选用 xff0c 但是记录下该方法的使用 1 xff0c 创建WEBAPI 项目 xff0c 打开nug
  • 委托和事件

    一 委托与事件的区别 委托是一种用于存储方法引用的引用类型 xff0c 它定义了一种类型安全的调用回调方法的方式 事件使用委托来封装触发时将要调用的方法 xff0c 事件是一种函数成员 委托是指向一个方法的指针 xff0c 而且我们采取和调
  • OS文件/目录方法----获取当前py文件的路径

    获取当前py文件的路径 xff1a 1 直接获取 只返回当前文件的工作目录 aa 61 os getcwd print 39 当前文件的路径 39 aa 输出 当前文件的路径 G PycharmProjects SeleniumUnitte
  • vscode如何配置git-2022.10

    文章目录 1 vscode填写git配置2 打开git命令行界面 windows本地已经安装git 并配置成功 1 vscode填写git配置 在搜索框中搜索 terminal integrated automation profile w
  • LCD12864串口高级操作

    上面是LCD12864的串口通信时序图 其中RW是方向位 xff0c RS是命令数据选择位 xff0c SID为数据线 xff0c SCLK为时钟线 xff0c CS为使能端 其中CS为1时使能时序操作 xff0c 由图可以看出 xff0c
  • Ubuntu server 18.04 服务器配置

    文章目录 前言一 下载镜像 制作系统u盘启动盘二 安装设置三 创建用户 给普通用户root权限四 GPU驱动安装五 miniconda安装 操作虚拟环境常用指令六 pytracking环境配置总结 前言 例如 xff1a 原有centos服
  • OpenCV数据载入、显示与保存

    一 图像存储器 OpenCV提供了一个Mat类用于存储矩阵数据 Mat类用来保存矩阵类型的数据信息 xff0c 包括向量 矩阵 灰度或彩色图像等数据 Mat类分为矩阵头和指向存储数据的矩阵指针的两部分 矩阵头中包含矩阵的尺寸 存储方法 地址
  • Colab运行YOLOv5训练自己的数据集

    最近想使用YOLOv5模型训练自己的数据集 xff0c 但是没有GPU 所以白嫖一下Google的Colab 第一 xff1a 制作自己的数据集 这里给出一篇自己看过的博客写和博主自制的视频 xff0c 我觉得讲的挺好 xff0c 数据集方
  • HC05主从蓝牙通信的配置步骤

    HC05主从一体化蓝牙模块 xff0c 可以配置为一个主蓝牙和一个从蓝牙 xff0c 两个蓝牙之间实现互相通信 拿到蓝牙之后只需接VCC GND RX TX 首先让蓝牙进入AT模式 先按住蓝牙上的微动开关 xff0c 然后给蓝牙上电 蓝牙上
  • 游记_秦皇岛-北戴河两日游

    写在开篇 在北京上学 xff0c 经常收到各种关于秦皇岛 北戴河的安利 xff0c 一直想去但是都没有实现 xff0c 前段时间终于和男朋友决定用一个周末的时间 xff08 周五晚上从北京出发 xff0c 周六早上到秦皇岛 xff0c 周日
  • STM32学习之路(首篇)

    STM32的学习之路 xff0c 到目前为止学习32也有一段时间了 xff0c 学习32的过程和学51单片机的道路差不多 首先要拥有自己的32开发板 xff0c 我买的是正点原子的开发板 xff0c 商家提供了很多学习资料 xff0c 一开
  • STM32学习之路(五---IIC)

    IIC是由数据线SDA和时钟SCL构成的串行总线 xff0c 可以发送和接收数据 在CPU与被控IC之间 xff0c IC与IC之间进行双向传送 IIC总线在传送数据过程中共有三种类型的信号 xff0c 分别是 xff1a 开始信号 xff
  • PWM调速的原理

    PWM调速实质上是调节占空比 xff0c 我们都是根据占空比的大小来衡量速度 xff0c 但是为什么我们调节占空比就可以实现对速度的调节呢 xff1f 这就需要我们了解调速的本质 xff0c 我们用PWM调节速度问什么能够实现 xff1f
  • keil中显示expected expression

    在keil中出现error expected expression的错误 xff0c 网上很多人都是在 Misc Cortrols这里改一下写c99就好了 xff0c 但是我改过之后还是没好 xff0c 依然报警告 xff0c 后来我自己的
  • Linux学习(C语言学习之Gcc)

    言之者无罪 xff0c 闻之者足以戒 诗序 Linux的学习需要对C语言有一个透彻性的了解 xff0c 需要有非常好的C语言基础 xff0c Gcc是Linux中的C文件的一个编译器 xff08 当然也不只局限于C文件 xff09 Gcc最
  • 如何在 python中查询某个函数的使用方法

    在Python 中查询某个函数的使用 方法时由两种途径 xff1a 1 利用help来查询 xff0c 比如用help来查询print内置函数的使用 xff0c 直接打开Shell输入 help print 就可以了 2 利用Python官
  • 玩转电机驱动——电机编码器

    玩转电机驱动 电机编码器 文章目录 玩转电机驱动 电机编码器前言一 旋转编码器1 光学编码器2 光学旋转编码器与Arduino连接3 程序 二 Arduino Encoder h库相关知识1 硬件要求2 基本用法3 了解正交编码信号4 示例