寒武纪2019秋招嵌入式软件开发笔试-牛客网刷题

2023-05-02 15:59:44 浏览数 (2)

寒武纪2019秋招嵌入式软件开发岗笔试

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

我答的:单片机的IO口可以配置为开漏输出和推挽输出两种模式,它们的主要区别在于输出方式和驱动能力不同。 开漏输出是指输出器件(通常是晶体管)的集电极被接到一个共用的开漏端上,输出时只能拉低电平,而不能提供高电平,因此需要外部上拉电阻来使输出变为高电平。这种输出方式适用于多个器件共用同一条信号线的情况,如I2C总线。 推挽输出则是指在输出器件中使用两个相反极性的晶体管,既可以拉高电平也可以拉低电平,因此不需要外部上拉电阻,具备较强的驱动能力。这种输出方式适用于需要直接驱动负载的情况,如LED灯、继电器等。 因此,选择开漏输出还是推挽输出应根据具体情况而定。

2. 单片机里定时器有什么作用和优势?

我答:定时器是单片机中常见的一个模块,它可以计算时间并产生定时中断,具有如下作用和优势:

  1. 计时功能:定时器可以通过内部晶振或外部时钟源计算时间,实现程序的精确延时或周期性操作,并且不占用CPU资源。
  2. 定时中断功能:定时器可以产生定时中断,当计数器达到预设值时,向CPU发出中断请求,从而及时处理需要周期性执行的任务,提高系统的效率和可靠性。
  3. PWM波形生成:定时器可以生成PWM(脉冲宽度调制)波形,用于控制电机、LED灯等模块的亮度、速度等参数。
  4. 频率测量:定时器也可以作为频率计的基础模块,通过计算输入信号的脉冲数来测量其频率。
  5. 外设驱动:定时器还可以用来产生各种时序信号,驱动其他外围设备(如LCD屏幕、蜂鸣器等)的工作。

综上所述,定时器的作用和优势在于提供精确的计时和定时中断功能,实现一系列应用,减少CPU负担,提高系统效率和稳定性。

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

我答的:Nyquist采样定理指出,对于一个带限信号,为了能够完全恢复其原始信息,采样频率必须大于或等于信号最高频率的两倍。也就是说,如果信号带宽为B,则采样频率Fs至少要大于2B。

根据题目中给出的条件,需要分析的信号频率范围为200Hz-10kHz,因此信号带宽为B=10kHz-200Hz=9800Hz。为了满足频谱分辨率不低于40Hz的要求,可以使用512点FFT算法进行频谱分析,每个频率点之间的间隔为Fs/N,其中N为FFT的长度,即N=512。将40Hz代入上式,得到采样频率应当大于或等于2*40Hz = 80Hz。

所以,为了满足以上条件,采样频率应该在大于等于80Hz的范围内选择,一般选用稍微高于最小要求的采样频率,例如100Hz或更高的采样频率。

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

我答的:ADC的最小分辨率取决于其位数,对于12位ADC而言,它的电压分辨率为:

代码语言:javascript复制
Vref / (2^12) = 3V / 4096 ≈ 0.732mV

其中Vref为ADC的基准电压,2^12表示12位二进制数所能表示的数量。

因此,单片机内置12位精度的ADC采样的电压最小分辨率为0.732mV。

如果单片机ADC输入口电压为1V,则将该电压值代入ADC转换公式中,得到:

代码语言:javascript复制
ADC值 = 1V / 3.3V × 2^12 ≈ 1221

即ADC值约为1221。注意,由于ADC的量化误差和噪声等原因,实际采样值可能会存在一定误差,需要根据具体应用情况进行相应的处理。

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

我答的:同步通信和异步通信的主要区别在于通信双方时钟同步的方式,具体如下:

  • 同步通信:通信双方使用相同的时钟信号进行同步,在发送数据之前需要建立好时钟同步关系。常见的同步通信方式包括SPI、I2S等。
  • 异步通信:通信双方不使用相同的时钟信号进行同步,而是通过使用一组特定的起始位和停止位来确认每个字符的传输开始和结束。常见的异步通信方式包括UART、RS232等。

UART属于异步通信方式,它以固定的波特率(包括110、300、1200、2400、4800、9600、19200、38400、57600、115200等)进行通信;

SPI属于同步通信方式,并采用了全双工模式,在数据传输时同时可以读写数据;

I2C也属于同步通信方式,并采用了半双工模式,在通信时需要先发送一个从设备地址,在收到从设备的应答后再发送数据。

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

我答的:通过I2C接口读取设备X的寄存器Y的值的过程一般分为以下几个步骤:

  1. 发送起始信号:主控制器向总线发送一个起始信号,通知所有设备开始通信。
  2. 发送设备地址:主控制器将设备X的地址发送到总线上,并指定读取操作。设备地址是由7位二进制数组成,最高位为0,其余6位为设备的固定地址。
  3. 等待应答:主控制器在发送完设备地址后会等待从设备对其发出应答信号,确认设备已经正确接收了地址信息。
  4. 发送寄存器地址:主控制器将要读取的寄存器地址Y发送到设备X,告诉设备需要读取哪个寄存器的值。
  5. 等待应答:主控制器再次等待从设备对其发出应答信号,确认设备已经正确接收了寄存器地址信息。
  6. 读取寄存器值:主控制器向设备发送读取请求,并从设备上读取出寄存器Y的值。
  7. 发送停止信号:主控制器在完成读取操作后,向总线发送一个停止信号,通知所有设备结束通信。

以上就是通过I2C接口读取设备X的寄存器Y的值的基本过程,需要注意的是,在进行I2C通信时,不同设备的地址和寄存器定义可能会有所不同,需要根据具体情况进行相应的调整。

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

我答的:中断是指在程序执行过程中,当发生某个事件或条件满足时,系统暂停正在执行的程序,并转而去处理与该事件有关的任务。它可以提高单片机的响应速度和工作效率,常用于处理外设数据、实现多任务并发等。

单片机中断处理的过程一般包括以下几个步骤:

  1. 中断请求:当一个外部事件被触发时(如按键按下、定时器溢出等),相关的中断请求线会被拉低,向单片机发送中断请求信号。
  2. 中断允许:单片机内部有一个中断使能寄存器,通过设置该寄存器的相应位,可以决定是否允许处理来自外部的中断请求。如果中断使能被禁止,则即使产生了中断请求,也无法进入中断服务程序。
  3. 中断响应:当CPU检测到中断请求信号后,它会立即暂停当前任务,并跳转到中断服务程序的起始地址处执行。
  4. 中断处理:中断服务程序是专门设计用来处理中断请求的代码段,它会根据不同的中断源进行相应的数据处理和操作,将中断处理结果保存在相应寄存器中,并在完成处理后恢复程序执行状态。
  5. 中断返回:中断服务程序在处理完中断请求后,需要使用一条特殊指令(如RET或RETI)返回到原来的程序执行状态,继续运行未完成的任务。

以上就是单片机中断处理的基本过程,需要注意的是,中断服务程序需要尽可能快地完成中断处理,并尽量避免引入额外的延迟和负载,以保证系统的稳定性和可靠性。

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

我答的:相比于正常子函数,中断服务函数具有以下几个特点:

  1. 特殊调用方式:中断服务函数是由硬件自动调用的,在程序执行过程中会暂停当前任务并跳转到中断服务函数的入口处执行,因此需要注意函数的参数传递、返回值等问题。
  2. 临界区限制:中断服务函数在执行过程中,可能会与其他中断服务函数产生冲突,因此需要保证代码段的可重入性和线程安全性。一般采用禁止中断、关键段保护等方式来实现。
  3. 时间限制:中断服务函数的执行时间一般较短,需要尽可能快地完成中断处理,并尽量避免耗时操作,以保证系统的实时性和响应速度。

需要注意的地方包括:

  1. 中断优先级:不同的中断源可能会产生多个中断请求,需要根据中断优先级来确定哪一个中断服务函数应该优先执行。一般优先级越高的中断服务函数,其响应时间越短,优先级越低的中断服务函数,则需要等待前面的中断服务函数执行完后再进行响应。
  2. 栈空间:中断服务函数需要使用栈空间来保存上下文环境,但是栈空间有限,如果栈溢出,会导致严重的程序崩溃和数据丢失等问题。因此需要合理分配栈空间,并注意栈溢出的情况。
  3. 共享资源:不同中断服务函数可能会共享同一些资源,如全局变量、计时器等,在处理这些资源时需要采取相应的互斥保护措施,以避免产生竞态条件和死锁等问题。

总之,中断服务函数的设计需要考虑到许多因素,包括可重入性、响应时间、中断优先级、栈空间、共享资源等等,需要仔细分析设备的需求和性能要求,并进行相应的优化和调整。

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

我答的:将a的bit 6置1的代码:

代码语言:javascript复制
a |= (1 << 6);

将a的bit 6置0的代码:

代码语言:javascript复制
a &= ~(1 << 6);

以上两行代码中,<< 表示左移运算符,<< 6 表示将二进制数 1 左移 6 位,得到一个只有第 7 位为 1 的二进制数。而 ~ 表示按位取反运算符,~(1 << 6) 表示将左移后得到的二进制数按位取反,即只有第 7 位为 0,其他位均为 1 的二进制数。于是,对 a 进行或运算或与运算即可将其第 7 位设置为 1 或 0。

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

代码语言:javascript复制
输入:”255.255.255.255”
输出:255 255 255 255 (数组) 

我答的:以下是将IP地址字符串转换为int型整数数组的示例代码:

代码语言:javascript复制
#include <stdio.h>
#include <string.h>

int main()
{
    char str[] = "255.255.255.255";
    int nums[4];
    int i, j;
    char *token;

    token = strtok(str, ".");
    for (i = 0; i < 4; i  )
    {
        nums[i] = atoi(token);
        token = strtok(NULL, ".");
    }

    // 输出结果
    for (j = 0; j < 4; j  )
    {
        printf("%d ", nums[j]);
    }
    printf("n");

    return 0;
}

其中,strtok 函数用于将输入的字符串按照指定的分隔符 “.” 进行分割,得到四段子串,每一段子串对应一个 IP 地址中的数字部分。而 atoi 函数则可以将字符串转换为整数类型。

最后将得到的四个整数存储在 nums 数组中,并依次输出即可。

0 人点赞