《嵌入式系统开发》期末复习资料
《嵌入式系统开发》期末复习资料集
一、单项选择题
以下选项中不属于嵌入式系统的是( )
A. 手机
B. 微波炉
C. 笔记本电脑
D. B型超声诊断仪ARM Cortex-M3 内核采用的是( )架构。
A. CISC
B. RISC
C. 混合架构
D. 以上都不是STM32 微控制器开发中,Keil 是一种常用的( )。
A. 硬件开发板
B. 开发平台
C. 编程语言
D. 调试工具STM32 最小系统不包括以下哪个电路( )。
A. 电源电路
B. 网络电路
C. 时钟电路
D. 复位电路嵌入式 C 语言中,用于定义常量的关键字是( )。
A. const
B. static
C. volatile
D. externGPIO 在嵌入式系统中的作用是( )。
A. 通用输入/输出接口
B. 串口通信接口
C. 中断控制接口
D. 显示控制接口STM32F103 引脚图中,引脚的功能( )。
A. 固定不变
B. 可以通过编程配置
C. 只能作为输入
D. 只能作为输出在 STM32 编程中,"#ifdef DEBUG"预处理指令的作用是?
A. 定义调试宏"DEBUG"
B. 条件编译,仅在定义 DEBUG 时编译后续代码
C. 禁止编译器优化代码
D. 声明调试函数中断处理流程不包括以下哪个步骤( )。
A. 中断请求
B. 中断响应
C. 中断屏蔽
D. 中断返回STM32 中断优先级设置机制中,优先级数值越小表示( )。
A. 优先级越高
B. 优先级越低
C. 与优先级无关
D. 以上都不对串口接收时,判断是否接收到新的数据,应该判断哪一个标志位( )
A. RXE
B. TXE
C. RXNE
D. TC以下哪种不是 STM32 的启动模式( )。
A. 主闪存存储器启动
B. 系统存储器启动
C. SRAM 启动
D. 外部存储器启动在嵌入式 C 语言中,若定义数组
int arr[5] = {1, 2, 3, 4, 5};,则arr[2]的值为( )。
A. 1
B. 2
C. 3
D. 4异步串行通信中,起始位的作用是( )。
A. 表示数据传输的开始
B. 校验数据
C. 同步时钟
D. 表示数据传输的结束在 STM32 开发中,使用标准外设库时,初始化 GPIO 引脚的函数一般在( )文件中。
A. stm32f10x.h
B. stm32f10x_gpio.c
C. main.c
D. stm32f10x_rcc.c异步串行通信(UART)中,数据传输的基本单位是?
A. 字节(Byte)
B. 帧(Frame)
C. 数据包(Packet)
D. 字符(Character)在 ARM 存储系统中,对于 32 位数据 0x12345678,采用大端模式存储在地址 0x00000000 开始的内存中,地址 0x00000003 存储的字节是( )。
A. 0x12
B. 0x34
C. 0x56
D. 0x78若异步串行通信的波特率为 9600bps,每个字符包含 1 个起始位、8 个数据位、1 个奇偶校验位和 2 个停止位,则每秒最多能传输的字符数是( )。
A. 800
B. 960
C. 1200
D. 1600假设某流水线处理器有 3 个阶段,每个阶段执行时间分别为 2ns、3ns、2ns,执行 10 条指令的吞吐率( )执行 20 条指令的吞吐率。
A. 大于
B. 小于
C. 等于
D. 无法确定STM32 的 DMA1 控制器有( )个通道?
A. 4
B. 5
C. 6
D. 7以下关于 DMA 的描述,正确的是( )
A. DMA 必须通过 CPU 才能完成数据传输
B. DMA 可以在不占用 CPU 的情况下完成内存与外设间的数据传输
C. DMA 只能用于内存到内存的数据复制
D. DMA 会显著降低系统的整体性能在嵌入式 C 语言中,若定义数组
int arr[5] = {1, 2, 3, 4, 5};,则arr[2]的值为( )。
A. 1
B. 2
C. 3
D. 4以下哪个选项可以用作数字信号处理( )
A. MCU
B. MPU
C. DSP
D. FPGA以下哪个选项是上拉输入模式( )
A. GPIO_Mode_IPD
B. GPIO_Mode_AIN
C. GPIO_Mode_AF_PP
D. GPIO_Mode_IPUUART 双机通信中,设备 1 的 RXD 应该连接到设备 2 的( )引脚上。
A. RXD
B. TXD
C. GND
D. VCC
二、填空题
1.STM32 时钟系统中,通过 PLL(锁相环) 可将时钟源进行倍频。
2.CISC 和 RISC 架构中,CISC 架构指令集更复杂。
3.抢占优先级总是 高于 响应优先级。
4.嵌入式 C 语言中,const 关键字用于声明变量在内存中的地址不会被意外改变。
本题考察嵌入式C语言中用于限制变量内存地址不被意外改变的关键字。在C语言中,const关键字的核心作用之一是声明只读变量,即变量的值(对应内存中的数据)不能被修改,而从内存地址的角度来看,由于const变量通常被存储在只读存储区(如ROM)或被编译器限制修改权限,其内存地址自然不会被意外改变。其他关键字如volatile用于表示变量可能被外部修改,static用于静态存储,auto用于自动存储,均不涉及地址不可变的特性。因此,符合题意的关键字是const。
5.某流水线有 4 个阶段,各阶段执行时间分别为 2ns、3ns、4ns、2ns,其流水线周期为 4 ns。
6.在 ARM 存储系统的大端模式下,对于 16 位数据 0x1234,存放在地址 0x2000 开始的内存中,地址 0x2000 存储的字节是 0x12 。
7.一个完整的 DMA 传输过程包括 DMA 请求、DMA 响应 、DMA 传输、DMA 结束。
8.异步串行通信中,波特率为 2400bps,每个字符包含 1 个起始位、7 个数据位、1 个奇偶校验位和 1 个停止位,每秒能传输的字符数为 240 个。
9.STM32 开发中,常见的开发模式有 基于寄存器开发 、基于标准外设库开发和基于 HAL 库开发。
10.ARM 存储系统的小端模式下,地址 0x3000 存储 32 位数据 0x5678ABCD,地址 0x3003 存储的字节是 0x56 。
11.异步串行通信的数据帧格式由起始位、数据位、奇偶校验位 和停止位构成。
12.STM32 的中断优先级分 抢占优先级 和 响应优先级 两类优先级。
三、简答题
1.简述嵌入式 C 中 volatile 关键词。
答:在嵌入式C语言中,volatile关键字用于告诉编译器,变量的值可能在程序未明确指定的情况下发生改变,因此编译器不应该对这个变量进行优化。这通常用于处理硬件寄存器、中断服务程序、多线程环境等场景,确保变量的最新值被正确读取和使用。
2.简述中断优先级的判断原则。
答:CPU正在执行的中断服务程序不能被同级或低级优先级中断请求中断。 CPU正在执行的中断服务程序可以被高级优先级中断请求中断,实现中断嵌套。 CPU同时接收到几个中断请求时,首先响应优先级最高的中断请求。
3.简述 DMA 的工作原理。
答:DMA(即直接内存访问)既是一种数据传输技术,又是微控制器的一种片上外设,它允许外部设备(如硬盘、网卡)不通过CPU,直接与系统内存进行数据交换。其本质是通过硬件组成的直接数据通路,实现I/O设备与内存之间的成组数据快速传输,特别适用于高速I/O设备。相比于中断方式,DMA 方式不需要像中断处理方式那样保留现场、恢复现场,而是由 DMA 控制器直接控制,这样节省了 CPU 资源,提高了传输效率。
4.根据 STM32 的命名规则,芯片 STM32F103ZET6 中各符号代表什么含义?
答:STM32 代表 ARM Cortex-M3 内核的 32 位微控制器,ST 为意法半导体,M 为微控制器的缩写,32代表是 32 位的芯片,F 代表芯片的系列为基础级,103 为增强型系列为主流入门级,Z 表示此芯片有 144管脚,E 表示具有 512KB 的 Flash,T 表示此芯片采用 LQFP 封装,6 表示芯片工作温度范围为-40~+85℃。
5.从作用、要求、属性和目的几个角度,简述嵌入式 C 中 const 关键字。
答:①作用:将变量声明为 只读,防止其值在程序运行时被意外修改;②要求: 必须在声明时进行初始化、不能出现在赋值语句的左边;属性:值是不可变的只读属性;目的:节省 RAM(将数据存储在 Flash/ROM 中)、提高代码健壮性和安全性、增强代码的可读性和可维护性。
6.分别简述 GPIO 的几种输入输出模式。
答:输入模式:模拟输入、浮空输入、上拉输入、下拉输入模式;输出模式:推挽输出、开漏输出、复用推挽输出、复用开漏输出模式。
7.计算机体系结构主要有冯·诺依曼结构与哈佛结构,请简述其区别?
答:冯·诺依曼结构采用指令和数据统一存储,使用同一套总线传输;哈佛结构将程序指令存储和数据存储分开,使用不同的总线传输指令和数据。冯·诺依曼结构简单、成本低,但存在总线冲突;哈佛结构运行效率高,但结构复杂、成本高。
8.简述 CMSIS 标准。
答:CMSIS是ARM公司为Cortex系列微控制器制定的软件接口标准。它提供了一种统一的接口,使得软件开发人员可以更容易地在不同的Cortex-M系列微控制器之间移植代码。
四、计算题
1.现有一个三级指令流水线分为取指、分析和执行三个部分,其中,取指周期为 1ns,分析指令周期为 3ns,执行指令周期为 2ns,则完成 100 条指令其吞吐率为多少?
解:由题可知,T取指=1ns,T分析=3ns,T执行=2ns,指令条数N=100条,则
流水线周期取决于所有阶段中最慢的阶段的执行时间T流=Max(T取指,T分析,T执行)=Max(1ns,3ns,2ns)=3ns;
完成第一条指令执行时间需要T完=(T取指+T分析+T执行)=1ns+3ns+2ns=6ns;
完成100条指令所需的时间T总=T完+(N-1)×T流=6+(100-1)×3=303ns;
计算吞吐率,带入数值得:\begin{aligned} T_{吞} &= \frac N T_{总}\\ &=\frac{100}{303}{\rm 条/ns} \end{aligned}
2.串口通信中,某字符速率为 800 字符/秒,若每个字符包含 1 个起始位,8 个数据位,1 位校验位,2 个停止位。在传输序列中,每个字符帧前后各有 4 位空闲位,空闲位不计入字符帧的有效传送位中。波特率为?已知系统时钟为 36MHz,USART_BRR 控制器设置的数值是?
解:由题中可知,每个字符的有效位 = 起始 1 + 数据 8 + 校验 1 + 停止 2 = 12 位/字符。(空闲位不计入,这里不加那 8 位空闲位。)
又因为字符速率 800 字符/秒 ,则 比特率(波特率) = 800 × 12 = 9600 bit/s = 9600 Baud.
用系统时钟 f_clk = 36 MHz 计算 USARTDIV:USARTDIV = f_clk / baud = 36,000,000 / 9,600 = 3,750.0。
对应 STM32(过采样16倍)的 BRR 写法:Mantissa(整数部分) = 3750,Fraction(小数部分) = 0.0×16=0 →
BRR(十进制数) = 3750 × 16 = 60,000。
BRR(十六进制)= 0xEA60。(十进制转十六进制通过除16取余法实现)
3.在异步串行通信中,每个字符由 1 个起始位、8 个数据位、0 个校验位和 1 个停止位组成。若通信波特率为 38400bps,计算每秒钟最多能传输多少个字符?
解:由题中所给的已知条件,总位数=起始位+数据位+校验位+停止位=1+8+0+1=10 位/字符;
波特率表示“每秒传输的位数”,即 38400 位/秒。所以:
4.假设选定的中断优先级分组为二分组,即抢占优先级占两位,响应优先级占两位。在执行常规程序时,来了中断 a(2,3)[注意:在这里指抢占优先级为 2,响应优先级为 3,下同],打断了当前的常规程序,形成第一次中断嵌套,在执行中断 a 时,来了中断 b(2,0),在执行 b 时,又来了 c(3,3)、d(3,2)、e(1,0)、f(3,2)。请问哪些中断会形成中断嵌套?最后的总体执行顺序是什么?请画图展示。
解:(1)a 打断常规程序(嵌套 1);e 打断 b(嵌套 2)。
(2)总体执行顺序:a → e → b → d → f → c。
(3)

五、编程题(会在程序段中随机设置填空)
1.GPIO 流水灯
// led.h 文件:
#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"
void LED_Init(void);
#endif
// led.c 文件:
#include "led.h"
void LED_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOF, &GPIO_InitStructure);
}
// main.c 文件:
#include "stm32f10x.h"
#include "led.h"
void Delay(__IO u32 nCount)
{
for(; nCount !=0; nCount--);
}
int main(void)
{
LED_Init();
while(1)
{
GPIO_SetBits(GPIOB, GPIO_Pin_5);
Delay(720000);
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
Delay(720000);
GPIO_Write(GPIOF, ~0x0001);
Delay(720000);
GPIO_Write(GPIOF, ~0x0002);
Delay(720000);
GPIO_Write(GPIOF, ~0x0004);
Delay(720000);
GPIO_Write(GPIOF, ~0x0008);
Delay(720000);
GPIO_Write(GPIOF, ~0x0010);
Delay(720000);
GPIO_Write(GPIOF, ~0x0020);
Delay(720000);
}
}
2.中断编程代码
// exti_key.h 文件:
#ifndef __EXTI_KEY_H
#define __EXTI_KEY_H
#include "stm32f10x.h"
void EXTI_Key_Init(void);
#endif
// exti_key.c 文件:
#include "exti_key.h"
#include "misc.h"
void EXTI_Key_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOE,&GPIO_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line3);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
// main.c 文件:
#include "stm32f10x.h"
#include "led.h"
#include "exti_key.h"
int main(void)
{
LED_Init();
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
EXTI_Key_Init();
while(1)
{
}
}
// 中断服务函数:
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
GPIO_WriteBit(GPIOB,GPIO_Pin_5,(BitAction)((1-GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5))));
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
// 另外一种中断处理程序,实现 LED灯翻转
uint8_t led =1;
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
led = ~led; //状态翻转
//如果等于 1,则 PB5 复位点亮,否则置 1熄灭
if(led == 1)
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
else
GPIO_SetBits(GPIOB,GPIO_Pin_5);
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除 EXTI3的中断标志位
}
3.串口代码
// USART初始化头文件 USART_Init_Config.h,代码如下:
#ifndef __USART_INIT_CONFIG_H
#define __USART_INIT_CONFIG_H
#include "stm32f10x.h"
void USART_Init_Config(void);
#endif
// USART初始化程序 USART_Init_Config.c 文件:
#include <stdio.h>
#include "USART_Init_Config.h"
void USART_Init_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//开启 GPIOA和 USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);
//USART1_TX,设置 PA9为复用输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX,设置 PA10 为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1参数配置
USART_InitStructure.USART_BaudRate = 115200; //设置波特率为 115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位占 8 位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止位
USART_InitStructure.USART_Parity = USART_Parity_No; //无校验
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure); //初始化串口 1
USART_Cmd(USART1, ENABLE); //使能串口 1
}
// 主程序 main.c文件,代码如下:
#include "stm32f10x.h"
#include <stdio.h>
#include "led.h"
#include "USART_Init_Config.h"
int main(void)
{
LED_Init();
USART_Init_Config();
char Temp;
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))
{
USART_ClearFlag(USART1,USART_FLAG_TC);
Temp = USART_ReceiveData(USART1);
USART_SendData(USART1,Temp);
USART_ClearFlag(USART1,USART_FLAG_RXNE);
}
}
}
// 另一种实现方式:
int main(void)
{
while(1)
{
if(USART_GetFlagStatus(USART1,USART_IT_RXNE) == SET)
{
ch = USART_ReceiveData(USART1); //接收数据
USART_SendData(USART1,ch); //发送数据
//循环等待发送完毕
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) != SET);
}
}
}
- 感谢你赐予我前进的力量

