18级嵌入式系统复习提纲
第1讲 STM32F4体系结构
1、嵌入式系统的概念
以应用为中心、以计算机技术为基础、软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统。
2、了解ARM体系结构的演变进程
1991年开始共推出7个版本,V1~V3未用于商业授权。V4T开始商业授权,T表示16位Thumb指令,ARM7TDMI,冯诺依曼结构,三级流水线,0.9MIPS/MHz。V5增强ARM和Thumb指令切换的支持,增加了DSP指令支持(后缀E)、Java支持(后缀J)V6版增强DSP和多媒体处理指令,增加SIMD指令扩展,对音、视频处理性能有极大提升,Thumb-2指令。2004年发布V7版,ARM首次为其体系结构命名,命名为Cortex,分为A(应用)、R(实时)、M(微控制器)三个系列
3、掌握STM32F4的时钟树:有哪几个时钟源、特点,正点原子战舰开发板时钟配置
5个时钟源
LSI:低速内部时钟,RC 振荡器,频率为 32kHz 左右。供独立看门狗、RTC、自动唤醒单元使用
LSE:低速外部时钟,接频率为32.768kHz 的石英晶体。主要是 RTC 的时钟源
HSI:高速内部时钟,RC 振荡器,频率为 16MHz。可以直接作为系统时钟或者用作 PLL输入
HSE:高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围4MHz~26MHz。开发板接8M晶振。HSE也可以直接做为系统时钟或者 PLL 输入。
PLL:锁相环倍频输出 。主 PLL:由 HSE 或者 HSI 提供时钟信号,并具有两个不同的输出时钟。PLLP:生成高速的系统时钟(最高168MHz)PLLQ:生成 USB OTG FS 的时钟(48MHz)、随机数发生器的时钟和 SDIO时钟。专用 PLL(PLLI2S):生成精确时钟,从而在 I2S 接口实现高品质音频性能
4、时钟相关函数在哪个.h和.c文件定义(其他模块同样),时钟源使能函数、外设时钟使能函数(要知道哪个外设挂在哪个总线上,截图打印下来参考)、时钟源选择函数,分频因子配置函数,外设复位函数
文件:stm32f4xx_rcc.h、stm32f4xx_rcc.c
时钟源使能函数:
void RCC_HSICmd(FunctionalState NewState); void RCC_LSICmd(FunctionalState NewState); void RCC_PLLCmd(FunctionalState NewState); void RCC_PLLI2SCmd(FunctionalState NewState); void RCC_PLLSAICmd(FunctionalState NewState); void RCC_RTCCLKCmd(FunctionalState NewState);
外设时钟使能函数:
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
使能:ENABLE.失能:DISABLE
时钟源选择函数:
void RCC_HSEConfig(uint8_t RCC_HSE); void RCC_LSEConfig(uint8_t RCC_LSE); void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ);//分频因子配置 void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);//系统时钟源选择 void RCC_HCLKConfig(uint32_t RCC_SYSCLK); void RCC_PCLK1Config(uint32_t RCC_HCLK);//外设(APB1)配置 RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);//设置系统时钟源为HSI RCC_PCLK1Config(RCC_HCLK_Div2);//设置APB1时钟为HCLK的2分频
外设复位函数:
void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_APB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState);
状态参数获取清除函数
uint8_t RCC_GetSYSCLKSource(void); void RCC_GetClocksFreq(RCC_ClocksTypeDef*RCC_Clocks); FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG); void RCC_ClearFlag(void);
5、ARM存储空间,大端排序、小端排序
A:SRAM或外设地址;AliasAddr:别名地址
n:位序号,若A为字节地址,则n为0…7,若A为字地址,则n为0…31
#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr,bitnum) MEM_ADDR(BITBAND(addr,bitnum))
第2讲 GPIO
1、STM32F4ZGT6共有多少组多少位GPIO(其他资源也同样,比如有多少USART,这个知识点后面就不单独列了)
7组16位IO端口(GPIOAGPIOG,PAPG)
1组2位端口GPIOH(GPIOH.0/PH0、GPIOH.1/PH1)
7×16+2=114
2、GPIO的工作方式、特点
4种输入模式
浮空输入:输出关闭,上下拉关闭
上拉输入:下拉电阻关闭,上拉电阻打开。无输入时,默认高电平。
下拉输入:上拉电阻关闭,下拉电阻打开。无输入时,默认低电平。
模拟输入:一定是浮空输入,不能上下拉。
4种输出模式
开漏输出、推挽式输出、开漏复用功能、推挽式复用功能(均可上、下拉)
上电复位后,GPIO默认为浮空状态(上下拉电阻都不加),部分特殊功能引脚为特定状态。
推挽输出:可以输出强高、低电平,连接数字器件
开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)
复用输出:数据来自复用外设的输出脚
3、打开相应GPIO的时钟(其他资源同样要求,后面不单独列出)
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
4、GPIO相关寄存器的作用
端口模式寄存器(GPIOx_MODER)、端口输出类型寄存器(GPIOx_OTYPER)、端口输出速度寄存器(GPIOx_OSPEEDR)、端口上拉下拉寄存器(GPIOx_PUPDR)、端口输入数据寄存器(GPIOx_IDR)、端口输出数据寄存器(GPIOx_ODR)、端口置位/复位寄存器(GPIOx_BSRR)、端口配置锁存寄存器(GPIOx_LCKR)、复用功能寄存器(GPIOx_AFRL & GPIOx_AFRH)
5、库函数的操作方法:GPIO初始化;输出0、1;读取等
GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能时钟 //GPIOF9,F10初始化设置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;//IO口 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉 GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOF9,F10 void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//输出1 GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//调用示例 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);//输出0 void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,BitAction BitVal);//按位输出 void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);//输出 uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);//按位读输入 uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);//读取输入 GPIO_ReadlnputDataBit(GPIOF,GPIO_Pin_9);//示例 GPIO_ReadlnputData(GPIOF);//示例 uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);//按位读输出 uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);//读取输出
6、寄存器方式操作方法
RCC->AHB1ENR|= 1<<5;//打开GPIOF时钟,RCC_AHB1ENR.5 GPIOF->MODER &= ~(3<<2*9);//GPIOF.9通用输出模式 GPIOF->MODER |= 1<<(2*9); GPIOF->OSPEEDR &= ~(3<<2*9);//GPIOF.9速度100MHz GPIOF->OSPEEDR |= 3<<(2*9); GPIOF->PUPDR &= ~(3<<2*9);//GPIOF.9上拉 GPIOF->PUPDR |=1<<(2*9); GPIOF->OTYPER &= ~(1<<9);//GPIOF.9推挽输出模式 GPIOF->OTYPER |=0<<9; GPIOF->ODR|= 1<<9;//GPIOF.9=1,熄灭DS0 GPIOF->ODR&=~(1<<9); //第九位输出0 GPIOF->ODR|=1<<9; //第九位输出1 GPIOF->BSRRH = 0x0200; //第9位输出0 GPIOF->BSRRL = 0x0400; //第10位输出1 uint32_t data=GPIOF->IDR //读取输入 uint32_t data=GPIOF->ODR //读取输出
7、位带操作
//位带区别名地址计算公式的c语言宏定义 #define BITBAND(addr, bitnum) ((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射 #define GPIOA_ODR_Addr (GPIOA_BASE+20) //0x40020014 #define GPIOF_ODR_Addr (GPIOF_BASE+20) //0x40021414 #define GPIOA_IDR_Addr (GPIOA_BASE+16) //0x40020010 #define GPIOF_IDR_Addr (GPIOF_BASE+16) //0x40021410 //IO口位带操作的c语言宏定义 #define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //位带输出(写) #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //位带输入(读) PFout(9)=1;//输出1 PFout(9)=0;//输出0
8、寄存器开发与固件库开发的优缺点
寄存器开发方式的特点
运行速度快、占用存储空间小;需要学习、记忆各寄存器的功能、格式、每位作用含义,STM32F4有数百个寄存器
固件库开发方式的特点
直接调用固件库函数,无须深入了解各寄存器的具体格式
运行速度较慢、占用存储空间较大
9、理解CMSIS标准
使不同芯片公司Cortex-M4内核的芯片在软件上基本兼容。Cortex Microcontroller Software Interface Standard,Cortex微控制器软件接口标准
10、GPIO与其他模块结合的应用
驱动LED、按键,中断,USART等
11、GPIO端口复用:
注意初始化GPIO时一定选择****复用功能****,即GPIO_InitStructure.GPIO_Mode = ****GPIO_Mode_AF;*并用*GPIO_PinAFConfig();****进行复用功能配置。要知道哪个资源可以复用哪些引脚,把我们学过的资源都整理出来备查
第3讲NVIC与EXTI
EXTI挂载在APB2上。
1、NVIC与EXTI的概念
NVIC:Nested Vectored Interrupt Controller,嵌入向量中断控制器
EXTI:External Interrupt/event controller,外部中断/事件控制器
2、NVIC相对VIC的优点
快,ns级响应速度,实时性强。标准,只要是Cortex内核,不同公司用法一样。
3、NVIC的中断管理规模(多少级中断、内核中断、外部中断各多少)、STM32F407的中断管理规模
256级可编程中断设置(8位),16个内核中断,240个可屏蔽中断,每个IO口都可以作为中断源。
管理中断:非屏蔽请求NMI、可屏蔽请求IRQ。中断源是IO口、外设、内核中断、系统异常中断
stm32只支持92个(10个内核中断,82个可屏蔽中断)4位16级优先管理,5组分组(没有使用Cortex内核IP的全部8位)
4、NVIC中断的优先级管理规则,理解抢占优先级、响应优先级,中断优先顺序、中断嵌套规则、中断优先级分组。STM32F4对NVIC中断优先管理上的实现
优先级分为抢占优先级(主优先级)、响应优先级(从优先级)。
中断嵌套规则:高抢占优先级嵌套低抢占优先级,同级不可嵌套,小号优先。
响应优先级不嵌套,只决定多个相同抢占优先级、不同响应优先级同时申请时的相应顺序,小号优先。
两种优先级都相同的多个中断源同时申请时,首先响应中断地址(向量)低(小号)
优先级规则针对中断通道而非中断源。
中断优先级分组:9种组合。
分组0:8位全用于响应优先级(0:8)
分组x:x位抢占优先级,8-x位响应优先级(x:8-x)
STM32对NVIC中断优先管理实现:只用高4位,16个可编程优先级
5、NVIC相关寄存器的含义
在core_cm4.h
ISER[8]
:中断使能寄存器组
ICER[8]
:中断失能寄存器组
ISPR[8]
:中断挂起寄存器组
ICPR[8]
:中断解挂寄存器组
IABR[8]
:中断激活标志位寄存器组
(stm32只用3个)
IP[240]
:中断优先级寄存器组(stm32只用82个,高4位)
STIR
:软件触发中断寄存器组
6、固件库方式对NVIC初始化、中断优先级分组设定方法
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct); typedef struct { uint8_t NVIC_IRQChannel; //通道 uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级 uint8_t NVIC_IRQChannelSubPriority; //响应优先级 FunctionalState NVIC_IRQChannelCmd //使能、失能 } NVIC_InitTypeDef; //示例 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 分组2 NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //EXTI0通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00;//0抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x02;//2响应优先级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能 NVIC_Init(&NVIC_InitStructure);//NVIC初始化
中断分组配置在寄存器SCB->AIRCR[10..8]
中进行。
固件库函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
例如:NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2)
(在初始化时配置一次,一般不改)
7、中断与事件区别
中断:需CPU执行ISR(中断服务程序)完成相关操作
事件:靠脉冲发生器产生一个脉冲,不需CPU干预,由硬件自动完成相关操作,如触发AD转换
可以这样简单认为,事件机制提供了一个完全由硬件自动完成触发到产生结果的通道,不要软件的参与,降低了CPU的负荷,节省了中断资源,提高了响应速度,是利用硬件来提升CPU芯片处理能力的一个有效方法。