比赛中遇到的问题和记录的杂记

本文详细介绍了51单片机的准双向口、开漏输出、推挽输出结构及其特点,并对比了bit与sbit的区别。此外,还深入探讨了编码器的工作原理、类型以及增量式和正交编码器的应用场景和技术参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

准双向口、开漏输出、推挽输出结构介绍

1. 准双向口结构(一般用于51单片机)

  准双向口,也就是说不是真正的双向口,真正意义上的双向口是需要通过设置专门的“输入输出方向寄存器”将IO口设为输入模式或者输出模式,才能实现对应的输入输出功能。而准双向口则不需要设置,作为输出时直接向口线寄存器写;作为输入时则需要先向IO口写1再去读。准双向口的内部电路结构具体解释如下:
当寄存器为1时,左边的场效应管断开,右边的场效应管导通,于是输出被电源上拉为1,输出高电平;当寄存器为0时,左边的管子导通,右边的管子截止,输出管脚相当于直接通过左边的管子接地,输出低电平。在读取数据时,如果寄存器的值为1,当管脚接低电平时,采集到时输入数据为1,反之为0,这种情况下是可以正确的读取数据的,但是如果寄存器的值为0 ,则左边的场效应管导通,输出相当于直接与地线相连,此时无论外部输入为高电平还是低电平,采集到的输入数据都是0,这样就不能正确的读取数据了。所以对于准双向口,作为输入口使用时,必须先向该IO口写1,再读取,这就是准双向口的特点。

2.开漏输出结构

  开漏(open drain),这里的“漏”指的是场效应管的漏极(drain),对应于三极管的集电极(collector),开漏就是指场效应管的漏极保持开路,直接接出作为输出口。
  当寄存器为0时,管子导通,输出直接通过管子接地,输出低电平;当寄存器为1时,管子截止,输出脚相当于悬空,为高阻态,因此开漏输出接口不能够正确的输出高低电平。对于开漏输出结构,输出必须接上拉电阻,才能够正常使用。外接了上拉电阻后,当寄存器为1时,输出被电源上拉为高电平,寄存器为0时,输出口通过管子直接接地,为低电平,这样就可以正确的读取外部数据了。
很多芯片都提供开漏输出结构,这是因为开漏输出结构有很多优点:

a. 充分利用外部电路的驱动能力,减小芯片内部的驱动,从而降低芯片的功耗,提高芯片工作稳定性
b. 可以通过改变上拉电源的电压,改变信号的传输电平,比如某芯片的输出为3.3V电平,其输出口的上拉电源可以为5V,这样就很方便的实现了电平转换。

  当然,开漏输出也存在明显的缺点:在输出脉冲信号时,在脉冲的上升沿,电源通过上拉无源电阻对负载充电,其速度较慢,导致上升时间变长,因而会导致脉冲上升沿变坏,上拉电阻阻值越大,充电时间就越长,因此其速度越慢,而阻值较小时,其功耗又会变大,因此在设计时要兼顾速度和功耗。而对于下降沿,电源通过芯片内部的场效应管放电,其速度较快,所以上拉电阻对脉冲的下降沿影响不大,某些情况下可以考虑用下降沿输出。

3.推挽输出

  推挽输出也是一种很常见的输出结构,其内部电路具体介绍如下:

  与准双向口类似,只是右边的场效应管为强上拉作用,因而输出电流较大,适用于需要大电流驱动的场合。在使用推挽结构时,要注意不要将两个IO口短接,因为如果一个IO口为高电平而另外一个为低电平时,会有很大的电流流入芯片,可能烧坏芯片。
  总之呢,在使用一些不熟悉的芯片时,一定要注意其IO口的结构,根据IO口结构设计合适的电路,以免出现一些意想不到的错误。

bit 和Sbit区别介绍(51单片机)

bit和sbit都是C51扩展的变量类型。

bit

  1. bit编译时分配空间,sfr(特殊功能寄存器)的bit。SFR是系统指定的内存地址。
  2. bit 动态分配的,有编译器来指定内存地址。
  3. bit 可以在外部或内部定义。
  4. bit是编译器在的可寻址区分配的一个位变量,是不定的,不是绝对地址目标。

  bit和“int char”之类的差不多,只不过"char"=8位," bit=1位而已",这两个都是变量,在编译过程中分配地址。除非具体指定,否则这个地址是随机的,是整个可寻址空间。bit只有0和1两种值,意义有点像Windows下VC中的BOOL。

sbit

  1. sbit 只能在外部定义全局变量。
  2. sbit 要在最外面定义,就是说必须定义成外部变量.sbit定义的是SFR(特殊功能寄存器)的
  3. sbit更像是类型定义,不像是变量定义。
  4. sbit位寄存器是可位寻址的绝对地址目标,定义后编译器是不会改变位置的。
      所有可位寻址的位都可由sbit指定,这包括可位寻址区和SFR中的位。sbit是对应可位寻址空间的一个位,可位寻址区:20H~2FH。一旦用了"sbi xxx = REGE^6"这样的定义,这个sbit量就确定地址了。sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。
    典型应用是:
      sbit P0_0=P0^0;//即定义P0_0为P0口的第1位,以便进行位操作。

keil编译时遇到的错误和解决办法

unterminated conditional directive错误

  可能是没写#endif,在有#endif的情况下还报错,是头文件互相包含的问题,解决头文件互相包含的需求比如A要使用B,B又使用了A,可以在A.h中声明B,然后在A.cpp中包含B的头文件B.h,不过要注意代码逻辑不要循环递归调用了…

解决代码卡死的问题:

  1. 在可能会卡死的地方设置断点,进行简单单步调试来看是否会显示从而判断它到底卡在哪一步了。
  2. 在卡的地方用延时函数来进行,预防时间不够mcu反应不过来。

解决编码器读不了脉冲的问题:

  一定一定要看你自己的编码器是正交的还是方向的,像逐飞的编码器一般他就会推荐你用正交编码器,要问为什么的话是因为他的函数库就是用的正交编码器写的,最简单的地方就是你用encount读不了数的时候,一定要试试count也许就好了
  当然,我事后还是把正交编码器,增量式编码器和带方向的编码器仔细看了看,最终我的速度环很nice的成功了,这里就粘贴下我从网上找的编码器的种类及其相关资料吧。

编码器介绍
  1. 什么是编码器?
      简而言之,编码器是一种提供反馈的传感设备。编码器将运动转换为电信号,该信号可由运动控制系统中的某种类型的控制装置读取,例如计数器或PLC。 编码器发送反馈信号,可用于确定位置,计数,速度或方向。控制设备可以使用该信息来发送特定功能的命令
  2. 编码器如何工作?
      编码器使用不同类型的技术来创建信号,包括:机械,磁性,电阻和光学 - 光学是最常见的。在光学传感中,编码器基于光的中断提供反馈。如下图描绘了使用光学技术的增量式旋转编码器的基本结构。 从LED发出的光束穿过代码盘,代码盘上有不透明的线条(很像自行车轮上的辐条)。当编码器轴旋转时,来自LED的光束被光盘上的不透明线条中断,然后被光电探测器组件拾取。这产生一个脉冲信号:light = on; no light= off。信号被发送到计数器或控制器,然后发送信号以产生所需的功能。
  3. 绝对式编码器和增量式编码器
      编码器可以产生增量或绝对信号。增量信号不表示特定位置,只表示位置已更改。另一方面,绝对编码器对每个位置使用不同的“字”,这意味着绝对编码器既提供位置已改变的指示,也提供编码器绝对位置的指示。
  4. 关于编码器的AB相输出
      每个编码器都会有AB两相脉冲正交输出(即相位差90度),在输出方式上分为电压输出和集电极开路输出两种输出方式。其中集电极开路输出在采集脉冲是需要加一个上拉电阻。同时有的编码器还有一个Z相信号,即编码器机械零位信号,每当编码器转到机械零位,Z相输出一个脉冲,可用于矫正脉冲长时间的积分误差。AB相正交输出还有一个重要的作用就是区分轮子的正反转,通过正交解码可以判断出电机在正转还是反转。
增量式编码器介绍

  增量式编码器(又名双通道增量式编码器),用于将线性移位转换为脉冲信号。通过监控脉冲的数目和两个信号的相对相位,用户可以跟踪旋转位置、旋转方向和速度。另外,第三个通道称为索引信号,可用于对位置计数器进行复位,从而确定绝对位置。

工作原理:

  增量型编码器通过内部两个光敏接受管将编码器的转向转化为A相和B相脉冲的时序和相位关系。编码器每转还输出一个Z相脉冲以代表零位参考位。A、B 两点对应两个光敏接受管,A、B 两点间距为 S2,编码器的光栅间距分别为S0 和S1。

正交编码器介绍
编码器正交编码工作原理

  当编码器以某个速度匀速转动时,输出波形中的S0:S1:S2 比值与实际编码器的S0:S1:S2相同。如果编码器做变速运动,可以把它看成为多个运动周期的组合,那么每个运动周期输出波形的S0:S1:S2比值与实际编码器的S0:S1:S2仍相同,通过输出波形可知每个运动周期的时序。
  我们把当前的A,B 输出值保存下来,与下一个A,B 输出值做比较,就可以得出编码器的运动方向。用编码器运动角位移除以所消耗的时间,就得到编码器运动的角速度。
如果S0=S1,且S2=S0/2,1/4个运动周期就可以得到运动方向和位移角度,否则要1个运动周期才可以得到运动方向和位移角度。
  综上可知,可以通过判断A相和B相的相位关系来判断编码器的正反转,通过Z相脉冲获得零位参考位。

关于增量型编码器的一些技术参数如下:
  1. 分辨率:编码器每转提供的通或暗的刻线数叫分辨率,也称解析分度或直接称多少线。一般每转分度5~10000线。
    信号输出:信号输出形式有正弦波(电流或电压)、方波(TTL/HTL)等多种。其中TTL方波的形式为长线差分信号(对称A+、A-;B+、B-;Z+、Z-)。
  2. 信号连接:编码器的脉冲信号一般连接计数器、PLC、计算机。形式有单相连接(用于单方向测速、计数);AB两相连接(用于双向测速、计数及判断方向);ABZ三相连接(用于带参考位修正的位置测量);差分连接(用于远距离传输)。
      增量型编码器在角度测量和角速度测量中较绝对型编码器具有廉价和简易的优点。但存在抗干扰能力较差、有零点累计误差、接受设备停机需断电记忆,开机需找参考位等问题。一般应用在测速、测转动方向、测移动角度、测相对距离等方面。A和B信号输出相位差90度的方波信号,根据A B信号超前和滞后来判断方向。

直立车机械结构方面

关于车的前瞻

  需要一定的前瞻保证提前检测到道路前方的信息,在入弯时需要减速,出弯时需要加速,而加减速需要一定的距离,所以前瞻理论上应该至少等于传感器采集数据周期内车子前进的距离+加速或减速需要的距离。
  目前看来前瞻的作用更多体现在提前转弯,在速度快时,提前转弯显得尤为重要。而且前瞻越大以后过小s弯时车的左右摆动幅度会越小

如何放置电感

  使得两个传感器采集到的数据差,经过某种函数变换后,与实际偏差线性相关,主电感水平横向放置,这样能保证传感器不受横向的导线影响,那么十字路就与普通的弯道就没什么区别了。辅电感水平向前放置,这样在没有弯道的时候检测不到信号,而一旦检测到弯道就有明显的信号出现,而且可以根据两边信号的强弱来判断是左直角还是右直角还是十字等等,如果两组电感不够可以考虑再加一组,暂目前看来两组已经足够。
  函数变换过程如下:采集实际数据,包括偏离中心线的距离x,和对应的两个传感器的示数差e;将数据输入matlab,利用cftool工具进行拟合,发现e=a*sin(bx)这个函数的拟合效果非常不错;求这个函数的反函数,就得到了x=1/b * arcsin(e/a);现在根据两个传感器的示数差e就能得出传感器偏离中线的距离x了。
显然我们的控制算法需要的是一个线性的量,如果不进行这种变换,直接用e进行控制,那么控制起来会经常出现过头的现象,而用x进行控制则要平滑得多。而且这样经过变换后还有一个好处,如果环境改变,我们就只需要修改变换函数,使得得出正确的偏移量,而后面的控制算法的参数可以不用改,这样就把数据的采集与处理和控制算法分离开来,调试起来更容易。参看官方给的参考方案,主电感可以采用两组,采集两个方向的磁场强度,从而推测出电感与中心线的夹角等等其它信息。这个还有待深入研究。

智能车速度控制部分

  采用裸增量式PID控制方法,目前只用了P,且加了限幅,结果是速度不稳定,在目标速度上下来回波动,周期比较长。
  原因分析:直立车与四轮车相比,它的速度控制和直立控制是直接耦合在一起的,因此速度控制不能剖开直立控制来做。初步分析现在的算法,问题出在,在速度带到目标速度前,速度控制量就已经饱和,而只有当速度超过目标速度后,速度控制量才会下降,而刚开始下降时,车依然是加速的,这势必会大大加长速度调节周期。在速度控制上,我们之前所做的理论分析远远不够就开始编码看现象,这是浮躁,得改。后来确实遇到了很多问题,事实证明,无论做什么,一步一步扎扎实实走是很重要的。

信号源问题

  用逐飞的信号源一定要在线接好后观察是不是绿灯。如果是红灯那么你的电感会采集不到电压值,会让你很头疼的。

智能车转向控制部分

  终于来到转向环的调试了,先多看两篇文章,大概知道电感采集的值得大小在哪里合适,可惜你会发现他并没有大小得要求,只要左右两边得电感值差不多大就行,后面在进行差值运算的时候可以方便调成参数。
转向环我出现的问题就是,他的电感其实我都不知道到底取多少,按照学长说的只要两边差不多一样就可以,后面可以进行差值计算偏差然后转向,现在的问题是貌似直立车在赛道中间没办法进行运动,反而在赛道边缘可以很好的运动。
我代码的电感值大概就两百多就行,太大了反应有点太快和敏感,如果确实电感值最小也有一两千,就直接在接收电感原始值那里减少就行。
  当然了,如果你愿意可以先用例程看下电感的采集值到底有多少,然后在去看下源程序,记住,采集的时候要用滤波的那个函数,10次滤波,这样子采集的值才差不多稳定。然后在源程序中显示的时候一定要看下显示函数在显示时所要的时间。我碰到的问题就是把显示放到中断函数的后面去了,这样子显示就是断断续续的,不是很明显。
 &emsp现在我碰到的问题还是电感的转向环的问题,首先我试着改变电感的采集函数,但是发现他改变后变得左右摇晃剧烈,然而我不改得话,他在跑到得边缘可以跑的很稳,我不是很懂,就先测他在跑到得边缘得时候那个电感靠的近,我再给根据那个靠的近的电感,把他的采集值剪掉一点。转向环我现在试着在我原有的代码上读ad电感值时进行滤波函数,这样子的唯一问题就是左右摇摆太大,现在这个问题还在解决。
最新问题(驱动板的信号输出信号线要接对.)

  1. 转向环可想而知也是主要求快(速度越高越是要求转向环反应越快,其次求稳,因此也和直立环一样建议使用PD控制。
  2. 如之前所说,D的主流作用是抑制震荡,当然这有一个前提,就是D的符号给对了,大家不如大胆的想想若是D的符号给反了会怎么样?其实就是会加剧P引起的震荡,起了一个反作用。这也正是为什么很多人在调转向环时单给一个P能凑合着跑,但加入了D之后就和酒驾了一样,直道都会走的歪七扭八的大多就是这个原因了。前期的时候我们就因为这个错误被卡了好几天,直到一个偶然的机会在和一位曾经研究过直立车的研究生学长聊天时才恍然醒悟,但同时也想到了这种反向D的一个“非主流”作用,就是在偏差过大时不妨就给一个反向的D,以此能让小车更快的回到中线,当然这是比较进阶的用法,效果前期也不太明显,大家不妨在后期有空可以试试。
  3. 关于转向环的PD参数动态诊定方法自古以来便是各个学校传承的“祖传代码”中最核心机密部分,博主手上的方案也不例外,但我们没有祖传代码(当然从我这开始就有了HHH,但不懂能传几代…),而是参考自别的学院一位无缘得见的研究生学长的毕设方案,在这里也不太方便直接把程序贴出,但每每看到那段代码,还是十分敬佩那位学长的实践能力和天马行空的思维。以此调出的转向环在我眼里真心担得起“完美”两个字。在这里也能小小的泄露一点“天机”:将P和D与速度和偏差相关联。有心的朋友不妨照着这个思路大胆的去试试。

  我终于知道转向环的pid也要调试,现在就从p开始0.45刚好差不多,也有左右抖动现象,现在调D,之前是0.45还是抖动,加大D的调试试试.

智能车整体调试记录

  一般来说,直立车的控制可分为直立环、转向环、和速度环,首先要写的肯定是直立环,直立环根据姿态传感器的数据,进行直立环PID控制,输出直立环PWM,使车保持直立状态,直立车直立是基础,当然直立环也不是越硬越好,这个看个人的需要吧,关于直立的角度,经过我的多次实验,PWM值一定不要太低,过低后会带来很多不必要的麻烦(比如上坡道时车不稳,贴地,电感值异常等),一般直立环调节到原地站立在机械零点,给予下压或者上挑干扰后可以在短距离的前后移动后恢复稳定状态,这时候就可以加转向环了,之前刚开始调完直立环后,我直接加的速度环,发现虽然给两个电机相同的PWM值,但是我的车就是不跑直线,后来经过数据采集后发现,两者的转速也没有什么规律可言,通过差值PWM来使其走直线也是不可行的,索性就直接先加转向环,通过转向环的作用来纠正其偏离中心赛道的偏差,发现效果很好,调完转向环后再调速度环(同时调也行),转向环和速度环都可以看做是对直立环的干扰,推荐使用串级PID的方法。

现在碰到的问题是转向环在速度快的时候反应不过来。

为了对付转向环,我用控制变量法:

  1. 首先检查是不是电感的问题:(p:0.65,D:0.5)。这个时候在一些转弯和某些知道上会自动转弯,这个时候先检测两边电感值是否一样。现在我调地电感值左右两边在1798左右,中间地两千多,这样子试下看是否是电感问题结果似乎还是不行,那么就看下是不是中间电感地问题,结果好像跟电感并没有关系。
  2. 那就看是不是PD地值得问题,首先先用原来的值来检测下看是否有问题,(P:0.15,D:0.1)

  这个暂且搁置一下;最近我把车模得方案给改了,那么先让我实现上面得所有并把直立环调硬再继续把。
  因为是双车传球,所以我会用到逐飞得超声波传感器,最近我得想用其超声波测距,一个前面一个后面,再装两个蓝牙模块,用PC机做上位机并给出一定指令。
  现在我出现了新的问题就是驱动板似乎好像不能用来,我用例程来对电机进行驱动但似乎并不能驱动电机:
  对此我进行排除法,现在的排除问题有杜邦线的信号传输问题,在主板上我给他信号线,在驱动板上也可以接受到信号。这就意味着驱动板是有信号的;接下来我试着看下是否是驱动板和主板没有共地的缘故或者说地的某个地方短接了。
现在发现,主板的驱动信号A12和C9那部分似乎和芯片没有连接上。我将根据原理图的连接关系查找问题所在。
  马上,我发现连接电机接口的上拉电阻并没有和接口接在一起,这也就意味着它虚焊了,为了验证猜想,我拿一块新的板子来进行对比研究。然而我发现是我错了在新的板子上面他们也是一样的现象很明显主板上面并没有虚焊和短接的错误。
 &msp;那么我就按照同样的道理检查驱动板上是否也有同样的原因。我根据原理图检查信号线的走向和芯片的信号问题发现也没有问题,然后奇迹出现了,居然又可以了。
我发现,可以用虚拟示波器来调直立环这样子可以更加直观的看到。
链接//这是相关资料链接
  我把直立车的驱动板拿去给逐飞的检修,发现了原来所谓的升压问题,可能是驱动板的某个地方沾染灰尘而短路或者有些信号问题,不仅如此还要仔细检查是否有虚焊的问题,不如哪个模块出了问题,先全部都加点焊锡先,排除虚焊,再对这原理图看到底是什么问题。
  最近我没事调直立车的直立环:我发现我以前的固定思维阻挠了我调车,其实不应该说你把P值固定了就可以一直加D然后让他稳定,有时候其实你应该减小P的值然后增大D值这样子就可以让直立车以一个比较软的方式快速的回复直立,这里的PD我还是建议你们用matlab或者C语言编写一下,适当的感受比较好,我最终的PD值位P:-140,D:60这里可以看出,确实D是让他恢复迅速的一个必要条件。最好的方法就是抓住两个轮子,要用力,然后看车子的稳定情况,如果上下摇摆很大,但是你放开的时候有似乎很平稳,就加大D值一直到车子有点颤抖,然后减小P值然后增大D值,当D值大到车很稳不论是抓住两个轮子还是普通状态下,就成功了。
  接下来就调三岔,小车在三岔路口很明显地电感值会减小,我们的方法是判断识别三岔地电感条件,用一个技术地方式来进行方向地控制,到达那个条件之后通过人为地控制车地偏差,然后进行方向控制。对了,我们双车的传球是通过计数延时来传球。但是我不建议你们这么做。
  最后总结吧,怎么说,按照我的学长来说还是太逊了,队友虽然不强甚至有点坑,但是自己却并没有把自己所需要学的技术学的更深。希望你们不要被老师工作室还是比赛所迷惑,专心搞一件事,希望你们能够冲进国赛。


  我提醒你们在选择队友搞硬件时一定要仔细仔细再仔细,不然,到时候板子拿到手一测是很搞心态的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值