说明

我的第一个项目是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项目的记录相关推荐

  1. 菜鸟运行第一个vue项目记录

    近期打算着手重构现有的测试平台,由于现在用的平台是layui+flask+uwsgi+nginx框架大家都已经比较熟悉了.所以在新平台选型时本着让大家多接触新东西.新挑战的原则.平台重构选用的框架为v ...

  2. SpringSecurity学习:1(第一个SpringSecurity项目)

    此博客是记录自己学习过程的记录 第一个SpringSecurity项目 导入依赖 详细的步骤我就不多说了,使用IDEA创建过SpringBoot项目的人一般都能看懂. 这一步我们可以在使用IDEA创建 ...

  3. 从一个前端项目实践 Git flow 的流程与参考

    Git flow 出自 A successful Git branching model,这里使用了一个前端项目配合本文稿实施了 git flow 并记录流程作出示例和参考,对 hotfix 与持续部 ...

  4. docker build命令详解_Docker 搭建你的第一个 Node 项目到服务器

    本文你能学到什么 Docker 是什么 Docker 概念 关于 Docker 的概念是确实不太好总结,下面我通过四点向你说明 Docker 到底是个什么东西. Docker 是世界领先的软件容器平台 ...

  5. Anytime项目开发记录0

    Anytime,中文名:我很忙. 开发者:孤独的猫咪神. 这个项目会持续更新,直到我决定不再维护这个APP. 2014年3月10日:近日有事,暂时断更.希望可以会尽快完事. 2014年3月27日:很抱 ...

  6. 没有文档,没有老员工讲解,悲催的新人如何快速熟悉一个新项目?

    本文来自闪客Sun的投稿,博客地址: https://www.cnblogs.com/flashsun/p/9450066.html 看完你就会明白,虽然有一定的方法论,但是不下功夫,没有耐心,还是万 ...

  7. prism项目搭建 wpf_Prism完成的一个WPF项目

    本着每天记录一点成长一点的原则,打算将目前完成的一个WPF项目相关的技术分享出来,供团队学习与总结. 总共分三个部分: 基础篇主要针对C#初学者,巩固C#常用知识点: 中级篇主要针对WPF布局与Mat ...

  8. 把python37添加到环境变量配置_关于在win 10上成功创建一个Django项目时遇到django-admin的手动配置环境变量问题。...

    前言 初学Python Web 在创建第一个Djang项目的时候出现了很多的问题,今天和大家分享并记录一下这次艰难的历程! 一.官网下载Python以及安装Django 1.Python的下载安装 链 ...

  9. 01-Flutter移动电商实战-项目学习记录

    01-Flutter移动电商实战-项目学习记录 一直想系统性的学习一下 Flutter,正好看到该课程<Flutter移动电商实战>的百度云资源,共 69 课时,由于怕自己坚持不下去(经常 ...

  10. 第一个django项目

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 说在前面 ...

最新文章

  1. JGG | 肠道微生物研究助力穿山甲圈养保护
  2. Shiro 权限框架使用总结
  3. 题目3:文本文件单词的检索与计数(实验准备)
  4. html 分割线_零基础网页设计/前端/html,第四课:前三课总结,以及单标签img
  5. 字节跳动python面试_字节跳动的面试感受
  6. 大学计算机基础B这本书哪有,大学计算机基础b试卷
  7. SAP C4C,CRM和S4HANA的Saved Query使用介绍
  8. java字符串底层实现_「JAVA」细述合理创建字符串,分析字符串的底层存储,你不该错过...
  9. python qt 拖拽组件使用方法_Python QT组件库qtwidgets的使用
  10. 【数据结构与算法】带环单链表查找环的入口算法
  11. 为什么真正的神经元学得更快
  12. python thread.event
  13. 基于人脸识别的商业大数据2
  14. 南昌航空大学961数据结构真题答案
  15. python无头浏览器截图_selenium3使用谷歌无头浏览器、截图
  16. python简单爬虫获取行政边界点坐标
  17. android 刷recovery,安卓手机怎么刷入Recovery 命令行刷入Recovery教程
  18. 成功解决We recommend that if you want Anaconda registered as your system Python, you unregister this Pyt
  19. oracle latch等待,latch等待事件汇总
  20. vue创建一个简易版高德地铁路线图

热门文章

  1. RNN预测股票开盘价(TensorFlow,tensorboard可视化)
  2. Windows虚拟主机有哪些优势?
  3. java中编写一个三角形类,java 三角形类Triangle java 三角形类 Triangle的用法详解
  4. FORCE_CONSTANTS中3阶力常数大小与原子间距的分析脚本
  5. 中国大学慕课——程序设计与算法(一)第二周测验
  6. UVA 10499 正义的土地
  7. 1506.01186-Cyclical Learning Rates for Training Neural Networks
  8. web页面PC端和移动端的区别
  9. Dao和Repository,你还傻傻分不清吗?
  10. 通过 JavaMail 访问 Hotmail 邮箱(hotmail不提供smtp和pop3服务)