2005-02-16 17:32:00 czeus 阅读数 1898
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3487 人正在学习 去看看 朱有鹏
让单片机运行速度更快一些

作 者:■ 清华大学 林 彬  北京邮电大学 石玉泽

引 言:

1 问题的提出

1.1 硬件技术背景

  单片机的频率越来越高,RAM的访问速度也来也快,但单片机系统的效率并不一定成比例的提高。
目前,使用的主流单片机有80386EX(50MHz,外部地址/数据总线16位)、MPC860T(66MHz,外部地址/数据总线32位)以及DS80C32(25MHz,外部地址/数据总线8位);使用的SDRAM有HY57系列、K416系列(访问速度100MHz或133MHz);使用的SRAM 如IDT71024、IDT7256(50MHz);使用的Flash有AT29C512、SST39VF040、AT29C010(8MHz或15MHz)等。可见,SDRAM,SRAM的速度和单片机是匹配的,甚至比单片机的速度更快一点,不需要单片机插入等待状态。而Flash的访问频率则比单片机慢2~6倍,单片机往往要通过插入多个等待状态来和它相匹配,况且Flash多为8位,而当前单片机多为16,32位,更多的降低了单片机的工作性能。

  根据上述分析,如果提高Flash的访问速度,扩展Flash为16位或32位,那么程序执行的速度就快了,单片机的性能也就提高了。如果能够将这一想法变成事实,而且成本低廉的话,那是最好不过的事情。事实上,可以将8位的Flash扩展为16位、甚至32位,但要付出2~4倍的成本。由于Flash结构及工艺原因,在目前不可能有高达66MHz的商用化且价格低廉的Flash。所以,只能通过其它方式来提升单片机的运行速度。

1.2 软件技术背景

  首先,看看传统单片机程序的运行原理,为了便于说明,假定硬件平台为860T,时钟为50MHz;SDRAM空间4M×32bit,地址范围从0x00000000~0x00FFFFFF,访问时间10ns;Flash空间512K×8bit,访问时间为100ns,地址范围从0x02800000~0x0287FFFF(至于其它单片机,运行原理大致相同,可以类推)。860T在上电后,PC(Program Counter)=0x2800100,程序从PC指定的地方执行,首先执行初始化代码(BootCode),再执行主程序(AppCode)。程序从Flash中读取指令(code),来完成数据的传输——可能是SDRAM和内部寄存器的传输,SDRAM之间的传输,SDRAM和外设的传输,中断处理等各项工作。可见在程序运行时,很大一部分时间是从Flash中读取指令,而这个过程是很费时间的。以假定的860T硬件平台为例,因为Flash访问时间为100ns,所以读一条指令的时间至少是100ns,也就是说860T读一条指令的时候要等待100ns。(指令cache通过预取指令的方式,可以使实际取指令时间短一些,但这种方法的效果并不明显,况且很多单片机还没有指令cache。)

  860T平台的内存分配如图1所示。
       
2 将代码从Flash搬运到SDRAM中的原理

  通过上述分析,初始化代码BootCode只在程序启动的时候执行,就是慢一点,也可以接受。真正影响性能的是主程序(AppCode),因为这里的代码在不停的重复执行,如果可以缩短它的取指令时间,则单片机的空闲时间将大大减少,性能也就提高了很多。SDRAM的速度比较快,如果将代码搬运到SDRAM中,取指令时间就减少了很多;而且SDRAM空间大,不会因为代码占用了一部分空间而影响性能。但这不仅仅是简单的搬运过程,有物理存储器地址的变化牵涉在这个过程中。将软件源代码转换成可执行的二进制映像包括三个步骤:首先,每一个源文件都必须被编译或汇编到一个目标文件(object file);第二步,所有的目标文件要连接成一个目标文件,它叫可重定位程序(relocation program);最后,在一个称为重定址(relocation)的过程中,要把物理存储器地址指定给可重定位程序里的每个相对偏移处,生成一个可执行的二进制映像文件。如果在Flash中运行,则所有的物理存储器地址应该在Flash的地址空间中。如果要在RAM中运行,则所有的物理存储器地址应该在Flash的地址空间之中。也就是说,如果要使从Flash中搬运到SDRAM中的代码可用,则必须改变被搬运代码的物理存储器地址。

3 搬运代码的实现方法

  下面结合假定的硬件平台,详细描述物理存储器地址重定位,代码搬运的原理及过程。我们编写两个c文件——RomTool.c、RAMapp.c。

  RomTool.c完成860T初始化,SDRAM的刷新,中断及外设的初始化;Flash到SDRAM的代码搬运驱动模块及跳转模块。对应的二进制映像文件为RomTool.bin。

  RAMapp.c是实际的应用程序, 对应的二进制映像文件为RAMapp .bin。RAMapp.bin被搬运后在SDRAM中运行。

3.1 物理存储器地址映射规则

  RomTool.c的物理地址映射规则为:数据放在起始为0x3000,大小为0xf0000的SDRAM空间里;代码被烧结在起始为0x02800000,大小为0x10000的Flash空间里,不会被搬运,也在该空间里运行。
所以在RomTool.lnx中指定的定位规则也应该是这个地址范围,如下:
MEMORY
{
ram1: ORIGIN = 0x00003000, LENGTH = 0xf000
flash: ORIGIN = 0x02800000, LENGTH = 0x1000
}
SECTIONS
{
.data : {} > ram1
.text : {} > flash
}

  RamApp.c的物理地址映射规则为:

  数据放在起始为0x3000,大小为0xf0000的空间里;代码被烧结在起始为0x02810000,大小为0x70000的Flash中,它要被搬运到起始为0x00F00000,大小为0x70000的SDRAM空间里,即RamApp.Bin实际在SDRAM中运行。

  所以,在RamApp.lnx中指定的定位规则应该在SDRAM中,如下:
MEMORY
{
ram1: ORIGIN = 0x00003000, LENGTH = 0xf000
ram: ORIGIN = 0x00F00000, LENGTH = 0x7000
}
SECTIONS
{
.data : {} > ram1
.text : {} > ram
}

  最后,在860单片机系统的地址映射规则如图2所示。对照图1,可以观察到这和传统的程序地址映射有很大不同。
        
3.2 搬运的过程

  860T上电复位,RomTool.bin首先被执行,完成初始化工作后,运行代码搬运函数,将RAMapp.bin搬运到SDRAM中,随后改变PC(Program Counter)的值,无条件转移到SDRAM中运行RAMapp.bin,如图3所示。
          
3.3 搬运代码的驱动模块及跳转模块源代码

(1)搬运代码驱动模块的代码
void MoveCodeF_to_RAM(UWORD *FlashCode_Add, UWORD *RamCode_Add,UWORD CodeLen) {
do{
*RamCode_Add++ = *FlashCode_Add++;
CodeLen?
} while ( CodeLen!=0)
}
该段代码是将开始地址为FlashCode_Add,长度为CodeLen的Flash代码搬运到开始地址为RamCode_Add,长度为CodeLen的SDRAM 中。

(2)主函数及跳转模块
#define FlashCode_Add_V 0x02810000
#define RamCode_Add_V 0x00f00000
#define CodeLen_V 0x00070000/4
void main(){
UWORD *I=(UWORD *) FlashCode_Add_v;
UWORD *j= (UWORD *) RamCode_Add_v;
UWORD *k= (UWORD *) CodeLen_V;
MoveCodeF_to_RAM( (UWORD *) i, (UWORD *) j, (UWORD *)k );
# 跳转模块
asm(“addis r2,0,0x00f0”);
asm(“ori r2,r2,0x0000”); # 代码起始地址0x00f00000
asm(“mtspr LR,r2”);
asm(“bclr 20,0”); # 无条件转跳到链接寄存器
# (LR)中的地址
}
FlashCode_Add_V:被搬运代码的首地址,在Flash中。
RamCode_Add_V:被搬运代码的目标地址,在RAM中。
CodeLen_V:被搬运代码的长度,按32位计算。
该函数在调用代码搬运MoveCodeF_to_RAM函数,将代码从Flash搬运到SDRAM中后,将程序指针转移到SDRAM中。注意跳转的地址一定要和RamCode_Add_V一致。

4 小 结

可见,正确完成代码搬运的关键在于:
① 确定被搬运代码的物理地址映射规则, 物理地址一定是在SDRAM中;
② 被搬运代码是被烧结在Flash中,后来又被搬运到SDRAM中;
③ 无条件转移到SDRAM中,运行被搬运代码(应用程序代码)。
对于其它型号的单片机,可以根据该原理类推,方法是一样的,只是具体的代码不同而已。相信你的单片机系统在经过这样的处理后,效率一定会高很多。
2019-01-17 15:16:06 Emoeror_Zhang 阅读数 256
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3487 人正在学习 去看看 朱有鹏

目录

1、影响效率的因素

使用延时函数

代码精简

宏定义

数据类型

定义变量

条件编译

C、汇编混编

2、如何提高效率

保障时效性

精简代码

变量类型

宏定义

定义变量

条件编译

C、汇编混合编译


1、影响效率的因素

  • 使用延时函数

  • 代码精简

  • 宏定义

  • 数据类型

  • 定义变量

  • 条件编译

  • C、汇编混编

2、如何提高效率

  • 保障时效性

       裸机系统中,在main函数里面while(1)一直在运行,使用延时函数会造成无效的等待时间,使单次while()循环执行延长,程序执行时间延长,时效性差。使用延时器的方法、中断定时执行。

  • 精简代码

        C是面向过程编程,也要注重面向对象的思想编程,利用结构体、联合体、共同体的特性,将特性一直的变量一起结构化,函数实现过程也要注意拓展,接口使用结构体输入参量,将步骤一致的实验过程整合到一个函数里面,配合for、while实现循环使用,精简函数代码。

  • 变量类型

         1、大小适合:使用合适的数据类型,避免造成内存的浪费,如0-255范围,可以定义成unsigned char ,也可以是unsigned int,但是内存使用大小不一样。

         2、符号类型:数据是否有负数,没有负数的数据就定义成unsigned。

  • 宏定义

         一些经常使用的变量,不限类型,需要经常更改或者寄存器经常用到,还有一些简单的程序如,比较大小的三目程序都可以使用宏定义。

  • 定义变量

      局部变量,全局变量,静态局部变量,静态全局变量的异同:

     (1)局部变量:在一个函数中或复合语句中定义的变量,在动态存储区分配存储单元,在调用时动态分配,在函数或复合语句结束时自动释放;

     (2)静态局部变量:在一个函数中定义局部变量时,若加上static声明,则此变量为静态局部变量,在静态存储区分配存储单元,在程序运行期间都不释放;静态局部变量只能在该函数中使用;静态局部变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));静态局部变量在函数调用结束后不自动释放,保留函数调用结束后的值;

    (3)全局变量:在函数外定义的变量称为全局变量;全局变量在静态存储区分配存储单元,在程序运行期间都不释放,在文件中的函数均可调用该全局变量,其他文件内的函数调用全局变量,需加extern声明;

    (4)静态全局变量:在函数外定义变量时,若加上static声明,则此变量为静态全局变量;静态全局变量在静态存储区分配存储单元,在程序运行期间都不释放,静态全局变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));只能在当前文件中使用。

     一般情况下就定义成局部变量,这样不仅运行更高效,而且很方便移植。局部变量大多定位于MCU内部的寄存器中,在绝大多数MCU中,使用寄存器操作速度比数据存储器快,指令也更多更灵活,有利于生成质量更高的代码,而且局部变量所的占用的寄存器和数据存储器在不同的模块中可以重复利用。当中断里需要用到的变量时,就需要定义成全局变量,并且加volatile修饰一下,防止编译器优化。如果数据是只读的比如数码管的断码、汉字取模的字库需要放在ROM里,这样可以节省RAM,51单片机是加code,高级点的单片机都是加const修饰。

       一般情况下,全局变量尽量不使用,影响整体程序的结构性,对于维护、二次开发影响较大。

  • 条件编译

       使用条件编译,只有当条件满足时,才会进行编译。这样减少程序实际运行代码,优化代码,对于单片机的ROM、RAM负载减少,功率也降低。

  • C、汇编混合编译

      C和汇编汇编一般在Bootloader、或者UcosII、FreeRtos等等实时操作系统时常见,汇编操作内核寄存器,和C实现混编。

2018-10-12 19:02:29 jonah_king 阅读数 2271
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3487 人正在学习 去看看 朱有鹏

想必,很多人会对这个问题有困惑?
单片机运行的时候,是运行在哪里? FLASH(ROM)?还是RAM。

这就需要我们了解上一篇的内容,单片机的运行视图和加载视图@jonah_king。

我们程序的运行其实是由多种方式的,不过一般常见的有两种。
运行在ROM里的和运行在RAM里的。

一般比较小的系统,也就是说,单片机本身内部就有FLASH的。这种FLASH不同于通用的FLASH,他是支持随机地址访问的。这样的单片机,一般程序都存储在FLASH里,然后运行的时候,PC指针也可以到固定的FLASH地址里去取指令,所以呢,程序是运行在FLASH里的。

还有一类,是相对比较大一些的系统,这些系统的程序,相对来说都是比较大的,单片机也都是比较强大的。
他们的FLASH一般都是外挂的大FLASH,这样的FLASH就有个特点,不支持随机地址访问,必须一页一页的访问,这样的话,程序就不能运行在FLASH里,因为下一条指令会招不到。 怎么办呢,那就有办法啊,RAM支持随机地址访问啊,我们把FLASH里面的内容搬移到RAM里,就可以了,这样访问起来就会更快了。

通俗点来讲呢,我们说一个电脑的内存有多大,就是这个RAM,我们的系统和程序都是在那4个G里运行这的。
所以啊,一般说来,一个操作系统的内核,其实是没有太大的。

说白了,就是一些简单的单片机,他的FLASH支持随地地址访问,为了降低程序,程序就运行在了FLASH里面了。

2018-12-09 20:02:59 lin5103151 阅读数 1193
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3487 人正在学习 去看看 朱有鹏

单片机的最小系统就是让单片机能正常工作并发挥其功能时所必须的组成部分,也可理解为单片机正常运行的最小环境。
在这里插入图片描述
其主要构成为四部分:
1.单片机芯片
2.系统电源
3.时钟电路
4.复位电路
这四个部分不可缺少,缺少其中一部分,便会造成单片机无法正常运行。以STM32F103C8T6单片机为例。

  1. STM32F103C8T6单片机
    单片机,相信大家应该都知道,主要作用是程序的执行和外部电路的控制。
    在这里插入图片描述

  2. 系统时钟
    系统时钟是由晶振、电容、电阻构成的。单片机内部振荡器在外部晶振、电容的作用下产生自激振荡,为单片机提供12MHz的正弦信号。时钟电路相当于单片机的心脏,它的每一次跳动(振荡节拍)都控制着单片机执行代码的工作节奏。振荡得慢时,系统工作速度就慢;振荡得快时,系统工作速度就快。此款单片机提供有内部时钟,无特殊要求可省去此电路。
    在这里插入图片描述

  3. 复位电路
    由电容串联电阻构成,我们知道,电容的电压不能突变的,当系统一上电,单片机的RST脚将会出现一个持续的高电平,并且,这个高电平持续的时间由电路的电容值来决定.STM32单片机的RST脚检测持续到持续到20us以上的高电平后,会对单片机进行复位操作。所以,适当组合RC的取值就可以保证可靠的复位。
    在这里插入图片描述

  4. 系统电源
    由于我们使用的电源适配器产生的直流电压为5V,单片机的工作电压为3.3V。所以需要对电压进行降压处理。此电路使用了LP3965-3.3芯片,可将5V转换为3.3V。
    在这里插入图片描述

  5. 其他辅助电路
    此电路可供用户进行程序调试和下载
    在这里插入图片描述

信号指示灯:可作为程序正常运行的状态灯
在这里插入图片描述
BOOT0/BOOT1:这两个引脚可控制单片机程序的启动方式,

  1. BOOT0=X,BOOT=0:主闪存存储器启动
  2. BOOT0=0,BOOT=1:系统存储器启动
  3. BOOT0=1,BOOT=1:内置SRAM启动
    此电路BOOT0=0,BOOT1=0,单片机程序为默认启动模式。
    在这里插入图片描述

此电路的电容和磁珠只要是作为系统电源的滤波处理。
在这里插入图片描述

以上就是单片机最小系统的全部电路。

如果您喜欢,可关注个人公众号“电子应用学习馆”,获取更多的资料例程
在这里插入图片描述

2015-09-25 09:14:56 lwz19921219 阅读数 836
  • 51单片机综合小项目-第2季第4部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第2季第4个课程,也是51单片机学完之后的一个综合小项目,该项目运用了开发板上大多数外设设备,并将之结合起来实现了一个时间、温度显示以及报警功能、时间调整功能等单片机控制常见的功能,有一定代码量,需要一定调试技巧和编程能力来完成,对大家是个很好的总结和锻炼,并且能拓展项目经验。

    3487 人正在学习 去看看 朱有鹏
该总结在百度云网盘中 ,可以打开下载--------点击打开链接

51单片机最小系统

阅读数 1804

单片机

阅读数 5213

没有更多推荐了,返回首页