发 帖  
原厂入驻New
[问答]

STM32的位带怎么操作?

57 STM32 PWM
分享
本章将首先介绍在线仿真调试程序的方法,然后讲解STM32的位带操作,最后学习通用定时器的输出比较功能产生PWM,并且通过实用例程进一步强化实际产品开发能力。
0
2021-6-15 06:07:19   评论 分享淘帖 邀请回答
1个回答
  4.1 Keil在线仿真调试
  51单片机程序相对简单,调试程序时依靠程序员根据实验现象做分析,改动程序进行逻辑验证的方式查找程序逻辑错误。随着要实现的功能越来越复杂,所选用的单片机从51单片机换到了STM32,所要编写的代码量也成倍增加,因此调试工具也要鸟枪换炮,采用ST-Link在线调试程序。
  在线仿真调试就是将程序下载到系统中运行后,可以对程序进行逐步跟踪并且察看数据的变化。有了在线仿真调试功能,程序员可以测试每一行源代码,从而找出程序错误。在这个过程中,程序员可以通过设置断点,显示和监控内存内容、寄存器内容、控制输入输出等多种方式,从而找出错误根源。
  在线仿真调试可以实现Keil软件和目标板的联调,更加直观了解单片机运行的过程,高效快速排查问题,从而提高产品和项目开发的效率。
  4.1.1 软件配置
  在所构建的工程模板中的system_stm32f10x.c文件中,有两段针对系统时钟的宏定义,如图4-1所示,用户选择哪个时钟就在图4-1左侧一段取消注释哪个时钟,其他时钟全部注释掉,这里系统默认用的是72MHz。
  
  图4-1 系统时钟宏定义
  在线调试仿真,Keil软件的配置信息必须要和实际目标板的运行时钟一致,因此在Debug选项卡中选择ST-Link仿真器,然后点击Settings按钮,如图4-2所示。
  
  图4-2 debug窗口
  打开Trace选项卡,在Core Clock处填写系统时钟72.000000MHz,如图4-3所示。
  
  图4-3 设置硬件仿真时钟频率
  当程序编译通过,显示0错误0警告的时候,选择菜单项Debug--》Start/Stop Debug Session,或者点击图4-4中红色方框内的按钮,进入在线仿真调试页面。
  
  图4-4启动/结束仿真调试按钮
  在程序窗口中显示代码行号的左侧灰色区域点击鼠标左键,设置断点(红色标记)。如图4-5所示:
  1、Reset:为程序复位;
  2、Run:为全速运行;
  3、Step:为单步执行,一次执行一条语句。当遇到函数时就进入并且继续单步执行;
  4、Step Over:也是单步执行,但它遇到函数时不会进入函数内部,而是直接执行整个函数;
  5、Step Out:单步执行到函数内时,用step out就可以执行完函数余下部分,并返回到上一层函数。
  点击全速运行,程序就会循环执行,如果设置了断点,每次运行到断点处就会停止。此时,可以通过点击view菜单,打开watch窗口,然后设定所要观察的变量和寄存器,当运行到断点处或者单步运行时,就可以观察出寄存器状态。
  
  图4-5 Keil仿真界面
  在实际项目和产品开发的过程中,调试程序功能往往是程序员的最重要的工作,而在线仿真调试这个功能非常重要,体现在可以帮助程序员快速查找定位问题和解决问题。这个重要的功能主要是针对逻辑错误查找的,因此难以举例演示,这个功能的重要性需要慢慢在开发中体会。
  4.2 位带操作
  4.2.1 位带、位带识别区
  前边操作STM32的GPIO时都是采用操作寄存器的方式,也就是一次性操作16位,这种方式编程比较复杂,单片机的执行效率也低。编写程序代码时,更多时候是操作一组GPIO中的某一位,而其它位不需要操作,这种情况下希望用更加简易的方式,不需要对16个口全部操作,就可以使用STM32的位带操作。
  如果之前学过51单片机,对位带并不陌生。在51单片机中有一部分寄存器,可以直接对寄存器中的某一位进行读写;比如sbit LED = P1^0; LED = 0;再比如TR0 = 1;这些都是位带操作。除此之外,51单片机的内存地址20H到2FH这16个字节共128位的内存,是可以位操作的,其他内存地址只能字节操作。用C语言编程时,内存的位操作一般不直接使用,但可以直观的感受到寄存器的位操作。
  STM32的位带在《Cortex-M3权威指南》资料中有详细介绍,可以进行位带操作的有两部分,分别是SRAM区的最低1MB范围和片内外设区的最低1MB范围。SRAM区1MB的内存一般编程的时候不常用,用的比较多的是片内外设区的最低1MB,也就是外设寄存器所在地址空间。
  编程操作时,不方便对外设寄存器的某一位直接访问,因此在片内外设区另外开辟了一个32MB大小的寻址空间,取名为位带别名区。在这个地址空间中,每4个字节对应了位带区的一个位。有了这层关系,对位带别名区的某4个字节的操作,就等价于对这个地址对应的位带区的某一位的操作。
  Cortex-M3的地址空间是4GB,片内外设的地址从0x40000000到0x5FFFFFFF共512MB。其中从0x40000000到0x40100000的地址空间是片内外设的1MB的位带区,从0x42000000到0x43FFFFFF是对应的32MB的位带别名区,如图4-6所示。
  
  图4-6 片内外设地址
  一般情况下,要改写某一个寄存器某一位的值,如果不采用位带操作,要分三步,第一步读出寄存器的值,第二步改变需要改变的那一位,第三步将改变后的值写进寄存器;而如果采用位带操作程序代码会更简单,代码执行效率也更高。
  4.2.2 位带和位带别名区
  编写代码时我们要操作某个寄存器的某一位,比如是GPIO的某一个IO口,那在程序中直接操作的就是相对应的位带别名区的一个32位的地址。首先确定要操作的寄存器的地址,也就是他的位带地址,然后确定要操作的是哪一位,最终根据映射关系计算出要操作的这一位所映射的位带别名区的地址。
  统一用一个片上外设区和SRAM区的位带与位带别名区的映射公式:
  
  1、其中addr表示的是外设寄存器的地址,bitnum表示的是要操作的这一位在这个寄存器的第几位。
  2、(addr & 0xF0000000)+0x2000000区分的是片上外设区还是SRAM区的位带,片上外设区的位带地址是从0x40000000到0x40100000,SRAM区的位带地址是从0x20000000到0x20100000,大多数情况下只操作外设。
  3、(addr &0x00FFFFFF)《《5)表示这一位所在的寄存器的第0位对应的位带别名区地址。由于位带区的一个寄存器是32位,因此映射到位带别名区就是32个字节,左移5相当于乘以32。
  4、bitnum《《2是确定这一位相对于寄存器第0位对应的位带别名区地址的偏移地址。由于相对于寄存器的第0位,每偏移1个位,位带别名区就偏移4个字节,因此需要左移2位,相当于乘以4。
  0x4001080C~0x4001080F表示的是GPIO端口A上“端口输出数据寄存器(ODR)” 4字节的地址空间。该寄存器的0~15位,对应端口A上的16个引脚。以0x4001080C地址空间中的第0位(0 bit)为例,它表示PA0引脚,通过膨胀关系,在位带别名区有一个4字节(32bit)大小的区域也表示PA0引脚,该区域的起始地址为0x42210180,如图4-7所示。之前我们是通过对ODR寄存器的第0位“置1”,控制PA0引脚输出高电平,现在我们可以直接对PA0对应的位带别名区的地址空间置1,实现同样的功能,并且操作更简单,效率更高。
  
  图4-7位带区与位带别名区的膨胀对应关系图
  实际开发中,位带主要是应用在GPIO端口操作。将GPIO端口输入/输出数据寄存器的数据位通过公式找到对应的位带别名区地址,将代码保存在config.h文件中,若想使用位带操作,必须添加以下代码,之后的例程中默认在config.h中添加代码。具体代码如下:
  
  
  通过上面位带设置程序,对IO口赋值时不必再使用“位设置”或“位清除”函数,而是可以像操作51单片机的IO口一样操作STM32的GPIO引脚。比如以PA1引脚为例,设置其为输出模式:
  首先使用宏定义PA1对应的位带区地址,即: define PA1 PAout(1) 。其中PA1为宏定义的引脚名称,这个可以随意设置,PAout(1)才是关键,其中PA表示GPIO端口A,out表示输出模式,in表示输入模式;(1)表示引脚号。
  通过这种操作,可以用PA1 = 1; 替代GPIO_SetBits(GPIOA, GPIO_Pin_1);
  4.2.3 练习
  将2.6,3.6.3,3.9小节中的程序,改为位带方式,重新编写一编,在此不再粘贴代码,具体代码可以到“Kingst-32F1开发板配套光盘\《ARM嵌入式编程与实战应用--STM32F1系列》例程\Lesson4”文件夹下查看。
  4.3 RGB调色
  在音乐广场、KTV、酒吧等场所,往往都有激情四射的舞台灯光,效果绚烂夺目,本小节通过开发一套简易舞台灯控制系统来提高读者的实际产品开发能力。
  4.3.1 RGB调色原理
  前边介绍过RGB小灯的发光原理,理论上三原色相互搭配,可以产生七色,如图4-8所示。有了七种颜色,就可以编程实现单色显示、单色渐变、渐变切换、单色闪烁、闪烁切换等复杂的功能,让简单的RGB小灯通过程序发挥出强大的功能。
  
  图4-8 RGB调色
  4.3.2 PWM脉宽调制
  PWM是Pulse Width Modulation的缩写,它的中文名字是脉冲宽度调制,一种说法是它利用微处理器的数字输出来对模拟电路进行控制的一种有效的技术,其实就是使用数字信号达到一个模拟信号的效果。
  首先从它的名字来看,脉冲宽度调制,就是改变脉冲宽度来实现不同的效果。我们先来看三组不同的脉冲信号,如图4-9所示。
  
  图4-9 PWM波形
  这是一个周期是10ms,即频率是100Hz的波形,但是每个周期内,高低电平脉冲宽度各不相同,这就是PWM的本质。在这里大家要记住一个概念,叫做“占空比”。占空比是指高电平的时间占整个周期的比例。比如第一个周期的占空比是40%,第二周期的占空比是60%,第三周期的占空比是80%,这就是PWM的解释。
  如果我们用100Hz的信号,如4-9所示,假如高电平熄灭小灯,低电平点亮小灯的话,第一部分波形熄灭4ms,点亮6ms,亮度最高,第二部分熄灭6ms,点亮4ms,亮度次之,第三部分熄灭8ms,点亮2ms,亮度最低。通过定时器的输出比较功能,就可以实现PWM的脉冲宽度调制,来调整小灯的亮暗程度。
2021-6-15 17:41:50 评论

举报

只有小组成员才能发言,加入小组>>

1992个成员聚集在这个小组

加入小组

创建小组步骤

关闭

站长推荐 上一条 /5 下一条

快速回复 返回顶部 返回列表