1、讲一下STM32时钟系统
时钟系统类似于脉搏,控制着CPU的命脉,STM32的时钟源又不像51的时钟源那么单一,因为STM32的MCU较为复杂,且外设较多,并不是所有的外设都需要那么高的时钟频率,而且较高的频率对功耗和抗干扰都不具优势,所以对复杂的MCU系统往往采取多个时钟源,STM32有5个时钟源,HSI、HSE、PLL(这三个往往作为系统时钟)、LSI(外部看门狗时钟)、LSE(STC时钟源)。
2、c语言中堆和栈的区别
1、数据结构上:
- 都是一种数据项按序排列的数据结构。
- 栈:一种具有先进后出性质的数据结构
- 堆:堆是一种经过排序的树形数据结构、通常我们所说的堆的数据结构,是指二叉堆、虽然存储有序,但是我们取值是可以任意的。
2、申请与释放方式
- 栈:系统自动分配空间,生命周期在函数运行期间,运行结束便被系统回收
- 堆:程序员手动分配,如果不手动释放,所占用空间将一直存在
3、申请效率
- 栈:由系统自动分配,速度较快。但程序员是无法控制的。
- 堆:是由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
4、申请空间大小限制:
- 栈:栈是向低地址扩展的数据结构,是一块连续的内存的区域,这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的
- 堆:堆的大小一般看内存的大小。
5、存放信息
- 栈: 在函数调用时,第一个进栈的是主函数中函数调用后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。 - 堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排
3、假如一个单片机上电之后不运行?这是为什么?
- 检查晶振工作是否正常
- 检测EA脚是否拉低。单片机EA引脚表示存取外部程序代码之意,低电平动作,当此引脚接低电平后,系统会取用外部的程序代码(存于外部EPROM中)来执行程序。EA引脚必须接低电平,因为其内部无程序存储器空间。
4、精度和分辨率有什么区别
像数字化的温度传感器,一般精度指的是传感器读回的数据与绝对温度的差值,而分辨率指的是传感器能感知的最小温度变化。
5、你来说一下中断的处理流程是什么样子的?
- 中断响应:设置程序断点,并将断点地址压入栈进行保护,接着将程序转到中断服务程序的入口地址。
- 中断处理:从中断服务程序的第一条指令开始执行直到返回指令为止。
- 中断返回:中断处理程序的最后一条指令是中断返回指令RETI,该指令的作用将断点地址从栈中弹出,程序继续从断点地址开始执行
6、中断的优点
- 实时性
- 充分利用系统资源,提高CPU效率
7、讲一下grep的作用
查找相应文件中符合条件的字符串
8、I2C的开始信号、I2C配置主机模式端口该怎么配置
- 开始信号: SCL为高电平期间,SDA由高电平向低电平进行跳边,产生开始信号。
- 主机模式端口的配置:
-
硬件模式:端口设置为复用模式,复用为I2C、开漏输出、既不上拉也不下拉。
void I2C1_GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_I2C1);
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_I2C1);
}
- 软件模拟:设置普通输出模式,推挽输出、配置上拉电阻
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
IIC_SCL=1;
IIC_SDA=1;
}
9、讲一下extern的作用
-
声明外部变量
-
在C++文件中调用C方式编译的函数
extern "C" {
... C++可以重定义,而C中没有重定义
}
10、讲一下static的作用
- 函数内部的变量值保持不变
- 模块内、函数外的变量,模块内的任意函数都能使用,但模块外的函数无法调用
- 定义在模块内的函数,模块外无法调用。、
11、讲解下GPIO是什么,有几种模式
- GPIO就是通用的输入输出端口
- 有8中模式:4输入(上拉输入、下拉输入、浮空输入、模拟输入)、4输出(推挽输出、开漏输出、复用推挽输出、复用开漏输出)
12、进程通信的方法
- 管道
- FIFO
- 消息队列
- 信号量
- 共享内存
13、MQTT与HTTP的区别
- MQTT以数据为中心,传输量小、速度快
- HTTP以文本为中心,传输量大,速度较慢
- 两个都是基于TCP(传输层之上的),都是属于应用层的协议,MQTT协议一般采取明文传送,而HTTP可以采用HTTPS进行加密。
14、MQTT的消息类型有哪些
- 连接
- 发布
- 订阅
- 订阅确认
- 取消订阅
15、STM32-ADC配置
- 引脚配置
- 使能引脚时钟与ADC时钟
- 设置端口为模拟输入,不带上下拉电阻
- 设置ADC的通用控制寄存器CCR
- 设置ADC的采样模式-独立模式
- 设置ADC的分频系数
- 初始化ADC参数
- 设置ADC的分辨率
- 转换方式 - 关闭连续转换模式
- 设置对齐方式 - 右对齐
- 开启AD转换器
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_CommonInitStructure.ADC_TwoSamplingDelay =
ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitStructure.ADC_DMAAccessMode =
ADC_DMAAccessMode_Disabled;
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStructure);
ADC_Cmd(ADC1, ENABLE);
}
u16 Get_Adc(u8 ch)
{
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
ADC_SoftwareStartConv(ADC1);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
return ADC_GetConversionValue(ADC1);
}
u16 Get_Adc_Average(u8 ch,u8 times)
{
u32 temp_val=0; u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch); delay_ms(5);
}
return temp_val/times;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)