找回密码
 立即注册
查看: 5393|回复: 10

【已建议送实验箱】学习心得《STC32位8051单片机原理及应用-STC32G12K128》何宾教授

[复制链接]
  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-21 11:28:54 | 显示全部楼层 |阅读模式
本帖最后由 angmall 于 2023-8-29 22:10 编辑

在本贴我将分享我的学习心得和一些笔记


首先,非常感谢STC为广大单片机学习者提供了一次这么难得的免费学习课程,教学研讨会。
感谢贵司负责人沈慧琴小姐通知这个STC教学研讨会。


在此之前我介绍一下我的底子,本人是海事船舶 无线电与雷达系统 安装与维修专业,学习过C/C++语言;电工电子;微机原理;51单片机;PIC; AVR。
由于专业侧重点的原因,对于以上课程学习的比较浅显,但是个人对于单片机,嵌入式非常感兴趣,想要继续深入学习,
现在已经退休,比较有时间深入学习,因此参加本次课程,好好学习,掌握知识,提升自己!


STC15W-001.jpg

跟随着何兵教授,学习51单片机已经有一段时期了,开始学用STC15W。
对传统8051进行了全面提速,指令速度甚至提高了24倍,大幅度提高了片内集成外设的种类和数量,跟更多的高功能部件。
指令代码完全兼容传统的8051单片机,提供了21个中断源和两级中断优先级。
IAP15W4K58S4一个芯片就是一个仿真器,首次实现一个芯片就可以仿真。
扩大了对这门课程学习,收获满满。




STC8A-001.jpg

后来再跟何兵教授学用 STC8A8K64S4A12单片机。
代表的是 STC8系列超高速8051单片机,该系列是STC价格最低,功耗最低,速度最快的单片机。
该系列单片机同时支持Keil uVision 环境下的纯软件仿真和硬件在线仿真与调试功能,该单片机本身就是一个仿真芯片。
指令代码完全兼容传统的8051单片机,提供了22个中断源和4级中断优先级。
将传统8051单片机内特殊功能寄存器SFR扩展到了扩展特殊功能寄存器XSFR,进一步增强了处理器对单片机集成外设的控制能力,这也增强了 C语言指针的应用。




试用过STC16,感觉只有15与8好用,现在终于可以用上了32位单片机。
STC32G作为一个简易的单片机,可以以一个廉价的价格实现用户的需求,可以降低用户实现需求的成本,同时降低开发难度。
此国产单片机造价相对进口单片机价格低廉,性能强大,可以很大程度上降低一些产品的成本,从而应用也不会太复杂。因此可能会替代很多低复杂度的32位ARM的场景。


Book001a.jpg

而STC32G也可以更好的让开发者从51单片机过渡过来。
STC32G也相对于STM32更加稳定,性价比高。
需要对单片机的功能实现有一个全面的认识,对单片机可实现的功能,以及如何适配项目,查询相关资料需要有清晰的认识。
学习单片机较为重要点是学习他人的东西,学习别人的成品项目,竞赛作品,多动手。
需要有创新精神,创造出一些令人眼前一亮的东西,发散思维。


单片机也称MCU微控制处理器,主要由晶体振荡器(Osc,也称晶振,以前都是外置,现在直接内置了)、CPU、
SRAM静态随机访问存储器、flash闪存、ADC和DAC数模转换器组成。
Box001.jpg





https://www.stcaimcu.com/forum.php?mod=redirect&goto=findpost&ptid=3325&pid=22119


2023-7-25,今天下午参与了第一次教学课程,在何老师的细心讲解之下,我对于单片机的基本架构和对于MCS-51,251的指令集有了大致的了解。也学到了嵌入式系统的硬件和软件的分层结构。


今天学习何宾老师的课有2个重要的知识点:
1,  STC32G12K128是真32位数据总线的32位8051,只是指令集兼容 Intel80251 CISC指令集
     Intel80251是8位数据总线,分时拼出16位,分时拼出32位
2,CISC/RISC;
     CISC:
     不等长指令集,有短有长的指令集组合,是相对复杂设计才可实现的指令集,用来实现的组合逻辑相对复杂;
     相同晶圆制造工艺制程,指令集组合逻辑复杂,可获得的主频相对较低,部分单条指令相对功能复杂而强大;
     空间代码效率高,省程序存储器,相对可在较低的主频完成复杂的任务
     RISC:
     等长指令集,指令相对简单,是相对简单设计就可实现的指令集,用来实现的组合逻辑相对简单;
     相同晶圆制造工艺制程,指令集组合逻辑简单,可获得的主频相对较高,但指令相对简单;
     空间代码效率相对较低,浪费程序存储器资源,相对要在较高的主频完成复杂的任务;
     由于是简单的等长指令,RISC 的逻辑和算术运算指令没有见到直接对存储器操作的指令;
     由于是简单的等长指令,RISC 的直接寻址的逻辑和算术运算指令只是对寄存器
     RISC放弃了一些CISC常用的组合逻辑较复杂的指令/芯片内部走线会较长,获得了较高的主频
所以不简单介绍汇编语言程序设计,微机原理是无法讲透的


本次课程只是第一次,涉及到的知识并不深入,能让我很好地理解、入门,我也会在后续课程中努力学习,希望在学成之后能独立完成一些项目
是的,STC32G系列单片机,STC32G是真正的32位单片机。
它的程序运行时间缩短为原来的STC15/STC8系列的3分1。跟他的指令条数也减少50%。
代码的储蓄容量减少为原来的80%.


之前用的都是8位单片机,想进一步学习高端国产32位单片机,有这样一次学习机会真的很好。支持国产单片机


2023-7-28


了解了STC系列单片机的发展历史。知道了单片机的IAP和ISP,将本地固化程序的方式称为在系统编程 (In system Programming,ISP) ;而将另一种固化程序的方式称为在应用编程 (In Application Programming,IAP),IAP技术是从结构上将Flash存储器映射为两个存储空间,与ISP相比,IAP的实现更加灵活。


STC32G系列单片机的功能
了解了STC32G12k128系列单片机的主要特点
不仅包括了它的处理器内核,工作电压,工作温度,flash储存器,sram12k共字节,也详细讲解了它的时钟控制,复位,中断,数字外设等


明白了单片机命名规则及封装封装类型
有双列直插式封装DIP,薄型四方扁平式LQFP,方形扁平无引脚QFN等封装类型,还有引脚的定义。


STC32G系列单片机引脚的驱动原理
准双向输出类型可以用作输出和输入功能,而不需要重新配置I/0口输出状态。
强推挽输出,高阻输入,开漏输出。


单片机硬件下载电路
硬件USB直接下载,STC32G系列单片机内集成了兼容USB2.0/USB1.0协议的硬件模块,因此支持自带的硬件USB下载用户程序。


最后老师详细为我们讲了keil软件的下载的安装。


第二节课感悟
此试验箱目前所焊接的传感器较全,免去了新人硬件链接的麻烦,留出的万能板也给予这个试验箱拓展更多的功能的能力。
DAC的安装可以极大的方便我们学习和掌握更多模块。
PWM模拟器的应用范围极广,这个模块的添加很舒适。
外部存储器也为我们在开发不同项目时提供了切换的便利。
各类转接口的焊接可以让此试验箱具备与多样终端通信的能力。
矩形按键的设置可以让我可以在这个箱中实现更多的功能,让我所做出来的成品具备更加直观的表现形式,添加更多的实用性。
综上所述,此试验箱所包含的各种传感器以及各类外接接口,可以让后期我们在学习过程中,根据我们自己的需求,去手动添加更多的外接设备,让这个试验箱具备更加强大的功能。


回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-21 11:30:39 | 显示全部楼层
本帖最后由 angmall 于 2023-8-22 19:59 编辑

7月25日  第一集:
1、单片机是指单个集成电路(IC)芯片上的小型计算机,也成微控制器(MCU)。
2、MCU主要面向嵌入式应用,这些应用面向自动控制产品和设备。
3、通常,在MCU内包含一个/多个中央处理器单元(CPU)、易失性和非易失性存储器,以及可编程的输入和输出设备。
4、晶体振荡器(OSC),它为MCU提供最基本的时钟源。
5、CPU是MCU中的核心功能单元。a.从MCU外部获取的所有信息都要汇集到CPU进行处理,CPU将处理后的数据送到存储器或者外设。b、CPU是指令集架构(ISA)的具体体现,也称为微架构,它所采用的ISA决定了MCU的性能和特点。
6、静态随机访问存储器(SRAM),主要勇士暂时保存在程序运行过程中所需要的数据,它充当了易失性存储器的角色。这种类型的存储器的主要特点是需要上电来保存信息,当MCU断电时,保存在易失性存储器中的数据会丢失。
7、闪存(Flash Memory),主要用于保存程序代码,它充当了非易失性存储器的角色。这种类型的存储器的主要特点是不需要上电来保存信息,当MCU断电时,程序代码仍然会保存在非易失性存储器中。
8、通用串行收发器(UART),它是一种以串行方式发送和接收数据的肩带外部设备。在MCU中,UART是标准配置。


终于明白STC32确实是32位单片机,过去一直弄不明白比8051快70倍是怎么实现的。


7月25日  第二集:


1、不同厂商的MCU内集成的CPU核有所不同。MCU厂商根据ISA设计CPU,以最终实现ISA中每条指令期望实现的功能。准确来说,所谓的处理器核类型实际上是不同的ISA.
2、本质上 MCS-51是一个8位宽度的MCU。(8位算数逻辑单元、8位数据总线和8位寄存器。)
3、MCS-51 MCU所使用的ISA包含111条指令,其中49条为单字节指令,46条为双字节指令,以及16条是三字节指令,这是复杂指令计算机(CISC)的典型代表。CISC的典型的特点就是具有可变的指令长度,并且允许在存储器上执行算术和逻辑运算。
4、8/16/32位的MCS-251 MCU.片内提供24位线性寻址能力,可寻址到达16MB的存储器空间。可通过字节、字和双字方式访问处理器核内的寄存器。丰富的指令集,包括16和32位算术和逻辑指令。


7月25日  第三集:


1、STC32是真正的32位单片机。
2、明白了8位/16位/32位寄存器之间的关系,更好的学习单片机。
3、知道了通过仿真反汇编了解程序运行的底层逻辑。


7月28日  第四集:
1、了解STC单片机的发展历史。
2、IAP和ISP的概念,使用方式。
3、STC32G12K128系列单片机的特点、性能、参数。


7月28日  第五集:
1、单片机的名明规则及封装形式。
2、STC 32 G/F   G:该系列单片机内无硬件浮点处理单元,F:该系列单片机内有硬件浮点处理单元。
3、四种I/O口驱动模式。
4、试验箱电路的介绍。
5、准双向口(弱上拉)。


7月28日  第六集:
1、Keil 的介绍。
2、Keil的下载安装。


8月1日  第七集:
1、一个完整工程的建立。(命名尽量不使用中文)
2、CPU Mode的设置
3、Memory Model 不同设置底层代码运行的不同,选择合适自己程序的需要进行设置。
4、Code Rom Size 的设置


8月1日  第八集:
1、工程中文件的添加。
2、实验箱流水灯电路的分析。
3、代码优化的不同级别对应的优化内容。(优化运行速度还是代码的大小)
4、生成文件的设置。
5、生成文件的说明。


8月1日  第九集:
1、程序的下载。
2、硬件在线调试。
3、进制数。
4、数的表示方法。


今天何宾老师讲解Keil使用。
1、Memory Model 设置,采用C与汇编的对照方式,讲明白了为什么用XSmall模式。
2、编译器的优化设置,生成的各种目标文件的详细解释,过去没有注意过。
3、STC-ISP的使用,在线调试仿真设置;常用码制的讲解。
总体,过去只会用,不知道为什么,今天重新认识Keil, 能听专家的详细讲解,温故知新,受益非浅。
详细说明了Keil的使用,真的是可以从头开始学习的。
温故知新,始终是没有错的,通过这次讲课,对以前没有使用的软件调试功能进行了认真学习,已经能够使用基本功能进行工作了!


8月4日  第十集:
1、十进制转换二进制数的方法(长除法和比较法)。
2、正数、负数、浮点数在单片机中的表示。以及在汇编中到底是怎么运行的。
3、十进制小数转换二进制数。(长乘法和比较法)。
4、计算机中正数和负数的区分。
5、负数符号幅度表书法和二进制补码.
6、有符号、无符号在单片机内是怎么运行的。
7、浮点数在单片机中是大端显示。
8、Intel MCS-251单片机是对其Intel MCS-51单片机的扩展和发展,STC32系列MCU是对 Intel MCS-251的进一步改进和发展。


  今天晚上又看了一遍,了解了stc32位创新的硬件加速算法,非常好,是不是以后只要把值写上,他自己就算了,不用再写些代码给它转换了。


8月4日  第十一集:
1、堆栈的特殊存储器空间,其作用主要用于保存上下文(也称为现场)。
    今天这节课学习到了堆栈和指针,入栈递增,出栈递减。还有stc位技术创新,xsfr特殊功能寄存器。妙,实在是妙。中国人真聪明。


8月8日  第十二集:
1、在小端模式中,先保存最低有效位,或者是低字节。最后是最高有效位,或者是高字节。
2、在大端模式中,先保存最高有效位,或者是高字节。最后是最低有效位,或者是低字节。
3、内部基本RAM其容量为256字节,扩展RAM其容量为3840字节。总容量为4K。
4、低128字节RAM兼容传统51单片机。
5、内部扩展RAM使用MOVX,在C语言中使用xdate声明存储类型访问内部扩展RAM.


这一天,何老师介绍了堆栈及指针,加深了对堆栈的理解,堆栈是一种特定的存储结构,一端是固定的(栈底),一端是浮动的(栈顶),数据的存入和取出,遵照“后进先出“的原则。栈指针(SP)属于特殊功能寄存器,在内存中用地址单元位81H。入栈指令PUSH,出栈指令POP。
这节主要讲8位的字节存储顺序,小端,低-高 。程序存储听得迷迷糊糊呀。明天再听一遍。




8月8日  第十三集:
1、24-bit 地址总线,32/16/8 bit 数据总线。
2、EDATE相当于传统的256字节区域(RAM),XDATE相当于传统的扩展RAM.
3、对于24位地址总线,高8位表示访问的段空间(定位访问的区域),低16位表示当前访问段空间的具体存储单元位置。
4、字节寄存器、字寄存器、双字寄存器之间的关系。


    这节课主要讲stc32位单片机的内部结构,寄存器八位,十六位,三十二位的拼接。


认真看了几期讲座了,何教授和陈教授都分别讲到了汇编语言,同时现场有些同学也对汇编语言是否需要学习进行了一些讨论。
个人觉得,学习汇编语言编程当然比单纯用c51编程要困难一些,起码对单片机的内部结构和硬件(如寄存器)那些得有一些了解才行。
但是,学习汇编语言之后,能够更加深入的了解单片机硬件,有针对地高效使用硬件资源,同时,对于用c51编程也更加高效,软件质量也更高。
所以,还是要认真学习掌握一下汇编语言,一些小程序尽量用汇编来写,这样就能很快地掌握汇编语言。
比较大的程序还是可以用c51来写,有了汇编语言的基础加持,软件质量会更好!




8月11日  第十四集:
1、实例演示寄存器的运行过程。
2、R10就是寄存器B.
3、R11就是累加器ACC.
4、DR56扩展的数据指针(DPX)
5、DR60扩展的堆栈指针(SPX)
6、N,负标志,Z,零标志。


   这节课通过kell实操对八位,十六位,三十二位拼接,更明白了。4个专用的寄存器,R10 R11 DR56   DR60.程序状态字,AC,F0,RS1,OV,UD,P,CY,AC,何老师讲的太透彻了。


8月11日  第十五集:
1、STC32G将堆栈放在EDATA区域,设计深度64K,实际提供4K.
2、STC32G XDATA设计深度64K--8M,实际提供8K.
3、SFR区域内均可位寻址。


今天这节课讲了中断原理,处理紧急事件的能力。电平,脉冲信号反馈表示。中断的处理过程讲解,中断系统的术语,识别中断源。中断优先级0-3级共四级。


8月15日 第十六集
今天何老师讲了:1、数据类型和端,2、指令集中符号规则,3、单片机CPU寻址模式,4、单片机指令模式的选择,5、单片机CPU指令类型和格式。内容丰富,需要课后认真消化,结合实操,利用仿真,加深理解,举一反三,努力掌握。


   这节课讲数据类型和端      指令集的符号规则     单片机CPU寻址    指令模式的选择   单片机cpu指令类型和格式  bit    1     byte   8     word   16    double  word  32
mcs-251  字和双字以大段形式保存在内存和寄存器文件。 MOV指令    @Ri-ro或r1间接寻址,Rn-0-7  Rm0-15 rmd   rms  wrj16位寄存器,wr0-wr30 偶数
tttt对应目标寄存器  DRk32位寄存器    dir8   dir16直接寻址地址   #data   8位立即数,#data16  16位立即数   #0data16  #1data16  32位立即数。#short  表示常数,仍是立即数。  vv  除2  bit  位寻址,yyy  二进制编码,bit51直接位寻址 , rel  addr11,  11位目标地址  addr16  addr24.
机器指令包含两部分:操作码和操作数    寻址模式:寄存器寻址,立即寻址,直接寻址,间接寻址,位移寻址,相对寻址,位寻址。


何老师讲解 C251 汇编指令


1、主要是16位、32位的操作,与C51的区别;估计除老师外,没多少人弄明白,
能用C251汇编的人,绝对是大牛。
2、指令模式选用SOURCE模式,机器码是原先8051指令时候要加0xA5前缀。


原先8051具有的111条指令表,BINARY不需要加A5,
红色框中有重复功能的指令在SOURCE模式下需要加A5前缀
80251新增加的高效指令,
SOURCE模式不需要加A5,BINARY模式需要加A5前缀





1、助记符语言描述


    MOV 是数据的传送
    ADD 是数据的相加运算
    ANL 是数据的逻辑与运算


    #8BH,前面带井号,说明是立即数


2、操作码


    (1)数据传送类
            MOV、MOVX、MOVC
            必须指明操作对象从哪来,到哪去。(源地址、目的地址)




    (2)数据操作类
            ADD、SUBB、MUL、DIV
            一般靠运算器完成,一般需要两个操作对象




    (3)程序控制类
            AJMP(SJMP、LJMP)
            JZ、JC、JB(JNZ、JNC、JNB)
            ACALL(LCALL)
            RET


            CJNE


            操作对象是程序计数器PC和一个数




    (4)逻辑操作类
            ANL、ORL、XRL




3、操作数


    可以是数据,也可以是地址


注意:
    a、数据只能是整数,不能是小数;
    b、数据是十六进制且是以字母开头时,该数据应该加一个前导0;
    c、数据前有前缀#,则表示数据是立即数,如果没有前缀#,则数据为直接地址


二、指令格式及分类


    [标号: ] 操作码助记符 [第一操作数][, 第二操作数][, 第三操作数] [; 注释]


    标号,也用过子程序的名字。
    操作数,可能有0~3个操作数。


    指令的存储格式:
        指令长度:单字节、双字节、三字节




    指令中的符号约定:
        A:累加器ACC
        B:寄存器B
        C:进位借位标志
        addr8:8位内部RAM地址


        bit:位地址,内部RAM中的可寻址位和SFR中的可寻址位
        #data8:8位立即数


        #data16:16位立即数


        @:间接寻址


        rel:8位带符号偏移量


        Rn:当前工作区(0~3区)的工作寄存器,(n=0,1,...,7)


        Ri:可用作地址寄存器的工作寄存器R0和R1


        (X):X寄存器的内容


        ((X)):由X寄存器寻址的存储器单元内容,即X中存放的值作为地址,相当于指针的功能


        ->:数据传送方向


        /:按位取反


        


三、寻址方式(7种)


    1、立即寻址
        指令中的源操作数是立即数。


    2、寄存器寻址
        指定寄存器的内容为操作数,对寄存器ACC、B、DPTR和CY寻址时,具体的寄存器已隐含在其操作码中。
        而对选定的8个工作寄存器R7~R0,则用指令操作码的低3位指明所用的寄存器。


    3、直接寻址
        指令中包含了操作数的地址。
        a、特殊功能寄存器SFR;
        b、内部数据RAM中的00H~7FH(128个字节单元);
        c、位寻址空间。


    4、寄存器间接寻址
        指定某一个寄存器的内容作为操作数地址,使用时,前面加“@”表示间接寻址。


    5、变址寻址
        由偏移量寄存器和基址寄存器DPTR或PC相加所得结果作为操作数地址。
        例:MOVEC A, @A + PC


    6、相对寻址
        主要用于相对跳转指令。
        注:该偏移量有正负号,所转移的范围为相对于当前PC值的 -128~+127 之间。


    7、位寻址
        对位地址空间的每一位进行运算和传送。


备注:
原先8051具有的
    00H~1FH:工作寄存器区(32个单元,分为4组,每组R0~R7)
    20H~2FH:可位寻址区(20H~2FH,128个位)
80251新增加的
    00H~FFH:工作寄存器区(32个单元8位,每组R0~R31,DR0~DR60单元16位,WR0~WR24单元32位)
    20H~7FH:ebdata 全部支持位寻址。


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-23 14:23:22 | 显示全部楼层
8月15日
今天何老师继续讲解 C251 汇编指令
控制指令  RET ERET RETI
转移指令 AJMP EJMP LJMP SJMP JMP JC JNC JB JNB JBC JZ JNZ JE JNE JG JLE JSL JSGE JSLE
JSG CJNE DJNZ
空操作指令 NOP TRAP




STC 32位单片机的指令系统包含268条功能强大的指令。


指令是使计算机内部执行的一种操作。是提供给用户编程使用的一种命令,计算机能够执行的指令的集合称为指令系统。
用二进制代码来描述指令功能的语言称为机器语言。由于机器语言不能被人们识别,记忆,理解和使用,因此常用助记符来表示每条机器语言指令。
用助记符描述指令功能的语言称为汇编语言,用助记符表示的机器指令称为汇编语言指令,所谓助记符就是帮助记忆的文字符号,
由于单片机最初都是由西方国家的企业生产,因此助记符基本是该命令语句的英文简略表示形式,在学习时记住这些助记符的英文含义将会事半功倍。




第7章 汇编语言程序设计。
编写汇编语言程序的基本格式。
可以看通Keil的A251用户手册。


主要内容
汇编语言程序结构和段分配
符号和符号名字
表达式和操作符
控制语句
条件汇编
宏的定义和调用
设计实例1,LED驱动和控制。
设计实例2,按键中断和LED控制。


汇编语言程序结构和段分配
所谓的汇编语言程序就是按照一定的规则组合在一起,机器语言助记符汇编助记符命令


汇编代码中段的分配


段 (Segment) 是代码块或数据存储器
段是可重定位的或绝对的。
可重定位的段,具有名字类型和其它属性。
将来不同模块的相同名字的段,看作是同一段的一部分,称为部分段
L251链接器/定位器将具有相同名字的多个部分段合并位一个段。


注:绝对段不能与其他段组合。




CODE段和常数
CODE段,也称为代码段,它是用来保存程序中汇编助记符描述的机器指令部分以及程序中所用到的常数和表格等。
CODE段放在STC32G系列单片机中的程序Flash存储空间
注:CODE段可以有由MOVC指令,并且通过DPTR寄存器进行访问


DATA段
数据段DATA中的存储器位置可以通过直接和间接存储器访问来寻址。
在兼容MCS251 ISA的 STC32G系列单片机实现中SFR在DATA段中的地址大于0x80。SFR的位置只能通过直接访问来寻址。


BIT段
BIT段中的存储器位置可用8051中的位指令寻址。


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-28 09:03:52 | 显示全部楼层
8月22日。继续和老师学习的汇编课程控制指令。


-返回指令 RET (*)
该指令从子程序中返回
当从子程序返回时,从堆栈中依次弹出PC的高字节和低字节,且堆栈指针SP减2。程序在恢复的PC地址处继续执行,该地址通常是紧跟在ACALL或LCALL之后的指令,该指令不影响标志位
-无条件跳转指令


LJMP JMPADR
执行该指令前,标号JMPADR分配于程序代码空间地址为0x1234的位置,该条指令所在的程序代码空间的地址为0x0123
在执行完指令后,程序计数器PC的内容(PC)=0x1234


短跳转SJMP rel
该指令实现短跳转,控制程序无条件地跳转到指定地址
■具体来说,将PC递增两次后,PC加上指令第二个字节中的所有符号和相对偏移来计算跳转目标地址
■因此允许目标地范围是从该指令的前128个字节到它之后127个字节之间。不影响标志位
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)-(PC)+2
[10000000][相对地址]
2
3(PC)-(PC)+rel




间接跳转JMP@A+DPTR(*) 该指令实现间接跳转
■具体来说,将累加器A的8位无符号内容与16位数据指针相加,并将结果的和加载到程序计数器PC的低16位中。这是后续指令取指的地址
累加器A的内容和数据指针不受影响不影响标志位
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC.15:0)←(A)+(DPTR)
[0111 0011]
1
4


间接跳转
累加器存放从0到6的偶数。以下指令序列跳转到从JMP_TBL开始的跳转表中的四个AJMP指令之一:
MOV
DPTR,#JMP TBLJMP
@A+DPTR JMPTBL:
AJMP LABELOAJMP LABEL1 AJMP LABEL2
LABEL3
如果累加器在该序列开始时存放04H,则执行跳转到LABEL2注:AJMP是一个两字节指令,因此跳转指令每隔一个地址开始


进位标志CY控制的跳转指令JC rel (*)
■如果设置进位标志CY,则跳转
■具体来说,如果置位了进位标志CY,则跳转到指定的地址;否则,继续执行下一条指令
■在将PC递增两次之后,通过将第二个指令字节中的有符号相对偏移加到PC来计算跳转的目标地址
该指令不改变标志位
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+2
如果(CY)=1,则
[01000000][相对地址]
2
1/3(PC)←(PC)+rel


条件跳转指令
进位标志CY控制的跳转指令JC rel(*)
如果设置进位标志CY,则跳转
■具体来说,如果置位了进位标志CY,则跳转到指定的地址;否则,继续执行下一条指令
■在将PC递增两次之后,通过将第二个指令字节中的有符号相对偏移加到PC来计算跳转的目标地址
该指令不改变标志位
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+2
如果(CY)=1,则
[01000000][相对地址]
2
1/3(PC)←(PC)+rel




机器码
字节数
时钟数(PC)←(PC)+2
如果(CY)=1,则
[01000000][相对地址]
2


进位标志CY控制的跳转指令JNC rel (*)
如果未设置CY标志位,则跳转
■具体来说,如果清除进位标志CY,则跳转到指定的地址;否则,继续下一条指令
在将PC递增两次指向下一条指令之后,通过将第二个指令字节中的有符号相对偏移加到PC来计算目标地址
该指令不影响标志位
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)-(PC)+2
10101 00001相对地址如果(CY)=0,则
2
1/3(PC)-(PC)+rel


设置指定位的跳转指令如果设置了指定位,则跳转
具体来说,如果设置了指定位,则跳转到指定的地址;否则,继续执行下一条指令
在将指令递增到下一条指令的第一个字节之后,通过将指令字节中的有符号相对偏移加到PC来计算跳转的目标地址
该指令不改变标志位和测试位


设置指定位的跳转指令JB bit,rel
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+4
如果(bit)=1,则
[10101001][00100yyy][直接地址][相对地址]
4
1/3(PC)-(PC)+rel
■yyy为直接地址中指定的位偏移
在二进制模式下,需要在机器码前面添加前缀0xA5




—清除指定位的跳转指令如果清除指定位,则跳转
■具体来说,如果清除了指定位,则跳转到指定的地址;否则,继续执行下一条指令
在将指令递增到下一条指令的第一个字节之后,通过将指令字节中的有符号相对偏移加到PC来计算跳转的目标地址
不改变标志位和测试位




指定位置位跳转后清零
指定位置位则跳转,并且在跳转后清除指定位
■具体来说,如果指定位为“1”,则跳转到指定地址;否则继续下一条指令。如果该位为“0”,则不会清除该位
在将PC递增到下一条指令的第一个字节之后,通过将指令字节中的有符号相对偏移加到PC来计算目标地址


条件跳转指令
指定位置位跳转后清零JBC bit,rel
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)-(PC)+4
如果(bit)=1,则
[10101001][00010yyy][直接地址][相
4
1/3 (bit)=0,且
对地址](PC)←(PC)+rel
在二进制模式下,需要在机器码前面添加前缀0xA5




有关累加器的跳转指令JZ/rel(*)
当累加器A内容为零时,则跳转
■具体来说,如果累加器A的所有位均为零,则跳转到指定的地址;否则,继续执行下一条指令。PC递增2次,PC加上指令的第二个字节中的所有符号相对位移来计算跳转地址
该指令不修改累加器的内容,且不影响标志位该指令执行的操作和机器指令格式
操作
机器码
字节数
时钟数(PC)←(PC)+2
如果(A)=0,则
[01100000][相对地址]
2
1/3(PC)←(PC)+rel




—由Z标志位控制的跳转指令JE.rel
若相等,则跳转
■具体来说,如果设置了标志位Z,则跳转到指定的地址;否则,继续执行下一条指令。在将PC递增两次之后,通过将第二个指令字节中的有符号相对位移加到PC来计算目标地址
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)-(PC)+2
如果(Z)=1,则
[01101000][相对地址]
2
1/3(PC)←(PC)+rel
在二进制模式下,需要在机器码前面添加前缀0xA5




由Z标志位控制的跳转指令JNE rel
若不相等,则跳转
■具体来说,如果清零了标志位Z,则跳转到指定的地址;否则,继续执行下一条指令。在将PC递增两次之后,通过将第二个指令字节中的有符号相对位移加到PC来计算目标地址
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+2
如果(Z)=0,则
[01111000][相对地址]
2
1/3(PC)←(PC)+rel
■在二进制模式下,需要在机器码前面添加前缀0xA5




—由Z和CY标志位控制的跳转指令JG rel
如果大开,则跳转
Z-6.(%
■具体来说,如果同时清除了标志立Z和CY,则跳转到指定的地址;否则继续执行下一条指令。在将PC递增两次之后,通过将第二个指令字节中的有符号相对位移加到PC来计算目标地址
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+2
如果(Z)=0且(CY)=0,
[00111000][相对地址]
2
1/3 则(PC)←(PC)+rel
在二进制模式下,需要在机器码前面添加前缀0xA5




—由Z和CY标志位控制的跳转指令JLE rel
如果小于或等于,则跳转
■具体来说,如果设置了标志位Z或CY,则跳转到指定的地址;否则,继续执行下一条指令。在将PC递增两次之后,通过将第二个指令字节中的有符号相对位移加到PC来计算目标地址
该指令执行的操作和机器指令格式
操作
机器码
字节数
时钟数(PC)-(PC)+2
如果(Z)=1或(CY)=1,则
[00101000][相对地址]
2
1/3(PC)←(PC)+rel
在二进制模式下,需要在机器码前面添加前缀0xA5




由标志N和OV控制的跳转指令JSL rel
如果小于,则跳转(带符号)
■具体来说,如果标志位N和OV不同,则跳转到指定的地址;否则,继续执行下一条指令。在将PC递增两次之后,通过将第二个指令字节中的有符号相对位移加到PC来计算目标地址
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)-(PC)+2
如果(N)≠(OV),则
[01001000][相对地址]
2
1/3(PC)-(PC)+rel
■在二进制模式下,需要在机器码前面添加前缀0xA5




标志位N、OV和CY控制的跳转指令JSG rel
如果大于,则跳转(有符号)
■具体来说,如果清除了标志位Z且标志位N和OV具有相同的值,则跳转到指定的地址;否则,继续执行下一条指令。在将PC递增两次之后,通过将第二个指令字节中的有符号相对位移加到PC来计算目标地址
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+2
如果[(Z)=0且(N)=(OV)],则
[00011000][相对地址]
2
1/3(PC)←(PC)+rel
在二进制模式下,需要在机器码前面添加前缀0xA5




-比较跳转指令CJNE<dest>,<src>,rel 比较,如果不相等,则跳转
具体来说,比较前两个操作数的大小,如果它们的值不相等,则分支
在将PC递增到下一条指令的开头之后,通过将指令最后一个字节中的有符号相对偏移加到PC来计算目标地址
如果<dest—byte>的无符号整数值小于<src—byte>的无符号整数值,则设置CY标志位,且不影响两个操作数




-比较跳转指令CJNE<dest>,<src>,rel 前两个操作数允许四种寻址模式组合
累加器可以与任意直接寻址的字节或立即数数据进行比较,任意通过间接寻址的RAM空间或工作寄存器都可以与立即数进行比较
CNJE指令影响CY标志,N标志和Z标志




-比较跳转指令
CJNERn,#data,rel (*)
该指令执行的操作和机器指令格式操作
机器码
字节数
时钟数(PC)←(PC)+3
如果(Rn)≠#data,则 (PC)←(PC)+相对偏移
[10111rrr][立即数][相对地址]
3
3/4 如果(Rn)<#data,
(CY)=1 否则,(CY)=0




—递减跳转指令DJNZ递减。如果不为零,则跳转
■具体来说,如果结果值不为零,则将指定位置减1并跳转到第二个操作数指定的地址。原始值0x00下溢到0xFF。在将PC递增到下一条指令的第一个字节之后,通过将指令最后一个字节中的带符号相对位移值加到PC来计算目标地址值
递减的位置可以是寄存器或直接寻址的字节该指令影响N以及Z标志位




第七章 汇编语言程序设计






汇编语言程序结构和段分配
符号和符号名字
表达式和操作符
控制语句
条件汇编
宏的定义和调用
设计实例一:LED驱动和控制
设计实例二:按键中断和LED控制


汇编语言程序结构和段分配
所谓的汇编语言程序就是按照一定的规则组合在一起机
器语言助记符和汇编器助记符命令
这些按一定规则组合在一起的汇编语言助记符机器指令,能通
过KeilMDK软件的处理,转换成可以在STC32G系列32位单片
机处理器核上按照设计要求运行的机器代码


汇编语言程序结构和段分配
汇编语言程序框架
一个完整的可以运行在STC32G系列单片上的汇编语言程序代码
下面的汇编语言程序将保存在STC32G系列单片机程序存储器中(即CODE段,具体地址由TABLE符号指定)中的4个常数0x0123、0x4567、0x89ab、0xcdef搬移到STC32G系列单片机 内的数据存储器中(即EDATA段,具体地址由STORE指定)


汇编语言程序结构和段分配
汇编代码中段的分配
段(segment)是代码块或数据存储器段是可重定位的或绝对的
可重定位的段具有名字、类型和其他属性
将来自不同模块的相同名字的段看作是同一段的一部分,称为部分段
L251链接器/定位器将具有相同名字的多个部分段合并位一个段注:绝对段不能与其他段组合


汇编代码中段的分配
-DATA段
myprogSEGMENT CODE
;定义CODE段myprog RSEG
myprog
;引用该段LJMP
main
;无条件跳转到mainORG
0200H
;定位到代码段中地址为200H的位置main:
MOV
A,IO_PORT2
;端口IO_PORT2的值0xFF加载到累加器AMOV
VALUE, #0xa5
;立即数#0xa5保存到VALUE指向的存储单元ADD
A,VALUE
;(A)+(VALUE)→(A), 0xFF+0xA5→0xA4=(A) MOV
VALUE2,A
;累加器A的值保存到VALUE2指向的存储器单元MOV
R1,#VALUE
;将VALUE存储器地址加载到寄存器R1ADD
A,@R1
;将((R1))+(A)→(A) END


汇编代码中段的分配
-BIT段
BIT段中的存储器位置可用8051中的位指令寻址位于位可寻址存储器位置中的SFR可以用位指令寻址
可位寻址SFR位置为80H、88H、90H、98H、0AOH、OA8H、OBOH 0B8H、0COH、0C8H、0DOH、0D8H、OEOH、OE8H,OFOH和 OF8H(可位寻址的只能是可以被8整除的地址)


汇编代码中段的分配
-HDATA段和HCONST
HDATA和HCONST存储器只能在兼容MCS-251 ISA的
单片机中使用MCU指令访问
HDATA和HCONST存储器在经典的251设备上使用存储器分组
进行仿真
HDATA和HCONST存储器可通过DRO...DR28和DR56访问。任何存储
器位置均可通过这些寄存器访问


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-28 09:19:34 | 显示全部楼层
8月25日。继续和老师学习的汇编课程
设计汇编实例
转移数据从Flash存储器到片内SRAM存储器。


先用 C语言编写。
  1. void main(void)
  2. {
  3.                 unsigned short const TABLE[4]={0x0123,0x4567,0x89ab,0xcdef}; //FF:XXXX CODE
  4.                 volatile unsigned short edata STORE[4];
  5.                 unsigned char i;
  6.                 for(i=3;i>=0;i--)
  7.                         STORE[i]=TABLE[i];
  8. }
复制代码

看一下反汇编的程序。
  1. ;       FUNCTION main (BEGIN)
  2.                                                 ; SOURCE LINE # 1
  3.                                                 ; SOURCE LINE # 2
  4.                                                 ; SOURCE LINE # 3
  5. 000000 7E540000    R  MOV      WR10,#WORD0 ?tpl?0001
  6. 000004 7E440000    R  MOV      WR8,#WORD2 ?tpl?0001
  7. 000008 69320006       MOV      WR6,@DR8+0x6
  8. 00000C 69220004       MOV      WR4,@DR8+0x4
  9. 000010 69120002       MOV      WR2,@DR8+0x2
  10. 000014 0B2A00         MOV      WR0,@DR8
  11. 000017 7A1F0000    R  MOV      TABLE+4,DR4
  12. 00001B 7A0F0000    R  MOV      TABLE,DR0
  13.                                                 ; SOURCE LINE # 6
  14. 00001F 7E7003         MOV      R7,#03H
  15. ;---- Variable 'i' assigned to Register 'R7' ----
  16.                ?C0004:
  17.                                                 ; SOURCE LINE # 7
  18. 000022 7402           MOV      A,#02H           ; A=R11
  19. 000024 ACB7           MUL      R11,R7           ; A=R11
  20. 000026 49250000    R  MOV      WR4,@WR10+TABLE
  21. 00002A 59250000    R  MOV      @WR10+STORE,WR4
  22. 00002E 1B70           DEC      R7,#01H
  23. 000030 BE7000         CMP      R7,#00H
  24. 000033 50ED           JNC      ?C0004
  25.                                                 ; SOURCE LINE # 8
  26. 000035 22             RET      
  27. ;       FUNCTION main (END)
复制代码

接下来是用汇编语言,用MCS-51指令编写。
  1. data_seg1 segment code
  2. rseg data_seg1
  3. TABLE: DW 0x0123,0x4567,0x89ab,0xcdef ;four data is in code memory (ff:xxxx)
  4. data_seg2 segment edata
  5. rseg data_seg2
  6. STORE: DSW 4                                                ; 4*2=8B (00:xxxx) EDATA
  7. prog_seg segment code
  8.         rseg prog_seg
  9.         LJMP main
  10.         ORG 0x220
  11. main:
  12.         MOV  DPTR, #TABLE
  13.         MOV  WR0, #STORE
  14.         MOV  R4, #0x04
  15. CON:
  16.         MOV  A, #0x0
  17.         MOVC A, @A+DPTR
  18.         MOV  R2, A
  19.         INC  DPTR
  20.         MOV  A, #0x0
  21.         MOVC A, @A+DPTR
  22.         MOV  R3, A
  23.         MOV  @WR0, WR2                        ; {R2,R3}=WR2
  24.         INC  DPTR
  25.         ADD  WR0, #0x02
  26.         MOV  A, R4
  27.         SUBB A, #0x01
  28.         MOV  R4, A
  29.         JNZ  CON
  30.         LJMP $
  31. ;-------------------------------------
  32. ;-------------------------------------
  33. END
复制代码

然后把它改成用MCS-251指令。
  1. data_seg1 segment code
  2. rseg data_seg1
  3. TABLE: DW 0x0123,0x4567,0x89ab,0xcdef ;four data is in code memory (ff:xxxx)
  4. data_seg2 segment edata
  5.                 rseg data_seg2
  6. STORE: DSW 4                                                ; 4*2=8B (00:xxxx) EDATA
  7. DPXL DATA 84H                                                 ; s:84h
  8. //sfr DPXL=0x84;
  9. prog_seg segment code
  10.                 rseg prog_seg
  11.                 LJMP main
  12.                 ORG 0x220
  13. main:
  14.                 MOV  DPTR, #TABLE
  15.                 MOV  DPXL, #0xff            ;{DPXL,DPTR}=FF: #TABLE
  16.                 MOV  WR0,  #STORE                        ; addr(STORE)
  17.                 MOV  R4,   #0x04
  18. CON:
  19.                 MOV  WR6,  @DR56
  20.                 MOV  @WR0, WR6
  21.                 INC  DR56, #2
  22.                 INC  WR0,  #2
  23.                 DEC  R4,   #1
  24.                 JNZ  CON
  25.                 LJMP $
  26. ;-------------------------------------
  27. ;-------------------------------------
  28. END
复制代码

可以看得出用251指令比较简短。





回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-29 17:11:03 | 显示全部楼层
8月29日。
继续和何宾老师学习的汇编课程
条件汇编
避免了重复编写,使源程序更加简洁、易读。


宏的定义和调用
在预处理期间,每次使用宏时都会内联扩展(由其定义替换)。
函数定义仅出现一次,无论调用多少次。 宏可能会增加代码大小,但不会产生与函数调用相关的开销。




设计实例一:LED驱动和控制
IO口设置
  1. P4M0         DATA 0xB4 ;
  2. P4M1         DATA 0xB3 ;
  3. P4           DATA 0xC0 ;
  4. P6M0         DATA 0xCC ;
  5. P6M1         DATA 0xCB ;
  6. P6           DATA 0xE8 ;
  7. CSEG AT 0x0000
  8.         LJMP  main
  9. my_prog SEGMENT CODE
  10.         RSEG my_prog
  11.         ORG   0x200
  12. main:
  13.         USING 0
  14.         MOV   P4M0, #0x00 ;
  15.         MOV   P4M1, #0x00 ;
  16.         MOV   P6M0, #0x00 ;
  17.         MOV   P6M1, #0x00 ;
  18.         MOV   P4, #0x00 ;
  19.         MOV   A, #0xFE
  20. LOOP1:
  21.         ACALL delay
  22.         RL    A
  23.         MOV   P6, A
  24.         JMP   LOOP1
  25. ;//=========================
  26. ;//延时子程序
  27. ;//=========================
  28. delay:
  29.         MOV   WR4, #0xFFFF
  30. delay1:
  31.         SUB   WR4, #1
  32.         JNE   delay1
  33.         RET
  34. END
复制代码



设计实例二:按键中断和LED控制

  1. P4M0         DATA 0xB4
  2. P4M1         DATA 0xB3
  3. P4           DATA 0xC0
  4. P6M0         DATA 0xCC
  5. P6M1         DATA 0xCB
  6. P6           DATA 0xE8
  7. IT0         EQU S:0x88.0
  8. IT1         EQU S:0x88.2
  9. EX0         EQU S:0xA8.0
  10. EX1         EQU S:0xA8.2
  11. EA          EQU S:0xA8.7
  12. my_prog SEGMENT CODE
  13.         RSEG my_prog
  14.         LJMP main
  15.         ORG 0x0003
  16.         LJMP int0
  17.         ORG 0x0013
  18.         LJMP int1
  19.         ORG 0x200
  20. main:
  21.         USING 0
  22.         SETB  IT0
  23.         SETB  IT1
  24.         SETB  EX0
  25.         SETB  EX1
  26.         SETB  EA
  27.         MOV   P4M0, #0x00
  28.         MOV   P4M1, #0x00
  29.         MOV   P6M0, #0x00
  30.         MOV   P6M1, #0x00
  31.         MOV   P4, #0x00
  32.         MOV   A, #0xFE
  33.         MOV   P6, A
  34. LOOP:
  35.         JMP   LOOP
  36. int0:
  37.         RL    A
  38.         MOV   P6, A
  39.         RETI
  40. int1:
  41.         RR    A
  42.         MOV   P6, A
  43.         RETI
  44. END
复制代码






回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2025-05-08 08:36:09

719

主题

1万

回帖

1万

积分

管理员

积分
15717
发表于 2023-8-29 19:23:03 | 显示全部楼层
楼主对我们的免费公开课 认可/支持/给力,建议主动联系我们同事
=====提前获得 【免费+包邮送】的 STC32G12K128实验箱 或 STC8H8K64U实验箱
=====现在送的,都可以利用MCU自带的 硬件USB直接仿真,硬件USB直接下载

【免费+包邮】 送/申样/采购 可加 如下 QQ或微信联系
加STC华南区客服刘经理QQ: 3398500488 ;微信:18106296592  要求 【免费+包邮】 送, 还免费教仿真  
加STC华南区客服曹经理QQ:1933892258 ;微信:18106296595 要求 【免费+包邮】 送, 还免费教仿真
加STC华东区客服聂经理QQ:2593903262;微信:18106296598  要求 【免费+包邮】 送, 还免费教仿真
加STC西北区客服孙经理QQ: 1347154513 ;微信:18106296593  要求 【免费+包邮】 送, 还免费教仿真
加STC华北区客服石经理QQ: 1638975601 ;微信:19952583876  要求 【免费+包邮】 送, 还免费教仿真
加STC华中区客服唐经理QQ:2571301708 ;微信:18106296589 要求 【免费+包邮】 送, 还免费教仿真
加STC东北区客服张经理QQ:3141888640 ;微信:19952583265   要求 【免费+包邮】 送, 还免费教仿真
加STC西南区客服张经理QQ:3141888640 ;微信:19952583265   要求 【免费+包邮】 送, 还免费教仿真
工作时间:  8:30-12:00,13:00-17:30(周一 到 周五, 法定节假日除外)

【免费+包邮】 送/申样/采购传统电话热线:0513-55012928、0513-55012929、0513-55012966
工作时间:  8:30-12:00,13:00-17:30(周一 到 周五, 法定节假日除外)

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-8-29 21:34:20 | 显示全部楼层
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:529
  • 最近打卡:2025-05-09 00:14:59

10

主题

1163

回帖

5207

积分

论坛元老

积分
5207
发表于 2023-9-4 10:09:33 | 显示全部楼层
9月1日。
继续和何宾老师学习的C语言程序设计


第八章C语言程序设计


主要内容
存储器区域
数据类型
类型限定符
存储类别
绝对位置变量
指针
函数
属性
预处理器
内嵌汇编程序
定制文件
存储器区域


STC32G系列单片机兼容MCS—251 ISA,因此支持用于程序和数据的多个物理分离的存储区域或存储器空间
每个存储区域都有一定的优点和缺点
这些存储空间可能是读取但不写入、读取或写入、比其他存储空间更快地读取或写入
STC32G系列单片机上可用的各种存储空间与大多数大型计算机、小型寄存器和微型计算机架构有很大的不同
在这些架构中,程序、数据和常数都加载到计算机内的同一物理存储空间


存储器区域 - Flash -FF:xxxx
--程序存储器
程序(CODE)存储器为只读。在STC32G系列单片机中程序存储器位于单片机的内部
该单片机支持高达64KB的程序存储器。然而,可以使用代码库来扩展程序空间
一些单片机提供了更大的代码空间
程序代码,包含所有函数和库例程,保存在程序存储器中□
常数变量也可以保存在程序存储器中
STC32G系列仅执行保存在程序存储器中的程序
通过使用存储器类型标识符code,C语言程序可以访问程序存储器区域
-程序存储器
声明code对象的用法如下:
unsigned char code code_constant;
注:存储器类型code是为了与C51编译器兼容而实现的。应该使用const near或const far代替代码。这通常会生成更好的代码,应该在新的STC32G系列单片机中使用,而不是存储器类型code


存储器区域 - 00:xxxx
-内部数据存储器
内部数据存储器位于STC32G系列单片机的内部,并且是读/写的
data和idata存储区域位于STC32G系列单片机内,并且可以写入和读取
data存储器是片上存储器的前128字节。idata存储器是片上存储器的前256个字节。还有一个从20h开始的16字节区域,可用短8051兼容指令进行位寻址
声明idata变量的方法如下:
unsigned char idata variable;
对内部数据存储器的访问非常快,因为它可以使用8位地址访问


存储器区域
-内部数据存储器
内部数据存储器可以分为三种不同的数据类型,包括data
bdata ebdata


存储器区域
-内部数据存储器
存储器说明符data是指内部数据存储器的前128个字节□
此处保存的变量使用直接寻址进行访问■声明data变量,如下所示:
unsigned char data fast_variable ;


存储器区域
-内部数据存储器
存储器说明符bdata指定的内部数据区(20h~2Fh)中的16字节可位寻址的存储器
该存储器类型说明符允许程序开发人员声明也可以在位级别访问的数据类型
声明bdata变量,如下所示:
unsigned char bdata bdata_var;


存储器区域
-内部数据存储器
存储器说明符ebdata是指内部数据区(20h~7Fh)中的扩展251 共768位可寻址存储器
该存储器类型说明符允许程序开发人员声明也可以在位级别访问的数据类型
然而,与bdata存储区域相比,对ebdata存储器的位访问需要更长的操作码编码
声明edata变量,如下所示:
unsigned int ebdata eb_var ;


存储器区域
-内部数据存储器
【例8—1】存储器说明符ebdata的用法
struct s{                                                         //定义结构体s
unsigned intb0:3;                                                 //整型变量b0,分配3个二进制位
unsigned intb1:2;                                                 //整型变量b1,分配2个二进制位
unsigned intb2:1;                                                 //整型变量b2,分配1个二进制位
unsigned intb3:1;                                                 //整型变量b3,分配1个二进制位
unsigned intb4:1;                                                 //整型变量b4,分配1个二进制位
unsigned intb5:1;                                                 //整型变量b5,分配1个二进制位
unsigned intb6:1;                                                 //整型变量b6,分配1个二进制位
unsigned intb7:4;                                                 //整型变量b7,分配4个二进制位};


存储器区域
-内部数据存储器 struct s ebdata v;                    //声明结构体变量v,且保存在ebdata区域
void main(void) {                                     //声明主程序main
v.b0=4;                                               //结构变量v的元素b0赋值为4
v.b1=3;                                               //结构变量v的元素b1赋值为3
v.b7=15;                                              //结构变量v的元素b7赋值为15
if (v.b1) {                                           //如果结构变量v的元素b1的值不为0
v.b0=7;                                               //结构变量v的元素b0赋值为7
}
}
存储器区域
-内部数据存储器
对于上面的设计代码,变量的位分配
位号       0x20.7      0x20.6         0x20.5       0x20.4      0x20.3     0x20.2      0x20.1       0x20.0
变量                                                                      v.b7        v.b6         v.b5
位号       0x21.7       0x21.6         0x21.5        0x21.4     0x21.3     0x21.2      0x21.1      0x21.0
变量        v.b4          v.b3          v.b2           v.b1                 v.b0


存储器区域
-内部数据存储器
0xFF0000       020030      UJMP           C:0x0030
14:void main(void){
15:     v.b0=4;
0xFF0003      7E3520      MOV        WR6,v(0x20)
0xFF0006      5E70F8     ANL         R7,#0xF8
0xFF0009      4E7004     ORL           R7,#0x04               //R7[3:0]=0x04
0xFF000C      7A3520    MOV         v(0x20),WR6 // {R6, R7}=WR6
16:                    v.b1=3;
0xFF000F    4E7018        ORL         R7,#0x18      //0x18逻辑“或”R7,R7.4,R7.3置1 0xFF0012       7A3520      MOV         v(0x20),WR6     //
17:                 v.b7=15;
0xFF0015         4E603C      ORL            R6,#0x3C
0xFF0018        7A3520       MOV         v(0x20),WR6


存储器区域
-外部数据存储器
片内/片外的外部数据存储器是读/写的
由于外部数据存储器是通过数据指针寄存器(必须加载地址)间接访问的,因此它比访问内部数据存储器慢
STC32G系列单片机提供了片上XRAM空间,该空间使用与传统外部数据空间相同的指令进行访问。该XRAM空间通常通过配置SFR寄存器启用,并于外部存储器空间重叠
可能有多达64KB的外部数据存储器。然而,该地址空间不一定必须用作存储器。硬件设计可能会将外设映射到存储器空间中。如果是这种情况,开发的程序将访问外部数据存储器来编程和控制外设。这种技术称为存储器映射的I/O
声明xdata变量的方法如下:
开发的程序将访问外部数据存储器来编程和控制外设。这种技术称为存储器映射的I/O sfr 80H~FF,
PWM, USB,....声明xdata变量的方法如下:
unsigned charxdlata variable;


存储器区域
-近存储器
近存储器(nearmemory)区域的地址范围为00:0000~00:FFFF,这是STC32G系列单片机存储器的前64KB
部分寄存器位于STC32G系列单片机的内部,并且可以使用16位寻址进行快速的访问
近存储器区域在汇编语言级别由存储器类EDATA或ECONST表示,使用直接寻址访问保存在近存储器中的变量
声明near对象的方法如下:
unsigned charnear near_variable;


存储器区域
-远存储器
远存储器(farmemory)区域表示STC32G系列单片机的完整地址范围
远存储器区域在汇编语言级别中使用存储器类HDATA或HCONST表示
使用间接寻址来访问存储器类型far定义的变量
地址计算仅为16位,因此将远对象的数据大小限制为64KB
然而,远变量可以驻留在存储器中的任何位置,这允许总大小多达16MB


存储器区域
-远存储器
声明far对象的方法如下:
unsigned charfar far_variable[0x10000];
unsigned charconst far far_const_variable[0x4000]= {1,2,3,...};
unsigned int i;
unsigned charfar_func (void) {
return(far_variable);


存储器区域
-大存储器
与far相反,huge使用32位运算进行地址计算,因此允许无限的对象大小
程序开发人员可以有一个数MB大小的单个数组或结构
在大存储器(hugememory)中,声明的变量的大小可以达到16MB-1


存储器区域
-大存储器
声明huge对象的方法如下:
unsigned charhuge huge_variable[0x50000];
unsigned charconst huge huge_const_variable[0x20000] = {1,2,3,...};
unsigned longl;
unsigned intfunction (void) {
return (huge_variable[l]);
}
存储器区域
--SFR存储器
STC32G系列单片机为SFR提供128字节的存储器
SFR是位、字节或字大小的寄存器,用于控制定时器、计数器、串行I/O和外设
注:可以使用MOV指令直接访问SFR存储器,不能使用间接寻址模式


数据类型
C251编译器提供了几种可以在C程序中使用的基本数据类型
编译器支持标准C数据类型以及MCS—251 ISA特有的几种数据类型
数据类型                                     位数        字节数                                        值的范围
Bit                                           1                                                        “0”或“1” -
signed char                                   8            1                                          -128~+127
unsigned char                                 8            1                                           0~+255
enum                                         16            2                                         -32768~+32767
signed short int                             16            2                                         -32768~+32767
signed int                                   16            2                                         -32768~+32767
unsigned int                                 16            2                                           0~+65535
signed long int                              32            4                                      -2147483648~+2147483647
unsigned long int                            32            4                                          0~+4294967295
float                                        32            4                                 +1.17549435E-38~+3.4028235E+38
double                                       64            8                                     ±2.2250738585072014E-308
                                                                                                 ±1.7976931348623158E+308
idata,data,pdata(指针)                    8            1                                           0~0Xff near,
xdata,code(指针)                          16            2                                            0~0xFFFF
far,huge(指针)                            32            4                                           0~0Xffffff
sbit                                          1                                                         “0”或“1”
sfr                                           8            1                                             0~+255
sfr16                                        16            2                                             0~+65535


数据类型
标准C语言所支持的类型
本节只介绍标准C语言所支持数据类型中的基本类型,包括
void
char
int
enum
float
double


标准C语言所支持的类型
-void
数据类型void定义了没有返回值的函数,没有参数列表的函数以及指向未定义类型对象的指针
其用法如下:
voidfunction-name (argument-list);
return-type function-name(void);
void *name;
其中
function-name为函数的名字
argument-list为传给函数的参数
return-type为函数的返回类型
name为指向void对象的指针
标准C语言所支持的类型
数据类型int定义了1个二进制整数
其格式为:
<[>{signed| unsigned}<]> <[>{long | short}<]> int name<[>=value<]>;
其中
name为变量的名字
value为分配给变量的值
signed或unsigned显式声明数据类型是有符号的还是无符号的
long或short声明整数是32位或16位的整数


标准C语言所支持的类型
--enum
关键字enum(枚举)定义了一组int类型的常数
其格式如下:
enum [tag]{name [= value],...};
其中
tag为enum集的名字
name为枚举常数的名字
value为分配给常数的值。如果缺少值,则假定它是集合+1中的前一个常量的值。列表中第一个常数的默认值为0
标准C语言所支持的类型
--float
数据类型float定义了IEEE—754浮点数
其格式如下:
float name<[>=value<]>;
其中
name为变量的名字
value为分配给变量的值
标准C语言所支持的类型
-float
在兼容MCS—251ISA的STC32G系列单片机中,浮点数按下面格式保存
地址                     地址+0          地址+1          地址+2        地址+3
内容                   SEEE EEEE          EMMM MMMM       MMMM MMMM      MMMM MMMM
表中
s表示符号位,取值为“1”表示负数,“0”表示正数
E是指数
M是24位尾数(保存23位)。最高位24位总是为“1”,因此无需保存


标准C语言所支持的类型
-float
浮点数—12.5,其保存在STC32G系列单片机中保存为十六进制数0xC1480000
该十六进制数在存储器中的保存格式
地址                   地址+0                地址+1                     地址+2             地址+3
内容(十六进制)         0xC1                   0x48                       0x00                0x00
内容(二进制数)      1100 0001               0100 1000                  0000 0000           0000 0000
表中:
符号位为“1”,表示该浮点数为负数
指数为“10000010”,等效于十进制数130
尾数为“1001000 0000 0000 0000 0000”,等效于十进制小数0 5625


标准C语言所支持的类型
-float
因此,真正的十进制浮点数表示为:
(-1)1x(1+0.5625)x2130-127=(-1)x1.5625x8=-12.5
注:STC32G系列单片机中不包含捕获浮点错误的中断向量。因此,软件必须对这些错误条件进行适当的响应
标准C语言所支持的类型
-float
C251库函数_chk float_允许程序开发人员快速的检查浮点状态
作为替代方案,可以使用下面的联合体来保存浮点值
union f{
float   f;                                //浮点数的值
unsigned long ul;                         //无符号长整型数
}
该联合体包含一个浮点数和一个无符号长整型数,用于执行浮点运算以及响应IEEE的错误状态
标准C语言所支持的类型
-float
检查浮点运算状态的C语言代码
#include<intrins.h>                                     //包含头文件intrins.h
#include <stdio.h>                                      //包含头文件stdio.h
#include<reg251s.h>                                     //包含头文件reg251s.h
voidmain(void)                                          //主函数main
{
float f2=1.0,f3=0.0;                                    //声明浮点数f2和f3
float f1;                                               //声明浮点数f1
SCON=0x52;                                          //初始化串口寄存器SCON
TMOD=0x20;                                          //初始化串口寄存器TMOD
TCON=0x69;                                          //初始化串口寄存器TCON
TH1=0xF3;                                           //初始化串口寄存器TH1
f1=f2/f3;                                           //浮点数f2和f3相除,除数f3为0
标准C语言所支持的类型
-float
switch(_chkfloat_(f1))
{                                                           // 调用chkfloat,判断浮点运算结果
case 0:                                                     //取值为0,表示浮点运算结果正常
printf ("result is a number\n");break;               //在Keil UART窗口打印信息
case 1:                                                     //取值为1,表示浮点除数为零
printf ("result is zero\n");break;                          //在Keil UART窗口打印信息
case 2:                                                     //取值为2,表示浮点运算上溢
printf ("result is +INF\n"); break;                         //在Keil UART窗口打印信息
case 3:                                                     //取值为3,表示浮点运算下溢
printf ("result is -INF\n"); break;                         //在Keil UART窗口打印信息
case 4:                                                     //取值为4,表示不是一个数
printf ("result is NaN\n"); break;                          //在Keil UART窗口打印信息
}


标准C语言所支持的类型
--double
数据类型double定义了IEEE—754浮点数
其格式如下:
                double name <[>=value<]>;
其中
name为变量的名字
value为分配给变量的值
注:只要没有使用FLOAT64编译器命令,数据类型double和数据类型float就是相同的。在这种情况下,类型douable的变量使用与类型float相同的4字节存储类型
STC32G12K128_549a.png



数据类型
-位寻址对象
位可寻址对象是可以作为字或者位寻址的对象
只有占据STC32G系列单片机内部存储器的位可寻址区域的数据对象属于这一类别
C251编译器将用bdata或ebdata存储器类型声明的变量放到位可寻址区域
存储器类型bdata是指8051兼容位空间;ebdata指定扩展的STC32G系列单片机的位空间
bdata和ebdata存储器类型都像数据存储器类型一样处理,除了变量驻留在片上数据存储器的位可寻址部分中
注:对于bdata,该存储器区域的总大小不能超过16字节;对于ebdata,则不能超过96字节


数据类型
-位寻址对象
程序开发人员可以声明全局bdata/ebdata变量,如下所示
int bdataibase;                                //位可寻址的int型
char bdatabary [4];                            //位可寻址的数组
int ebdata ibase;                              //ebdata可位寻址的int型
char ebdata bary [4];                          //ebdata可位寻址的char型
上面的例子中,变量ibase和bary是可位寻址的。因此,可以直接访问和修改这些变量的各个位。使用sbit关键字声明访问bdata变量位的新变量
sbitmybit0=ibase^0;                              //ibase的位0
sbit mybit15=ibase^15;                           //ibase的位15
数据类型-位寻址对象
sbitAry07=bary[0]^7;                             //bary[0]的位7
sbit Ary37=bary[3]^7;                            //bary[3]的位7
sbit ebBit0=ebase^0;                             //ebase的位0
sbit ebBit15= ebase^15;                          //ebase的位15
sbit ebAry07=eary[0]^7;                          //eary[0]的位7
sbit ebAry37= eary[3]^7;                         //eary[3]的位7


数据类型-位寻址对象
上面的例子表示声明,而不是对ibase/ebase和bary/eary变量 的位的赋值
例子中的符号“^”后面的表达式指定使用该声明访问的位的位置。该表达式必须是常数值
范围取决于声明中包含的基变量的类型。范围是:
0~7用于char和unsigned char;
0~15用于int、unsigned int,short和unsigned short;
0~31用于long和unsigned long;
注:C251编译器假设使用sbit声明访问的对象以小端字节顺序保存。这是sfr16类型的情况。然而,像int和long这样的标准C类型以大端保存


数据类型-位寻址对象
此外,可以为sbit类型提供外部变量声明,以访问其他模块中的这些类型。例如:
extern bitmybit0;                             //ibase的位0
extern bitmybit15;                            //ibase的位15
extern bitAry07;                              //bary[0]的位7
extern bit Ary37;                             //bary[3]的位7
extern bit ebdata eBit15;                     //外部基于ebdata的位
extern bitebdata ebAry37;                     //外部基于ebdata的位


数据类型-位寻址对象
涉及sbit类型的声明要求使用存储器类型bdata或ebdata声明基对象
注:基于ebdata的外部位的声明需要存储器类型ebdata。如果没有显式存储器,则假定默认空间bdata
唯一例外的是特殊功能位的“变种”。如果要声明基于SFR的位则必须省略存储器空间
下面的例子说明了基于上述声明更改ibase和bary位的方法
Ary37=0;                                  //清除bary[3]的位7
bary[3] ='a';                             //字节寻址
ibase=-1;                                 //字寻址
mybit15=1;                                //设置ibase的位15


数据类型-位寻址对象
除了用bdata声明的变量位于内部数据存储器的可位寻址
部分之外,bdata存储器类型的处理方式于数据存储器类似
注:该存储器区域的总大小不能超过16字节


数据类型-位寻址对象
除了位标量类型声明sbit变量之外,还可以为结构和联合声明sbit。比如:
unionIft                                  //声明联合类型lft
{
float mf;
long ml;
};
sbit tcpf31=tcp.u.ml^31;                  //浮点位31
sbit tcpm10=tcp.m1^0;                     //字符位0
sbit tcpm17 = tcp.m1^7;                   //字符位7
数据类型-位寻址对象
bdata structbad                           //声明结构类型bad,设置在bdata区域
{
char m1;union Ift u;
}tcp;


数据类型-位寻址对象
bit类型定义单个位变量。其用途如下:
bit name<[>=value<]>
其中:
name为位变量的名字
value为分配给位变量的值
bit类型可用于变量声明、参数列表和函数返回值
数据类型-位寻址对象
位变量和其他C数据类型一样声明。例如:
static bitdone_flag =0;      //声明并初始化位变量done_flag  //函数testfunc返回类型为bit,参数类型为bit
bit testfunc(bit flag1,bit flag2)
{
...
return(0);                        //函数返回类型为bit
}


数据类型
位寻址对象
所有的位变量都保存在STC32G系列单片机的8051兼容内部存储器区域中的位段中
因为该区域只有16个字节长度,所以在任何一个范围内最多可以声明128位变量
注:对STC32G系列单片机的扩展位的访问比对标准8051兼容位区域的访问产生更多的代码。因此,程序开发人员应尽可能使用标准的8051兼容位区域,以最大化性能
数据类型-位寻址对象
STC32G系列单片机支持位于数据存储器地址范围0x20~0x7F中扩展位可寻址区域。该区域最多支持768位变量
要在扩展位区域中定位位,需要指定ebdata。如下所示:
bit ebdatastate1;                                          //在扩展位空间声明位变量state1
bit function(bit flag)                                     //在8051位空间的位参数flag
{
bit ebdatalocal_bit;                                       //在扩展位空间声明本地位变量localI_bitlocal_bit=flag;
return(local_bit);                                         //函数返回扩展位空间位变量local_bit
}


数据类型-位寻址对象
下面的限制适用于位变量和位声明:不能将位声明成指针。例如:
bit *ptr;                                     //非法的
位类型的数组无效。例如:
bit ware[5];                                  //非法的
禁止中断的函数(#pragma disable)和使用显式寄存器声明的函数(using n)不能返回类型为bit的值
C251编译器为尝试返回位类型的此类函数生成错误消息


数据类型-特殊功能寄存器
STC32G系列单片机位访问SFR提供了独特的存储区域在程序中,SFR用于控制定时器、计数器、串行I/O、端口I/O和外设
SFR位于地址0x80~0xFF之间,可以作为位、字节和字访问
特殊功能寄存器Sfr
sfr类型定义了一个SFR
其格式如下:
sfrname=address;
其中
name为SFR的名字 address为SFR的地址
SFR的声明方式与其他C变量相同。唯一的区别是指定的类型是sfr而不是char或int


特殊功能寄存器
S- 例如:
sfrP0=0x80;                                                      //端口0的地址为80h
sfrP1=0x90;                                                      //端口1的地址为90h
sfrP2=0xA0;                                                      //端口2的地址为0A0h
sfrP3=0xB0;                                                      //端口3的地址为0B0h
P0、P1、P2和P3是SFR名字声明
sfr变量的名字与其他C变量声明一样定义sfr声明中可以使用任何符号名字
等号(“=”)后面的地址规范必须是数字常数。不允许使用带有运算符的表达式。此常数表达式必须位于SFR地址范围(0x80~0xFF)内。
注:不能在函数中声明sfr变量,它必须在函数体之外声明


特殊功能寄存器
--sfr16
sfr16类型定义了一个16位SFR
其格式如下:
sfr16name=address;
其中:
name为16位SFR的名字
address为16位SFR的地址
STC32G系列单片机中具有16位的SFR,这些SFR是使用SFR存储器中连续的地址创建的,以指定16位的值
其余规则同sfr的声明


特殊功能寄存器
--sbit
bit类型定义SFR中的一位
其格式如下:
sbitname=sfr-name ^bit-position;
sbitname=sfr-address^bit-position;
sbitname=sbit-address;
其中:
name为SFR位的名字
sfr-name为之前定义的sfr的名字
bit-position为SFR内位的位置
sfr-address为SFR的地址
sbit-address为SFR位的地址


特殊功能寄存器
--sbit
对于基于STC32G系列单片机的应用程序,通常需要访问SFR内的各个位
sbit类型提供对位可寻址SFR以及其他位可选址对象的访问例如:
sbit EA=0xAF;
该声明将EA定义为地址0xAF的SFR位。在STC32G系列单片机中,这是中断使能寄存器中的使能控制位


特殊功能寄存器
--sbit
sbitname=sfr-address ^bit-position;
字符常数(sfr地址)指定sbit的基地址。它必须能被8整除
比特位置(必须是0~7之间的数字)跟随'^”,并指定要访问的比特位置。例如:
sbit OV=0xD0^2;
sbit CY=0xD0^7;
sbit EA=0xA8^7;


特殊功能寄存器
--sbit
需要注意以下的一些限制条件:
并非所有SFR都是位可寻址的
只有地址可被8整除的SFR才是位可寻址的
特殊功能位表示一个独立的声明类,它不能与其他位声明或位字段互换
sbit数据类型声明可用于访问使用bdata内存类型说明符声明的变量的各个位




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:126
  • 最近打卡:2025-05-06 16:45:31
已绑定手机

19

主题

208

回帖

522

积分

高级会员

积分
522
发表于 2024-7-18 22:19:18 | 显示全部楼层
写的很详细,厉害
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-9 03:34 , Processed in 0.139926 second(s), 108 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表