PICC——函数

发布者:HarmoniousCharm最新更新时间:2020-03-17 来源: eefocus关键字:PICC  函数  长度限制 手机看文章 扫描二维码
随时随地手机看文章

函数的代码长度限制

PICC决定了C原程序中的一个函数经编译后生成的机器码一定会放在同一个程序页面内。中档系列的 PIC 单片机其一个程序页面的长度是 2K字,换句话说,用 C 语言编写的任何一个函数最后生成的代码不能超过 2K字。一个良好的程序设计应该有一个清晰的组织结构,把不同的功能用不同的函数实现是最好的方法,因此一个函数 2K字长的限制一般不会对程序代码的编写产生太多影响。如果为实现特定的功能确实要连续编写很长的程序,这时就必须把这些连续的代码拆分成若干函数,以保证每个函数最后编译出的代码不超过一个页面空间。


调用层次的控制

中档系列 PIC 单片机的硬件堆栈深度为 8 级,考虑中断响应需占用一级堆栈,所有函数调用嵌套的最大深度不要超过 7 级。编程员必须自己控制子程序调用时的嵌套深度以符合这一限制要求。


PICC 在编译时将严格进行函数调用时的类型检查。一个良好的习惯是在编写程序代码前先声明所有用到的函数类型。例如:

void Task(void);

unsigned char Temperature(void);

void BIN2BCD(unsigned char);

void TimeDisplay(unsigned char, unsigned char);


这些类型声明确定了函数的入口参数和返回值类型,这样编译器在编译代码时就能保证生成正确的机器码。笔者在实际工作中有时碰到一些用户声称发现 C 编译器生成了错误的代码,最后究其原因就是因为没有事先声明函数类型所致。


建议大家在编写一个函数的原代码时,立即将此函数的类型声明复制到原文件的起始处,见例 11-1;或是复制到专门的包含头文件中,再在每个原程序模块中引用。


PICC 可以实现 C 语言的中断服务程序。中断服务程序有一个特殊的定义方法:

void interrupt ISR(void);


其中的函数名“ISR”可以改成任意合法的字母或数字组合,但其入口参数和返回参数类型必须是“void”型,亦即没有入口参数和返回参数,且中间必须有一个关键“interrupt”。


中断函数可以被放置在原程序的任意位置。因为已有关键词“interrupt”声明,PICC 在最后进行代码连接时会自动将其定位到 0x0004 中断入口处,实现中断服务响应。编译器也会实现中断函数的返回指令“retfie”。一个简单的中断服务示范函数如下:


void interrupt ISR(void) //中断服务程序

{

      if (T0IE && T0IF)   //判TMR0中断

      {

            T0IF = 0;    //清除TMR0中断标志

             //在此加入TMR0中断服务

      }

      if (TMR1IE && TMR1IF) //判TMR1中断

      {

            TMR1IF = 0;   //清除TMR1中断标志

            //在此加入TMR1中断服务

       }

}      //中断结束并返回


PICC 会自动加入代码实现中断现场的保护,并在中断结束时自动恢复现场,所以编程员无需象编写汇编程序那样加入中断现场保护和恢复的额外指令语句。但如果在中断服务程序中需要修改某些全局变量时,是否需要保护这些变量的初值将由编程员自己决定和实施。


用 C 语言编写中断服务程序必须遵循高效的原则: 


代码尽量简短,中断服务强调的是一个“快”字。


避免在中断内使用函数调用。虽然 PICC 允许在中断里调用其它函数,但为了解决递归调用的问题,此函数必须为中断服务独家专用。既如此,不妨把原本要写在其它函数内的代码直接写在中断服务程序中.


避免在中断内进行数学运算。数学运算将很有可能用到库函数和许多中间变量,就算不出现递归调用的问题,光在中断入口和出口处为了保护和恢复这些中间临时变


中档系列 PIC 单片机的中断入口只有一个,因此整个程序中只能有一个中断服务函数。


PICC 提供了较完整的 C标准库函数支持,其中包括数学运算函数和字符串操作函数。在程序中使用这些现成的库函数时需要注意的是入口参数必须在 bank0 中。


变量就需要大量的开销,严重影响中断服务的效率。

关键字:PICC  函数  长度限制 引用地址:PICC——函数

上一篇:PIC单片机输出比较(PWM)模块介绍
下一篇:PIC单片机软件平台----MPLAB IDE和MPLAB X IDE

推荐阅读最新更新时间:2024-11-12 08:02

STM32F4读写内部FLASH【使用库函数
STM32F4Discovery开发帮使用的STM32F407VGT6芯片,内部FLASH有1M之多。平时写的代码,烧写完之后还有大量的剩余。有效利用这剩余的FLASH能存储不少数据。因此研究了一下STM32F4读写内部FLASH的一些操作。 【STM32F4 内部Flash的一些信息】 STM32F407VG的内部FLASH的地址是:0x08000000,大小是0x00100000。 写FLASH的时候,如果发现写入地址的FLASH没有被擦出,数据将不会写入。FLASH的擦除操作,只能按Sector进行。不能单独擦除一个地址上的数据。因此在写数据之前需要将地址所在Sector的所有数据擦除。 在STM32F4的编程手册上可找到F
[单片机]
STM32F4读写内部FLASH【使用库<font color='red'>函数</font>】
STM32 PWM波驱动模拟舵机(库函数版)
数字舵机 vs 模拟舵机 “数字舵机区别于传统的模拟舵机,模拟舵机需要给它不停的发送PWM信号,才能让它保持在规定的位置或者让它按照某个速度转动,数字舵机则只需要发送一次PWM信号就能保持在规定的某个位置。” 到底模拟舵机与数码舵机在实际使用中有什么区别呢?我自己总结大致有以下几点: 1 数码舵机在位置准确度方面要高于模拟舵机。 2 在同样标称1.6公斤的舵机面前数码舵机在实际表现中会感觉更加“力气大”而模拟舵机就会“肉”点。 3 模拟舵机由于控制芯片是模拟电路,所以即便是相同型号的舵机会存在小小的性能差异,而数码舵机在一致性方面就非常好。 4 数码舵机一般均采用PID优化算法,所以,线性要好过模拟舵机。 5 对于高灵敏度
[单片机]
STM32 SysTick定时器常见问题及延时函数的实现
Q:什么是SYSTick定时器? SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD 寄存器中自动重装载定时初值。只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息。 Q:为什么要设置SysTick定时器? (1)产生操作系统的时钟节拍 SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 (2)便于不同处理器之间程序移植。 Cortex‐M3处理器内
[单片机]
STM32 SysTick定时器常见问题及延时<font color='red'>函数</font>的实现
函数信号发生器对两路同步窄脉冲信号的输出能力比较
方案1:普源信号发生器DG5000系列 Fig1 普源DG5000系列函数信号发生器 Fig2 普源DG5000系列脉冲波指标 根据实测,普源DG5000函数信号发生器在当需要输出一个10kHz周期重复,5Vpp峰峰值,脉宽为5ns的脉冲时,双通道具备同步输出设置 Fig3 正脉宽设置为5ns 通过示波器观察到实际波形如下: Fig4 正脉宽设置5ns时,输出的脉冲波形 由Fig 4 可以看出,输出5ns脉宽方波时,正脉宽的顶端是尖的,不是很平,这是由于当前条件下的函数信号发生器输出最窄脉宽到了极限,所以有些失真。 当设置脉宽取10ns时,DG5000信号发生器的输出波形近似脉冲矩形,顶端较平。 Fig5 用5
[测试测量]
<font color='red'>函数</font>信号发生器对两路同步窄脉冲信号的输出能力比较
ARM学习易搞混的:函数指针和指针函数
在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,和大家的一些总结,整理到此,和大家分享。 首先它们之间的定义: 1、指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针 类型标识符*函数名(参数表) int*f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。 表示: float*fun(); float*p; p=fun(a);
[单片机]
STM32库函数USART_SendData问题和解决方法
1. 问题及现象 使用USART_SendData()函数非连续发送单个字符是没有问题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。 如: 1 2 for(TxCounter = 0;TxCounter RxCounter; TxCounter++) USART_SendData(USART1, RxBuffer ); 2. 原因 此API函数不完善,函数体内部没有一个判断一个字符是否发送完毕的语句,而是把数据直接放入发送
[单片机]
第3阶段——内核启动分析之创建si工程和分析stext启动内核函数(4)
1 创建内核source sight 工程 1.1 点击 “add all” 添加所有文件,后面再慢慢删去Arch目录和Include目录中与2440芯片没用的文件。 1.2 点击Remove Tree 删除Arch文件夹,再添加与2440相关的硬件核心代码以及其它公用的代码  Arch:包含了平台,处理器相关的代码,并包括boot文件夹。 1.2.1 点击Add Tree添加以下子目录: linux-2.6.22.6/arch/arm/boot (启动配置文件) linux-2.6.22.6/arch/arm/common (公共文件) linux-2.6.22.6/arch/ar
[单片机]
第3阶段——内核启动分析之创建si工程和分析stext启动内核<font color='red'>函数</font>(4)
linux 中断驱动和led驱动读写的函数清单
请注意, linux的应用层对字符设备都是采取文件读写的方式,所以说我们的驱动程序也是用的是文件的形式。 我们需要把所有的驱动程序封装到文件的读写形式里面。 1、 static int XXX_open(struct inode *inode, struct file *file) //这个函数是挂载到struct file_operations open里面的。 此函数需要完成对各种引脚或者总线的硬件初始化,中断初始化 等等 2、static ssize_t XXX_write(struct file *file, const char __user *buf, size_t count, loff_t* ppos) /
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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