1。芯片启动 首先stm32会根据启动方式(参考手册2。4节)从启动位置加载启动代码到内存中,之后开始执行启动代码,一般启动代码使用官方提供的即可xxx。s 启动代码的工作: 初始化堆栈空间,定义异常向量表调用SystemInit系统初始化初始化时钟,调整异常向量表执行main主函数 芯片要开始工作,必须初始化时钟和内存,stm32的内存使用片内SRAM,可以直接使用,时钟需要初始化,ARM芯片需要定义异常向量表,执行C语言代码必须初始化堆栈。 stm32f407推荐的主时钟频率168MHz 2。产生原始频率的硬件 (1)晶振 (2)RC(LC)振荡电路 原始频率不会很高,使用前必须升频,升频使用PLL(升频)电路 CPU时钟系统的大体结构 3。stm32f407的原始时钟 HSIRC高速内部振荡时钟16MHSEOSC高速外部晶振426M(8M)以上两个时钟源可以直接作为系统主时钟,也可以通过PLL升频后作为主时钟LSIRC低速内部振荡时钟32K看门狗LSEOSC低速外部晶振32。768KRTC stm32f407的时钟树 PLL的输出时钟PLL输入时钟XPLLNPLLMPLLP 168M8MX33682 4。将keil5的工程的系统时钟配置为168MHz (1)修改systemstm32f4xx。c的254行 definePLLM8 (2)修改stm32f4xx。h的127行 该文件是只读属性文件,要去文件系统中找到该文件,去掉只读属性defineHSEVALUE((uint32t)8000000)!ValueoftheExternaloscillatorinHz 练习: 将系统主频配置为168M 修改PLL,调节系统主频 definePLLN336168MdefinePLLN432216M超频definePLLN16884M降频 系统总线时钟频率: SYSCLK时钟168MHzHCLKAHB总线168MHzAPB1时钟42MHzAPB2时钟84MHz 按键驱动 1。看原理图 从原理图可知: 按键松开引脚高电平 按键按下引脚低电平 按键对应的引脚: S1PA0 S2PE2 S3PE3 S4PE4 如何读取输入引脚的电平 (1)读取输入数据寄存器(IDR)对应位的值1输入高电平0输入低电平 (2)位段操作PAin(0)0输入低电平PAin(0)1输入高电平 (3)库函数uint8tGPIOReadInputDataBit(GPIOTypeDefGPIOx,uint16tGPIOPin);传入哪一组哪个脚,返回该引脚的电平 练习: 完成其他三个按键的检测程序,分别使用寄存器位段库函数判断 实现一下功能: 按下S2,D2亮按下S3,D3亮按下S4,D4亮 key。c includestm32f4xx。h includekey。h voidkeyinit(void) { GPIOInitTypeDefGPIOInitS 1。开启GPIOA的时钟 RCCAHB1PeriphClockCmd(RCCAHB1PeriphGPIOARCCAHB1PeriphGPIOE,ENABLE); 2。GPIO初始化PA0 GPIOInitStruct。GPIOModeGPIOModeIN;输入模式 GPIOInitStruct。GPIOPuPdGPIOPuPdNOPULL;无上下拉 GPIOInitStruct。GPIOPinGPIOPin0;PA0 GPIOInit(GPIOA,GPIOInitStruct); GPIOInitStruct。GPIOPinGPIOPin2GPIOPin3GPIOPin4;PE2PE3PE4 GPIOInit(GPIOE,GPIOInitStruct); main。c includestm32f4xx。h includeled。h includesys。h includekey。h intmain() { intkeyflag0; 初始化 ledinit(); keyinit(); while(1){ if(S10){ 延时消抖10ms delay(100); if(S10){ 真实按键事件 if(keyflag0){按下没有松开 D1D1;取反 keyflag1; } } } else{ 延时消抖10ms delay(100); if(S1){ keyflag0; } } } } lcd。c includestm32f4xx。h includeled。h voiddelay(unsignedintms) { inti,j; for(i0;i) for(j0;j5000;j); } voidledinit(void) { GPIOInitTypeDefGPIOInitS 1。开启GPIOEGPIOF的时钟 RCCAHB1PeriphClockCmd(RCCAHB1PeriphGPIOERCCAHB1PeriphGPIOF,ENABLE); 2。GPIO初始化PF9PF10PE13PE14 GPIOInitStruct。GPIOModeGPIOModeOUT;输出模式 GPIOInitStruct。GPIOOTypeGPIOOTypePP;推挽输出 GPIOInitStruct。GPIOSpeedGPIOSpeed50MHz;高速 GPIOInitStruct。GPIOPuPdGPIOPuPdNOPULL;无上下拉 GPIOInitStruct。GPIOPinGPIOPin9GPIOPin10;PF9PF10 GPIOInit(GPIOF,GPIOInitStruct); GPIOInitStruct。GPIOPinGPIOPin13GPIOPin14;PE13PE14 GPIOInit(GPIOE,GPIOInitStruct); 3。LED默认关闭 GPIOSetBits(GPIOF,GPIOPin9GPIOPin10); GPIOSetBits(GPIOE,GPIOPin13GPIOPin14); } lcd。h ifndefLEDH defineLEDH defineD1PFout(9) defineD2PFout(10) defineD3PEout(13) defineD4PEout(14) voiddelay(unsignedintms); voidledinit(void); endif key。h ifndefKEYH defineKEYH defineS1PAin(0) defineS2PEin(2) defineS3PEin(3) defineS4PEin(4) voidkeyinit(void); endif sys。h该文件由系统定义 ifndefSYSH defineSYSH includestm32f4xx。h IO口操作宏定义 defineBITBAND(addr,bitnum)((addr0xF0000000)0x2000000((addr0xFFFFF)5)(bitnum2)) defineMEMADDR(addr)((volatileunsignedlong)(addr)) defineBITADDR(addr,bitnum)MEMADDR(BITBAND(addr,bitnum)) IO口地址映射 defineGPIOAODRAddr(GPIOABASE20)0x40020014 defineGPIOBODRAddr(GPIOBBASE20)0x40020414 defineGPIOCODRAddr(GPIOCBASE20)0x40020814 defineGPIODODRAddr(GPIODBASE20)0x40020C14 defineGPIOEODRAddr(GPIOEBASE20)0x40021014 defineGPIOFODRAddr(GPIOFBASE20)0x40021414200x14 defineGPIOGODRAddr(GPIOGBASE20)0x40021814 defineGPIOHODRAddr(GPIOHBASE20)0x40021C14 defineGPIOIODRAddr(GPIOIBASE20)0x40022014 defineGPIOAIDRAddr(GPIOABASE16)0x40020010160x10 defineGPIOBIDRAddr(GPIOBBASE16)0x40020410 defineGPIOCIDRAddr(GPIOCBASE16)0x40020810 defineGPIODIDRAddr(GPIODBASE16)0x40020C10 defineGPIOEIDRAddr(GPIOEBASE16)0x40021010 defineGPIOFIDRAddr(GPIOFBASE16)0x40021410 defineGPIOGIDRAddr(GPIOGBASE16)0x40021810 defineGPIOHIDRAddr(GPIOHBASE16)0x40021C10 defineGPIOIIDRAddr(GPIOIBASE16)0x40022010 IO口操作,只对单一的IO口! 确保n的值小于16! definePAout(n)BITADDR(GPIOAODRAddr,n)输出 definePAin(n)BITADDR(GPIOAIDRAddr,n)输入 definePBout(n)BITADDR(GPIOBODRAddr,n)输出 definePBin(n)BITADDR(GPIOBIDRAddr,n)输入 definePCout(n)BITADDR(GPIOCODRAddr,n)输出 definePCin(n)BITADDR(GPIOCIDRAddr,n)输入 definePDout(n)BITADDR(GPIODODRAddr,n)输出 definePDin(n)BITADDR(GPIODIDRAddr,n)输入 definePEout(n)BITADDR(GPIOEODRAddr,n)输出 definePEin(n)BITADDR(GPIOEIDRAddr,n)输入 definePFout(n)BITADDR(GPIOFODRAddr,n)输出 definePFin(n)BITADDR(GPIOFIDRAddr,n)输入 definePGout(n)BITADDR(GPIOGODRAddr,n)输出 definePGin(n)BITADDR(GPIOGIDRAddr,n)输入 definePHout(n)BITADDR(GPIOHODRAddr,n)输出 definePHin(n)BITADDR(GPIOHIDRAddr,n)输入 definePIout(n)BITADDR(GPIOIODRAddr,n)输出 definePIin(n)BITADDR(GPIOIIDRAddr,n)输入 endif 3。按键消抖延时消抖 以上按键程序不管是否有按键事件发生,都会占用CPU来进行判断,这种方式叫做轮询,效率比较低,CPU提供了效率更高的方式中断。