0%

嵌入式笔试题笔记

寒武纪笔试题

  1. 单片机IO口开漏输出和推挽输出有什么区别?

    开漏输出:只能输出低电平,如果要输出高电平必须通过上拉电阻才能实现。就类似于三极管的集电极输出。

推挽输出:推挽输出既可以输出低电平,也可以输出高电平,可以直接驱动功耗不大的数字器件。导通损耗小、效率高、既提高电路的负载能力,又提高开关速度

补充

  • 上拉&下拉输出电阻作用: 防止输入端悬空,减少外部电流对芯片的干扰,限流,增加高电平输出时的驱动能力。
  • 浮空输入:IO的电平是不确定的,有外部输入决定。多用于外部按键。
  • 模拟输入: 即关闭施密特触发器,将电压信号传送到片上外设模块(不接上下拉电阻)。
  1. 单片机里定时器有什么作用和优势?

    作用:计数器、延时、输入捕获(解码和测量时间间隔)、输出比较(主要输出PWM波)、单脉冲输出、触发中断(对其他模块进行操作)

    优势:不需要CPU参与,精确

  1. 什么是Nyquist采样定理?如果需要通过512点FFT分析200-10KHz信号频谱,频谱分辨率不低于40Hz,此时采样频率需在什么范围?

    ​ 频率分辨率可以理解为在使用DFT时,在频率轴上的所能得到的最小频率间隔f0=fs/N=1/NTs=1/T,其中N为 采样点数,fs为采样频率,Ts为采样间隔。所以采样频率不低于20480hz.与采样频率的不低于20000hz综 合得不低于20480hz (做不来、也没看懂解析)

  1. 已知单片机内置12位精度的ADC,单片机工作电压3.3V,ADC基准电压3V,请计算ADC采样的电压最小分辨率是多少?如果单片机ADC输入口电压为1V,则采样得到的值是多少?

    ​ 3.3/4096 V 4096/3.3(自己的答案)

    ​ 3/4096 v 1365(4096/3)(评论区答案)

  1. 同步通信和异步通信有什么区别?UART、SPI和I2C分别属于什么类型的通信方式?

    ​ 同步通信: 发送端与接收端时钟频率一致。 逐字符发送,无间隙。通信效率高。

    ​ 异步通信: 不要求接收端时钟和发送端时钟同步。 需要有起始位和停止位,传输效率较低。

    ​ UART:异步通信。

    ​ SPI:同步通信。

    ​ I2C:同步通信

  1. 简述通过I2C接口读取设备X的寄存器Y的值的过程

    发送i2c开始信号-发送设备x的地址-等待设备应答-发送寄存器Y的地址-等待应答-发送i2c开始信号-发送设备X的读地址-等待设备应答-接收寄存器Y的数据-等待应答-停止i2c

  1. 中断是什么?请简述单片机中断处理的过程

    中断: CPU在正常执行程序的过程中,由于内部/外部事件的触发或程序的预先安排引起CPU暂时中断当前正在运行的程序,而转去执行中断服务子程序,待中断服务子程序执行完毕后,CPU继续执行原来的程序

    中断处理的过程:

    ​ 第一步:保护现场,将当前位置的PC地址压栈;

    ​ 第二步:跳转到中断服务程序,执行中断服务程序;

    ​ 第三步:恢复现场,将栈顶的值回送给PC;
    ​ 第四步:跳转到被中断的位置开始执行下一个指令;

  1. 相比于正常子函数,中断服务函数有什么特点和需要注意的地方?

    ​ 无返回值、不能向中断服务函数传递参数、短小、需要快进快出、不能递归调用自身

  1. 对于char型变量 a,写两段代码分别将 a的 bit 6置1和置0

    ​ a| = (a<<6);

    ​ a& = ~(a<<6);

  1. 请写一段代码,可以将输入为”0.0.0.0”—“255.255.255.255”的字符串转换为int型整数数组。

    输入:”255.255.255.255”

    输出:255 255 255 255 (数组)

    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
    26
    27
    28
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>

    int main(void)
    {
    char ch[20];
    int num[20],len = 0,count = 0;

    scanf("%s", ch);
    len = strlen(ch);
    printf("%d\n", len);
    for (size_t i = 0; i < len; i++)
    {
    if (ch[i] == '.')
    {
    count++;
    continue;
    }
    num[count] *= 10;
    num[count] += (ch[i] - '0');
    }
    for (size_t i = 0; i < 4; i++)
    {
    printf("%d ", num[i]);
    }
    }

-------------THE END-------------

欢迎关注我的其它发布渠道