嵌入式随笔
嵌入式期末复习
概述
嵌入式系统是一种专用计算机,可靠性要求高,但是不一定体积小,功耗低
嵌入式系统三要素:嵌入性、专用性、计算机(没有实时性)
嵌入式系统软硬件可以裁剪,针对需求定制
Cortex-M3
采用的架构是ARMv7
ADC的位数指标指的是其数字输出的二进制位数
处理器寄存器R0-R12 通用寄存器
R13堆栈指针寄存器
R14寄存器是链接寄存器
R15程序计数器
CM3有两种堆栈模式,可以分别对应特权模式和非特权模式,而不能同时使用4个堆栈
CM3既提供了小端存储模式,也提供了大端存储模式
Cortex-M3体系架构中,有了位带位操作后,可以使用普通的加载/存储指令来对单一的比特进行读写
STM32F103 最高运行频率只有72MHz
德州仪器生产的是ARM,而不是STM32,STM32是意法半导体生产的
ARM采用的是RISC架构(简单指令集)既可以有32位,也可以有64位
X86采用的是CISC架构(复杂指令集)
IO、定时器、RCC
GPIO(通用输入/输出)引脚的内部微弱的上拉和下拉电阻是在引脚被配置为输入(Input)模式时使用的。这些内部上拉和下拉电阻用于确保输入引脚有一个稳定的逻辑级别,防止输入悬空导致的不确定状态。
当引脚被配置为输出(Output)模式时,它们是由外部电路驱动的,因此不需要内部的上拉或下拉电阻。
推挽(Push-pull)和开漏(Open-drain)是输出模式的两种类型,它们描述的是输出引脚的电气行为,而不是与内部上拉或下拉电阻的激活直接相关。
外设的时钟频率并不是都一样的,可能有APB或者AHB时钟驱动,导致其不同于系统核心时钟(HCLK)
STM32的所有端口都具有中断能力,当使用外部中断线时,相应引脚要配置成输入模式
对于通用定时器TIMx,其工作模式包括:输入捕获、PWM输入模式、PWM输出模式、定时计数模式、单脉冲模式
CM3内核支持256个中断,16个内核中断,240个外部中断,并且拥有256级的可编程中断设置。
中断屏蔽器可以屏蔽 除了NMI外所有异常和中断
当“TIMx_CR1.ARPE = 1”的时候,STM32中有自动重装载寄存器和预加载寄存器(TIMx_ARR)。
STM32提供了三种不同的时钟源,其都可被用来驱动系统时钟SYSCLK,这三种时钟源分别为(HSI、HSE、PLL)
时钟(Clock)是时序逻辑的基础,用于触发逻辑单元状态的更新,具有特定频率。
STM32中通用定时器的时基单元包括:计数器寄存器、预分频器寄存器、自动装载寄存器
通讯接口
RS232C
RS232C串口通讯中,波特率是指每秒传输的位数
USART
使能USART1时钟 USART1EN=1
设置波特率USART BRR {...}=115200
1个起始位 CR1 M=0,8个数据位
偶校验 CR1 PS=0
发送接收使能 CR1 TE=RE=1
USART中断 RXNE(或TC) CR1 RXNEIE=1(或 TCIE=1)
整个USART模块使能 CR1 UE=1
清除中断为 SR TC=0
1个停止位 CR2 STOP=b00
禁止硬件流控制 CR3 CTSE=RTSE=0
I2C
IIC总线包括两根线:SCL(控制线)SDA(数据线)
从机应答主机所需要的时钟仍是主机提供的
SPI
SPI双线双向模式:SPI_CR1 BIDIMODE=0
设置SPI为主SPI模式: SPI_CR1 MSTR=1
设置发送数据大小、帧结构:SPI_CR1 SPI_DFF=0
空闲状态时,SCK保持低电平:CR_1 CPOL=0
数据捕获,从时钟n边缘开始 CR_1 CPHA=n-1
启用软件从设备:CR_1 SSM=1
控制波特率 CR_1 BR=000
发送第一个数据 LSBFIRST=0
CRC多项寄存器:CRCPOLY=7
使能SPI2: SPE=1;
CS控制片选信号,WR控制读写信号,SCK时钟信号
//发送数据同时接收数据的样例
u8 sndRecv(u8 data){
CS=0;
u8 tmp;
delay_us(1);
for(i=0;i>i;i++){
SCK(CLK)=0;//输出(MOSI)
//然后读取data最高位是否有数据
if(data&0x80)
WR=0;
data=data<<1;//数据左移一位
delay_us(1);
SCK=1;//读取(MiSO)
tmp=tmp<<1;//左移一位,用来放数据
tmp|= T_IN_STATUE//tmp接收
//这里的T_IN_STATUE 其实是宏定义中的获取的数据
//宏定义中PA6为MISO,GPIOA->IDR&0x40(0b0100 0000)?1:0
delay_us(1);
}
return tmp;
}
练习
-
嵌入式系统是指对可靠性、成本、体积、功耗有严格要求,专业性较强,以应用为中心的专用计算机系统
前台:通常处理高优先级任务,如响应时效性高的外部事件(常常由硬件中断触发
后台:处理低优先级或者不急迫的任务。这些任务在没有中断时执行,通常是系统主循环中的一部分
-
//前台中断 void Tim1ms_IRQ(){ handle_1ms_event()//1ms事件 int count_10ms=0; while(++count_10ms==10){ handle_10ms_event();//10ms事件 count_10ms=0; } //100ms同理 } //后台循环 void main(){ while(1){ action1(); } }
-
CPU处理能力、功耗大小、成本大小、体系结构、对外设、OS、开发工具的支持、可靠性、可用性
-
非实时系统:windows、embeded、linux
实时系统:RT-Linux
微控制:Free RTOS
刷道题,旁边有点吵
ID:560
暴力 O(n^2)
超时答案:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int n=nums.size();
int i=0;
int res=0;
int sum;
while(i<n){
if(i==n-1){
if(nums[i]==k){
res++;
}
break;
}
int j=i+1;
int sum=nums[i];
if(sum==k)res++;
while(j<n){
sum+=nums[j];
if(sum==k)res++;
j++;
}
i++;
}
//if(sum==k)res++;
return res;
}
};
提示:使用前缀和
...看完提示写,用前缀和还是超时...
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int n=nums.size();
int i=0;
int res=0;
int sum;
vector<int> pre;
pre.push_back(0);
while(i<n){
pre.push_back(pre[i]+nums[i]);
int j=i;
while(j>=0){
if(pre[i+1]-pre[j]==k)res++;
j--;
}
i++;
}
return res;
}
};
官方题解:
用前缀和的同时用哈希表...这样第二轮循环可以不用,因为可以直接find(pre-k)
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int, int> mp;
mp[0] = 1;
int count = 0, pre = 0;
for (auto& x:nums) {
pre += x;
if (mp.find(pre - k) != mp.end()) {
count += mp[pre - k];
}
mp[pre]++;
}
return count;
}
};
考完发的博客,结束!
稳了!