首页 > 嵌入式八股 - ARM体系结构二
头像
渴望wlb的柯基很安静
发布于 昨天 16:56 北京
+ 关注

嵌入式八股 - ARM体系结构二

11、什么叫上升沿和下降沿触发

  • 上升沿触发:信号从低电平跳变为高电平时触发事件(如中断、采样)。
  • 下降沿触发:信号从高电平跳变为低电平时触发事件。

12、数码管扫描频率?共阴极和共阳极的区别?

通常来说扫描频率需≥50Hz,这是由于人眼的视觉暂留,如果低于这个频率,你会明显感觉到屏幕在闪烁,长时间观看容易疲劳。推荐 100Hz 左右。

  • 共阴极与共阳极区别
  • 共阴极:所有段选引脚接 LED 阳极,公共端接 GND,段选高电平点亮。
  • 共阳极:所有段选引脚接 LED 阴极,公共端接 VCC,段选低电平点亮。

13.ADC采样位数代表什么?什么因素影响ADC精度和转换速率?有什么滤波算法?

  • 采样位数

表示 ADC 能将模拟量转换为数字量的精度,如 12 位 ADC 的分辨率为1/(2^12) = 1/4096,即最小可区分Vref/4096的电压变化(Vref 为参考电压)。

  • 影响 ADC 精度和速率的因素
  • 精度:参考电压稳定性、输入噪声、非线性误差、温度漂移
  • 速率:ADC 时钟频率、转换位数(位数越高,速率通常越低)、采样时间
  • 滤波算法
  • 软件滤波:滑动平均、中位值滤波、限幅滤波(适合低速采样)
  • 硬件滤波:RC 低通滤波(滤除高频噪声)

14.中断如何设置?中断中任务过多有什么危害?

  • 中断设置步骤(以 STM32 为例):
  • 使能中断控制器(NVIC)对应通道;
  • 配置触发源;
  • 编写中断服务程序(ISR),处理核心逻辑。
  • 中断中任务过多的危害
  • 中断响应延迟:阻塞其他高优先级中断,导致实时性下降
  • 栈溢出风险:ISR 中执行复杂操作(如大量局部变量、函数调用)可能耗尽栈空间
  • 数据一致性问题:长时间占用中断可能导致主程序与 ISR 共享数据更新不及时

原则:ISR 应 快进快出,仅处理紧急操作,复杂逻辑放到主程序。

15.波特率是什么?

比特率:每秒钟传送的比特数量,又称为传信率。比特率基本单位为bit/s或bps。

波特率:每秒钟传送的符号(码元)数量,又称为传码率,单位是波特(Baud、B,即symbol/s)

16.串口通信起始位如何判定?i2c总线仲裁?

  • 串口起始位判定:UART 通信中,空闲状态为高电平,当检测到一个持续 1 位时间的低电平时,判定为起始位,随后开始接收数据位。
  • I2C 总线仲裁:当多主设备同时发送数据时,通过 “线与” 逻辑仲裁
  • 若某设备发送高电平,而检测到总线为低电平,则该设备退出仲裁(失去总线控制权);
  • 最终只有一个设备能继续占用总线,保证数据传输不冲突。

17、IIC 速率

IIC协议定义了多种数据传输速率标准,以适应不同的应用需求。以下是IIC协议的主要数据传输速率标准:

  • 标准模式(S) :速率为100 kbps。
  • 快速模式(F) :速率为400 kbps。
  • 高速模式(HS) :速率为3.4 Mbps。
  • 超高速模式 :速率为5 Mbps。

18、中断函数可不可以有参数、返回值,在中断中可以进行 printf 函数打印吗?

中断服务函数注意的四大点:

  • 中断服务函数不能传入参数;
  • 中断服务函数不能有返回值;
  • 中断服务函数应该做的短小精悍
  • 不推荐在中断服务函数中使用printf函数,printf函数可能会引入较大的代码体积和运行时开销,而在中断服务中不应该执行过多复杂操作,以免影响实时性和系统性能。

19、I2C、SPI、UART 发送高低位

  • I2C先发送数据最高位,就像我们写数一样(这里面只有这个协议读法含有数字)
  • SPI可配置
  • UART 先发送数据最低位

20、手敲IIC

(我遇到过两回面试手敲IIC。)

这个一般面试官会给你说明一下,然后你可以按照说明进行编写。其实不需要太严谨,只要大致思路、流程正确即可。

重点分为起始、传送(读\写)、停止、等待应答。

(下面是直接找的,可以参考下,网上有很多,大致思路、流程正确即可)

/*-------------------------------------------------*/
/*函数名:IIC起始信号                              */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Start(void)
{
	SDA_OUT();     //SDA线输出模式
  IIC_SDA_H;	   //SDA拉高  
	IIC_SCL_H;     //SCL拉高	  
	Delay_Us(4);   //延时
 	IIC_SDA_L;     //SCL高电平的时候,SDA由高到低,起始信号
}
/*-------------------------------------------------*/
/*函数名:IIC停止信号                              */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Stop(void)
{
	SDA_OUT();     //SDA线输出模式
	IIC_SDA_L;     //SDA拉低
	IIC_SCL_H;     //SCL拉高
 	Delay_Us(4);   //延时
	IIC_SDA_H;     //SCL高电平的时候,SDA由低到高,发出停止信号					   	
}
/*-------------------------------------------------*/
/*函数名:等待应答                                 */
/*参  数:无                                       */
/*返回值:0:成功  1:失败                         */
/*-------------------------------------------------*/
char IIC_Wait_Ack(void)
{
	unsigned char timeout=0; //定义一个变量,用于计算超时时间
	
	IIC_SDA_H;	             //SDA拉高
	SDA_IN();                //SDA线输入模式 
	IIC_SCL_H;	             //SCL拉高
	 
	while(READ_SDA){         //等待SDA变低电平,表示应答到来,不然一直while循环,直到超时	
		timeout++;           //超时计数+1
		if(timeout>250){     //如果大于250	
			IIC_Stop();      //发送停止信号
			return 1;        //返回1,表示失败
		}
		Delay_Us(2);         //延时
	}
	IIC_SCL_L;               //SCL拉低
	Delay_Us(20);            //延时	
	return 0;                //返回0,表示成功
} 	

/*-------------------------------------------------*/
/*函数名:读取一个字节                             */
/*参  数:ack:是否发送应答 1:发 0:不发           */
/*返回值:读取的数据                               */
/*-------------------------------------------------*/   
unsigned char IIC_Read_Byte(unsigned char ack)
{
	unsigned char i;           //定义一个变量用于for循环 
	unsigned char receive;     //定义一个变量用于保存接收到的数据
		
	receive = 0;               //清除receive,准备接收数据
	SDA_IN();                  //SDA设置为输入
    IIC_SCL_L;                 //SCL拉低
    Delay_Us(20);               //延时	
	for(i=0;i<8;i++){          //for循环,一位一位的读取	 
		IIC_SCL_H;             //SCL拉高 
		Delay_Us(20);           //延时
        receive<<=1;           //左移一位,准备下次的读取
        if(READ_SDA)receive++; //读取数据
		Delay_Us(20);           //延时
		IIC_SCL_L;             //SCL拉低  
		Delay_Us(20);           //延时 		
    }					 
    if(!ack){        //不需要发送
		SDA_OUT();   //SDA线输出模式 
		IIC_SDA_H;   //时钟脉冲的高电平期间保持稳定的高电平
		IIC_SCL_H;   //SCL拉高
		Delay_Us(2); //延时
		IIC_SCL_L;   //SCL拉低 
	}else{           //需要发送
		SDA_OUT();   //SDA线输出模式 
		IIC_SDA_L;   //时钟脉冲的高电平期间保持稳定的低电平
		IIC_SCL_H;   //SCL拉高
		Delay_Us(2); //延时
		IIC_SCL_L;   //SCL拉低
		IIC_SDA_H;   //SDA拉高
	}
    return receive;
}

全部评论

(1) 回帖
加载中...
话题 回帖

近期热帖

热门推荐