c/c++语言中有很多地方要用到extern,但是如果没有真正的了解它的意义,会给编程带来很大的麻烦,为了使大家少走弯路,特祥细的说明一下。
对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c文件的程序之前必须加上int i进行定义。extern int i=0;这一句声明和定义都做了。
对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。如果在头文件中定义,则编译的时候会出现重复定义的错误。如果只有头文件中声明就会出现没有定义有警告。
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: K
MODULE: 222.obj (222)
出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)
对于比较小的程序,一般只有一个c文件和一个头文件,全局变量我们通常会直接定义在c文件中,在程序之前加int i定义。如果要在头文件中定义有以下两种方法:用extern来声明:extern int i;这一句只是对变量i进行声明,在c文件的程序之前必须加上int i进行定义。extern int i=0;这一句声明和定义都做了。
对于大一点的程序,有很多c文件和头文件,这个时候全局变量就必须在头文件中声明(不需要初始化),然后在一个c文件中定义(该初始化的要初始化)。如果在头文件中定义,则编译的时候会出现重复定义的错误。如果只有头文件中声明就会出现没有定义有警告。
*** ERROR L104: MULTIPLE PUBLIC DEFINITIONS
SYMBOL: K
MODULE: 222.obj (222)
出现上述错误则是因为变量k重复定义,把你的头文件中的变量定义前加extern(只是变量声明不用初始化),再在某一个你要调用该变量的c文件的程序之前再定义(注意第一个调用的c文件要负责附带初始化该变量,其他调用的c文件就不需要初始化过程啦)
今天调试时遇到了这个问题,以前都不注意这些警告错误,现在看来争取要做到:0错误,0警告。
中断中和中断外都调用了同一个串口打印函数,一直有上述的报警,没在意,今天调试时发现串口打印出了一些乱七八糟的东东,且程序也不知道跑哪里去了,很郁闷。最后查到是上述这个问题导致的,现在解决办法为采用第二种办法,第一种办法据说要耗很多存储空间,以后慢慢体会。
说说几个小问题吧,一般我们在用KEIL的时候,只要编译器报
说说几个小问题吧,一般我们在用KEIL的时候,只要编译器报
- 0 Error(s) 一般我们都不去管多少个 Warning(s).了,一般这样程序基本都能运行,但是其实仔细想想,这里还是有问题的,否则编译器没事吃饱了撑得,报什么警告啊~~~
今天来说说*** WARNING L15: MULTIPLE CALL TO SEGMENT这个问题!
其实这个问题应该是引起注意的,有可能引起程序冲突,但是一般时候程序运行不会有问题,但是如果出来问题,那将会是很讨厌的问题.
分析一下 产生这一警告的一个根源是:例如在主循环里调用了一个函数,而在中断服务中,
你又一次调用了同样的函数。这样当主循环运行到该函数中时, 一旦产生中断,则在中断里又再次调用该函数!而使得该子函数发生了重入,这时,经管概率很低,但是很可能出错!这样,编译器就给出了警告!告诉你*** WARNING L15: MULTIPLE CALL TO SEGMENT ,表达的意思是发生了重入!字面意思自己理解去吧~~~
想要避免这种情况的方法
一.用reentrant使函数重入
关于reentrant的说明:
1,重入函数不能传递bit类型的参数和变量;
2,重入函数建立的是模拟堆栈区,所以不使用一般函数位于存储模式默认空间的可覆盖式堆栈,而是在同一空间从顶端另行分配一个非覆盖式的重入堆栈。
small 默认空间是 data;
compact 默认空间是 pdata;
largr 默认空间是 xdata;
3,由于要保存参数和局部变量,所以会消耗很大的栈空间;尽量少用这种模式;
4、 在同一程序中可以定义和使用不同存储器模式的重入函数,任意模式的重入函数不能调用不同存储器模式的重入函数,但可以调用普通函数。
5、 实际参数可以传递给间接调用的重入函数。无重入属性的间接调用函数不能包含调用参数。
5、 实际参数可以传递给间接调用的重入函数。无重入属性的间接调用函数不能包含调用参数。
二.如果空间多的话,可以定义两个同功能的函数,分别在中断和中断外调用
别的方法没研究出来,嘿嘿~~~对了 我建议用第二种方法好点,第一种有些限制,不爽~~
WARNING L15: MULTIPLE CALL TO SEGMENT
这个问题必须注意,可能引起程序冲突,假设你用于自动化领域,则可能导致信号产生尖峰。 产生这一警告的一个根源是:你在主循环里调用了一个函数(如aaa),而在中断服务函
数里,你用调用了这个函数(如aaa)。这样当主循环运行到该函数中 是,一旦产生中断,则在中断里又再次调用该函数!这时,很可能出错! 避免这种情况的方法很多:如,在进中断的时候置需调用该函数的标志,而在主循环中调用该函数
需要确认注册邮箱后才能开通博客,立即确认我的邮箱
LOGO
窗体顶端
文章 搜索 高级搜索 3 3
∙ 滤波器new!
∙ LED驱动 new!
∙ 新能源 new!
∙ PLL
∙ PCIE协议
∙ 可穿戴
∙ LSI
∙ FCI
窗体底端
热点搜索: 无线路由器拆解 Allegro16.3 Keysight示波器 特权同学 2015IIC China
首页 新闻 实例 技术 专题 参考设计 下载 视频 论坛 博客 小组 在线研讨会 热点专区
设计中心: 模拟 电源 嵌入式 测试与测量 通信 EDA 可编程器件 微处理器与DSP 消费 汽车 工业 医疗
∙ 加入博客大赛第二季,长知识!
∙ 2015博客大赛第1季获奖名单
∙ 创新奖在线投票活动发奖通知
∙ 每天登陆1秒签到,赚E币换礼!
EDN电子技术论坛>博客 >smallbright博客 >玩转儿传感器之超声波模块HC-SRO4的使用
窗体顶端
窗体底端
smallbright的博客——电子作坊 | |
博主:smallbright 介绍: 从一个初学者出发,一个菜鸟的身份,去玩转儿电子世界! 文章(2) 访问(2769) 评论(0) 投票(0) 订阅本博 | |
博文列表查看方式:
玩转儿传感器之超声波模块HC-SRO4的使用 | 发布时间:2013-12-05 20:00:45 |
技术类别:单片机 | |
需要确认注册邮箱后才能下载,立即确认我的邮箱 |
超声波模块的使用说明
拿到超声波模块(模块型号是HC-SRO4)看见了,该模块有4个接口,分别是vcc,Trig,Echo,GND。如图1所示。
图1
当时以为Trig,Echo引脚要用到计数器,或者定时器2的捕获模式呢?后来发现自己错误了。
下面讲解一下,超声波模块是怎么用的。Trig引脚相当于该模块的开关,给Trig引脚一个至少持续10us的高电平脉冲信号,该模块就可以开始工作了。这时,该模块会自动从这两个“大喇叭”发送8个40KHZ的方波,然后自动检测是否有信号返回。如果有信号返回的话,那么该模块的Echo口就会输出一个高电平,高电平持续的时间呢,就是超声波从发送到接收的时间啦!我们要做要做的就是开启超声波模块,然后再通过Echo知道超声波从发送到接收的时间就可以啦!怎么样简单吧!
再啰嗦几句,讲解一下,编程的细节问题。
模块电源是什么意思1. 怎么能准确读到Echo高电平的呢??
没错用定时器,可以这样,当开始检测高电平时,就开启定时器,进行计数,当Echo变为低电平时,然后读取TH0,TL0中的值。但是,要是超声波回波脉宽比较长,也就是说如果高电平的时间持续的时间长,造成了定时器溢出怎么办?这时可以开启定时器中断,进行延时等待,期间设置一个变量,用来计算等待的时间,即,高电平持续的时间就是从TH0,TL0读取的数,加上定时器等待的时间,再减去以前装的初值。这种计数也不是无限长的,超声波回声脉宽最多18ms,也就是说等待18ms后就不用再等待了,这时候读出来的时间也不准了。后面的工作我想你应该知道怎么做了吧。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论