第一个STM8项目的记录
说明
我的第一个项目是stm8。
显示部分是点阵加数码管,通过串口控制下位机变频器的运行。虽然看起来很简单,但是项目复杂度超过我以前开发板上的所有项目,因此碰到了很多前所未有的问题。在此记录一笔。
注,这是本人第一个项目的记录,不保证科学与正确
1,misplaced local declaration错误
变量必须在函数的最开始处一口气全部声明或者定义掉
这其实是说明cosmic不支持c99的原因。
2,stm8中,各数据类型长度
类型 | 长度 |
---|---|
char | 1字节8bit |
int | 2字节16bit |
short int | 2字节16bit |
float | 4字节32bit |
double | 4字节32bit |
long int | 4字节32bit |
long long int | 4字节32bit |
为了以后移植方便,我决定采用C99的扩展类型uint8_t uint16_t这种。
3,STVD的中断中不能使用long类型
小标题只是该bug的表现之一。确切的bug描述是
在stm8_interrupt_vector.c使用超过2byte的类型。就会产生类似段重合之类的错误。
下面是bug的详细描述。
3.1。
在stm8_interrupt_vector.c中,函数定义里的变量不能超过2个byte。这个函数不仅仅是中断处理函数,还包括放在这个文件中的普通函数,这个变量限制对全局变量局部变量同样有效。
3.2。
同样,在这个文件中的变量默认是signed类型,就算在使用前声明为extern unsiged也不行,但是在使用中进行强制类型转换(unsigned int )或者数字后面加u是可行的。
这句话的意思是比如声明变量的时候为unsiged int,那么理论上的变量范围是0~65535。而stm8的int类型是2byte,理论上是不会报错的。
但是实际上,如果变量使用的时候超过了32768。那么就会报错。即变量在使用过程中如果超过了有符号类型的最大值,那么编译器就会进行扩展成4byte。
这种bug,即使在使用文件前extern一下也是不行的。
但是,如果在使用中,再进行一次强制类型转换(unsigned int)或者数字后面加个u,却是的可行。
3.3。
不可以用long类型。即不可以让变量超过2个byte。
3.4。
但是,如果函数定义在其他地方,而该文件只是声明引用的话,没有问题。因此很多人没发现问题是,他们把中断函数定义放在了其他地方,而stm8_interrupt_vector.c只是声明。
此外我查看lxf文件,发现stm8_interrupt_vector.cs是链接在const区的,也许问题出在这里。但是我水平不够,暂时无法发现真正的原因。
4,IAR的一些初始化操作
iar for stm烧录程序,开始新建工程时候选择芯片是无效的,一定要在打开工程后右击工程-option-general option-选择芯片。不然能编译,但是下载无效。
此外,若是使用标准库,还需要在C/C++Compiler中的preprcessor选择工程头文件路径和预定义符号
当前工程文件目录代码是PROJDIRPROJ_DIR
预定义符号选择芯片就可以了。
需要在工程里添加标准库的C源码文件,h文件不用添加,上面包含了。
对不需要的C文件,要么不添加进去,要么右击option-exclude from build排除编译之外。
5,stm8的一些问题
stm不能同时初始化多个同功能的定时器,我初始化了2个时间不同的溢出定时器结果出现问题。且这个不是时间重合带来的问题,因为我只要一开第二个定时器的功能就会出问题。至今未能找到原因。因为我后来只用了一个定时器。
stm的定时中断处理程序的时间是微秒级。
曾经,我定时处理程序是10us一次,然后处理了很多东西,结果发现定时不准时。最后发现,是10us处理一次太快了。导致处理中多次被中断,进而影响时间。
后来,我用了个定时器1ms的中断,但是实际运行中发现,40行的代码,全部只进行取余判断从来递增递减取反置一相关全局变量。抓波形测出一次中断运行时间居然要170us以上。换句话说,1ms中断时候,在中断中运行的时间就接近五分之一。
后来我用了10ms的中断,结果同样的代码,运行时间缩短到了50us以下。看来中断的进入转出需要比较长的时间。
用stm的蜂鸣器必须配置选项字节中的AFR7为BEEP。
LSI的时钟校准是通过AWU测定的。如果把这个外设时钟关了,会进入忙循环导致没有任何反应。
不能关,蜂鸣器外设是通过这个使能的,关了就开不了了
6,串口发送速度
在用定时器控制串口发送频率时,有点特殊。
串口本身的发送时间是20~30ms,按照下位机的要求,我的定时器规定100ms中断一次,然后发送数据,那么出现的情况是如下这样。
0ms定时器中断写1—-30ms串口发送数据完毕,对定时器flag写0—-100ms定时器中断写1—-30ms后串口发送数据完毕。
在这里上一串串口数据发送结束到下一串数据发送开始,中间间隔是70ms。而我想要的是上一串串口数据结束到下一串数据开始,中间间隔100ms。
解决方法,有两种。
1是将定时器中断弄长一点,比如130ms,那么就能使100ms间隔了,不过这个方法的问题时,串口本身发送数据的时间是不定的。也即是串口数据之间的间隔是不定的。
2是定时器中断时间短一点,比如1ms一次,那么当数据大于100ms时发送数据,发送完写0,等下一次大于100ms再次发送数据。这种方法间隔比较准确。
3最后敲定最终方案,10ms一次加1,15次后开始发送。
7,一些C错误
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
运算符两边都是volatile变量的警告。一般来说volatile不应该参与计算。
神奇的缺少)错误,是因为#define的时候多加了个分号。
神奇的缺少;错误,是在预处理文件中发生的,原因是前一个预处理文件的最后一个语句忘了加分号。
在使用标准库可变参数时候。va相关函数,总是发现数据不对。
最后发现是va_arg在计算步长是用的是int(2个字节),而我是却将其设为uint8_t一个字节。将u8改成int就对了。
在测试串口的时候,发现串口怎么也不发送数据。最后检测发现,没有清除发送完成中断的flag。同样的问题,我在定时器处理的时候也发生过。
所以下次注意,不用忘记在中断处理程序中清除中断相关flag,当然如果不用(我用不到发送完成中断),最好不要随便开中断。尤其是那种不是自动处理的中断。
同样的,我还不小心开了校验中断,因此会莫名其妙的不发送数据。
这里总结下,stm的中断flag必须手动清除!!如果找不到,那么能不用就不用。
外部中断这个我没找到如何手动清除,如果出问题要注意。查资料得出,8s没有,8l有。
expected an identifier,使用enum类型报错。是因为重复定义,前面#define了。
要小心执行一次和执行多次的区别,有些函数我们只需要在一定时间内执行一次就好了。
在stm的程序容量超过32k(地址超过64k),会出现奇怪的定义错误。
在iar设置里面降代码改成large就可以了。这个其实就是stvd长指针的意思。
8,其他
原本我是TIM4 8位中断,后来10ms不够了,所以用了TIM3,但是发现不能中断。反复检查初始化没有问题。
后来发现,利用库函数校准LSI的时候,需要用到TIM3的捕获功能,这个函数一定要放在主函数时钟初始化之后,定时溢出初始化之前。
我在进行LED半秒闪烁的时候,先开始是等于一个时间值(比如50)然后开,等于另一个时间值(比如100)关,但是发现总是闪烁几下,卡1-2秒,再正常。
后来我改成了范围判断,正常了。
原因是程序速度跟不上,正好跳过了这个定时值,时间值是根据定时器定期变化的,变化的频率是10ms的时间。但是程序运行中这个函数的运行频率不一定正好10ms内一定能运行一次。实际情况可能是,函数正好在49的时候运行了下,51的时候又运行了,恰恰是跳过了50。
所有的取余运算都会有这个,很可能会跳过需要的数值。个人认为改成范围判断会好很多。
在进行同一个点阵,但是同时显示两个不相关内容时,发现会有闪屏现象
因为其中一个内容需要定时闪烁一个点,我为了使两种显示不冲突,用的是或运算填充数据,即读出数据,或运算,输入数据。因此,闪烁功能的实现必须要清空屏幕才能搞定。
后来我改了下,在跑圈内部等到闪烁的时候请空屏幕。然后把中间的数字显示放到了跑圈下面。改了下两个函数的调用次数,总算搞定。
后来采用了更好的显存显示方案。再也没有这种问题。因为对显存的各种操作,只要最后没有显示出来,那是可以任意更改不用考虑次序的。
因此这里总结显示的输出模式是
1,填充显存数据
2,根据不同的情况略微修改显存数据
3,输出。然后123循环。
这样的好处是,修改的时候不涉及输出,因为1,和2的数据可以不同也不会闪屏。
9,优化
容量居然不够用。
标准库的初始化函数占据空间比寄存器大,是大很多很多,我测试了两个函数的寄存器实现和库实现。编译出来的容量库比寄存器大了一个8倍,一个20倍
查看发现,所有的只读变量,包含只读常量数据,代码全部在flash里面。
所有的可写全局变量,静态全局变量还有堆栈全部在RAM中。
查看iar汇编代码。
在定时中有两种判断定时方法,首先定义一个全局的节拍,每次定时器中断加1,记录开机到现在的所有节拍数。因此,一种是取余置相关全局flag为0。外部函数判断这个flag是否为0
另一种是设置外部flag不断递减,只到0。外部判断是否为0.
两种方法比较后发现,取余的方法一般是30个字节,而递减到0的方法有15个字节。
其中,第一种方法,取余有22+字节,剩下8字节赋值
第二种,自增自减是4字节,剩下是判断是否为0
第一个STM8项目的记录相关推荐
- 菜鸟运行第一个vue项目记录
近期打算着手重构现有的测试平台,由于现在用的平台是layui+flask+uwsgi+nginx框架大家都已经比较熟悉了.所以在新平台选型时本着让大家多接触新东西.新挑战的原则.平台重构选用的框架为v ...
- SpringSecurity学习:1(第一个SpringSecurity项目)
此博客是记录自己学习过程的记录 第一个SpringSecurity项目 导入依赖 详细的步骤我就不多说了,使用IDEA创建过SpringBoot项目的人一般都能看懂. 这一步我们可以在使用IDEA创建 ...
- 从一个前端项目实践 Git flow 的流程与参考
Git flow 出自 A successful Git branching model,这里使用了一个前端项目配合本文稿实施了 git flow 并记录流程作出示例和参考,对 hotfix 与持续部 ...
- docker build命令详解_Docker 搭建你的第一个 Node 项目到服务器
本文你能学到什么 Docker 是什么 Docker 概念 关于 Docker 的概念是确实不太好总结,下面我通过四点向你说明 Docker 到底是个什么东西. Docker 是世界领先的软件容器平台 ...
- Anytime项目开发记录0
Anytime,中文名:我很忙. 开发者:孤独的猫咪神. 这个项目会持续更新,直到我决定不再维护这个APP. 2014年3月10日:近日有事,暂时断更.希望可以会尽快完事. 2014年3月27日:很抱 ...
- 没有文档,没有老员工讲解,悲催的新人如何快速熟悉一个新项目?
本文来自闪客Sun的投稿,博客地址: https://www.cnblogs.com/flashsun/p/9450066.html 看完你就会明白,虽然有一定的方法论,但是不下功夫,没有耐心,还是万 ...
- prism项目搭建 wpf_Prism完成的一个WPF项目
本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要针对C#初学者,巩固C#常用知识点: 中级篇主要针对WPF布局与Mat ...
- 把python37添加到环境变量配置_关于在win 10上成功创建一个Django项目时遇到django-admin的手动配置环境变量问题。...
前言 初学Python Web 在创建第一个Djang项目的时候出现了很多的问题,今天和大家分享并记录一下这次艰难的历程! 一.官网下载Python以及安装Django 1.Python的下载安装 链 ...
- 01-Flutter移动电商实战-项目学习记录
01-Flutter移动电商实战-项目学习记录 一直想系统性的学习一下 Flutter,正好看到该课程<Flutter移动电商实战>的百度云资源,共 69 课时,由于怕自己坚持不下去(经常 ...
- 第一个django项目
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 说在前面 ...
最新文章
- JGG | 肠道微生物研究助力穿山甲圈养保护
- Shiro 权限框架使用总结
- 题目3:文本文件单词的检索与计数(实验准备)
- html 分割线_零基础网页设计/前端/html,第四课:前三课总结,以及单标签img
- 字节跳动python面试_字节跳动的面试感受
- 大学计算机基础B这本书哪有,大学计算机基础b试卷
- SAP C4C,CRM和S4HANA的Saved Query使用介绍
- java字符串底层实现_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...
- python qt 拖拽组件使用方法_Python QT组件库qtwidgets的使用
- 【数据结构与算法】带环单链表查找环的入口算法
- 为什么真正的神经元学得更快
- python thread.event
- 基于人脸识别的商业大数据2
- 南昌航空大学961数据结构真题答案
- python无头浏览器截图_selenium3使用谷歌无头浏览器、截图
- python简单爬虫获取行政边界点坐标
- android 刷recovery,安卓手机怎么刷入Recovery 命令行刷入Recovery教程
- 成功解决We recommend that if you want Anaconda registered as your system Python, you unregister this Pyt
- oracle latch等待,latch等待事件汇总
- vue创建一个简易版高德地铁路线图
热门文章
- RNN预测股票开盘价(TensorFlow,tensorboard可视化)
- Windows虚拟主机有哪些优势?
- java中编写一个三角形类,java 三角形类Triangle java 三角形类 Triangle的用法详解
- FORCE_CONSTANTS中3阶力常数大小与原子间距的分析脚本
- 中国大学慕课——程序设计与算法(一)第二周测验
- UVA 10499 正义的土地
- 1506.01186-Cyclical Learning Rates for Training Neural Networks
- web页面PC端和移动端的区别
- Dao和Repository,你还傻傻分不清吗?
- 通过 JavaMail 访问 Hotmail 邮箱(hotmail不提供smtp和pop3服务)