option byte介绍

串口波特率计算补充

由于单片机内部的RC时钟引起的误差而导致的产品失效,比如 Uart串口通信(常温不可以通信,温度高才行)、Watchdog看门狗复位失灵等等。所以在这里补充一下串口波特率相关计算。“串口波特率的最大偏差多少,对方就不能接收了或出错了?”

最常见的10位串口的输出时序( 1个起始位 + 8个数据位 + 1个停止位 )

image-20240401172627745

我们要确保实际波特率对应的 D0 ~ D7 时区段,都分别落在对方波特率的采样点的范围内,

从多个常见的波特率推送来看,****最大偏差一般在5% 以内都可以正常通信。

但考虑到不同芯片的采样点的方式有所不同,以及一帧的串口位不同(数据位越长,累计的偏差会更多),建议确保波特率控制在2%以内最好。

image-20240401174220374

  • 值得注意的是,每次接收数据采样点均会从第1 bit 数据初始化,这意味着采样偏差并不会累积至下一次数据传输,如图1所示,每次检测到下降沿时将重新开始进行数据采样。

image-20240401174311722

转载 –> 单片机冷启动下重启问题分析

问题现象

客户反馈MCU作为他们产品的控制芯片,在常温下工作是正常的,但是稍微冷冻下就会启动失败,重现率100%,再次加热或者恢复到常温又能正常工作。

问题分析解决

从客户描述上来看,猜测很大可能是硬件问题,因此带了一块STM32F030-NUCLEO板过去,想着做个芯片交换测试看下结果。

到达客户现场,了解到客户只是使用了内部高速晶振HSI。先使用示波器抓下VDD和NRST的启动波形,在常温下发现并没有明显异常。于是做低温测试,为了对比,基于STM32F030-NUCLEO板了写了一个只使用内部高速晶振HSI , 翻转一个LED灯的程序。

结果显示,STM32F030-NUCLEO板能正常启动,而客户的板子问题重现,再次测量其VDD和NRST的启动波形,发现VDD上电过程中有稍微不规则波形,但感觉不至于导致MCU无法启动。考虑到当前客户板子上的MCU跑的是客户自己的程序,为了统一对比,将客户板子上的MCU烧录成NUCELO板上一样的程序,再次做低温测试,结果显示客户的板子也能正常启动!

于是可以初步断定,此问题与客户自己的软件有关,而与外围电路无关。

接下来对比测试代码与客户自己的代码,并再次做低温测试验证结果,最终发现客户的时钟树配置有个参数有问题:

image-20240329095021747

如上红色代码所示,RCC_OSCILLATORTYPE_NONE改成RCC_OSCILLATORTYPE_HSI后。问题现象明显改善,但经过测试,发现偶尔还会启动不正常的时候。但相对于之前100%可以重现的现象,至少说明之前软件的失误至少是一个因素。

现在问题变成偶尔重现,已经向前迈进一大步。接下来怀疑与硬件有关了,理由是同样的测试软件跑在用户的板子上和跑在NUCELO软件上的结果不一致。

因此接下来首先对于用户的板子的外围电路与STM32F030-NUCLEO板子的外围电路,发现客户MCU的BOOT0引脚是悬空的,于是加上一个外部10K下拉电阻,再次测试问题不再重现。

至此,问题解决!

后话

回过头来看这个问题,发现客户知道MCU使用的是HSI,可偏偏在代码中配置时钟树时使用的晶振类型却是NONE !这种问题现在看来是非常低级的问题,但在代码量大,或者代码迭代的过程中,之前写代码的人离职,后续接手的工程师又不能全盘了解所有代码的情况下时就会变得束手无策,当碰到此类莫名其妙的问题,特别是无法判断到底是硬件问题还是软件问题的时候,保持清晰的思路是非常重要的。(另外,对于这个现象,看门狗也是可能是一种思路。比如说冷启动的时候导致看门狗模块异常不能及时喂狗所导致的重启)。继续补充一下。在低温环境,要注意晶振负载电容随温度的变化

这里我需要强调的是,最有效的解决方法就是快速找到一个 “参照物”,而ST的DEMO板和示例代码就是在硬件上和软件上扮演这样一个参照物的角色。可以通过MCU交换测试来判断是不是芯片外围电路的问题或者芯片问题,可以使用Cube库下的示例代码,对比其运行结果来判断是否与软件有关。先从大方向明确问题到底是与硬件有关还是与软件有关,然后再做下一步分析,这种方法希望读者能有效掌握。

总结

转载这篇文章,对思路进行一下开阔,有的问题可能看似与软件无关,实则确实息息相关。遇到异常的时候,首先分析时钟,电源,复位是否都是正常,不论是从软件还是从硬件上来确认。

Linux下网卡命名规则

rename 规则
1
2
3
4
5
6
7
8
9
10
11
step1 依据/usr/lib/udev/rules.d/60-net.rules, 查看是否有ifcfg-xx配置文件(路径在/etc/sysconfig/network-scripts/),
是否有定义了指定MAC地址的配置文件(ifcfg-xx ,xx必须和配置文件的内容DEVICE一致),如果有,则命名改网卡;

step2 依据/usr/lib/udev/rules.d/71-biosdevname.rules,如果biosdevname使能了(安装了biosdevname这个包,且内核启动参数显式设置为1),
且网卡没有在step1中定义,则按照biosdevname命名规则rename网卡;(注意,如果没有安装biosdevname这个包,就没有这个文件)

step3, 依据/lib/udev/rules.d/75-net-description.rules,将udev工具会根据device属性将填写网卡的属性命名,可能一个网卡会有多个维度的名称;

step4,udev 根据step3中的赋值,按照指定的scheme规则,去给在step1 step2中没有命名的网卡命名;

强调:这个step顺序是在我们没有自定义自己的rules的前提下,如果用户自定义了自己的rules,则用户自定义为优先级最高
传统命名

centos6之前采用的都是传统的命名方式,如eth0,1…

可预测的命名

cenos7之后提供了可预测性的网卡命名方式。

1
2
3
4
5
如果从BIOS中能够取到可用的,板载网卡的索引号,则使用这个索引号命名,例如: eno1,如不能则尝试2
如果从BIOS中能够取到可以用的,网卡所在的PCI-E热插拔插槽(注:pci槽位号)的索引号,则使用这个索引号命名,例如: ens1,如不能则尝试3
如果能拿到设备所连接的物理位置(PCI总线号+槽位号?)信息,则使用这个信息命名,例如:enp2s0,如不能则尝试4
传统的kernel命名方法,例如: eth0,这种命名方法的结果不可预知的,即可能第二块网卡对应eth0,第一块网卡对应eth1
使用网卡的MAC地址来命名,这个方法一般不使用
自定义规则
1
2
3
4
5
6
7
在用户没有自定义rules文件前提下,step1中的网卡命名方式也可认为是一种用户自定义的网卡命名,
即在/etc/sysconfig/network-scripts/ifcfg-xx 文件,xx就是这个网卡名称,文件内容中体现MAC_ADDRESS、NAME,
这种情况下,则会按照配置文件中指定的名称来命名网卡

如果用户自定义了rules文件,放在/etc/udev/rules.d/目录下,则这个优先级是最高的;
比1中ifcfg-xx方式优先级更高,但是如果两者不一致,则在重启network服务时,会依据ifcfg-xx,
所以用户不应该同时采用里两种方式给同一个网卡命不同的名称

udevadm info /sys/class/net/网卡名

可以显示此时这个网卡的pcie信息,vendor_id,idbus等等信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@Bai5gc:/sys/class/net/eth1# udevadm info /sys/class/net/eth1
P: /devices/pci0000:00/0000:00:02.2/0000:03:00.0/net/eth1
E: DEVPATH=/devices/pci0000:00/0000:00:02.2/0000:03:00.0/net/eth1
E: ID_BUS=pci
E: ID_MODEL_FROM_DATABASE=Ethernet Connection X552 10 GbE Backplane
E: ID_MODEL_ID=0x15ab
E: ID_NET_DRIVER=ixgbe
E: ID_NET_LINK_FILE=/lib/systemd/network/99-default.link
E: ID_NET_NAME_MAC=enxb4a9fca897e7
E: ID_NET_NAME_ONBOARD=eno3
E: ID_NET_NAME_PATH=enp3s0f0
E: ID_PATH=pci-0000:03:00.0
E: ID_PATH_TAG=pci-0000_03_00_0
E: ID_PCI_CLASS_FROM_DATABASE=Network controller
E: ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller
E: ID_VENDOR_FROM_DATABASE=Intel Corporation
E: ID_VENDOR_ID=0x8086
E: IFINDEX=3
E: INTERFACE=eth1
E: SUBSYSTEM=net
E: SYSTEMD_ALIAS=/sys/subsystem/net/devices/eth1
E: TAGS=:systemd:
E: USEC_INITIALIZED=5061037
E: net.ifnames=0

ps:解释一下pci地址

  • /pci0000:00:这是根 PCIe 控制器的地址,pci0000:00 表示根控制器。
  • /0000:00:02.2:这是连接到根控制器的第一个 PCIe 设备的地址。0000:00:02.2 表示这个设备的总线号、设备号和功能号。
  • /0000:03:00.0:这是连接到第一个 PCIe 设备的下一个 PCIe 设备的地址。0000:03:00.0 表示新设备的总线号、设备号和功能号。
命名rule.d
biosdevname和net.ifnames两种命名规范
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
net.ifnames的命名规范为:设备类型+设备位置+数字

设备类型:

en 表示Ethernet
wl 表示WLAN
ww 表示无线广域网WWAN

实际的例子:

eno1 板载网卡
enp0s2 pci网卡
ens33 pci网卡
wlp3s0 PCI无线网卡
wwp0s29f7u2i2 4G modem
wlp0s2f1u4u1 连接在USB Hub上的无线网卡
enx78e7d1ea46da pci网卡


biosdevname的命名规范为: 要么是em开头,要么是p开头
实际的例子:

em1 板载网卡
p3p4 pci网卡
p3p4_1 虚拟网卡

硬链接 软链接 符号链接

链接

简单来说是文件共享的方式。

硬链接

具有同样的索引节点和文件属性,只有链接数=0的时候,才会用磁盘删除内容。

  • 不允许给目录创建硬链接。

  • 不可以给不同文件系统的文件间建立连接。因为 inode节点 是这个文件在当前分区中的索引值,是相对于这个分区的,当然不能跨越文件系统了。

软链接
符号链接

软链接也叫做符号链接。没有文件系统限制。软链接原文件/链接文件拥有不同的inode号,表明他们是两个不同的文件;建立软链接就是建立了一个新文件。当访问链接文件时,系统就会发现他是个链接文件,它读取链接文件找到真正要访问的文件。

  • 软链接的链接数目不会增加;

  • 可以给目录增加链接。

git svn常用操作

git

1
2
3
4
5
git add xxx 											// git添加文件

git commit -m "add syslog && ipaddress" // git提交本地

git push // git提交远端

svn

1
svn merge -r HEAD:12098 .        // svn回退到某个版本

  • 步进电机工作原理本质:靠励磁绕组产生的旋转合磁场带动转子做同步运动。由于励磁绕组通电之后产生的磁通量正比于电流大小,所以只要控制通过流过各个绕组的电流大小和方向就可以控制步进电机各个绕组产生的合磁场大小和方向。

  • 相数:是指电机内部的线圈组数,如4相就是有ABCD四组线圈。

  • 拍数:是指完成一个循环的通电次数。例如按照ABCD顺序完成一个循环,就称为单4拍。相邻的两个线圈也可以同时通电,例如可以按照AB-BC-CD-DA方式通电,这种就称为双4拍。注意,对同一个电机来说,单四拍与双四拍每拍转动的角度是相同的。还有一种方式是单个线圈与双个线圈轮流通电,就是A-AB-B-BC-C-CD-D-DA,这样就是四相八拍,这种方式工作时每拍转动的角度是4拍的一半。

  • 励磁方式:分为全步励磁和半步励磁,其中全步励磁又有一相励磁(在没每一瞬间步进电机只有一个线圈导通,步进电机旋转1.8度)和二相励磁(在每一瞬间,步进电机有两个线圈同时导通1.8度);半步励磁又称一二相励磁(线圈交替导通)。

  • 步距角:对应一个脉冲信号,电机转子转过的角位移用θ表示。θ=360度(转子齿数J*运行拍数),以常规二、四相,转子齿为50齿电机为例。四拍运行时步距角为θ=360度/(50*4)=1.8度(俗称整步),八拍运行时步距角为θ=360度/(50*8)=0.9度(俗称半步)。

  • 细分:通过等角度有规律的插入大小相等的电流合成向量,从而减小合成磁势的步距角。力矩越大,步进角越大。正弦细分驱动的本质实际上就是通过绕组A和绕组B的电流分别按照正,余弦规律变化,使得合成电流矢量圆周均匀旋转。

  • 升降速控制:运动速度根据运动参数当中的细分数和步数做选择。细分数约大平均运动速度越慢,反之越快。比如细分1024,相同的步数速度则会很慢。

  • 力矩速率关系:当步进电机转动时,电机各相绕组的电感将形成一个反向电动势;频率越高,反向电动势越大。在它的作用下,电机随频率(或速度)的增大而相电流减小,从而导致力矩下降。

  • 空载启动频率:即步进电机在空载情况下能够正常启动的脉冲频率,如果脉冲频率高于该值,电机不能正常启动,可能发生丢步或堵转。在有负载的情况下,启动频率应更低。如果要使电机达到高速转动,脉冲频率应该有加速过程,即启动频率较低,然后按一定加速度升到所希望的高频(电机转速从低速升到高速)。

  • 合成电流:以两相电机为例,如果控制绕组的电流按照正余弦变化,那么绕组合成电流矢量或者磁场矢量将以恒定大小,均匀角度做圆周运动。使得力矩恒定,步距角均匀。

    image-20240328203237016

SPWM 脉冲宽度调制技术

PWM

目前一般采用脉冲宽度调制(PWM)技术来精确控制绕组电流的大小。主要是因为冲量相等而形状不同的窄脉冲加在具有惯性的环 节上,效果基本相同。步进电机的绕组由于电流不会突变,具有明显的惯性 环节,因此可以用 PWM 技术来控制电机绕组的电流大小。

如图所示。周期脉冲 信号的导通阶段对绕组进行充电,截止阶段绕组通过续流回路 进行放电。当脉冲的频率和宽度达到一定值时,绕组的电流将基本是一个恒定值, 并带有微小的纹波信号。当脉冲宽度改变时,绕组的电流也将发生变化。所以 PWM 可用来精确控制绕组电流的大小。

image-20240328203617119

即pulse width modulation,脉冲宽度调制,实际上就是周期的矩形波,然后每个周期的占空比都可以自己设置就叫做调制。

相比SPWM,多加了一个S,即sin,正弦脉宽调制。还是这个周期的矩形波,但不同的是占空比不是固定的,而是按照正弦规律变化的。

SPWM一般由三角波(载波)和正弦波(调制波)比较而成,硬件生成方法是将三角波和正弦波加入比较器得到,软件是通过定时器或Epwm模块,按照中央计数模式生成三角波,经CCR比较模块动作产生对于高电平,即SPWM。

升降频控制技术

步进电机从静止启动时,由于惯性和摩擦力矩的作用,如果转动频率突变太 大可能会丢步甚至堵转;当步进电机在高速运转时如果突然停下来,则可能会过 冲,这些情况都会导致运动不平稳以及定位精度不高。所以引出了升降频控制技术。

由于步进电机升速过程当中输出力矩明显减少,因而步进电机的升速曲线的 设计尤为重要。步进电机的升速过程一般由突变频率和加速曲线过程。

实际上步进电机转动频率不是连续变化的而是离散的,因而升速曲线一般 是指运行频率与脉冲数的关系曲线。由于步进电机降速过程中输出力矩增大,因而对降速曲线的要求比升速曲线 低得多,只要保证不因为惯性而过冲超步即可

image-20240328204102555

SPWM 软件生成

利用单片机来生成PWM,然后让占空比按照正弦规律变化。

步骤
  • 生成载波,比如要生成一个10KHZ的三角波,将计数器设置加减计数、周期设为1/10K

  • 生成正弦波,用软件生成正弦表即可,

  • 将正弦波和三角波比较。设置计数值到达的时候进行比较,改变比较值,用查表法获得,用于下一个周期比较。调制度m = 正弦表最大值/三角波计数最大值。 如正弦表最大值4200,三角波最大计数值8400,m=4200/8400=0.5,此时spwm最大占空比为50%,设置m=1,spwm最大占空比为100%。

    image-20240325084615541

    要注意因为是单极性调制,spwm和三角载波都是大于0的。在单相全桥逆变电路中,开关管交替导通时输出电压Ud自然会倒过来为负,Ud经过滤波就是一个正弦波。

定时器相关

一般电机控制都是边沿对齐模式,FOC电机一般使用中心对齐模式。

边沿对齐模式 –> 在递增计数模式下,计数器从0递增到ARR值,然后重新从0开始计数并产生计数器上溢事件。

DSP控制三相步进电机时,为什么会用一对互补的PWM波形来控制?

对于某种特定的电机来说,每一相位都有高位的MOS和低位的MOS,要驱动这两个MOS还不能同时开和同时关,必须上开下关或者下开上关,所以要用互补的PWM来控制。如果是用专门的MOS驱动芯片驱动的话,是可以用一路PWM的。

syslog.conf介绍

syslog采用可配置的、统一的系统登记程序,随时从系统各处接受log请求,然后根据**/etc/syslog.conf**中的预先设定把log信息写入相应文件中、邮寄给特 定用户或者直接以消息的方式发往控制台。ps:不同平台下的文件不一定相同,可以在etc下grep /var/log/messages等来查看文件名。

具体示例

*.err;kern.debug;daemon.notice;mail.crit [TAB] /var/adm/messages

这行中的“action”就是我们常关心的那个/var/adm/messages文件,输出到它的信息源头“selector”是:

*.err – 所有的一般错误信息;

kern.debug – 核心产生的调试信息;

daemon.notice – 守护进程的注意信息;

mail.crit – 邮件系统的关键警告信息

0%