大疆
-
数据通信协议
常见的有SPI、I2C、UART等单线收发的通信协议,还有CAN、RS485等差分收发的协议。
总结图有空再补。 -
SPI需要几根线?工作原理?
通常需要四根线,分别是主机输出从机输入MOSI、主机输入从机输出MISO、主机输出时钟SCK和片选信号NSS,当存在多个从机时,多几个从机就需要补几根 NSS 片选信号线。
SPI定义了时钟极性CPOL和时钟相位CPHA:CPOL为0时,SCK空闲状态为低电平;CPOL为1时,SCK空闲状态为高电平。CPHA为0时,在SCK的奇数边沿进行采样;CPHA为1时,在SCK的偶数边沿进行采样。
这样,根据CPOL和CPHA的值可以定义四种运行模式(常用的是模式0和模式3):
模式 | CPOL | CPHA | 空闲电平 | 采样沿 | 触发沿 |
---|---|---|---|---|---|
0 | 0 | 0 | 低电平 | 上升沿 | 下降沿 |
1 | 0 | 1 | 低电平 | 下降沿 | 上升沿 |
2 | 1 | 0 | 高电平 | 下降沿 | 上升沿 |
3 | 1 | 1 | 高电平 | 上升沿 | 下降沿 |
SPI在对应的沿对电平进行采样,即读取该时刻的电平作为信号输出(要求此时信号稳定)。
对应的数据改变也就是触发,在相反的沿进行。(注意:模式中的采样沿都指主从设备的输入)
-
UART需要几根线,初始化配置需要配置什么?
UART不是USART,只需要Rx和Tx两根线即可进行通信,通信双方要使用相同的波特率,才能采样到正确的电平信号转换为0/1信号。以下是FPGA实现UART的时序图:
在STM32中配置UART需要配置波特率、字长、停止位数、校验位、硬件流控制以及读写功能共6个参数。通常我们选择115200bps、8位有效字长、停止位数为1、无奇偶校验位、不使用硬件流控制、同时使用读写功能。 -
UART波特率如何设置?
废话不多说直接上图:
分子的 f 是UART的时钟,一般为该UART挂载的(APB1/APB2)总线时钟。USARTDIV 是波特率寄存器中的无符号定点数:高12位为整数部分,低4位为小数部分。
当然,平时都是使用库函数配置波特率,库函数会自动算出分频系数的。 -
串口的接收和发送哪个会触发中断?
正确答案是两个都会触发中断,两个事件发生时都会使得串口的对应标志位置位并触发对应中断。不过通常使用接收中断,发送轮询的方式进行UART通信,必要时还可以配个DMA,岂不美哉。
-
中断更及时还是轮询更及时?
中断,因为一旦触发中断就进入中断服务程序,中断服务程序不完成是不会回到普通程序中,也自然不会有轮询操作。
-
中断现场保存的过程。
中断处理流程是请求中断、中断响应、保护现场、执行中断服务程序、恢复现场、中断返回。当出现优先级更高的中断时,就会进入中断嵌套。
保护现场:当出现中断时,把CPU现在的状态,也就是中断的出口程序保存在寄存器中,随后执行中断服务,当中断返回时,从寄存器中取出地址继续执行。保护现场起始就是保存中断前一刻的状态不丢失不破坏。
https://www.nowcoder.com/questionTerminal/2e85847c06684c2faeaf8728f72e5045?toCommentId=426573 -
函数调用压栈过程
在函数A中调用函数B时,首先在自己的栈帧中压入函数的返回地址,然后位函数B创建新的栈帧并压入系统栈。
函数栈帧中,首先是参数从右往左顺序入栈,然后是返回地址入栈,接着是栈帧调整:保存当前栈帧状态值、将当前帧切换到新栈帧,给新栈帧分配空间。
-
C程序分段
分为代码段、BSS段、数据段、栈和堆五个部分:
代码段: 存储二进制指令,通常是一块存储程序执行代码的内存;
BSS段:存放未初始化的全局变量和静态变量的一块内存;
数据段:存放已初始化的全局变量及静态变量;
栈:自动变量(函数内的局部变量)和数组;
堆:手动申请空间的变量。 -
全局、静态和自动变量的区别
全局变量是在所有函数体外定义的,在某文件中定义后改文件所有函数都可直接调用,外部文件通过 extern 声明后也可调用,生命周期为定义处至程序结束;
静态变量是用 static 修饰的变量,其生命周期同全局变量一致。在函数内定义的静态变量,在此进入函数时保留前次退出函数时的值;以 static 修饰的全局变量,通常不可被外部文件访问,外部文件若定义一个相同名称的全局变量,这两个变量是不一致的,编译器不会报错。
自动变量是在函数内定义的变量,其生命周期为定义处到本次函数调用结束。自动变量需要赋初值,否则为随机值、无效值,而全局、静态变量初值默认为0;
-
BootLoader启动过程
初始化处理器及外设、建立内存空间映射图、调用系统内核、跳转到用户程序。
-
MCU启动操作
A.初始化时钟;
B.关闭看门狗;
C.建立中断向量表;
D.初始化堆栈寄存器;
E.内存初始化。
-
STM32F1和F4的区别
内核不同:F1是ARM M3内核,F4是ARM M4内核;
主频不同:F1主频72MHz,F4主频168MHz;
浮点运算:F1无浮点运算单位,F4有;
功能性能:F4外设比F1丰富且功能更强大,比如GPIO翻转速率、上下拉电阻配置、ADC精度等;
内存大小:F1内部SRAM最大64K,F4有192K(112+64+16)。 -
内联函数
内联函数和宏很像,是代码被插入到调用者代码处的函数,通过编译器实现,调用时不需要像普通函数一样入栈,所以效率高。
它通过Inline进行限制。
它内部执行代码不能太多,一般不超过10行,不能有循环,不能有过多判断,也不能对内联函数取址。 -
启动文件的作用:
A.初始化堆栈指针SP
B.初始化PC指针,指向复位程序(其实就是BootLoader)
C.初始化中断向量表
D.配置系统时钟
E.调用C库函数 _main
华为
-
内联函数和宏定义的区别
A.宏是在代码处不加任何验证的简单替代,而内联函数是将代码直接插入调用处,而减少了普通函数调用时的资源消耗;
B.宏定义在预处理阶段进行替换(预处理器处理),内联函数在编译阶段进行替换(编译器处理);
C.内联函数在运行时可调试,宏定义不行;
D.编译器会对内联函数的参数类型做安全检查或自动类型转换,宏定义不会;
E.内联函数可以访问类的成员变量,宏定义不能; -
进程间通信方式
管道、FIFO、消息队列、信号量、共享存储、套接字