嵌入式面试相关

47 阅读1小时+

回答问题模板

  1. 它是什么
  2. 它有什么用,用在什么场景
  3. 怎么使用它
  4. 使用它的注意事项
  5. 它的实现原理是什么
  6. 它的优缺点是什么
  7. 有什么其他方式可以替代

什么是嵌入式系统

  1. 由微型控制器控制,有专门的软件和硬件组成的一种功能性设备
  2. 它通过软件程序用来控制硬件实现指定的功能和任务。
  3. 它广泛用于工业控制、消费电子、汽车电子、医疗设备、通信设备、军工等领域,像自动化设备的一些模块、机械臂、智能家居、无人机、医院的很多仪器等等
  4. 它的原理是通过一些传感器和其他模块,收到外部的信号,然后用编写好的程序去处理这些信号,然后驱动嵌入式设备本身的外设,去达到这个产品本身要实现的功能。
  5. 一般使用嵌入式设备需要考虑系统的资源、主频率、外设的数量、稳定性、和功耗控制
  6. 它的优点是结构简单、成本低、功耗低,可以根据具体业务订制开发,它的缺点是定制性开发,不适合大范围更改功能,并且资源受限,内存较小。

mcu时钟系统

  1. mcu时钟系统是mcu的心跳,控制整个芯片内部模块工作的时序和速度。
  • 主要组件包括
  • 时钟源:内部、外部晶振
  • 锁相环PLL:用于频率倍增
  • 分频器:用于降低频率供不同外设使用
  • 总线时钟树:将主时钟通过总线分发到AHB、APB、外设等
  1. mcu时钟系统用于控制mcu主频、外设工作频率等,为低功耗、稳定性提供灵活支持。
  2. 使用步骤,需要先选择外部或内部时钟源,然后配置锁相环倍频,再配置总线分频器,再然后切换系统时钟,最后是启用时钟
  3. 注意事项:不同芯片的主频上限不同,像stm32f1xx系列为72Mhz,stm32F4系列为168Mhz,GD32F3系列是108Mhz。锁相环必须稳定后才能使用,APB1总线不能超过36Mhz,USB时钟必须精确为48Mhz。外设通信速率需要匹配系统频率和分频设置
  4. 实现原理:外部或内部晶振振荡,经过振荡电路输出基准频率。锁相环将输入频率和参考频率进行比较,通过反馈控制电压控制振荡器,生成更高频率的稳定输出。分频器对输入时钟进行计数并输出每N次一个脉冲。时钟树把主时钟源通过选择器、锁相环、分频器等结构分发到不同模块,形成一棵时钟树。

什么是内存映射I/O和独立I/O

  1. I/O是处理器访问外部设备的引脚,内存映射I/O的寄存器地址映射到了处理器的内存地址中,可以直接访问和操作,独立I/O的外设寄存器地址和处理器内存空间的地址是分开的,需要用专门的指令来访问
  2. 它们都是通过指令来控制外设,只是内存映射I/O不需要专用指令,独立I/O需要专门的指令
  3. 内存映射I/O在ARM架构中比较普遍,独立I/O一般在x86架构中常见

什么是GPIO

  1. 是mcu中用于数字信号输入输出的通用引脚
  2. 它的作用主要是一些简单的数字信号交互,像读取按键是否按下,控制LED、蜂鸣器、继电器等设备、与一些需要根据时序使能高低电平的模块通讯,还可以模拟比如I2C之类通讯协议
  3. 使用GPIO主要有这些步骤,使能对应引脚的时钟,配置引脚的模式、配置上拉或下拉、设置输入或输出的值,还可以配置中断,比如按键触发中断
  4. 使用的时候还要注意引脚模式一定要正确。如果是要有驱动能力,需要用推挽。并且GPIO负载能力有限,大功率设备最好是配合MOS管来控制。并且还要防止悬空,引脚必须配置上拉或者下拉。如果是按键检测,还需要对GPIO的信号进行防抖
  5. 每个GPIO引脚内部都有一个控制电路,内部包含一个模式控制开关,用来控制是输入、输出、复用还是模拟,还有上拉和下拉电阻控制电路,还有数据寄存器ODR和IDR,还有电路连接到中断NVIC。具体是通过寄存器来设置引脚的行为。

什么是中断NVIC

  1. 中断是一种让cpu在执行当前任务时,临时中断当前的程序,转而执行某个紧急任务也就是中断任务的的一种机制,当中断任务处理完成后,cpu会自动返回原来被打断的地方继续执行原来的程序。
  2. 中断可以实时、高效的处理关键事件,避免轮询,提高系统资源的利用率。大部分外设都有中断事件,比如GPIO检测按键按下的电平变换,spi、i2c、串口等通信外设接收到数据的中断,定时器定时触发的中断,系统异常中断,还有电源相关的休眠和唤醒的中断。
  3. 使用中断包含以下步骤,使能开启对应外设中断,配置中断优先级,注册中断服务函数,自定义中断服务函数,在中断服务函数中清除中断标志位,防止中断重复进入,并编写中断触发后的业务逻辑。
  4. 使用中断函数要注意尽量短、快,不能有延时或耗时操作。不能中断函数中互相嵌套造成卡死。使用全局变量时要注意中断上下文与主循环之间的同步问题(需加volatile或互斥)。一定要记得清除中断标志位,不然会重复触发。还需要注意中断优先级,不能冲突。
  5. 中断的本质是cpu收到一个中断请求信号,然后硬件自动保存现场,跳转到中断向量表中指定的中断服务函数,然后执行中断服务逻辑,最后中断执行完成后,接收到中断返回指令恢复到原来的执行程序。
  6. 中断的优点是实时性强,能及时响应关键事件,无需轮询更节省CPU资源,适合事件驱动程序结构。缺点是程序流程被打断,结构复杂,多中断嵌套可能导致调试困难,中断内互相调用中断,会造成死锁系统崩溃等
  7. 除了中断,还有像轮询、定时器加状态机、RTOS开启多个子任务等方式可以达到相似的效果。

IRQ和FIQ有什么区别,在CPU里面是是怎么做的?

  1. IRQ是普通中断,在ARM架构中用于处理一把的外设中断,例如定时器中断,串口中断等;FIQ是快速中断,优先级更高,专门设计用于对实时性要求非常高的中断,比如紧急传感器信号,数据采集等。

什么是中断向量表

  1. 中断向量表是一个表格,里面存放着所有中断服务函数的地址。当mcu收到中断请求时,cpu会重中断向量表中读取对应的地址,然后跳转到该地址执行对应的程序。
  2. 中断向量表的作用是让中断信号和中断处理函数之间有一个映射关系,所有的中断处理函数都能在中断向量表找到对应的中断处理函数地址。
  3. 中断向量表一般在 startup_xxx.s(启动文件)中定义。

什么是UART?什么是USART?

  1. 统称串口,又叫串行通信协议,UART叫只支持异步,USART支持异步也支持同步,同步需要多接一根时钟线。
  2. 主要用在设备之间的串行通信,用途非常广泛,比如与上位机通信,与模块通信(像蓝牙、wifi、4G模块、GPS、部分传感器等),与其他MCU通信,输出日志,固件升级等
  3. 使用串口的步骤:
  • 使能串口时钟和对应GPIO的时钟,
  • 配置串口引脚并开启复用,tx发送,rx接收,sclk时钟,
  • 配置串口参数(波特率、没帧数据的位数、设置停止的位数、设置基偶校验位、是否使用硬件流控,一般只用于高速串口或蓝牙模块、设置串口的工作模块一般使用收发等)、
  • 使能串口、
  • 配置中断或者DMA的方式接收、
  • 发送和接收数据
  1. 使用串口进行通信需要注意发送方和接收方的rx与tx要交叉接,并且发送和接收端的波特率和数据格式要一致,否则会接受不到或者乱码。使用同步模式一定要连接sclk引脚,异步模式对时钟不敏感,但是不能长时间丢数据。若使用中断或DMA,需正确处理缓冲区和状态标志。需要选择合适的波特率,波特率过高容易出错。
  2. UART异步通信原理:两根线,TX引脚发送,RX引脚接受,无需时钟,只靠约定好的波特率,起始位1位低电平+8位数据位+可选基偶校验位+1或者两位高电平停止位组成一个完整的帧,发送端将字节转换为串行电平波形,接收端按波特率采样还原为字节数据。SART同步通信原理:三根线,TX引脚发送,RX引脚接受,需要共享时钟信号SCLK(主设备提供),数据与时钟线同时传输,传输效率更高,误码率更低。
  3. 串口接线简单,异步传输时无需时钟,适合长距离传输,应用广泛,驱动成熟,可以通过中断/DMA实现非阻塞收发。但是只能点对点通信,无法多主多从,通信速率有限,抗干扰能力一般。异步通信依赖时序精度,容易出现误码。
  4. 可以基于USART升级为RS232信号,增加抗干扰性。

什么是波特率

  1. 波特率是指串口通信中每秒传输的比特数,即每秒传输多少帧数据,1波特=1bit/s,比如波特率为9600,就表示每秒传输9600个bit
  2. 波特率决定通信速率,通信双方必须使用相同的波特率,否者会出现数据对不上的问题,像乱码和丢帧。
  3. 在使用usart或者uart时,发送端和接收端的波特率要保持一致。

什么是RS232

  1. RS232是一种升级版的USART,它规定了电压范围(+/-12V)和接口标准。
  2. 有些工业设备和上位机通信使用的就是RS232。
  3. 在mcu系统中,一般使用usart/uart+RS232电平转换芯片(如MAX232)实现232通讯。
  4. 非常注意,RS232使用+/-12v,不兼容MCU的TTL电平(需转换),并且逻辑1是-12v,逻辑0是+12v,和mcu的ttl电平是反的。它的通信距离较短,稳定范围小于15米,但是抗干扰能力比ttl电平稍强。
  5. RS232是异步串行通信,不需要发送时钟信号,通过一条线TX发送,RX接收,实现双工通信。

什么是TTL电平

  1. TTL电平是电路中使用的标准电平范围,逻辑0低电平为0v-0.8v,逻辑1高电平为2.0v-5.0v(常见为3.3v或5v),是一种低电压数字逻辑标准。
  2. TTL电平通常用于数字电路内部通信,电平接口,MCU的输入输出控制等。

什么是RS485通信

  1. RS485是一种串行通信的协议标准,它使用差分信号传输数据,用于设备间的半双工通信。与RS232不同,RS485使用两个线A/B传输数据,电压差表示逻辑值。A>B是逻辑1,A<B是逻辑0
  2. RS485一般用在工业控制、仪器仪表、传感器网络、安防、自动化、485串口屏等方面。
  3. 一般MCU设备中,使用UART+RS485转换芯片(如MAX485)来进行485通信。
  4. 注意所有设备的A/B线必须严格区分一致,通常为半双工通信,不支持同时收发。
  5. RS485使用差分信号传输,A>B是逻辑1,A<B是逻辑0。多个设备可以并联在同一条总线上,轮流发送数据(类似广播)。
  6. 它的优点是使用差分传输,抗干扰能力强,通信距离远(可达到1200米),支持多机通信(最多32个),布线简单(只需要两根线),并且成本低,广泛应用于工业现场。缺点是半双工通信。

什么是总线(Bus)

  1. 总线是在嵌入式系统重,不同部件之间传输数据、地址和控制信号的共享通信通道。它本质上是一组导线或传输媒介,用于在多个模块之间共享数据通路。从硬件角度看,它是一组信号线。从系统架构角度看,它是一种通信机制。
  2. 它的作用是连接系统内的各个功能单元(CPU、内存、外设等),实现数据传输、指令控制和资源共享。像MCU内部总线:AHP、APB。外设通信总线SPI、I2C、CAN、USB、RS485总线等
  3. 总线系统的原理:它由三类信号线组成,地址总线用来指定访问地址,数据总线用来传输数据,控制总线用来控制操作方向、时序、使能信号等
  4. 它的优点是能够节省引脚和线路资源(多设备共享)、系统扩展性强(易于添加新设备)、模块化设计、支持主从系统、一致性强,易于规划化通信协议。缺点是带宽受限,多设备共享时可能产生竞争、冲突处理复杂、总线加载能力有限,设备太多可能影响稳定性。通信延时高于点对点连接。

什么是DMA

  1. DMA是一种可以直接访问内存的硬件模块,它可以在不经过cpu参与的情况下,直接在外设和内存之间存储数据。DMA可以接管数据的搬运工作,让cpu可以专心做其他任务,从而提高系统效率。
  2. DMA可以将数据从外设搬运到内存或从内存搬运到外设,无需CPU逐个字节处理。常用于数据量大、实时性要求高或CPU负载高的场景。例如:串口接受数据,使用DMA连续接收数据不容易丢包、ADC采集可以将ADC数据写入缓冲区,SPI屏幕刷新使用DMA高速传输图像数据、音频播放使用DMA不间断发送音频流、摄像头/传感器数据采集等
  3. 使用DMA的步骤为:开启DMA相关外设时钟、设置DMA的源地址、设置DMA的目标地址、设置DMA传输方向、设置DMA传输的数据量、设置DMA工作模式、设置DMA优先级、初始化DMA通道、启动DMA功能、配置DMA中断。
  4. 使用DMA时需要注意:查看手册,看外设是否支持DMA,有些外设只有部分通道支持DMA。有些芯片要求按照2/4字节对齐DMA地址。不要冲突访问DMA正在搬运的数据。注意缓存的一致性。DMA缓冲区要常驻内存,不能是局部变量。DMA配置要精确,尤其是方向、数据宽度、数据长度。多通道DMA使用时,要合理分配通道,避免优先级冲突。

什么是I2C

  1. I2C是一种由SCL时钟线和SDA数据线两个引脚就可以组成的一种半双工、短距离、低速、一主多从式的同步串行通信总线。
  2. I2C可以实现多个设备之间的通信,一般用在mcu和传感器、mcu和OLED显示屏,mcu和一些扩展芯片等
  3. I2C的使用步骤为:使能I2C和对应GPIO引脚时钟、配置GPIO复用并设置为开漏模式、初始化I2C外设(设置通信频率、模式、时钟占空比、主机地址、应答机制、地址长度)、然后读写数据
  4. 使用需要注意,I2C是应答模式,发送设备时需要先发从机地址并且设备地址必须正确,并且从机需要给到回应;SDA和SCL硬件上必须加上4.7k左右的上拉电阻;通信频率不能超过从设备的最大值;一条总线上只能有一个主设备主动通信;多个设备地址冲突时需要硬件/软件处理(改地址脚或切换片选);若使用DMA/中断方式需要处理状态切换时序;还需要避免总线锁死(如中途复位未停止通信);
  5. I2C是基于时钟同步的主从式协议,传输时主机发出时钟,每次一个数据位;数据线SDA在SCL高电平期间稳定;数据线SDA在SCL高电平期间稳定;每一帧包含起始位、地址+读写位、ACK/NACK应答位、数据、停止位;SDA和SCL都采用开漏输出并且需要外部上拉;所有从设备监听总线,接收到自己的地址后才应答(ACK会是低电平,低电平表示收到,高电平表示我不接收);支持重复起始实现连续操作;一主多从;
  6. 它的优点是两根线,节省引脚和布局,并且一主多从,设备挂接方便,硬件扩展性强;协议简单外设广泛支持;支持半双工通信;缺点是速度较慢只能在100khz到400khz的速率范围,总线长度不能超过几米,多设备通信可能出错和冲突,开漏驱动和上拉电阻选择不当回导致信号质量差;无CRC校验机制,可靠性需靠软件处理
  7. 除了硬件I2C,还能用GPIO模拟I2C;

什么是CRC校验机制

  1. CRC(Cyclic Redundancy Check,循环冗余校验)是一种基于多项式除法的差错检测机制,用来判断数据在传输或存储过程中是否发生了错误。它不是加密手段,也不能纠错,只能发现错误。
  2. CRC用来检测数据是否发生错误(如位翻转、噪声干扰等); 比较可靠,能发现单个错误、连串错误、突发错误等。一般用在通信协议:如 Modbus、CAN、LoRa、以太网帧校验;存储系统:Flash 校验、内存数据完整性校验;嵌入式传感器数据包完整性检查;文件传输工具(如 zip)中校验压缩包完整性。
  3. 使用步骤为:发送端,对数据内容做一次CRC计算,得出一个CRC校验码,并将CRC校验码附带在数据末尾一起发送。接收端,接收到数据后用同样的算法进行CRC计算,比较计算得到的CRC和附带过来的CRC值是否一致;如果不一致,说明数据在传输过程中出现了错误。在mcu中可以通过软件算法、硬件CRC模块、Modbus协议栈中的CRC自动计算等方式实现

什么是Modbus

  1. Modbus是一种主从结构的串行通信协议,常用于工业自动化系统中。并且Modbus不仅是一个协议规范,也是一种数据帧格式,它可以运行在RS232、RS485、TCP/IP等物理层上。常见的Modbus协议版本有Modbus RTU、Modbus ASCII、Modbus TCP等
  2. Modbus的作用是让MCU与传感器、执行器中间进行数据读写。例如工业设备的温度、湿度、电压、电力等数据采集;控制继电器、阀门等远程设备、MCU与PLC之间的通信。

什么是CAN

  1. CAN是一种多主多从、广播式通信、高可靠性、实时性、抗干扰能力强的通信协议。
  2. can总线可以实现多个控制器ECU之间的数据通信,通常用于车辆内部各个控制模块之间的数据交互(如发动机、ABS、气囊);工业自动化设备之间的通信;医疗设备模块之间的通信;电池管理系统、电机控制器内部之间的通信等;
  3. 使用步骤为:初始化CAN外设、配置CAN过滤器(觉得接收那些ID的数据)、配置NVIC使能CAN中断、发送数据帧
  4. 注意事项:CAN为多主总线,多个节点可以主动发起通信,需依赖仲裁机制避免冲突;每个节点必须有终端电阻(一般为120R)连接在总线两端;数据传输必须符合波特率匹配;报文ID不代表地址,而是代表优先级和功能类型;需要配置过滤器决定接收那些ID;若使用中断接收,需妥善处理FIFO溢出和数据解析;
  5. CAN总线采用以下几个核心机制,每一帧的数据结构为起始位 、标志符(ID)、控制位、数据段、CRC校验和ACK应答;有仲裁机制:使用报文ID的二进制位优先级来判断那个节点先发送(0优先级大于1);非破坏性总线访问,当两个 节点同时发出帧时,低ID的节点获胜,高ID节点自动停止发送。多主多从结构,任意节点都可以主动发送数据,不需要轮询。广播通信,发送数据所有节点都能收到数据,但是通过过滤器,只接收自己需要的。
  6. CAN总线的优点是多主通信,节点的地位平等,有仲裁机制,通信冲突可自动解决,有ACK应答机制,CRC错误检测,重传,可靠性高,抗干扰能力强,适合恶劣工业环境,通信距离长,标准CAN通信距离可达1KM,不需要地址机制,广播式通信,不需要地址机制。缺点是帧长度固定,最多8字节,不适合大数据传输,软硬件复杂度较高,贷款最高位1Mbps;

什么是SPI

  1. SPI是一种摩托罗拉公司提出的全双工,主从式的同步串行通信协议。它通常由一个主设备和一个或多个从设备组成,使用SCLK时钟线,MOSI主机输出从机输入线,MISO主机输入从机输出线,NSS/CS片选信号线(低电平有效,主机控制哪一个从设备通信)
  2. SPI常用于高速、短距离的主从通信,例如TFT屏幕显示、OLED屏幕显示、传感器模块与mcu通信、flash或者EEPROM等存储设备和mcu通信等,
  3. 使用步骤为:使能GPIO和SPI时钟,配置GPIO(设置时钟、设置引脚复用推完输出、设置引脚最大切换速度、设置spi工作模式为全双工、设置设备为主机模式主机会生成SCK时钟信号、设置每次发送/接收的数据长度、设置spi工作模式具体为设置时钟空闲状态为低电平何设置时钟上升沿采样,有四种模式,设置spi频率,设置数据传输时先传送高位或低位,设置CRC校验用的多项式值,CRC根据需求是否开启,启动spi外设,使用SPI发送和接收函数收发数据)。
  4. 注意事项:主从必须共享同一个时钟源(SCLK由主机提供)。MOSI主机输出和MISO主机输入方向不能搞反,否则通信会失败。SPI是全双工通信,但不一定每次收发都使用双向。对于多从设备,主机需要通过NSS/CS片选信号选择通信目标。CPOL时钟极性/CPHA采样时机的时序参数必须与从机匹配,它们共同决定SPI在什么时候采样数据,在什么时候输出数据,否则会接受错误。有些设备对SPI收发时序比较敏感,需要仔细看数据手册。因为SPI是全双工通信,发送数据时必须也会收到一个字节(接收缓存不能忽视),但是接收到的这个字节可以没有意义。
  5. SPI的基本机制如下,主设备发送时钟信号SCLK,每一个时钟沿,MOSI或MISO线就传输一位数据,CPOL时钟极性和CPHA采样时机决定数据合适采样。一边发送一边接收,全双工数据交叉传输。一个片选cs对应一个从设备。主设备控制谁给低电平和谁通信。
  6. SPI的优点是通信速度快可达几十Mhz,一主多从,协议简单,开发移植方便。缺点是通信线较多,最少需要四根,不支持多主通信。无标准握手机制,数据完整性需要靠协议或者CRC保证。
  7. 有I2C、UART、CAN、USB、并口通信等方式可以替代

什么是并口

  1. 并口是一种同时通过多个数据线传输多个位(bit)数据的一种通信方式。通常在电子或嵌入式系统中使用,一次可以传输4、8、16、32位位宽数据。
  2. 并口通常用在高速数据通信,相比串口,速度快非常多。控制多个信号线,比如一次写一个8位命令给lcd屏幕。通常用在驱动并口lcd(ILI9341),mcu与外部SRAM/FLASH通信,MCU控制LED数码管矩阵、键盘矩阵等。
  3. 使用方式:方式一,GPIO模拟并口,用若干GPIO控制多根数据线,一起写入数据。方式二,使用专用外设,像FSMC灵活静态存储控制器
  4. 注意事项:IO引脚多,占用资源大,8位并口至少占用8个引脚,加上控制线可能十几个。线长不能太长,否则会出现信号失真或干扰。需要同步控制时序,写数据时要严格按照外设所要求的时序。速度和MCU主频有关,软件模拟的并口速度较慢。
  5. 并口的实现原理:并口本质上就是MCU同时控制多根GPIO引脚作为一组数据线,并通过另外几根控制线来同步读写动作。在硬件上,MCU芯片内部,多个io口通过总线与寄存器链接,当写入某个寄存器时,可自动输出整个字节或半字节到多个引脚。
  6. 并口的优点是多个位一起发送,比起串口,速度快很多,实现起来也简单,低速场合可以用GPIO模拟实现。缺点是引脚占用过高,一般需要8-16根数据线+控制线。pcb布线复杂,不适合长距离,容易受到干扰。

嵌入式中的以太网接口

  1. 以太网接口,也叫网线接口,是设备与网络交换数据的物理和电气接口,主要是通过RJ45接头连接网线,底层包括PHY芯片和MAC控制器。
  2. 以太网接口用来通过有线网络的方式,实现嵌入式设备联网通信。支持TCP/IP协议栈,进行远程控制、数据上传、OTA升级等功能。一般用在智能网关、智能摄像头、网络打印机等设备上。

什么是ADC

  1. ADC是模数转换器,是MCU的内置的外设之一。
  2. 它可以将传感器等外设输出的电压信号转换为数字信号。像读取电池电压,光照强度,温湿度,音频采样,电阻式触摸屏的位置采集等等都会用到。
  3. 使用ADC需要包含以下步骤,使能ADC时钟,设置分辨率,根据引脚选择ADC通道,GPIO设置为模拟输入模式,配置采样时间,设置采样模式(单次模式、连续转换模式、扫描模式),通过轮询或者中断的方式读取结果,根据精度4095以及对应传感器计算公式或曲线将ADC值转换为你需要的单位
  4. 使用ADC还需要注意,输入引脚只能接电压,并且电压不能超过3.3v。采样电路的电阻的阻抗尽量要小,否则会影响精度。还需要注意,ADC的通道要正确设置为模拟输入模式,不能是默认的GPIO。最后mcu的参考电压需要稳定并且精准,一般需要在参考电压输入前增加电容滤波。
  5. ADC的核心原理是将一个模拟的电压信号转换成一个对应的数字值,一般是采用比较器来逐次逼近,控制电路每次将采样参考电压的中间值进行比较,逐步逼近最终获取输入电压的数字值,像12位的ADC可以将0-3.3V的电压分成2的12次方份,也就是4096份。

什么是DAC

  1. DAC是数模转换器,是MCU内置的外设之一。
  2. 它可以将将数字信号转换为模拟电压输出。一般用在输出正弦波信号、音频信号、设置电压控制运放、模拟传感器数据等等。
  3. 使用DAC需要包含以下步骤,使能DAC时钟,根据引脚选择通道,设置触发方式,设置是否缓冲,配置输出引脚为模拟模式,设置DAC数据值。
  4. 使用DAC也要注意输出的电压范围通常是0-3.3v,并且不能驱动大负载,如果需要驱动大负载需要配合运放。如果需要输出稳定的正弦波之类的波形,需要配合DMA提高速率。还需要注意DAC引脚一定要配置为模拟模式,否则数据不稳定。最后输入精度一般是12位,可以将4096分为0-3.3v电压,如果需要更高精度,可以使用外部高精度DAC芯片。
  5. DAC的核心原理是内部用选择器加电阻进行分压。

什么是RTC时钟

  1. RTC实时时钟是MCU中用来持续提供当前时间信息的一个独立的硬件模块。
  2. 它可以提供实时时间,即使系统重启或掉电,时间也不会丢失。通常用于日历显示、钟表、定时采集、定时开关机、时间戳、低功耗系统等场景
  3. 使用步骤为:打开电源和时钟(开启PWR电源控制模块时钟,解锁备份寄存器和RTC的访问权限,开启外部晶振或内部晶振,等待晶振准备就绪,配置RTC时钟来源,使能RTC时钟)、初始化RTC(根据频率设置异步预分频器的分频值,设置同步预分频器的分频值,设置工作模式)、设置时间和日期、读取时间。
  4. 注意事项:尽量使用外部低速晶振LSE,内部晶振精度较差;断电后需要电池供电,否则时间会丢失;RTC的预分频系数要根据晶振频率精确配置;在低功耗系统中RTC可独立运行,不受MCU主电源影响;使用RTC唤醒时,需使用RTC Alarm(闹钟)或WakeUp Timer(唤醒定时器);
  5. RTC的实现原理为:使用一个低速定时器作为时间基准,通过预分频器将时钟精确分频到1hz(即每秒一次中断);再通过计数器记录时间,使用RTC Alarm(闹钟)或WakeUp Timer(唤醒定时器)唤醒MCU,内部有BCD编码存储时分秒,有硬件校时/进位逻辑,自动处理闰年、大小月等。
  6. RTC的优点是能在掉电/低功耗模式下持续计时;功耗低,适合电池供电场景;内部集成硬件日历/闰年/大小月/报警等功能;与主MCU分离,主系统运行不影响RTC;具备定时唤醒、报警、周期中断等功能;缺点是精度受晶振影响,每个月大概有一分钟左右的误差;初始化流程较为复杂,需注意备份域解锁、时钟源配置等;不适合高频率定时任务,只适合慢速定时记录时间戳;
  7. 有软件RTC、外部RTC芯片、网络时间同步等方式达到类似获取时间的效果。

什么是TIM定时器

  1. TIM指的是定时器/计数器外设(Timer),是mcu内部的硬件模块,用于对时间进行测量、延时、周期中断、PWM产生、编码器接口、输入捕获、输出比较等功能。有三种类型定时器,分别是基本定时器、通用定时器、高级定时器。
  2. 定时器用途非常广泛,例如:周期性中断用于任务调度、采样、led闪烁等;精确的微妙/毫秒级的延时;产生pwm用来控制电机、舵机、亮度、蜂鸣器等;测量脉冲宽度、频率、周期、占空比等输入捕获;定点输出事件或生成波形;单词定时或周期性唤醒等;
  3. 定时器的使用步骤为:开启定时器时钟、设置定时器参数(定时器周期也叫自动重装载值、预分频值、分频因子、计数模式、开启定时器更新中断、启动定时器)
  4. 注意事项:高级定时器和通用定时器的时钟来源不同,开启rcc时钟的时候需要选择正确的APB1/APB2;不同型号的MCU定时器数量和通道数不同,需要参数数据手册;定时器的工作模式(单次、自动重装、边沿触发)要根据应用选择;定时精度受Prescaler(预分频器)与Period(自动重装载值)配置影响,注意溢出问题;若要使用中断,必须正确位置NVIC和清除中断标志位;基本定时器TIM6/TIM7不能用于PWM只支持定时功能;如果使用pwm功能,还需要配置输出通道和GPIO复用;
  5. 定时器的原理为:TIM定时器内部有一个预分频器(Prescaler)和计数器(CNT);每个时钟周期,预分频器先分频后才驱动计数器递增;当计数器达到设置的自动重装载值也就是周期值的时候产生更新事件并清零计数;如果启用了中断,此时更新事件也会触发中断函数;在PWM模式下,定时器控制输出引脚的高低电平切换,行成占空比可调的波形;在捕获模式下,外部信号的边沿会锁存当前计数器的值,供软件读取时间间隔。
  6. 它的优点是精度高、多功能、响应快、支持中断和DMA,缺点是配置较为复杂、资源有限
  7. 基本定时器、通用定时器、高级定时器的区别:基本定时器仅具备基本的计数和定时功能用,在系统时间基准、延时、ADC触发等场景;通用定时器支持输入捕获、输出比较、PWM、编码器接口等用在PWM控制、捕获脉冲宽度、红外信号解码等场景;高级定时器具有通用定时器的全部功能,并且增强了PWM输出(如死区控制、互补输出等),适合电机控制、互补PWM输出、死区保护等复杂场景

定时器的死区控制是什么?

  1. 死区控制是定时器高级pwm输出功能的一部分,用于在高低两路互补pwm波形之间插入一个短暂的空白时间,防止两个开关在同一个时间导通导致电源短路。
  2. 一般用于电机、电感、电源逆变器等大功率负载中防止半桥或全桥驱动电路中上下管直通,避免电源损坏。

什么是PWM

  1. PWM脉宽调制时一种通过改变方波高电平持续时间(占空比)来连续模拟信号的方法,他不是连续电压的真正模拟输出,而是通过快速开关电平,在一定周期内控制开和关的比例来实现对功率或平均电压的控制。
  2. PWM一般用在通过调节输出电压平均值控制电机的转速、LED的亮度,通过固定频率+特定占空比控制舵机转动,通过滤波后得到连续模拟波形控制音频输出、波形合成,红外通信编码,开关电源驱动等
  3. 使用pwm的步骤为:使能GPIO时钟和TIM定时器时钟、配置PWM引脚、配置TIM定时器基本参数、配置PWM(配置PWM模式、使能通道输出、设置比较值确定占空比,设置比较输出极性为高电平或低电平)、使能定时器和PWM输出。
  4. 注意事项:频率设置要根据应用选择(LED调光需要1Khz以上,不然会闪烁)。PWM输出引脚必须是支持TIM的复用功能引脚,并且要配置为AF_PP。TIM定时器选择要合适,要看是否支持PWM输出通道,是否需要死区控制等高级功能。修改占空比时只需要更新CCR寄存器即可,不需要重新初始化定时器。
  5. PWM的实现原理:PWM是通过定时器计数器和比较器配合实现的,定时器不断计数,比较器设置一个值,当计数值小于比较值的时候,输出高电平,否则低电平,在整个周期内,高电平持续始建于比较值成正比,占空比=比较值/计数最大值。平均电压=高电平电压*占空比。
  6. PWM的优点是实现简单,占用资源少(用定时器+1个引脚即可),抗干扰能力强(为数字信号),控制精度高(占空比可调),无需DAC就能实现类似模拟控制。缺点是伪模拟信号,本质还是数字输出,输出端需要RC滤波之才能得到真正平滑模拟电压。高频PWM对电磁干扰EMC比较敏感,pcb布线需要注意。
  7. 像DAC、电阻分压/可调电源、变压器+可控整流、数字电位器、运放调制等可以达到类似控制效果。

什么是SysTick

  1. SysTick是ARM Cortex-M系列内核中集成的一个系统内定时器,属于内核外设,他是一个24位递减计数器,用于生成周期性中断。
  2. SysTick通常用来作非阻塞延时、周期性任务调度和用作操作系统时基。适合精确、固定周期的中断处理。
  3. 一般裸机开发会用一个SysTick.c文件来封装初始化和延时函数,步骤如下:配置时钟源、设置重装载值也就是定时周期,清空当前计数器值,配置中断优先级,开始SysTick和中断,实现中断函数
  4. 注意事项:SysTick只有一个通道,功能简单,不适合复杂定时控制,最大计数器为24位,最大定时时间有限,它不依赖外设时钟,是内核专属模块。注意一旦启用中断,将周期性进入SysTick_Handler(),必须在里面尽量减少做事;特别注意系统若使用RTOS,SysTick通常由内核接管,不应自行再用作普通定时器。
  5. Systick是一个倒计时定时器,使用固定频率时钟源,LODA重装载寄存器设置倒计时起始值,每到一个时钟周期,VAL计数值寄存器递减。VAL计数值寄存器递减到0时,自动重装LODA重装载寄存器,产生中断请求,设置状态标志位。他是有内核直接控制的,无需外部总线时钟参与,响应速度极快。
  6. 它的优点是与CPU紧密耦合,响应快,使用方便,配置轻量,并且不依赖外设时钟。缺点是功能单一,只有一个计时器,最大支持24位,时间有限,并且不能做多路控制或捕获比较。

SysTIck和TIM的关系和区别

  1. 一个是系统定时器,一个是外设定时器。
  2. 一个是简易周期中断,用于非阻塞延时,系统时间基数。一个是多功能定时器,用在pwm、按键消抖、AD触发、DMA驱动等
  3. 一个每个芯片只有一个,一个数量丰富并且有三种子类型基本定时器、通用定时器、高级定时器

什么是状态机

  1. 状态机是一种程序结构,他将系统的行为划分为若干状态,系统在某个时刻只处于一个状态中,依据输入事件或条件转移到另一个状态,并执行对应操作,她是一种基于状态+转移+动作的逻辑控制模型。
  2. 状态机用于对系统流程控制进行建模和实现,典型应用场景包括通信协议的状态,菜单界面的状态,点击驱动控制的转动、停止、加速、减速,按键的单击、双击、长按,任意需要分阶段,条件判断的任务逻辑都属于状态机
  3. 使用状态机,一般先定义好状态变量,通过条件判断当前是那个状态再处理逻辑,逻辑处理完以后再修改状态变量的状态
  4. 注意事项:状态要设计得明确、互斥、完整。状态转移条件要清晰可靠,避免死循环或无出口状态。尽量不要在一个状态中完成太多动作,应该分阶段。保证每次进入状态时都明确初始化(比如 定时器、变量)。
  5. 状态机是控制理论中的有限自动机概念在软件中的体现,它由状态集合、输入集合、状态转移函数、动作集合组成。程序每次循环根据当前状态和输入决定下一个状态,同时执行对应动作,最终形成一个状态到输入到转移到状态的闭环模型。简化数学表达:下一个状态=状态转移函数(当前状态,输入),动作输出=动作函数(当前状态,输入)
  6. 状态机的优点是程序结构清晰,行为逻辑清楚,易于扩展和维护,非常适合嵌入式流程控制,易于可视化建模。缺点是复杂状态下写法繁琐,状态很多时容易出错,需小心转移逻辑,判断条件可能冗长,多人协作时需要严格规范命名和注释
  7. 简易逻辑流程可以用ifelse实现,复杂任务序列可以用事件驱动机制,RTOS中可以用任务切换来代替部分状态机功能

什么是上电复位POR

  1. 上电复位是指当芯片第一次接通电源时,由内部电路自动触发的一次复位操作。
  2. 作用是在电源电压还没稳定之前,强制MCU保持在复位状态,让mcu的初始化状态是干净并且稳定的。除了初始上电会自动复位,在供电不稳定的情况下瞬间掉电至电压低于mcu要求,也可能触发上电复位
  3. 上电复位是MCU内部硬件实现,用户不需要显式配置或使用。只要mcu通电系统就会执行上电复位流程,跳转到复位向量,进入Reset_Handler函数。
  4. 必须确保mcu的供电电压上升足够快、稳定,否则上电复位可能失败。
  5. 它的原理是mcu内部包含一个电压比较器+RC延时电路,当vdd上升到门限电压后,启动延时计时微秒,等待供电稳点,然后自动释放复位信号,mcu开始执行程序

什么是看门狗

  1. 看门狗是一个定时器外设,必须由程序周期性喂狗("清零")。如果超时没有喂狗,系统会自动重启。
  2. 看门狗用于检测程序是否进入死循环、卡死、异常等情况,是嵌入式系统的自我恢复机制。
  3. 使用看门狗的步骤为:初始化看门狗(允许写入、设置分频系数、设置重装载值也就是超时时间、喂狗、启动看门狗),在主循环中周期性喂狗。
  4. 注意事项:看门狗初始化后无法关闭。喂狗频率必须小于设置的超时时间,否则会复位。如果程序卡住没喂狗,系统会重启。配置的值必须合适,太短会误触发,太长就失去了保护意义。
  5. 看门狗是一个独立的定时器电路,带有复位输出,程序运行时需要不断刷新看门狗,如果没有刷新,到达设定时间,自动触发复位,mcu会回到reset状态。看门狗独立于于主时钟,运行可靠,不会因为主系统异常而失效。
  6. 看门狗的优点是可以防止系统长时间卡死或跑飞,适合无人值守系统的自愈,硬件独立,可靠性高。缺点是程序逻辑必须设计合理的喂狗,否则会误复位
  7. 有专门的外部独立硬件看门狗芯片可以替代

什么是浮点运算单元FPU

  1. FPU是一种cpu内部用于处理浮点数运算的专用硬件模块,是于主整数运算单元(ALU)并列的一个专用运算核心。
  2. FPU可以提升处理浮点运算的速度和精度。常用在密集的带数学运算的场合,如大量float或double类型变量并大量做乘法除法的程序、信号处理、滤波处理、运动控制,机器学习等场景。
  3. 使用步骤:mcu开启FPU,使用支持浮点优化的编译参数,程序中用到float或者double
  4. 注意事项:必须启动代码启动了FPU,否则浮点运算仍走软实现,效率极低,编译器必须使用正确的浮点指令选项-mfpu和-mfloat-abi
  5. 注意float(32位单精度)与double(64位双精度)有差别:M4的FPU只支持float
  6. FPU浮点运算单元室一套专门的硬件运算电路,内部包含专门的浮点寄存器组,有标准的浮点加减乘除计算模块,有专门的指令来操作浮点数据,支持中断/异常处理下的上下文保存。
  7. 优点是运算速度快,比软件浮点快10-20倍,精度高,数值范围大,可以降低mcu负载,提高系统响应能力。缺点有些芯片不带FPU,浮点计算效率差。浮点上下文切换代价高。

嵌入式系统电源管理技术

  1. 嵌入式系统的电源管理技术,是指通过硬件控制和软件相结合,降低系统功耗,提高能源效率的一系列方法和机制,主要目的是在保证功能正常的前提下,让系统尽量低功耗运行,尤其适用于电池供电设备。
  2. 电源管理技术的作用是降低整机能耗,延长电池续航时间,减少发热,提高系统可靠性。像智能手表、蓝牙耳机、物联网终端、睡眠待机占大部分时间的系统等
  3. 使用上分硬件方式和软件方式,硬件上启用MCU低功耗模式、关闭未使用的外设时钟、外设模块、降低主频、切换低速时钟源、使用RTC唤醒、GPIO中断唤醒。软件上定时进入睡眠模式(例如freeRTOS的Tickless Idle),任务调度中自动休眠空闲mcu等
  4. 注意事项,那些外设还能正常工作需要明确(如RTC、低功耗定时器等),进入低功耗模式前要关闭或挂起不必要外设,唤醒后是否要重新初始化某些外设,注意I/O引脚在低功耗状态下是否有电平保持要求(有些引脚不能悬空),高速时钟从停止中恢复有延迟,唤醒后程序需要延时等候稳定。
  5. 实现原理:电源管理通过控制mcu不同电源区域的供电状态、时钟开关和电压等级等,实现了mcu内部有专门的功耗控制模块(PWR、RCC),控制CPU、Flash、SRAM和外设的电源区分,每种低功耗模式控制有那些模块断电、时钟停止。通过中断(GPIO、RTC、USART等)触发唤醒,恢复系统运行。常见模式有Sleep(CPU停止,外设工作,低功耗恢复快)、Stop(所有时钟关闭,可选保留RTC,功耗更低)、Standby(几乎全断电,仅保留唤醒引脚/RTC,功耗极低)
  6. 电源管理技术的优点是:显著降低功耗,延长设备使用时间,硬件配合软件灵活控制,满足复杂工作场景,多种低功耗等级适配不同需求,缺点是唤醒延迟时间不同,管理复杂,需严格规划那些资源在低功耗下保留。某些外设如usb不能在低功耗模式下工作。需要开发者对MCU特性,外设电源依赖有清晰理解。
  7. 类似实现方式:外部PMIC电源管理芯片,用于多电源域设备集中管理。软件层功耗优化,如优化任务调度,控制亮屏时间,节省无线发送频率。使用超低功耗芯片如STM32L系列。用时间唤醒系统而非轮询,减少空转耗电等

什么是RTOS

  1. RTOS是实时操作系统的缩写,是一种专门为实时响应要求较高的嵌入式操作系统,与通用操作系统比,RTOS更强调在严格时间限制内完成任务,比如几十微秒内响应中断或定时控制。
  2. RTOS用来管理多个任务之间的调度、通信和资源共享。保证任务在确定的时间内完成。提供任务优先级控制、时间片、消息队列、信号量等机制。能够降低代码的复杂度,提高系统的可维护性和扩展性。通常用在工业控制、汽车电子、物联网终端、医疗设备、嵌入式GUI系统、智能硬件等场景
  3. 使用步骤:移植RTOS内核到目标工程,创建任务、启动调度器、在任务中编写业务逻辑,使用RTOS的API实现资源管理
  4. 注意事项:任务优先级要合理设置,避免在任务重使用长时间阻塞操作,注意临界区和资源竞争,使用信号量或互斥锁保护,中断服务程序中不要调用阻塞函数,系统栈要足够大,避免任务栈溢出导致卡死,高精度延时建议使用定时器而非vTaskDelay
  5. RTOS的核心原理是基于一个抢占式的多任务调度器,它会根据优先级和任务状态决定那个任务能执行。主要包括以下模块:任务管理器(维护所有任务的状态、优先级、栈等)、调度器(定期或被中断触发时进行任务切换)、中断管理(实时响应外部事件如gpio、usart、dma等)、时间管理器(实现延时、定时器等)、同步机制(互斥锁、信号量、事件组等,用于任务间协作)、内存管理(分配和释放任务堆栈、动态对象)
  6. 它的优点是:实时响应,可以保证关键任务按时执行。多任务管理,任务结构清晰,便于维护和调试。灵活扩展,功能可分模块化开发,利于团队协作。提供像延时、同步、消息队列等常用服务,开发效率高。缺点是占用一定内存资源,相对裸机系统略复杂,调试门槛高,优先级不当或任务阻塞容易导致死锁、延迟等问题。中断管理复杂,尤其是涉及中断与RTOS API混用。

什么是任务调度和任务优先级

  1. 任务调度是RTOS的核心机制之一,用于管理多个任务的执行顺序。调度器根据任务的状态(就绪、运行、挂起、阻塞等)以及任务的优先级来决定那个任务应该被CPU执行。任务优先级是指RTOS分配给每个任务的重要程度,优先级越高,越容易被调度器选中运行。
  2. 任务调度和任务优先级的作用是,保证系统在复杂任务环境下仍然有序运行,实现多任务并发执行,有限执行关键、实时性要求高的任务。自动切换任务,提高cpu利用率。
  3. 创建任务的方法里一般有优先级参数,有专门的启动任务调度器的api。
  4. 注意事项:任务优先级不能都设置成一样,否则依赖时间片轮转(非抢占式会不公平)。优先级设置要合理,关键任务大于次要任务大于背景任务。避免高优先级任务执行过长或死循环,否则系统不会执行其他任务。任务中不要频繁调用阻塞操作,可能导致调度失效。若多个任务共用资源,要配合互斥量/信号量使用,否则会导致数据更新不及时。
  5. 调度器内部核心逻辑为:RTOS维护一个任务控制块数组,每个任务对应一个任务控制块。每个任务有就绪、挂起、阻塞、运行等状态标志和优先级数值。基准时钟SysTick周期性触发调度器检查任务状态。调度器选择就绪状态中优先级最高的任务切换到CPU运行。若当前任务优先级低于新任务,则触发上下文切换。调度方式分为两种,一种是优先级高的任务可以随时中断低优先级任务的抢占式调度。一种是任务需要主动让出CPU的协作式调度。
  6. 任务调度的优点是自动多任务切换,简化系统开发。通过优先级管理,保障关键任务实时响应。灵活支持多种任务调度模型像抢占式、时间片轮转。可以提高资源利用率和系统响应速度。缺点是优先级分配不合理会造成任务饿死。调度器切换频繁会有一定开销。系统复杂性增加,任务冲突较难调试。需手动管理任务栈、调度策略、资源同步。
  7. 替代方式:裸机开发+定时器轮询,这种方式使用循环加判断手动管理任务逻辑,简单,资源占用少,但是维护较为困难,逻辑复杂后效率很低。时间片轮转机制,所有任务优先级一样,系统定时调度,适用于低实时性的要求场景。

什么是上下文切换

  1. 上下文切换是指当CPU从一个任务(线程、进程)切换到另一个任务时,需要保存当前任务的运行状态(即上下文),并加载新任务的状态,从而继续运行新任务。上下文包括:程序计数器、栈指针、R0~R15寄存器、程序状态寄存器、系统资源等。
  2. 上下文切换用在支持多任务系统中多个任务切换运行,保证任务切换后,原任务能从中断/暂停的位置继续执行。实现抢占式调度和任务优先级管理。
  3. RTOS内核会自动完成上下文切换。像任务阻塞主动让出CPU,发生SysTick中断,调用taskYIELD()强制让出CPU都会触发上下文切换。
  4. 注意事项:上下午切换开销不小,频繁切换会降低系统效率,如果任务栈配置不合理,会在切换时造成栈溢出。尽量避免频繁的中断+调度,会造成任务抖动。
  5. Cortex-M架构下的上下文切换的原理,当前任务触发切换,保存当前任务上下文,查找下一个任务,恢复新任务上下文。这个过程借助PenSV异常(软件中断)实现,是Cortex—M系列专门为RTOS准备的机制。
  6. 优点是支持多任务系统运行,实现抢占式调度,实时响应。保持任务上下文完整,切换后可无缝恢复。缺点是切换过程需要保存/恢复多个寄存器,有一定时间开销。若栈空间补助,可能引发不可预测错误。浮点运算单元较多时开销更大。频繁切换影响系统性能。

什么是FreeRTOS

  1. FreeRTOS是一个开源的,轻量级的实时操作系统内核,专门为嵌入式设备设计,支持多种主流架构,像ARM公司的Cortex-M,开源架构RISC-V等。
  2. FreeRTOS用来管理多个任务在MCU上以类似并发的方式运行。提供优先级、抢占、延时等任务调度机制。提供实时性。提供基础的操作系统功能,像互斥、信号量、队列、事件、定时器等。一般用在工控、智能硬件、物联网设备、医疗仪器、消费电子、多任务控制逻辑复杂的嵌入式产品等。
  3. 使用步骤:移植FreeRTOS(下载FreeRTOS源,配置FreeRTOSConfig.h,添加任务管理,时间管理,内存管理等源码文件,配置内核定时器SysTick的中断用于调度器Tick)、创建任务、启动调度器、在任务中编写业务逻辑、通过信号量或队列或互斥锁的方式实现夸任务数据同步机制。
  4. 注意事项:任务栈不要设太小,否则容易栈溢出,中断使用FreeRTOS API时,要用xxxFromISR()系列函数。保证中断优先级设置符合FreeRTOS要求,低优先级中断(优先级数值越大优先级越低,一般要5以上)可以调用RTOS的API。动态内存管理策略选择需要慎重,一般默认选heap_4.c。定时中断频率会影响系统负载。避免任务间资源竞争、死锁、优先级反转。启动调度器vTaskStartScheduler()后,主函数不能返回,否则程序会卡死。若使用浮点运算单元FPU,需正确配置上下文切换支持。
  5. FreeRTOS的核心机制基于以下方面
  • 调度器:管理任务运行,根据优先级+时间片决定谁执行
  • 任务控制块:每个任务对应一个结构体,保存任务栈指针、状态、优先级等。
  • 上下文切换:用PendSV异常完成寄存器保存于恢复。
  • 系统节拍:周期中断用于驱动调度器。
  • 队列/信号量:基于数据结构实现任务间通信。
  • 内存管理:支持动态/静态分配,分为heap_1~heap_5方式。
  • 抢占/非抢占:支持优先级抢占或时间片轮转。
  1. FreeRTOS的优点为:开源、轻量、占用资源少。支持多种架构、移植性强。支持任务调度、通信、同步、定时器等功能。社区活跃,资料丰富。内核可以裁剪,自定义程度高。支持低功耗。支持浮点运算单元FPU、内存保护单元MPU、多核心对称资源共享SMP、静态内存等高级特性。缺点是功能相对简单,适合中小型嵌入式项目,不提供文件系统,驱动框架等高级功能。调度算法基于优先级,较为基础,不适合大规模复杂调度。没有内核态/用户态之分,安全性有限。
  2. 有国产的RT-Thread可以替代,组件丰富,适合中大型项目。还有uC/OS、Zephyr RTOS、ThreadX等可以替代。

你最熟悉的单片机是那个系列

  • 我最熟悉的单片机是gd32系列的,因为前几年疫情的时候,单片机整个的价格涨得非常高,加上供货周期也很长,所以当时我们在做项目选型的时候就尽量用国产的,那时候相对而言GD的单片机的一个价格和供货周期都比较合适,而且又是国产的,就是技术支持也比较及时,所以当时就选用了GD单片机,一直用了几年。
  • GD32E230C8T6,批量采购的价格在1块8左右,内核是cortex-m3,主频64m,flash64k,ram8k。
  • GD32F303RET6在3块出头,内核是cortex-M4,主频可以达到120m,flash有512k,ram有64k。
  • stm32f103C8T6,主频72Mhz,flash64k,ram20k
  • stm32f407IGH6,主频168Mhz,flash1M,ram192k
  • py32f030k28u6tr,主频48Mhz,falsh64k,ram8k

常见MCU厂商及型号

  1. stm32系列,美国ST公司,生态成熟,性能丰富,资料齐全,热门型号价格较高
  2. GD32系列,中国兆易创新公司,性能接近STM32,供货可控,价格较低,文档略粗糙
  3. ESP32系列,中国乐鑫公司,自带wifi或者语音模块,性价比较高,MCU性能较强,但功耗偏高
  4. py32系列,中国普冉公司,价格较便宜,供货较稳定

什么是CMOS Sensor

  1. CMOS Sensor是一种将光信号转化为电信号的图像传感器,它是数字相机、摄像头和视觉系统重的核心器件之一。
  2. CMOS Sensor可以将光照强度转换成数字图像数据,一般用在手机摄像头、安防摄像头、车载监控、工业相机、机器视觉检测、人脸识别系统的场景
  3. 使用步骤:首先要通过数字视频接口DVP或高速串行接口MIPI连接到主控MCU、提供供电、提供时钟、配置I2C或SPI、通过数字摄像头接口DCMI或缓冲区FIFO读取图像数据、处理图像数据、通过屏幕显示等

c语言内存模型是啥样的

  1. c语言内存通常化分为5个经典区域,代码段,用来存放机器指令。静态区,主要是全局变量和静态变量。堆区,用来动态分配内存,由程序员管理。栈区,一般是一些临时变量和地址,由编译器自动管理。堆区和栈区合在一起又叫动态区。常量区,只读的字符常量或const修饰符修饰的全局数据。

c语言中的变量定义在什么地方

  1. 全局变量和静态变量定义在静态区
  2. 局部变量定义在栈区

c语言代码如何运行的

  • 预处理:将所有的头文件及宏定义替换成真正的内容。
  • 编译: 将经过预处理之后的程序转换成特定汇编代码的过程。
  • 汇编:将汇编代码转化为机器码,生成.o文件
  • 链接:将多个目标文件以及所需要的库文件链接成最终可执行文件。

什么是指针函数,什么是函数指针

  1. 函数指针是一个指针,指向函数的地址,可以用来间接的调用函数。函数指针,是一个返回值类型为指针的函数。
  2. 函数指针一般用来以赋值的方式存储别的函数。指针函数,一般用在函数返回一个指针,可以在调用函数时,用一个指针接收函数内处理过的数据。
  3. 函数指针使用int (*pfun)();pfun=fun;
  • 函数指针使用
int* get_num() {
    static int value = 42;
    return &value;
}
  1. 注意事项: 函数指针注意,函数签名必须严格匹配,返回值额参数都要一致。使用前必须初始化一个有效函数地址。指针函数注意事项:不能返回局部变量地址,若返回的是堆分配的指针,调用者需要手动free()。
  2. 两者的区别:定义不同,一个是函数,返回值是指针,一个是指针,指向的是一个函数。写法不同,指针函数和方法名不用括号括起来。函数指针和方法名要括起来。

static关键字的作用

  1. static是静态的意思,用于控制变量或者函数,只在第一次执行时初始化一次,其生命周期贯穿整个程序运行期间,下次进入函数时会保留上一次的值,而不会重新初始化。
  2. 一般用在函数内部的局部变量,使变量在函数退出后依然保留其值。也用于全局变量或函数,限制其作用域,只能在本文件中访问,可以封装模块,让模块内部的变量和函数不暴露给其他.c文件

const关键字的作用

  1. const是常量的意识,用于声明值不可被修改的变量。
  2. cosnt使用场景: 声明全局或局部只读变量。函数参数加const,让函数内部不能修改传入参数。修饰结构体、数组、字符串常量,让它们只读。修饰指针。

#define的作用

  1. #define是宏定义,是一种预处理指令,定义一个常量并赋值,在编译之前由预处理器进行文本替换这个宏变量。

extern的作用

  1. extern用来声明一个全局变量,告诉编译器,这个变量在其他地方定义过了,我这里只是引用它,不会分配内存。实际开发中,通常会在一个.c文件中定义一次全局变量。然后在一个公共.h文件中使用extern声明。所有需要使用这个变量的.c文件,都通过引用这个头文件来共享它。这个变量就在所有.c文件中都是同一个变量,共享同一份值,不会重复定义,也方便统一维护。

typedef的作用

  1. typedef是一种类型重定义关键字,用于给已有的数据类型起一个新名字。
  2. 一般用来给结构体起别名、定义标准整型类型如uint8_t、封装状态机和回调函数等

volatile的作用

  1. volatile是c语言的一个类型修饰符,意思是易变的,不稳定的,它告诉编译器,这个变量的值可能在程序的某个不可预知的时间被改变,不是由当前代码,所以每次都必须从内存读取它的值,不能优化或缓存它的内容。
  2. volatile的作用是防止编译器优化导致程序错误,保证变量每次访问都读取实际内存内容,确保硬件、中断、共享内存等交互行为的正确性。
  3. 使用方式是: volatile int flag;
  4. 注意事项: 只是防止优化,不是线程安全手段。
  5. volatile的原理是一个编译器层面的提示,其本质作用是禁止编译器对变量的访问做优化。
  6. 总结:volatile是告诉编译器,这个变量随时可能被外部改变,请不要优化它,是嵌入式开发与中断、寄存器打交道时必须使用的关键字,但它不是线程安全的万能药,不能替代或原子性保护。

c语言常用数据类型及所占字节大小

  • char 字符型 1字节 等价于int8_t

  • unsigned char 服务号字符型 1字节 0-255

  • signed char 有符号字符型 1字节 -128-127

  • short 短整型 2字节 等价于int16_t

  • unsigned short 无符号短整型 2字节 0-65536

  • int 整型 4字节 等价于int32_t

  • unsigned int 无符号整型 4字节 0-2的32次方-1

  • long 长整型 4字节 在大多数嵌入式系统中与int一样

  • unsigned long 无符号长整型 4字节

  • long long 长长整型 8字节 等价于int64_t

  • float 单精度浮点型 4字节 精度6-7位小数

  • double 双精度浮点型 8字节 精度约为15-16位小数

  • int8_t 有符号 1

  • uint8_t 无符号 1

  • int16_t 有符号 2

  • uint16_t 无符号 2

  • int32_t 有符号 4

  • uint32_t 无符号 4

  • int64_t 有符号 8

  • uint64_t 无符号 8

32位系统中指针都是4字节

Ec800M4G模块联网流程

  • 发送AT指令,判断模块是否响应,正常会发挥ok
  • 发送AT+CPIN指令,检测SIM卡
  • 发送AT+GSN指令,获取15位的IMEI号
  • 发送AT+QCCID,获取4G模块id
  • 发送AT+CSQ,查看信号强度
  • 发送AT+CREG,查看注册状态
  • 发送AT+CGATT,查询模块是否附着GPRS网络
  • 发送AT+CGDONT=1,"IP","CMNET",设置PDP上网参数
  • 发送AT+NETOPEN,打开PDP上网通道
  • 发送AT+CGPADDR指令,获取ip地址,正常会返回AT+CGPADDR
  • 发送AT+CMQTTSTART,启动MQTT协议
  • 发送AT+CMQTTACCQ=0,"client_123",0,设置客户端ID
  • 发送AT+CMQTTCONNECT=0,"tcp://your.broker.com:1883",60,1,链接服务器
  • 发送AT+CMQTTSUB=0,"/your/topic",1,订阅主题
  • 发送AT+CMQTTTOPIC=0,12,发送消息

Pid算法有那些参数

  1. 在pid算法中,有三个核心参数,分别是比例P、积分I、微分D。
  2. 比列p用来快速响应误差,提供初始调整速度。积分i用来消除稳态误差,提高控制精度。微分d用来预测误差趋势,抑制系统震荡、超调。
  3. 总结:PID控制器主要由三个参数,比列系统kp,积分系数ki,微分系数kd,它们分别负责系统的响应速度、稳态精度和抑制震荡,在工程中要合理调参,并配合限幅与滤波使用,以获得稳定可靠的控制效果。

PID算法在电机驱动中有什么作用

  1. PID算法可以使电机控制系统实现高精度、高响应性、低误差的自动控制,并快速抑制误差、超调和震荡。控制电机按设定值运行,比如控制电机以指定转速运行,控制电机移动到设定角度,在伺服电机中调节扭矩

在ADC采样光纤信号中,用排序算法,中位算法,峰值算法有什么用

  1. 排序算法可以将一组ADC采样值从小到大或从大到校排列,如冒泡排序和快速排序。峰值算法可以将一组采样数组中的最大值或最小值,用于检测突发或极值变化。中位算法用来从已排序或未排序的值中提取中间的那个数,代表典型值。
  2. 在光纤信号测量系统中,ADC连续采样会不可避免收到电源波动、光源波动、模拟电路瞬时噪声等的影响,像利用排序加峰值算法就可以剔除掉数据的一些瞬间很强或者很低的数据变化,然后用中位算法得到稳定的结果。
  3. 排序、峰值、中值算法是光纤信号ADC采样中常用的数据预处理手段,用于剔除干扰、提取稳定值或突变信号,是嵌入式系统中提高精度与可靠性的关键步骤。

线程与进程的区别

  1. 进程是操作系统中资源分配的基本单位,是一个运行中的程序,拥有独立的内存空间、文件句柄、代码段、堆、栈等资源。线程是CPU调度的基本单位,线程运行在进程中,是进程中执行代码的最小单元。多个线程共享进程的内存和文件等资源。
  2. 进程用于系统中运行不同的程序,每个进程彼此隔离,互不干扰。线程用于并发执行程序的多个子任务,提高效率。在FreeRTOS的任务其实更类似线程,共享地址空间、数据区。在Linux嵌入式开发中,即用进程也用线程,如主控程序加子模块。
  3. 在FreeRTOS中通过xTaskCreate()创建线程(任务),在Linux系统中,创建进程用fork(),创建线程用pthread_create();
  4. 注意事项:线程共享资源,需要注意同步(加锁)。进程之间不共享内存,通信要用管道、消息队列、共享内存。创建线程比创建进程轻量,但是线程崩溃可能影响整个进程。嵌入式中资源有限,线程/任务数不宜过多。FreeRTOS下线程调度方式是优先级+时间片,Linux是多级调度器。

段码屏、液晶屏(点阵lcd)、TFT彩屏、oled屏、电容屏、电阻屏的区别

  1. 段码屏,显示内容固定,有预定义段组成的液晶屏,需要背光照明,一般用在显示内容较为固定的产品上,如电子秤、体温计、遥控器、充电宝等
  2. 点阵lcd,黑白或灰阶点阵显示屏,如12864,需要背光照明,可以自定义显示内容,一般用在工业手持设备,医疗仪器、菜单操作界面等
  3. TFT彩屏,采用TFT薄膜晶体管控制每个像素的彩色液晶屏,需要背光,可以自定义显示彩色内容,一般用在智能家电,图形界面,图像/视频显示。
  4. OLED屏,由发光二极管组成的自发光像素点,不需要背光,支持彩色,一般用在智能手表、穿戴设备、工业小屏等。
  5. 电阻屏是用来检测触摸的,通过压力使上下两层膜接触判断触控位置,可以用手指/笔/手套触控
  6. 电容屏也是用来检测触摸的,利用人体电场感应,检测电容变化判断触控位置,仅支持手指或专用的电容笔触控

什么是TCP/IP

  1. TCP/IP是传输控制协议/网际协议的简称,广义上是互联网通信协议族的统称,是现代网络通信的基础。它包含了一整套用于网络通信的协议,IP用来寻址和路由,TCP提供可靠的面向连接的传输,UDP提供不可靠的无连接的传输。
  2. TCP/IP用于设备之间通过网络进行通信,管理水如何从一台设备传输到另一台设备。像使用MQTT或者是HTTP用于嵌入式设备联网,服务器和客户端程序之间进行数据交互,视频、音频、网页浏览等。

c语言动态内存分配

  1. c语言的动态内存分配,是在程序运行期间根据实际需求来动态申请、使用和释放内存,而不是在编译期就确定所有变量的内存空间。函数有malloc分配内存、free释放内存等
  2. 动态内存分配用于在运行时灵活申请内存,以适应不同的数据规模,像链表、队列等

数组、链表、栈、队列的区别

  1. 这四种都是线性数据结构,用于有序存储和管理一组元素
  • 数组,固定大小,顺序存储,支持下标访问,应用场景主要是连续数据缓存、查表、排序、
  • 链表,每个元素包含指针,动态分配,按链连接
  • 栈,后进先出
  • 队列,先进先出

c语言中堆和栈

  1. 栈是一块由编译器自动管理的内存区域,用于局部变量、函数参数、返回地址、调用栈等的存储,是后进先出的结构。
  2. 堆是一块由程序员手动管理的内存区域,用于动态分配内存malloc/free,生命周期由自己控制,不自动释放

串行和并行的区别

  1. 串行,数据是一位一位依次传输,一条线负责一位传输。例如UART、I2C、SPI等。
  2. 并行,数据多位同时传输,多个数据线同时传送,比如8个并口同时传输一个字节。例如并口屏幕等。