资讯详情

【国六总结】蓝桥杯复习资料(含外设代码)

瞎叨叨

好消息十三届国赛300元买了3XL抹布! 这一次是套路,真的不需要扩展版,但是调试麻烦。 今年是参加蓝桥杯的最后一年,走出考场??快板挂小黄鱼,出去搓一顿。 其实这个资料是省赛前自己写的。不幸的是,今年没有参加扩展版的外设考试。如果你来找扩展版的外设,你可以Ctrl W下一篇。

客观题

好像官方有一本书,上面有客观题,不清楚。 这个东西基本靠平时的积累,考前不可能完全突击。以下是十二届前总结的一些客观题。

STM32相关

0.有些问题的答案可以直接回答Cube或者在手册中找; 1.RS至少需要232通信根线; 2.STM32提供的是哈佛结构的流水线; 3.STM32不支持数据类型; 4.STM32内部ADC工作原理是; 5.不属于串行通信; 6.RS逻辑1电平电压在232通信中 ; 8.根据总线传输的信息类型,嵌入式系统可分为等; 9.菊花链连接的接口是; 10.使用STM32开发USB外设应使用时钟源; 11.Cortex-M小端格式访问代码可用于3中; 12.存储芯片的存储容量为8KB,数据线根,地址线根(8KB = 8 * 1024Byte = 2 ^ 13); 13.STM32F103RBT6每个DMA通道具有事件标志; 14.功能简单但需要频繁调用的函数更适用; 15.STM32片内FLASH可以写一次位; 16.RS485最少需要通信根线; 17.不是一般嵌入式系统设计的主要目标; 18.ARM处理器有工作模式; 19.常用于用二进制数表示十进制数 BCD 编码; 20.Unicode 编码可用于表示汉字; 21.ASCII共128个字符; 22.STM32 微控制器 USART1 波特率通过PCLK2提供; 23.优先级中断位编辑(0x00~0xFF -> 0000 ~ 1111); 24.Cortex M3 支持系列处理器 Thumb-II 指令集 25.Cortex M3 读写操作可以支持单个比特位的操作 26.在 STM32 一个处理器 DMA 请求,至少占用个周期的 CPU 访问系统总线时间; 27.STM32 处理器 APB2 上的 IO 引脚最大翻转速度为; 28.USB通信速率 RS232; 29.Cortex-M3处理器中的寄存器R14代表,R15代表; 30.NAND FLASH存储器和 NOR FLASH存储器的区别在于; 31.Corte-M3有同时只能调用一个堆栈; 32.可以触发 STM32 微控制器复位; 33.外设分为,内核外设有; 34.

大部分数电模电

1.数字时序逻辑电路输出有关; 2.能够实现线与的是; 3.当温度升高时,二极管的反向饱和电流会升高; 4.设计一个8421BCD至少需要代码计数器触发器; 5.高阻抗信号源和低阻抗负载间适合接入阻抗匹配; 6.将三角波转换为矩形波需要使用; 7.将矩形波输入积分电路可获得; 8.场效应管导电阻 有关; 9.N 在由触发器组成的计数器中,最有效的状态个; 10.为了提高电压比较器的抗干扰能力,应选择; 11. 两个电压放大倍数相同(电路相同,晶体管相同) A 和 B 在负载开路的条件下,放大同一信号源的电压并测量电路 A 电路输出电压小,不考虑仪器的测量误差,说明 A 电路; 12. RLC 串联电路谐振频率为=当频率为1000时, 800Hz 激励正弦电压源时,电路呈现; 13. 信号用确定的时间函数来描述; 14. 由 5 个 D 由触发器组成的环形计数器的计数长度为; 15. 在数字电路中,三极管相当于开关,通常工作状态; 16. 如果两个逻辑函数是恒定的,它们必须是唯一的; 17. 没有压电效应的滤波器; 18. 脉冲波形常用于施密特触发器; 19. 运算放大器; 20. 单个操作放大器和多个电阻不能构成; 21. 分析操作放大器的基础是 ; 22. 三态门的输出状态包括:; 23.

三极管

工作参数计算

I C M I_{CM} ICM​:集电极最大允许电流; P C M P_{CM} PCM​:集电极最大允许功率, P C = I C ∗ U C E P_{C}=I_C*U_{CE} PC​=IC​∗UCE​; U ( B R ) C E O U_{(BR)CEO} U(BR)CEO​:反向击穿电压, U C E > U ( B R ) C E O U_{CE}>U_{(BR)CEO} UCE​>U(BR)CEO​会导致 I C I_C IC​急剧增大,三极管烧毁; 例题: 例题 题目给了四组参数,没有任何一组 U C E U_{CE} UCE​过大,但B选项 I C I_C IC​过大,先选上;然后开始计算剩下各组 P C P_{C} PC​,C选项120mW大于最大功率,故答案选BC。

工作状态判断

对于NPN型三极管 放大区: U C > U B > U E U_C>U_B>U_E UC​>UB​>UE​,发射结正偏,集电结反偏; 截止区: U B < U C , U B < U E U_B<U_C, U_B<U_E UB​<UC​,UB​<UE​,发射结和集电结反偏; 饱和区: U C E < U B E U_{CE}<U_{BE} UCE​<UBE​,发射结和集电结正偏; 三极管用作开关管时,通常工作在。 例题: A选项明显符合放大区要求,B选项在截止区,C选项在饱和区,D选项注意负号,实际也是在放大区,答案选AD。

运算放大器

首先是虚短和虚断的概念。简单说,虚短就是运放工作在线性区时,两输入端可被视为等电位(实际并不能物理短路两输入端);虚断是由于理想运放输入电阻无穷大,所以几乎没有电流流入运放输入端,可以被视作断路。

最常规的例1

根据虚短,反相输入端电流全部流过80K反馈电阻,可以对红色箭头所指节点应用KCL, 0.1 V 10 K + 0.2 V 10 K = U O 80 K \frac{0.1V}{10K} + \frac{0.2V}{10K} = \frac{U_{O}}{80K} 10K0.1V​+10K0.2V​=80KUO​​,最后算出 U O = 2.4 V U_O = 2.4V UO​=2.4V,反向输入端加上负号,故答案是-2.4V。

挖了大坑的例2

有些题目会强调单电源供电,此时结果就不符合上面的公式了。例题: 正常思路,前面是同向电压跟随器,后面是反向放大器,算出来-4V,选C。但这个题强调了是DC 12V,所以不选C,选D。Multisim仿真结果是1.36V,具体咋算我也不大清楚(祈祷别出个这玩意儿给你算吧🙏)。

还能这样玩的例3

带RC电路的题目,需要计算上限/下限频率。例题: RC电路截止频率 f = 1 / ( 2 π R C ) f=1/(2{\pi}RC) f=1/(2πRC),其中电容C的单位为法拉F。对于这个题,先换算电容单位,10uF=10^-6F=0.00001F,带入公式计算,约为159.155Hz,按题目要求取整,答案为159Hz。放大倍数 = - 10K / 100 = -100,答案为-100倍。

我看不懂但大受震撼的例4

还有一种差分减法器,如题: 这个就只有问百度了,真考到听天由命🙏

十三届第一场省赛的例5

写这部分的的时候是2022年5月8日,离第二场省赛好像还有6天。因为看不懂一个多月前写的虚短虚断是啥玩意儿,于是把第一场省赛的题拿来分析一遍。 先说仿真结果,3V。 然后再来分析,如下图: 前一个部分,典型的电压跟随器,输出电压(蓝色节点)为+1V。后半部分,由运放虚短可知,绿色节点电压与正向端输入电压相等,应为+2V;由运放虚断,可提出题目下面的那个手绘模型,接下来对绿色节点用KCL就解出来了:流出电流1mA,流入也应为1mA,红色节点电压应为绿色电压+I*R=+3V,分析完毕。

外设代码

HAL库还是LL库?

个人认为,评测系统中的一个指标是代码大小。在用HAL库狠凹第一套模拟题之后,各项功能已经是1:1复刻官方参考答案了,但仍只有89.2分(官方LL库答案98.2分),据此猜测代码大小也是评分指标之一,当然也只是猜测。之后我也尝试用LL库编写程序,但奈何水平不够,各个功能整合起来之后稳定性不如HAL库,以后有机会一定好好学学LL库。

FPU

相传在MDK的options for target的target选项卡下可以直接设置,但还是感觉用宏定义更安心一点,反正也费不了一分钟。在模拟测评中开不开对分数没有影响。

//MDK->Options for Target->C/C++->Define
__FPU_USED=1U,__TARGET_FPU_VFP,ARM_MATH_CM4

LED

LED部分最简单的操作方法就是操作ODR寄存器,有两种方法,在模拟评测系统上分数是一样的,但方法二更直观一些,临场不容易写错+易分析,故优先采用方法2。寄存器内容参考RM0440参考手册(英文手册实际上也没那么难看懂,至少GPIO部分不会有很多很多专业词+生僻词)。

//方法一:按位运算得到ODR的值
uint8_t code = 0x00;	//注意两个方法初始code恰好相反

void LED_SetStatus(uint8_t status, uint8_t serial)
{ 
        
	if(status == LED_ON)
	{ 
        
		code = code | (0x01 << (serial - 1));
		GPIOC->ODR = ~(code << 8);
	}
	else if(status == LED_OFF)
	{ 
        
		uint8_t temp = ~code;
		temp = temp | (0x01 << (serial -1));
		code = ~temp;
		GPIOC->ODR = (temp << 8);
	}
	else
	{ 
        
		code = 0x00;
		GPIOC->ODR = (0xFF << 8);
	}
	
	HAL_GPIO_WritePin(LE_GPIO_Port, LE_Pin, GPIO_PIN_SET);
	HAL_GPIO_WritePin(LE_GPIO_Port, LE_Pin, GPIO_PIN_RESET);
}

//方法二:操作BSRR控制ODR
void LED_SetStatus(uint8_t serial, uint8_t status)
{ 
        
	if(status == LED_ON)
	{ 
        
		GPIOC->ODR = code << 8;
		GPIOC->BSRR = 0x01 << (23 + serial);	//Set BRx
		code = GPIOC->ODR >> 8;
	}
	else if(status == LED_OFF)
	{ 
        
		GPIOC->ODR = code << 8;
		GPIOC->BSRR = 0x01 << (7 + serial);	//Set BSx
		code = GPIOC->ODR >> 8;
	}
	else
	{ 
        
		code = 0xFF;
		GPIOC->ODR = (code << 8);
	}
	
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);
}

按键

实现方案很多,还有用定时中断检测按键的(这个试了试效果不是很稳定,就弃了,也可能是我写的姿势不对)。除了写的这个方法,还可以用读IDR实现。经实验,分数也是没差别。长短按?省赛没写,国赛也不是用自己电脑,就简单说个思路吧:用1ms(1KHz)的定时器中断数数,判断是长按还是短按。

uint8_t KEY_CheckStatus(void)
{ 
        
	keyPressed = 0;
	
	if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)
	{ 
        
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_RESET)
		{ 
        
			keyPressed = 1;
		}
	}
	if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)
	{ 
        
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_RESET)
		{ 
        
			keyPressed = 2;
		}
	}
	if(HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET)
	{ 
        
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(KEY3_GPIO_Port, KEY3_Pin) == GPIO_PIN_RESET)
		{ 
        
			keyPressed = 3;
		}
	}
	if(HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == GPIO_PIN_RESET)
	{ 
        
		HAL_Delay(10);
		if(HAL_GPIO_ReadPin(KEY4_GPIO_Port, KEY4_Pin) == GPIO_PIN_RESET)
		{ 
        
			keyPressed = 4;
		}
	}
	
	if(keyPressed != keyPrevious)	//检测与上次按键是否相同
	{ 
        
		keyPrevious = keyPressed;		//不同则代表是第一次检测到,更新上次键值
	}
	else
	{ 
        
		keyPressed = 0;		//相同则代表之前已经检测过了,按下键值返回0
	}
	
	return keyPressed;
}

UART

一步登顶,直接DMA+空闲中断,省得纠结。

void UART_Init(void)
{ 
        
	__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huart1, rxBuf, sizeof(rxBuf));
}

void UART_IRQHandler(UART_HandleTypeDef *huart)	//记得添加到it文件里
{ 
        
	if(huart->Instance == USART1)	//串口1中断,如果是扔对应IRQHandler里的话这个if实际上没必要
	{ 
        
		if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)	//串口1空闲
		{ 
        
			HAL_UART_DMAStop(&huart1);
			uint8_t lenMsgReceived = sizeof(rxBuf) - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
			memcpy(rxDest, rxBuf, lenMsgReceived);	//copy数据,不在中断里处理数据
			memset(rxBuf, 0x00, sizeof(rxBuf));
			rxFlag = 1;
			
			__HAL_UART_CLEAR_IDLEFLAG(&huart1);
			HAL_UART_Receive_DMA(&huart1, rxBuf, sizeof 

标签: 三极管bc546to100uf100v分频器电容

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台