| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 嵌入式 -> STM32F407zg简单background和寄存器、IDE分别点亮LED交替闪烁 -> 正文阅读 |
|
[嵌入式]STM32F407zg简单background和寄存器、IDE分别点亮LED交替闪烁 |
?Goal
Background
当我们处于用户模式下,是没有权限实现模式转换(修改CPSR模式位)的,若想实现模式切换,需通过外部中断或是异常处理过程进行切换,则ARM指令集提供两条产生异常的指令,其中一个就是中断指令SWI。ST公司在ARM基础上主打外部设备,如USART,IIC,SPI等。 ARM处理器家族包括应用处理器,实时处理器和微控制处理器。STM32单片机属于微控制处理器。如图1,随着工艺与技术的提高,现在越来越多人使用Cortex处理器以代替传统的ARM处理器,因为Cortex处理器不仅易于使用且价格低廉。 对单片微型计算机的选择,结合选型手册根据客户要求进行选择。? ?
冯·诺依曼结构数据空间和地址空间不分开,即其指令和数据共享同一总线的结构,使得信息流的传输成为限制计算机性能的瓶颈,影响数据处理速度提高;哈佛结构数据空间和地址空间是分开的,即哈佛结构使用两个独立的存储器模块,分别存储指令和数据,每个存储模块都不允许指令和数据并存。STM32是基于哈佛架构的。 (冯诺依曼) ?(哈佛)
ARM CortexTM微控制器软件接口标准(CMSIS)是Cortex-M处理器系列的与供应商无关的硬件抽象层。使用CMSIS,用户可以调用寄存器访问芯片编写代码,为处理器和外设实现一致且简单的软件接口,从而简化软件的重用、缩短微控制器新开发人员的学习过程。 CMSIS是ARM公司与多家不同的芯片和软件供应商一起紧密合作定义的,提供了内核与外设、实时操作系统和中间设备之间的通用接口。
????????① 寄存器开发(底层) ????????② 标准库开发 ????????③ HAL库开发(STM32CubeMX) ????????STM32Cube IDE = STM32CubeMX + MDK(用图形界面方式自动生成代码) ? ? ?2. 时钟系统 ????????输入时钟系统
STM32F407ZG:168MHz,用PLL锁相环倍频8MHz到168MHz ????????输出时钟系统
? ? 3. 寄存器 ? ? ????① 开HSE外部高速时钟→设置寄存器,扯上参数将8MHz倍频到168MHz ? ? ????② GPIO设置,要先开GPIO时钟,为了让整个系统协同工作 ? ? 4. MDK界面 如图4,具体功能包括编译BUILD(编译单个文件、智能编译、完全编译),下载LOAD(连接板子在编译后下载程序),设置(魔术棒),调试,下载支持包等。 需要检测STLink是否成功连接,点击“魔术棒”,在Debug中选择ST-Link Debugger,选择SW,如果SWDIO有标识,则在flash download添加对应STM32型号的flash,实验用的STM32板子对应的flash为STM32F4XX Flash。 ? ? 5. GPIO知识整理 ????????可以通过软件将通用I/O(GPIO)端口的各个端口位分别配置为多种模式:
?????????图5中,输出数据寄存器为ODR,控制IO引脚是高电平还是低电平。 ? ? ? 6. JTAG和SWD区别 SWD模式比JTAG在高速模式下更可靠,在大数据量的情况下JTAG下载程序会失败,但SWD发生的几率小很多。在GPIO刚好缺一个的时候可以使用SWD仿真,这种模式支持更少的引脚。在板子体积有限时推荐使用SWD模式,它需要的引脚少,相应的需要PCB空间小。连接1,7,9,10就可以实现SWD模式。 Experiment Steps
为点亮LED指示灯,先在STM32_F4ZG_Pro核心板原理图中找如图6的自定义LED指示灯。图6中得知应操控PF9和PF10(即GPIO9,GPIO10),将其拉低为低电平从而导通点亮LED0和LED1。在中文参考手册中找到GPIOF的边界地址为0x4002 1400 - 0x4002 17FF。 配置GPIO端口需按顺序配置MODER,OTYPER,OSPEEDR,PUPDR,ODR寄存器。 首先配置MODER模式寄存器。看到其偏移地址为0x00,则在led.h中寻址MODER为#define GPIOF_MODER (*(volatile unsigned int *) (0x40021400 + 0x00)),其中第一个*意思为指向地址,第二个*为取地址,volatile的作用为防止编译器优化该变量,优化意思为在内存不够的情况下优化代码减少占用,但在debug时优化等级需为0。因为对于MODER寄存器而言,00代表输入,01代表通用输出模式,10代表复用功能模式,11代表模拟模式,因此为点亮LED灯,需将MODER9和MODER10都设置为01,即0101,其余都为0,则将MODER寄存器先清零再赋值。MODER寄存器清零的写法为GPIOF_MODER & = ~(0x0F<<(2*9));(其中0x0F对应二进制是1111),将1111取反后输入MODER9和MODER10。后再写GPIOF_MODER I = (0x05<<(2*9)); 将0101输入MODER9和MODER10中。完成MODER配置。 然后配置OTYPER输出类型寄存器。看到其偏移地址为0x04,则在led.h中寻址OTYPER为#define GPIOF_OTYPER (*(volatile unsigned int *) (0x40021400 + 0x04))。对于OTYPER寄存器而言,0代表输出推挽,1代表输出开漏。点亮LED等需选择推挽,因此需要将OT9和OT10设置为0 0,则将OTYPER寄存器先清零再赋值。OTYPER寄存器清零的写法为GPIOF_OTYPER & = ~(0x03<<9); 即将1 1取反输入OT9和OT10。然后写入GPIOF_OTYPER I = (0x00<<9); 将0 0输入OT9和OT10中。完成OTYPER配置。 接着配置OSPEEDR输出速度寄存器。看到其偏移地址为0x08,则在led.h中寻址MODER为#define GPIOF_OSPEEDR (*(volatile unsigned int *) (0x40021400 + 0x08))。对于OSPEEDR寄存器而言,00代表2MHz低速,01代表25MHz中速,10代表50MHz快速,11代表30pF时为100MHz高速,为点亮LED灯,只需低速即可实现,则将OSPEEDR9和OSPEEDR10都设置为00,即0000,其余都为0,则将OSPEEDR寄存器先清零再赋值。OSPEEDR寄存器清零的写法为GPIOF_OSPEEDR &= ~(0x0f << (2*9));(其中0x0f对应二进制是1111),将1111取反后输入OSPEEDR9和OSPEEDR10。后再写GPIOF_OSPEEDR |= (0x00 << (2*9)); 将0000输入OSPEEDR9和OSPEEDR10中。完成OSPEEDR配置。 随后配置PUPDR端口上拉/下拉寄存器。看到其偏移地址为0x0C,则在led.h中寻址PUPDR为#define GPIOF_PUPDR (*(volatile unsigned int *) (0x40021400 + 0x0c))。对于PUPDR寄存器而言,00代表无上拉或下拉,01代表上拉,10代表下拉,11代表保留,为点亮LED灯,默认用上拉,则将PUPDR9和PUPDR10都设置为01,即0101,其余都为0,则将PUPDR寄存器先清零再赋值。PUPDR寄存器清零的写法为GPIOF_PUPDR &= ~(0x0f << (2*9));(其中0x0f对应二进制是1111),将1111取反后输入PUPDR9和PUPDR10。后再写GPIOF_PUPDR |= (0x05 << (2*9)); 将0101输入PUPDR9和PUPDR10中。完成PUPDR配置。 最后配置ODR输出数据寄存器。看到其偏移地址为0x14,则在led.h中寻址ODR为#define GPIOF_ODR (*(volatile unsigned int *) (0x40021400 + 0x14))。对于ODR寄存器而言,0代表下拉,1代表上拉,为使两个LED灯闪烁,需要将ODR9和ODR10交替设置为0,则将PUPDR9和PUPDR10都设置为01或10,其余都为0,则将ODR寄存器先清零再赋值。ODR寄存器清零的写法为GPIOF_ODR &= ~(0x03 << 9);(其中0x03对应二进制是11),将11取反后输入ODR9和ODR10。后再写GPIOF_ODR |= (0x01 << 9);和GPIOF_ODR |= (0x02 << 9); 将01或10输入ODR9和ODR10中。完成ODR配置。
首先需要配置时钟,在Pinout & Configuration中的System Core点击RCC配置时间,选择配置HSE外部高速时钟,并选择Crystal/Ceramic Resonator。然后进入Clock Configuration中选择HSE,因为晶振为8MHz,将Input frequency设置为8MHz,首先需要归一化,故先“/8”,然后因为一定要“/2”,且在除以2后需达到168MHz,所以再除以2前“x336”。然后选择PLLCLK倍频,再调整参数配置AHB,APB1和APB2。因为已知输出时钟系统中,AHB为168MHz,APB2为84MHz且APB1为42MHz,所以分别“/1”,“/2”,“/4”即可配置,如图7。 ? 配置完时钟后配置GPIO。在Pinout & Configuration中点击PF9和PF10,选择GPIO_OUTPUT。在左侧的GPIO栏分别配置PF9和PF10,将它们的GPIO output level一个设置为High另一个设置为Low,将GPIO mode设置为Output Push Pull,将GPIO Pull-up/Pull-down设置为Pull-up,将Maximum output speed设置为Low。接着Porject Manager,设置完后选择自动生成代码。 CubeIDE是用HAL库开发的,HAL库的手册叫做stm32f4 hal and low-layer drivers。在生成的代码中,需要把(1)(2)两行代码写入main函数的while循环中,TogglePin的意思为不断的翻转,从而让LED可以亮灭闪烁。 HAL_Delay(1000); ?????????????????????????????????????????????????????????????(1) ? HAL_GPIO_TogglePin(GPIOF, LED0_Pin|LED1_Pin); ???????????????????????????????????(2) 最后Ctrl+B对项目进行编译,选择Run Configuration,然后配置文件,双击STM32 Cortex-M C/C++ Application,在C/C++ Application中调试器选择STLink,Main中选择led.elf,当看到Download verified successfully即可成功运行。 【其中库函数的启动文件和寄存器启动文件不同,不需要用到ST公司给的初始化时钟的函数。图形化界面不需要在启动文件调用SystemInit函数,故屏蔽掉,不过需要在外部实现SystemInit函数不然会报错。】 Result 都能看到STM32板子上D1和D2小灯交替闪烁,实验成功。 ? ? ? |
|
嵌入式 最新文章 |
基于高精度单片机开发红外测温仪方案 |
89C51单片机与DAC0832 |
基于51单片机宠物自动投料喂食器控制系统仿 |
《痞子衡嵌入式半月刊》 第 68 期 |
多思计组实验实验七 简单模型机实验 |
CSC7720 |
启明智显分享| ESP32学习笔记参考--PWM(脉冲 |
STM32初探 |
STM32 总结 |
【STM32】CubeMX例程四---定时器中断(附工 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 6:44:07- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |