历史上的今天

今天是:2024年09月17日(星期二)

2021年09月17日 | STM8将库函数移植为寄存器方法

发布者:Weasel 来源: eefocus关键字:STM8  库函数  移植  寄存器 手机看文章 扫描二维码
随时随地手机看文章

在使用使用STM32单片机的时候,喜欢使用库函数,由于stm32的寄存器太多了,如果直接使用寄存器的话,设置起来太麻烦了,而且stm32单片机速度快,容量大,使用寄存器要额提高不了多少效率。


对于STM8单片机来说使用寄存器还是很有必要的,本身stm8单片机的速度相比于stm32就会慢很多,同时芯片容量也比较小,使用库函数的话,比较占用空间,导致系统稍微大一点,芯片容量就不够用,所以在stm8单片机上,使用比较多的就是寄存器,stm8的寄存器也比较少,设置起来也比较简单。


但是好多stm8单片机的例程都是库函数版的,那么如何将库函数版的代码移植为寄存器版的呢?


这里使用LED闪烁的库函数代码来说明

image.png

打开一个LED库函数版的工程,首先从main函数开始,第一行代码就是系统初始化。
image.png

在BSP_Initializes()函数上单击鼠标右键,选择跳转到函数定义。

image.png

这时就会跳转到系统初始化代码处。这个初始化代码里面有两个函数,一个是初始化系统时钟,一个是初始化LED的端口。


用上面的方法,单击鼠标右键,跳转到时钟初始化函数里面。

image.png

这里面又调用了一个函数,那么继续使用右键跳转。

image.png

这时候就会跳转到系统的库函数里面来了,通过这个函数可以看出,此时操作的是CKL_CKDIVR寄存器。


然后在单片机手册中找到这个寄存器,可以看到这个寄存器是设置时钟分频值的。

image.png

说明时钟初始化的过程就是设置时钟分频值,那么这个分频值设置的是多少呢?

在CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); 这一行代码中,函数括号里面传递的参数CLK_PRESCALER_HSIDIV1,然后鼠标右键,选择跳转到定义。这个参数的值,就是设置CKL_CKDIVR寄存器的值。

image.png

通过宏定义可以看出,传递的参数值是0,也就是说设置CKL_CKDIVR寄存器的值为0.

image.png

通过芯片手册寄存器的介绍中可以看出,值为0,也就是寄存器设置为1分频。

既然知道了,时钟初始化的功能就是将CKL_CKDIVR寄存器的值设置为0,那么就可以系统时钟初始化的代码直接改为寄存器操作。

image.png

直接将CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); 这行代码屏蔽掉,然后使用 CLK->CKDIVR = 0x00;代替,下来重新编译下载,看一下LED灯的闪烁是否正常。

重新编译下载,LED灯闪烁正常,说明代码的替换暂时没有问题,接下来继续替换LED初始化部分的代码。

image.png

使用右键查找定义,依次向下查找。

image.png

最后跳转到了GPIO_Init这个库函数中,这个库函数代码比较长,设置的寄存器也比较多,那么要如何替呢?

这时候需要一个参数,一个参数来替换。

image.png

这个GPIO_Init函数有三个参数,分别是:


LED_GPIO_PORT,

(GPIO_Pin_TypeDef)LED_GPIO_PIN,

GPIO_MODE_OUT_PP_LOW_FAST

第一个参数是设置GPIO端口,第二个参数是设置端口引脚,第三个参数是设置端口模式。


首先使用右键查看LED_GPIO_PORT这个参数的具体含义

image.png

通过宏定义可以看到,端口是GPIOB,引脚是5脚,

这时候就可以在GPIO_Init函数内部查看GPIOB是写入了那个寄存器。

image.png

在代码代码中查看GPIOx可以看到,这个是用来选择设置哪个寄存器的,宏定义中设置的GPIOx为GPIOB,那么GPIO_Init函数中设置的就是GPIOB寄存器。


接下来看GPIO_Pin

image.png
image.png

GPIO_PIN_5的值是0x20,在GPIO_Init函数中设置了GPIPOB的ODR寄存器和DDR寄存器。

image.png
image.png

ODR寄存器用于设置端口的输出数据,DDR寄存器用于设置IO口的输入输出模式,这里用于驱动LED,那么IO口肯定要设置为输出模式。


那么这里肯定设置的是DDR5为1,也就是将DDR寄存器的第5位设置为1,将GPIOB口的第5个口设置为输出。


ODR寄存器用于设置输出0还是1,也就是用来控制LED亮灭的。


下面接着看第三个参数GPIO_MODE_OUT_PP_LOW_FAST

image.png

这个参数的值为0xE0,带入到GPIO_Init函数查看。

image.png

可以看到这个值并没有直接设置给寄存器,而是用来比较判断不同的位,设置不同模式的。

首先将0xE0转换为二进制

image.png

可以看到最高的3位数都是1.


然后在代码中分析,在判断语句中哪些代码会执行。

image.png

首先GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));

这行代码会执行,然后判断GPIO_Mode第7位是不是1,由于GPIO_Mode最高的3位都是1,所以条件成立。进入if语句,然后判断GPIO_Mode的第4位是不是1,GPIO_Mode的第4位是0,所以第二个if条件不成立。执行

GPIOx->ODR &= (uint8_t)(~(GPIO_Pin));这行代码。接下来执行 GPIOx->DDR |= (uint8_t)GPIO_Pin;

image.png

然后继续判断GPIO_Mode的第6位和第5位是不是1,GPIO_Mode的第5位和第6位都是1,所以执行

GPIOx->CR1 |= (uint8_t)GPIO_Pin; GPIOx->CR2 |= (uint8_t)GPIO_Pin;

这两行代码

将上面执行的代码整理后如下所示


GPIOx->CR2 &= (uint8_t)(~(GPIO_Pin));

GPIOx->ODR &= (uint8_t)(~(GPIO_Pin));

GPIOx->DDR |= (uint8_t)GPIO_Pin;

GPIOx->CR1 |= (uint8_t)GPIO_Pin;

GPIOx->CR2 |= (uint8_t)GPIO_Pin;`


分析后发现这三行代码会执行

然后将参数中的值替换为宏定义中的值


 GPIOB->CR2 &= (uint8_t)(~(0x20));

 GPIOB->ODR &= (uint8_t)(~(0x20));

 GPIOB->DDR |= (uint8_t)0x20;

 GPIOB->CR1 |= (uint8_t)0x20;

 GPIOB->CR2 |= (uint8_t)0x20;

image.png
image.png

通过代码和寄存器可以分析出,


第一行将CR2寄存器的第五位清零,也就是设置最大输出速度为2MHz。


第二行将ODR寄存器第五位清0,输出为0。


第三行将DDR寄存器第五位设置为1,也就是设置为输出模式。


第四行将CR1寄存器第五位设置为1,设置IO口为推挽输出模式。


最后一行将CR2寄存器设置为1,设置IO口的最大输出为10Mhz


由于寄存器复位后的默认值都为0,所以前两行的设置可以不要,只需要后面三行的设置代码就行,那么GPIO_Init()函数最终就可以简化为下面三行代码:


 GPIOB->DDR |= (uint8_t)0x20;

 GPIOB->CR1 |= (uint8_t)0x20;

 GPIOB->CR2 |= (uint8_t)0x20;


然后用这三行代码将GPIO_Init()函数替换

image.png

编译下载程序到单片机中,观察LED闪烁情况,下载完成后LED闪烁正常,说明代码设置也正常。


这样就将CLK_Configuration()函数和GPIO_Configuration()函数都替换为了寄存器版,为了方便观看,将寄存器的相关初始化都放在main函数中。

image.png

这样将所有的初始化代码就放在main函数里面,看起来就更方便了,通过寄存器将刚才一大堆系统初始化工作简化为4行寄存器设置的代码。这样程序执行起来的效率就更高效了。


同样可以将while语句里面的LED控制,也改为寄存器操作。

image.pngimage.png
image.png

LED_ON 可以替换为 GPIOB->ODR |= (uint8_t)0x20;


LED_OFF 可以替换为 GPIOB->ODR &= (uint8_t)(~0x20);


将主函数中的代码替换

image.png

重新编译下载,LED灯正常闪烁,说明代码替换是成功的。


这样通过一步步进入库函数,然后使用寄存器一行一行替换库函数,每替换一个就重新编译下载,观察测试结果,直到所有的代码都替换完。


STM8每个功能的寄存器都比较少,替换起来的时候还是比较快的,如果熟悉的话,一个库函数代码,几分钟就可以全部替换为寄存器代码了。每个功能设置的步骤基本都是一样的,一旦一个功能替换完成,以后遇见类似的库函数代码,直接就可以用以前替换好的寄存器代码去替代。比如初始化IO口,一般都是设置DDR、CR1、CR2这三个寄存器,所以如果遇到了IO初始化的库函数代码,直接用这个三行代码去替换就行,就不用进入到库函数中一行一行代码去分析了。

关键字:STM8  库函数  移植  寄存器 引用地址:STM8将库函数移植为寄存器方法

上一篇:STM8单片机 ADC模拟看门狗中文资料错误
下一篇:STM8单片机 PWM无波形输出解决方法

推荐阅读

ARRIS旗下致力于研发创新型有线及无线网络技术的优科网络公司(Ruckus Networks)日前宣布,已完成对爱财集团新办公大楼的无线网络全面覆盖工作,帮助该集团建立面向未来应用的新型无线网络,既为集团员工交付了最佳的网络使用体验,又通过访客认证实现了安全的访客管理制度。通过稳定、高效的无线网络覆盖,爱财集团员工的移动办公效率大大提高,对集团...
据中央社报道,今(16)日,砷化镓厂稳懋总经理陈国桦表示,目前产能已满载,预计第4季进设备扩产,明年产能将扩增5000片,扩产幅度约14%。陈国桦说,今年是5G元年,预期明年5G手机将达2亿台规模,后年可望进一步扩增,对化合物半导体有利;此外,化合物半导体还可应用于自动驾驶、扩增实境(AR)与虚拟实境(VR)等,将与生活密不可分。第3季为稳懋往年运...
就在上一周,笔者目睹了中国车圈历史上第一场“云约架”大战,对战双方分别是代表着插电式混动阵营的大众,和代表着增程式阵营的理想。故事的起因也是笔者我亲身经历的。就在上周的9月8日,笔者参与了大众在成都举办的全系SUV车型,以及全系PHEV车型的试驾会。就在第一日出发前的技术沟通会上,大众集团中国区CEO、大众汽车品牌中国CEO冯思翰,在回答媒体...
  浮球液位计是一种利用磁耦合原理来检测液位高度的仪表,作为一种连续量测量仪表,其具有结构简单、工作可靠等优点,但实际应用中也存在一定的测量盲区方面的不足。那么,浮球液位计是如何构成的?有没有减小盲区的方法?减小盲区又有什么意义呢?  众所周知,浮球液位计由浮球和导杆两大关键部件组成。其中,浮球内腔有强磁铁,导杆管腔内有干簧管。...

史海拾趣

问答坊 | AI 解惑

VOIP技术解析

Q《通信世界》:什么是VoIP技术?它有什么优势?   A(叶华):VoIP技术主要指通过Internet实时传送声音信号,即IP电话。广义上讲,它指的是通过IP网络实时传送多媒体信息。以前人们使用电 话进行交流,采用电路交换技术传送语音信号。现在越来越多 ...…

查看全部问答∨

新人拜求

我想要篇关于单片机的中英文期刊或者是其他的什么也好,中文字数2500左右,有的话发我邮箱asa102cn@sina.com 谢谢…

查看全部问答∨

取字模软件

取字模软件自己买[url=https://bbs.eeworld.com.cn/viewthread.php?tid=72780&extra=page%3D2&page=1&2]开发板[/url]时送的取字摸软件 很好用    要的快下啊…

查看全部问答∨

常用放大器芯片资料

本帖最后由 paulhyde 于 2014-9-15 09:42 编辑 这个材料还是比较齐全的,希望对大家有帮助  …

查看全部问答∨

面试最恼火的问题?

这几天忙着落实工作,头都大了.面试时最最头痛的就是一个问题! 本人22岁,工作3年,要求薪水3500,却碰到有老板说“电源说难不难,说简单也不简单,也有人拿5K,6K,8K,甚至1W.” 就是没有太多的经验和年龄不大才要求不是很高的,我一不要求管吃管住,二不要 ...…

查看全部问答∨

做好医疗电子设备的电子元器件的维修

从上世纪八十年代以来,医疗行业引进了许多先进的大型电子仪器及设备, 大到0)、核磁等,小到各种彩超、监护仪等。 随着它们的所有年限增加,陆续地从保修期进入了维修期,也有一些的设备已经进入了维修高峰期。这一点和国外发达国家医疗设备服役 ...…

查看全部问答∨

eboot DownloadImage函数中为什么要调用OEMMapMemAddr()??

DownloadImage核心代码: while (OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecAddr)                         && OEMReadData (sizeof (DWORD), (LPBYTE) &dwRecLen)     ...…

查看全部问答∨

GPRS频繁掉线call ready(请大侠指教)

GPRS链接上服务器后,接收数据几秒或几分钟就call ready重启了,我观察了一下出现call ready的时间间隔,没规律,随机,说明服务器没问题,用万用表测电源也没感到有问题(偶看到以前几位仁兄的帖子了),CIPSTATUS查询状态,是IP INITIAL,除了电 ...…

查看全部问答∨

电子制作的好帮手!

电子制作的好帮手,学习C51单片机的好工具!学习开发二者兼顾!其实你也可以开发自己喜爱的电子产品! 淘宝店里有详细功能介绍http://shop36364130.taobao.com 330658522(点击Q我)    …

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved