白一宁 发表于 2024-6-24 11:44:44

《STC最新8051单片机原理及应用-STC8H8K64U》学习打卡

第一节《STC最新8051单片机原理及应用-STC8H8K64U》视频课程导论单片机发展
[*]1995年前 Z80 单片机
[*]8086 单片机
[*]Intel 8031单片机
没有程序存储器
RAM很小
需要串门的仿真器
[*]Intel 8051
集成了4KB ROM,但只能将单片机程序交给厂家制作
需要专门的仿真器
[*]Intel 8751
集成了4KB EPROM,但需要专门的擦除器(紫外线照射)和编程器
需要专门的仿真器
[*]Atmel 89C51
集成了4KB 程序存储器,但需要专门的编程器
需要专门的仿真器
[*]STC 89C51
集成了4KB Flash程序存储器,可在系统可编程,不需要专门的编程器
需要专门的仿真器
[*]STC 12 系列,STC 15 系列
集成了4KB Flash程序存储器,可在系统可编程,不需要专门的编程器
IAP开头的单片机可设置为仿真器,不需要专门的仿真器
[*]STC8H8K64U
集成64KB Flash程序存储器,ISP,可设置为仿真器,资源丰富
超高速8051内核,完全兼容传统8051单片机
5个16位可自动重装在定时器,可编程始终输出功能
4个全双工UART,1个SPI,1个I2C,1个USB
15通道12位高速ADC
8路高级PWM
电子元件基础电阻https://image.lceda.cn/oshwhub/483a345249144e8a9f7399935d174c2f.png电容https://image.lceda.cn/oshwhub/f00aa29dc99043099e670e853b60d9ae.png二极管https://image.lceda.cn/oshwhub/e2656aec014a4c688fe69c66874db639.png三极管https://image.lceda.cn/oshwhub/9ec618dce185486db2b173f9ed56721b.png晶振https://image.lceda.cn/oshwhub/619cafd89d3944cda718f49cb8269885.png数码管本质是发光二极管,数码管有共阴极个共阳极之分
https://image.lceda.cn/oshwhub/2a132ddaa83648ec8d427e4cbf224a71.png学习单片机方法理论和实践相结合,软件和硬件相结合

白一宁 发表于 2024-6-25 22:31:24

本帖最后由 白一宁 于 2024-6-25 22:41 编辑

第二节 点灯大师启航,看到效果再理论准备安装环境
https://image.lceda.cn/oshwhub/9f8bda1182c042a496d0fbe531662fcc.png
查看开发板上焊接了LED位置
https://image.lceda.cn/oshwhub/6654a41430454d018628f553f05b52d2.png
查看原理图
https://image.lceda.cn/oshwhub/cb6e1ffc139944e39d55770efb7e6bf2.png开发点亮一颗LED#include "stc8h.h"   

void main(void)
{
   
    P2M1 = 0x00;
          P2M0 = 0x00;
   
    P21 = 0;                  

}

https://image.lceda.cn/oshwhub/b48d047fcff04d729d903aacb72c60ae.png
点亮8颗LED#include "stc8h.h"   

void main(void)
{
   
    P2M1 = 0x00;
          P2M0 = 0x00;
   
    P20 = 0;      
    P21 = 0;                  
    P22 = 0;                  
    P23 = 0;                  
    P24 = 0;                  
      P25 = 0;
      P26 = 0;
      P27 = 0;

}
流水灯 使用spi计算延时https://image.lceda.cn/oshwhub/77f93298dfcd49f39df3a96595b56265.png
#include "stc8h.h"

void Delay100us(void)        //@11.0592MHz
{
        unsigned char data i, j;

        i = 2;
        j = 109;
        do
        {
                while (--j);
        } while (--i);
}


void main(void)
{

    P2M1 = 0x00;   P2M0 = 0x00;

          P20 = 0;                //LED On
   Delay100us();
    P20 = 1;                //LED Off
    P21 = 0;                //LED On
   Delay100us();
    P21 = 1;                //LED Off
    P22 = 0;                //LED On
   Delay100us();
    P22 = 1;                //LED Off
    P23 = 0;                //LED On
   Delay100us();
    P23 = 1;                //LED Off
    P24 = 0;                //LED On
   Delay100us();
    P24 = 1;                //LED Off
    P25 = 0;                //LED On
   Delay100us();
    P25 = 1;                //LED Off
    P26 = 0;                //LED On
   Delay100us();
    P26 = 1;                //LED Off
    P27 = 0;                //LED On
   Delay100us();
    P27 = 1;                //LED Off
    P26 = 0;                //LED On
   Delay100us();
    P26 = 1;                //LED Off
    P25 = 0;                //LED On
   Delay100us();
    P25 = 1;                //LED Off
    P24 = 0;                //LED On
   Delay100us();
    P24 = 1;                //LED Off
    P23 = 0;                //LED On
   Delay100us();
    P23 = 1;                //LED Off
    P22 = 0;                //LED On
   Delay100us();
    P22 = 1;                //LED Off
    P21 = 0;                //LED On
   Delay100us();
    P21 = 1;                //LED Off

}








白一宁 发表于 2024-6-27 09:46:25

第三节 数字逻辑与基本数字电路数字电路和模拟电路书本上的解释:模拟信号是连续变化的量,数字信号则是离散的量
我的理解:模拟信号是有传感器或者元件直接产生的信号,数字信号是根据模拟信号转化为计算机可以识别的逻辑电平上升沿
数字电路中,数字电平从低电平(数字“0”)变为高电平(数字“1”)的那一瞬间(时刻)叫作上升沿。https://image.lceda.cn/oshwhub/23477acdd3e541e8b0e7ef85c6431405.png
下降沿
数字电路中,数字电平从高电平(数字“1”)变为低电平(数字“0”)的那一瞬间叫作下降沿https://image.lceda.cn/oshwhub/31c89c0c8c34433ba4a13ac8c33aaa99.png
逻辑门https://image.lceda.cn/oshwhub/eaeaf47766b541f7a861432cb725316a.png单片机的优点
[*]集成度高,体积小
[*]功耗低
[*]可靠性好
[*]加个低廉
单片机应用场景
[*]智能仪表
https://image.lceda.cn/oshwhub/b6a72e16bad848589a0a6a25f5fb8c1e.png
2. 工业农业实时监控https://image.lceda.cn/oshwhub/1043834c09ae4cdeb8368caea4b4b2d6.png
3. 计算机网络通讯领域https://image.lceda.cn/oshwhub/1030593748cf44628d052367064f136f.png
4. 家用电器https://image.lceda.cn/oshwhub/138dbf95aa4b4771ae574d6582c50cde.png
5. 医用设备领域https://image.lceda.cn/oshwhub/20137816e2dd4611a54e7be87a4570ce.png
6. 汽车设备领域https://image.lceda.cn/oshwhub/cc5a9ac4e2634558963dca94292a7f68.png
7. 其他办公设备,商业活动,机械制造,航空航天等仿真ISP工具开启仿真https://image.lceda.cn/oshwhub/0830c77acfa3478881daa78e00c51f61.pngkeil开始仿真调试https://image.lceda.cn/oshwhub/242808aef0224faabefa989e3c170c39.png



白一宁 发表于 2024-6-28 01:47:46

本帖最后由 白一宁 于 2024-6-28 01:50 编辑

第四节 单片机的内部结构,STC补充外围电路设计讲解微型计算机结构遵循经典的 冯·诺依曼 架构 运算器,控制器,存储器,输入设备和输出设备https://image.lceda.cn/oshwhub/9cb5947a2e324d449355d3e17eddbc7a.png传统8051单片机8051单片机中包含中央处理器、程序存储器(4KBROM)、数据存储器(128B RAM)、2个16位定时1计数器、4个8位I/0口、-个全双工串行通信接口和中断系统等,以及与I/0口复用的数据总线、地址总线和控制总线三大总线。
结构框图看上去较复杂,但是可以根据 冯·诺依曼 架构进行分析https://image.lceda.cn/oshwhub/fa7a22ecf1654195892016b8d0db0081.pngSTC8H8K64U单片机结构陈教授简化之后结构很明朗https://image.lceda.cn/oshwhub/a35c8197ea80458caa14b3f799cb4651.png运算器以8位算术/逻辑运算部件ALU为核心,加上通过内部总线而挂在其周围的暂存器TMP1、TMP2、累加器ACC、寄存器B、程序状态标志寄存器PSW以及布尔处理机组成了整个运算器的逻辑电路。运算器中包含程序状态寄存器PSW。程序状态寄存器

PSW 位地址字节地址D0H作用
D7HCY进位标志
D6HAC辅助进位标志
D5HF0用户可用标志
D4HRS1寄存器区选择位
D3HRS0寄存器区选择位
D2HOV溢出标志
D1HF1用户可用标志
D0HP奇偶标志
奇偶标志位,如果累加器ACC中1的个数为偶数,P=0;否则P=1.每个指令周期都由硬件来置“1”或清“0”。在具有奇偶校验的串行数据通信中,可以根据P设置奇偶校验位。控制器控制器是CPU的大脑中枢,包括定时控制逻辑、指令寄存器:译码器、地址指针DPTR及程序计数器PC、堆栈指针SP、RAM地址寄存器、16位地址缓冲器等存储器STC8H8K64U单片机的程序存储器和数据存储器是各自独立编址的,片内集成有3个物理上相互独立的存储器空间:程序Flash存储器(没有用作程序存储器的Flash存储器可以作为EEPROM使用)、内部数据存储器和扩展数据存储器特殊功能寄存器和内部数据存储器的80H~FFH单元地址重叠。https://image.lceda.cn/oshwhub/978a09d58cd44f3dac4fdf3acbc7da51.png程序Flash存储器用于存放用户程序、常数数据和表格等信息。STC8H8K64U单片机片内集成了64KB的程序Flash存储器,地址为0000H~FFFFH。8051单片机具有64KB程序存储器空间的寻址能力。单片机复位后,程序计数器的内容为0000H,从0000H单元开始执行程序。在程序Flash存储器中有些特殊的单元,这些单元是中断服务程序的入口地址(也称为中断向量)。每个中断都有一个固定的入口地址,当中断发生并得到响应后,单片机就会自动跳转到相应的中断入口地址去执行程序。例如,外部中断0(INTO)的中断服务程序入口地址是0003H,定时器/计数器0(TIMERO)的中断服务程序入口地址是000BH等
读取程序存储器中保存的表格常数等内容时,使用MOVC指令。STC8H单片机片内集成了256字节内部数据存储器(又称RAM),地址范围是00H~FFH,可用于存放程序执行的中间结果和过程数据。分为三部分:
[*]低128字节RAM(00H~7FH):也称为基本RAM区。基本RAM区又分为工作寄存器区、位寻址区、用户RAM和堆栈区。可以直接寻址和间接寻址。用“MOV”和“ MOV @Ri”形式的指令访问。
[*]高128字节RAM(80H~FFH):只能间接寻址。用“MOV @Ri”形式的指令访问
[*]SFR)区:地址范围为80H~FFH,只可直接寻址,用特殊功能寄存器“MOV”形式的指令访问
https://image.lceda.cn/oshwhub/5adee00b551246959a9ca57a52439bf4.png


白一宁 发表于 2024-6-29 08:51:02

第五节 存储器空间及存储器,单片机的引脚数据存储器高128字节RAM和特殊功能寄存器80H~FFH既为高128字节RAM区的地址范围,又为特殊功能寄存器区(SFR)的地址范围,地址空间重叠,但物理上是独立的。特殊功能寄存器是用来对片内各功能模块进行管理、控制、监视的控制寄存器和状态寄存器。特殊功能寄存器大体分为两类:一类与芯片的引脚有关,如P0~P7;另一类用于芯片内部功能的控制或者内部寄存器如中断控制、定时器、串行口、SPI接口、PWM模块、ADC模块的控制字等。特殊功能寄存器除了程序计数器PC和4个工作寄存器组外,其余的特殊功能寄存器在SFR区(即上述80H~FFH地址空间)和扩展RAM(称为XDATA)区的部分单元中。在SFR区的特殊功能寄存器称为传统特殊功能寄存器(SFR),逻辑地址位于XDATA区域的特殊功能寄存器称为扩展特殊功能寄存器(XFR)
传统特殊功能寄存器使用直接寻址方式访问。访问扩展特殊功能寄存器前需要将P_SW2(BAH)寄存器的最高位(EAXFR)置1,然后使用MOVX A,@DPTR和MOVX@DPTR,A指令进行访问。扩展数据存储区扩展数据存储区也称为扩展RAM区或外部RAM(简称XRAM)STC8H8K64U单片机一共可以访问64KB的扩展数据存储空间。在汇编语言中,XRAM使用“MOVX @DPTR”或者“MOVX@Ri”形式的指令访问。在C语言中使用xdata声明存储类型即可。如unsigned char xdata i= 0。
STC8H8K64U单片机片内集成了8192B的XRAM,地址范围为0000H1FFFH,可用于存放数据和变量。对于一般应用都能满足要求,不再需要外部扩
展RAM。验证https://image.lceda.cn/oshwhub/628a9d8a2a1246e294437cfbb16b8442.png单片机引脚不多说,直接画一个带USB通讯的核心板原理图https://image.lceda.cn/oshwhub/70deef6226f5459e8f0ad92c103d33ae.pngpcbhttps://image.lceda.cn/oshwhub/23e562e1028e41c1afe5045ed553c109.png3D渲染图https://image.lceda.cn/oshwhub/d000bfc0a84e40f4860aaa5dba7d2b73.pnghttps://image.lceda.cn/oshwhub/ae60e76b71ec4005a1e5f9767891aaf0.png

白一宁 发表于 2024-7-1 17:34:00

第六节 I/O口的工作模式,STC8H8K64U的汇编语言程序设计,初步入门IO口工作模式在使用STC8H8K64U单片机的I/0口时,应注意
[*]P3.0和P3.1口上电后的状态为弱上拉/准双向口模式。
[*]除P3.0和P3.1外,其余所有I/O口上电后的状态均为高阻输入状态,用户在使用I/O口前必须先设置I/O口模式。
[*]上电时如果不需要使用USB进行ISP下载,P3.0/P3.1/P3.2这3个I/O口不能同时为低电平,否则会进入USB下载模式而无法运行用户代码。
I/O口复用功能
[*]P0口可复用为数据总线(D7~D0)、地址总线低8位(A7~A0)、ADC输入(ADC8~ADC14)、串口3、串口4、T3时钟输出、T3脉冲输入、T4时钟输出、T4脉冲输入、PWM输出控制
[*]P1口可复用为ADC转换输入(ADC7~ADC0,无ADC2)、PWM输出、SPI通信线、第二串口、第三串口、系统时钟输出、外接晶体引脚、I2C通信线等
[*]P2口可作为地址总线的高8位输出(A15~A8)。另外,P2口还用于SPI和I2C以及PWM输出。
[*]P3口可复用为外部中断输入、计数器输入、SPI、I2C、比较器输入和输出、串口1、PWM输出等功能。
[*]P4口的复用功能可配置为SPI通信、读写控制信号、串口2、地址锁存信号等。
[*]P5口的复用功能可配置串口3、串口4、比较器输入、复位脚、系统时钟输出、SPI接口的从机选择信号、PWM输出。
[*]P6口可复用为PWM输出。
[*]P7口可复用为PWM输出和I2C接口。
I/0口的复用功能是通过设置相关的特殊功能寄存器实现的。https://image.lceda.cn/oshwhub/1e02ae9700c64ab5b4f3a8ae671805e4.pngI/O口的使用上拉电阻的链接传统方式https://image.lceda.cn/oshwhub/15baae24f9f94b8d8ed018d6fcc39989.png
STC8H8K64U可以通过ISP方式配置https://image.lceda.cn/oshwhub/3f2aff0644da45bcbbd820f146ef76bd.png拉电流和灌电流方式https://image.lceda.cn/oshwhub/e7de3c57895b452ab59cb8c4b5c584e8.png典型三极管控制电路https://image.lceda.cn/oshwhub/7322fc5b48c04f06a5ff658ba9749a1a.png当需要驱动的功率器件较多时,建议采用达林顿管驱动器ULN2803I/O外部状态的输入当I/O口工作于准双向口时,由于STC8H8K64U单片机是1个时钟周期(1T)的8051单片机,速度很快,如果通过指令执行由低变高指令后立即读外部状态此时由于实际输出还没有变高,有时可能读入的状态不对。这种问题的解决方法是在软件设置由低变高后加延时,然后再读IO口的状态。单片机应用的典型构成1.非总线扩展方式的单片机应用系统构成STC8H8K64U单片机内部已经有64 KB程序存储器和8192BRAM,可以满足一般应用的存储器需求。此时,单片机的P0、P2和P4口不用于总线方式,即P0口和P2口用于普通I0口功能;P4.2和P4.4不用于写控制信号和读控制信号,也用于普通I/0口功能。2.总线扩展方式的单片机应用系统构成如果需要扩展存储器容量或者并行I/O,需要使用总线扩展方式。此时8位的数据总线由P0口提供,16位的地址总线由P2和P0口构成。P4口中的/WR(P4.2)和/RD(P4.4)引脚的作用是写控制和读控制。ALE(P4.5)信号用于锁存器的锁存控制,以锁存由P0口输出的地址,从而实现地址和数据的分离。https://image.lceda.cn/oshwhub/cd5888ddd0a84a96b3e029d0ab5f666c.png
总线扩展方式下,P2口没有用到的口线不能再用作IO功能!汇编语言程序设计入门为什么学习汇编
[*]汇编语言有助于原理理解
[*]在嵌入式操作系统的移植过程中,还用到少许的汇编语言
[*]正在学单片机,此时不学,今后没有汇编语言相关课程的讲解了
伪指令伪指令并不产生目标程序,不影响程序的执行,仅仅产生供汇编用的某些指令,以便在汇编时执行一些特殊操作。1.设置起始地址ORG(Origin)例:ORG addre16
ORG是该伪指令的操作助记符,操作数addr16是16位二进制数,前者表明为后续源程序汇编后的目标程序安排存放位置,后者则给出了存放的起始地址值。ORG伪指令总是出现在每段源程序或数据块的开始。可使程序员把程序、子程序或数据块存放在存储器的任何位置。
例如:
                  ORG 2000H
                  MOV A, 20H
表示后面的目标程序从2000H单元开始存放。
若在源程序开始不放ORG指令,则汇编将从0000H单元开始存放目标程序2.定义字节DB(Define Byte)其中项或项表是指一个字节、数或字符串,或以引号括起来的ASCI码字符串。该指令的功能是把项或项表的数值(字符则用它的ASCI码表示)存入从标号开始的连续单元中。
例如 :
                  HERE:                  DB 84H                  ;(HERE)=84
                                                   DB 43H                  ;(HERE+1)=43H
又如:
                                                    ORG 1000H
                  SEG:                     DB 23H,'MSC-51'
则:
                            (1000H)=23H                            SEG的地址为1000H
                            (1001H)=4DH                            'M'的ASCI码
                            (1002H)=43H                            'C'的ASCI码
                            (1003H)=53H                            'S'的ASCI码
                            (1004H)=2DH                            '-'的ASCI码
                            (1005H)=35H                            数字'5'的ASCI码
                            (1006H)=31H                            数字'1'的ASCI码3.定义字DW(Define Word)<标号:> DW <项或项表>
DW的基本含义与DB相同,但DB一般用于定义8位数据(一个字节。DW定义16位数据即一个字。在执行汇编程序时,机器会自动按低位字节在前,高位字节在后的格式排列(与程序中的地址规定一致)。所以DW伪指令常用来建立地址表。4.为标号幅值EQU<标号:> DW <数值或表达式>
其功能是将语句操作数的值赋于本语句的标号,故又称为等值指令
例如:
                                                   BLK EOU 1000H
即把值1000H赋给标号BLK。需要注意的是,在同一程序中,用EQU伪指令对标号赋值该标号的值在整个程序中不能再改变。5.DATA指令符号名 DATA 表达式
DATA 指令用于将一个内部 RAM 的地址赋给指定的符号名。数值表达式的值在00H~0FFH之间,表达式必须是一个简单表达式。
例如:
                                                   BUFFER DATA 40H6.XDATA指令(External Data)<符号名> XDATA <表达式>
XDATA 指令用于将一个外部 RAM 的地址赋给指定的符号名。数值表达式的值在0000H~0FFFFH之间,表达式必须是一个简单表达式。'
例如:
                                                MYDATA XDATA 0400H7.定义位命令BIT<字符名称> BIT <位地址>
该指令用于给字符名称定义位地址。
例如:
                                                DOGOUT BIT P3.4
经定义后,允许在指令中用DOGOUT代替P3.4.8.文件包含命令INCLUDE$INCLUDE(文件名)
文件包含命令INCLUDE用于将寄存器定义文件(一般的后缀名为.INC)包含于当前程序中,与C语言中的#include语句的作用类似。
可以STC8H8K64U单片机的寄存器定义保存在文件STC8H.INC中,使用时,将STC8H.INC文件拷贝到当前工程文件夹或者Keil安装文件夹的C51UNC文件夹中,并在程序的开始处使用下面的命令将其包含到用户程序中:                                              $INCLUDE (STC8H.INC)实操https://image.lceda.cn/oshwhub/acce5a82dab044ecb81edb4adbddcc23.png$INCLUDE (stc8h.inc)   ;包含STC8H8K64U单片机寄存器定义头文件
    ORG                0000H
      LJMP      MAIN                        ;跳转到主程序
      ORG                0100H


MAIN: MOV                SP,#70H                  ;设置堆栈指针(可根据实际情况进行修改)
      MOV P2M0,#3cH
    MOV P2M1,#3cH
    CLR P2.0

L_MainLoop:                              ;主程序循环
   CLR P2.0
   LCALL DELAY500MS
   SETB P2.0
   LCALL DELAY500MS

DELAY500MS:                        ;@11.0592MHz
      PUSH      30H
      PUSH      31H
      PUSH      32H
      MOV                30H,#29
      MOV                31H,#14
      MOV                32H,#52
NEXT:
      DJNZ      32H,NEXT
      DJNZ      31H,NEXT
      DJNZ      30H,NEXT
      POP                32H
      POP                31H
      POP                30H
      RET

    END

白一宁 发表于 2024-7-3 10:43:34

第七节 STC8H8K64U的汇编语言程序设计进阶,宏汇编助记符语言机器语言(Machine Language)是用二进制数表示的指令,是CPU唯一能够直接识别和执行的程序形式。
机器语言的缺点是不直观,不易识别、理解和记忆,因此编写、调试程序时都不采用这种形式的语言。为了解决这个问题,引入了助记符。
汇编语言的指令通常由操作码和操作数组成。操作码指出的是要对操作数进行什么操作。操作数指出的是对什么数进行操作以及将操作的结果放到何处。为便于阅读和记忆,操作码用规定的缩写英文字母组成,称为助记符。例如:MOV是数据的传送
                  ADD是数据的相加运算
                  ANL是数据的逻辑与运算等例如:ADD A,#8BH
该指令表示把十六进制数8BH和累加器A的内容相加,将结果存在累加器A中。
其中ADD是操作码符号。
A和8BH是操作数。
例如:MOV A,#76H
该指令表示将十六进制的数据76H送到累加器A中,
其中的74H表示操作码,是指将一个数据传送到累加器A中,被传送的数据就是操作码的下一个字节,也就是第2个字节,即76H。操作码操作码是指令功能的英文缩写。下表给出了8051内核单片机指令系统中最常用的操作码。
https://image.lceda.cn/oshwhub/949f16a23b18422b84c9ebcc91ea46cc.png操作数操作数是一条指令操作的对象。操作数可以是数据,也可以是地址。不同功能的指令,操作对象形式不同。不同指令的操作数特点如下:
[*]传送类指令,必须指明操作对象从哪儿来(源地址),传到何处去(称为目的地址)
[*]数据操作类指令,一般靠运算器完成,数据操作类指令的对象一般是两个
[*]程序控制类指令的操作对象是程序计数器PC和一个数
[*]逻辑操作类有单操作数和双操作数之分
注意:
[*]数据只能是整数,不能是小数。
[*]当汇编指令中的数据是十六进制且是以字母开头时,该数据应加一个前导0,以表示后面的字母不是变量而是数字。
其中,带有中括号的内容是可以省略的内容或者指令格式中不需要的内容。
标号后面有一个冒号“:”,它实质上是标号所在行的指令的地址,根据程序设计的需要设置。标号是由字母开头的有意义的字符串组成
例如:
                  LOOP LOOP1 TABLE
指令格式及分类汇编语言的概念及格式用助记符来描述机器指令的语言称为符号语言或汇编语言
[标号:] 操作码助记符 [第一操作数] [,第二操作数] [,第三操作数] [;注释]在汇编语言程序中,标号也用作子程序的名字。根据指令的语法要求,一条指令中,可能有0~3个操作数
例如:
                  RETI                                                                        ;中断返回,无操作数
                  CPL                      A                                              ;累加器逐位取反,只有一个操作数
                  ADD                  A,#56H                            ;两个操作数的情况
                  CINE                   R2,#60H,LOOP          ;三个操作数的情况注释注释是为了阅读程序方便由编程人员加上的,并不影响程序的执行和功能,所以,注释部分不是必需的。
注释三种方式:
[*]使用“ ; ”,单行注释
[*]使用 “ // ” 单行注释
[*]使用“ /*..*/ ”的形式注释某一段内容。
寻址方式操作数是指令的重要组成部分,它指定了参与运算的数或数所在的单元地址,而如何得到这个地址就称为寻址方式。8051内核的单片机共有7种寻址方式:1.立即寻址指令中的源操作数是立即数,这种寻址方式叫做立即寻址。立即数的类型可以是数字也可以是字符,一般字长为8位或16位。
例如:
                  MOV A#28H                              ;把十六进制的立即数28H送入到累加器A中,机器码:74H 28H;
                  MOV DPTR,#0050                  ;H把十六进制的16位立即数0050H送入到DPTR中https://image.lceda.cn/oshwhub/1d6c90978a4b4eaca62f7f15320cff53.png2.寄存器寻址指定寄存器的内容为操作数,对寄存器ACC、B、DPTR和CY(进位标志,也是布尔处理机的累加器)寻址时,具体的寄存器已隐含在其操作码中。而对选定的8个工作寄存器R7~R0,则用指令操作码的低3位指明所用的寄存器
例如:
                  INC RS                  ;把寄存器R5的内容加1后再送回R5https://image.lceda.cn/oshwhub/5a98656bc105453cb588282e28efac0b.png3.直接寻址直接寻址就是在指令中包含了操作数的地址,即在指令中直接包含了参加运算或传送的单元或位的地址。直接寻址可访问三种地址空间:
[*]特殊功能寄存器SFR:直接寻址是唯一的访问形式。
[*]内部数据RAM中的00H~7FH的128个字节单元。
[*]位地址空间。
例如:
                  MOV                   A,45H                  ;把45H单元的内容送入累加器A中https://image.lceda.cn/oshwhub/95ae06faf0f442a3bdea5477d3849ada.png4.寄存器间接寻址指令指定某一寄存器的内容作为操作数地址。可用来间接寻址的寄存器有:选定工作寄存器区的R0、R1、堆栈指针SP或者16位的数据指针DPTR,使用时前面加@表示间接寻址。
例如:
                   MOV                   A,@RO                   ;将R0中的内容所表示的地址单元中的内容送给A
                   MOVX               @DPTP, A            ;将A中的内容送到DPTR指向的外部RAM单元中https://image.lceda.cn/oshwhub/b42baebc7658409890d3e87fc3d874ac.png5.变址寻址有两种
[*]用PC作基地址寄存器加上累加器A的内容形成操作数的地址A+PC
例如:
                  MOVC                   A,@A+PC                  ;读取A+PC指向的程序存储器单元的值送给A
[*]使用DPTR作基地址寄存器,加上累加器A的内容形成操作数的地址A+DPTR
https://image.lceda.cn/oshwhub/8e00a3109faf42ab93f6a1bde0b216f7.png6.相对寻址该寻址方式主要用于相对跳转指令。把指令中给定的地址偏移量与本指令所在单元地址(即程序计数器PC中的内容)相加,得到真正的程序转移地址。与变址方式不同,该偏移量有正、负号,在该机器指令中必须以补码形式给出,所转移的范围为相对于当前PC值的-128~+127之间。7.位寻址支持位单元存取操作是8051内核单片机的一个主要特点。位操作指令可以对位地址空间的每位进行运算和传送操作。
例如:
                  MOV                  C,P1.0                   ;将P1.0的状态传送到进位标志CY
                  SETB                   20H.6                   ;将20H单元的第6位置为1
                  CLR                     25H                         ;将25H位的内容清零

白一宁 发表于 2024-7-5 09:23:22

第八节 汇编指令一(数据传送/逻辑运算/算术运算)数据传送数据传送类指令是使用频率最高的一类指令。主要用来给8051单片机系统的内部和外部资源赋值、进行堆栈的存取操作等。数据传送类指令执行前后,对程序状态字PSW一般不产生影响。按其操作方式,又可把它们分为三种数据传送 -- MOVMOV指令的作用区间主要是内部数据存储器和特殊功能寄存器。
格式为 MOV <目的字节>,<字书>
字节>,<字书>
把第二操作数指定的字节变量传送到由第一操作数指定的单元中,源字节内容不变,一般不影响别的寄存器或标志
立即数送累加器A和Rn、内部RAM、SFR。共有4条指令:
                        MOV                           A,#data8                                 ;(A)←#data8
                        MOV                           addr8,#data8                   ;(addr8)←#data8
                        MOV                           @Ri,#data8                     ;((Ri))←#data8
                        MOV                           Rn,#data8                           ;(Rn)←#data8
@符号表示间接寻址,Ri中i-0或i=1https://image.lceda.cn/oshwhub/cba1d7702b8d472ab0ca317eb5f70384.pnghttps://image.lceda.cn/oshwhub/7ea920b8034c4fe390f872286a18360f.png
Rn、内部RAM、SFR与累加器A传送数据。共有6条指令
                        MOV                        A,addr8
                        MOV                        A,@Ri
                        MOV                        A,Rn
                        MOV                        addr8,A
                        MOV                        @Ri
                        MOV                        
间接寻址@Ri是以Ri的内容作为地址进行寻址,由于Ri为8位寄存器,所以其寻址范围可为00H~FFH。
例如:
                        MOV                        R1,#82H
                        MOV                        A,@R1外部数据存储器(或扩展并行I/0口)与累加器A传送指令MOVXMOVX指令主要用于累加器A和外部RAM或扩展并行I10口进行数据传送。这种传送只有一种寻址方式,就是寄存器间接寻址。寄存器间接寻址有两种方式:
[*]用R1或R0进行寄存器间接寻址
可访问外部数据存储器(或扩展并行I0口)256个字节中的一个字节。需使用P2口输出高8位地址,需要先给P2和Ri赋值,然后执行MOVX指令。
[*]用16位的数据存储器地址指针DPTR进行寄存器间接寻址
这种方式 能遍访64KB的外部数据存储器(或扩展并行I0口)的任何单元。
程序存储器向累加器A传送指令---MOVC对于程序存储器的访问,单片机提供了两条极其有用的查表指令
指令格式:
                        MOVC                           A,@A+PC                        ;PC←(PC)+1,(A)←((A)+(PC))这条条指令以PC作为基址寄存器,指令查表范围只能在以PC当前值开始后的256个字节范围使表格地址空间分配受到限制。
                        MOVC                           A,@A+DPTR                   ;(A)←((A)+(DPTR))
这条指令以数据指针DPTR为基址寄存器,由于DPTR可以通过指令来设置,表格常数可设置在64K程序存储器的任何地址空间。若DPTR已有它用,在将表首地址赋给DPTR之前必须保护k现场,执行完查表后再子以恢复。这两条指令采用变址寻址,以PC或DPTR为基址寄存器,以累加器A为变址寄存器,基址寄存器与变址寄存器内容相加得到程序存储器某单元的地址值,MOVC指令把该存储单元的内容传送到累加器A中。指令主要用于查表,即完成从程序存储器读取数据的功能。由于两条指令使用的基址寄存器不同,因此使用范围也不同。数据交换1.字节交换指令指令把累加器A中的内容与第二操作数的内容互相交换
                        XCH                           A, addr8                           ;(A)←→(addr8)
                        XCH                           A, @Ri                                 ;(A)←→((Ri))
                        XCH                           A, Rn                                     ;(A)←→(Rn)2.半字节交换指令指令把累加器A的低4位和寄存器间接寻址的内部RAM单元的低4位交换,高4位内容不变,不影响标志位。
                        XCHD                        A,@Ri栈操作堆栈区是将内部存储器的一部分区域划作专门用于堆栈的区域。堆栈区的操作规则是后进先出(LIFO-Last In First Out),即最后存入的数据将被最先取出。堆栈区当前的栈顶地址用堆栈指针寄存器SP中的值表示,即SP始终指向栈顶。https://image.lceda.cn/oshwhub/e6b298c8d51744999cd230be5e6db125.png逻辑运算算术运算算术运算类指令主要完成加、减、乘、除四则运算,以及增量、减量和二十进制调整操作。除增量、减量指令外,大多数算术运算指令会影响到状态标志寄存器PSW。表4-3反映了算术运算类指令对标志位的影响。https://image.lceda.cn/oshwhub/fb5a55294eb34157b606d67580e58d87.png加减法运算指令加减运算中,以累加器A为第一操作数,并存放操作后的结果。第二操作数可以是立即数、工作寄存器、寄存器间接寻址字节或直接寻址字节。1.加法指令: ADD,把源字节变量(立即数、直接地址单元、间接地址单元、工作寄存器内容)与累加器相加,结果保存在累加器中,影响标志AC、CY、OV、P。2.带进位加法指令: ADDC除了相加时应考虑进位标志外,其他与一般加法指令完全相同
例:设累加器A内容为0AAH,RO内容为55H,CY内容为1,执行指令:
                        ADDC                           A,RO
将使得: (A)=00000000B AC=1,CY=1,OV=0乘除法运算指令乘除运算指令在累加器A和寄存器B之间进行,运算结果保存在累加器A和寄存器B中。1.乘法指令 MUL AB该指令把累加器A和寄存器B中的8位无符号整数相乘,16位乘积的低字节在累加器A中高字节在寄存器B中,如果乘积大于255(OFFH),则溢出标志位置1,否则清0,运算结果总使进位标志CY清0。2.除法指令 DIV AB该指令把累加器A中的8位无符号整数除以寄存器B中8位无符号整数,所得商放在累加器A中余数存在寄存器B中,标志位CY和OV均清0。若除数(B中内容)为00H,则执行后结果为不定值,并置位溢出标志OV3.增量、减量指令增量指令INC完成加1运算(相当于C语言中的++),减量运算DEC完成减1运算(相当于C语言中的--)。这两条指令均不影响标志位(但对累加器A的操作将影响P标志)

白一宁 发表于 2024-7-5 16:46:54

第九节 汇编指令二(位操作/控制转移)位操作指令位操作指令以位为处理对象,分别完成位传送、位状态控制、位逻辑操作、位条件转移等功能,共有17条。可被汇编程序所识别的位地址表示方式如下:
[*]直接用位地址(十进制或十六进制数)表示,或写成位地址表达式表示。
[*]写成“字节地址,位数”方式。例如0B8H.0,20.1等。
[*]写成“字节地址,位数”方式。例如0B8H.0,20.1等。
[*]对于位寻址寄存器,可以用“字节寄存器名,位数”表示。例如P1.0,PSW.4等。
[*]用户使用伪指令事先定义过的符号地址。
位操作指令的操作码助记符及对应的操作数https://image.lceda.cn/oshwhub/68b60a0ce02c48229e0ad2ed8abe76b1.png位数据传送指令指令的功能是把第二操作数所指出的布尔变量送到由第一操作数指定的布尔变量中。其中一个操作数必为位累加器(进位标志CY),另一个可以是任何直接寻址位(bit)。指令执行结果不影响其他寄存器或标志。
                        MOV                         C,bit                         ;(C)←(bit)
                        MOV                         bit,C                         ;(bit)←(C)例:设片内数据RAM中(20H)=79H,指令:
                        MOV                         C,07H                        ;07H是位地址,即字节地址20H的第7位,将使(c)=0。位状态控制指令位状态控制指令包括位的清零、取反和置位位清0指令                        CLR                         bit                         ;(bit)←0
                        CLR                         C                           ;(C)←0https://image.lceda.cn/oshwhub/0c26673b5f6744a893126d4f9715e16c.png
修改0x25上的值位0x34https://image.lceda.cn/oshwhub/6d19685d2f5546b6b039655d2c3fa5e9.png
运行 CLR                        2AHhttps://image.lceda.cn/oshwhub/53d585a54d8748b3bfac697ac0effdc4.png位求反指令上述指令可把直接寻址位(bit)或位累加器C内容取反,不影响其他标志。
                        CPL                        bits                        ;(bit)←(/bit)
                        CPL                        C                              ;(C)←(/C)
取反前
https://image.lceda.cn/oshwhub/8116a8557dda448bb1bcdc3342d975af.png
取反后
https://image.lceda.cn/oshwhub/fc26e7590c13492c91e96a327d42841b.png位置指令()                        SETB                         bit                         ;(bit)←1
                        SETB                         C                               ;CY←1https://image.lceda.cn/oshwhub/5569d5420a74455f87154ccfa3076d9d.png位逻辑操作指令1.位逻辑“与“指令 ANL                        ANL                         C, bit                        ;(C)^(bit)
                        ANL                         C, /bit                      ;(C)^(/bit)
ANL指令将直接寻址位的内容或直接寻址位内容取反后(不改变原内容)与位累加器C相与,结果保存在C中。“/bit”表示对将位内容取反后再参与位操作。https://image.lceda.cn/oshwhub/030b5340cf3e4347bc0077bb9a968ef5.png2.逻辑或操作                        ORL                         C, bit                        ;(C)←(C)^(bit)
                        ORL                         C, /bit                      ;(C)←(C)^(/bit)https://image.lceda.cn/oshwhub/d74c0f30168d49419cf54c5145efcf54.png位条件转移指令位条件转移指令分为判进位标志C或判直接寻址位状态转移两种1.判进位标志C转移指令                        JC                         rel                        ;若(CY)=1,则(PC)←(PC)+rel,否则顺序执行
                        JNC                   rel                        ;若(CY)=0,则(PC)←(PC)+rel,否则顺序执行。
https://image.lceda.cn/oshwhub/428df09db50a47afb3db358c1ff5399e.png
实际应用中,一般在rel的位置写入欲跳转到的标号地址,偏移量由汇编程序自动进行计算。这样做有两个好处,一是程序的可读性好,二是不必进行偏移量的计算。2.判直接寻址位转移指令                        JB                         bit,rel                         ;若(bit)=1,(PC)←(PC)+rel
                        JNB                     bit,rel                         ;若(bit)=0,(PC)←(PC)+rel
                        JBC                     bit,rel                         ;若(bit)=1,(PC)←(PC)+rel,(bit)←0https://image.lceda.cn/oshwhub/fa5b0d180b4a455bbe00b1d2cc2a6698.png
在实际应用中,一般在rel的位置写入欲跳转到的标号地址,偏移量由汇编程序自动进行计算。控制转移类指令控制转移类类指令用于控制程序的走向。
控制转移类指令可分为两种:一种是程序转移指令,另一种称为子程序调用和返回指令。https://image.lceda.cn/oshwhub/6ad97745afc54d3e820960dc2d21339d.png

白一宁 发表于 2024-7-6 11:19:41

第十节 汇编语言程序设计的一般步骤和基本框架汇编语言程序设计的一般步骤和基本框架程序是指令的有序集合。编写一个功能完善的、完整的程序,正确性是最主要的,但整个程序占内存的空间大小、每条指令的功能、长度执行速度等都要考虑,尽可能使其优化。
一个完善的系统设计应该具有设计方案正确、程序结构规范等基本性质,这不仅给程序的设计和调试带来方便,加速调试过程,而且有益于程序的维护和升级。汇编语言程序设计的一般步骤
[*]分析课题,确定算法或解题思路。
[*]根据算法或思路画出流程图
[*]中断等资源的分配根据算法要求分配资源,包括内部RAM、定时器。
[*]根据流程图编写程序。
[*]上机调试源程序,进而确定源程序。
对于复杂的程序可以按功能分为不同的模块,按模块功能确定结构,编写程序时采用模块化的程序设计方法。汇编语言程序的框架
$NOMOD51
$INCLUDE (STC8H.H)   ;包含STC8H8K64U单片机寄存器定义头文件
;…这里可以编写程序中用到的一些符号定义(使用EQU、DATA、BIT等伪指令)
          ORG                0000H
START:        LJMP        MAIN                        ;跳转到主程序
                ORG                0003H
                LJMP        INT0_ISR      ;外部中断0入口
                ORG                000BH
                LJMP        T0_ISR                        ;定时器0中断入口
                ORG                0013H
                LJMP        INT1_ISR                ;外部中断1入口
                ORG                001BH
                LJMP        T1_ISR                        ;定时器1中断入口
                ORG                0023H
                LJMP        UART1_ISR                ;串口1中断入口
                ORG                002BH
                LJMP        ADC_ISR                        ;ADC中断服务程序入口
                ORG                0033H
                LJMP        LVD_ISR                        ;低电压检测中断服务程序入口
                ORG                003BH
                LJMP        PCA_ISR                        ;PCA中断服务程序入口   
                ORG                0043H
                LJMP        UART2_ISR                ;串口2中断服务程序入口
                ORG                004BH
                LJMP        SPI_ISR                        ;SPI中断服务程序入口
                ORG                0053H
                LJMP        INT2_ISR                ;INT2中断服务程序入口
                ORG                005BH
                LJMP        INT3_ISR                ;INT3中断服务程序入口
                ORG                0063H
                LJMP        T2_ISR                        ;定时器2中断服务程序入口       
                ORG                0083H
                LJMP        INT4_ISR                ;INT4中断服务程序入口
                ORG                008BH
                LJMP        UART3_ISR                ;UART3中断服务程序入口
                ORG                0093H
                LJMP        UART4_ISR                ;UART4中断服务程序入口
                ORG                009BH
                LJMP        T3_ISR                        ;T3中断服务程序入口
                ORG                00A3H
                LJMP        T4_ISR                        ;T4中断服务程序入口
                ORG                00ABH
                LJMP        CMP_ISR                        ;比较器中断服务程序入口
                ORG                00C3H
                LJMP        I2C_ISR              ;I2C中断服务程序入口
                ORG                00CBH
                LJMP        USB_ISR              ;USB中断服务程序入口
                ORG                00D3H
                LJMP        PWMA_ISR               ;PWMA中断服务程序入口
                ORG                00DBH
                LJMP        PWMB_ISR               ;PWMB中断服务程序入口
                ORG                011BH
                LJMP        TKSU_ISR               ;触摸按键中断服务程序入口(STC8H8K64U单片机没有该中断)
                ORG                0123H
                LJMP        RTC_ISR               ;RTC中断服务程序入口
                ORG                012BH
                LJMP        P0_ISR               ;P0中断服务程序入口
                ORG                0133H
                LJMP        P1_ISR               ;P1中断服务程序入口
                ORG                013BH
                LJMP        P2_ISR               ;P2中断服务程序入口
                ORG                0143H
                LJMP        P3_ISR               ;P3中断服务程序入口
                ORG                014BH
                LJMP        P4_ISR               ;P4中断服务程序入口
                ORG                0153H
                LJMP        P5_ISR               ;P5中断服务程序入口
                ORG                015BH
                LJMP        P6_ISR               ;P6中断服务程序入口
                ORG                0163H
                LJMP        P7_ISR               ;P7中断服务程序入口
                ORG                017BH
                LJMP        DMA_M2M_ISR   ;DMA_M2M中断服务程序入口       
                ORG                0183H
                LJMP        DMA_ADC_ISR   ;DMA_ADC中断服务程序入口
                ORG                018BH
                LJMP        DMA_SPI_ISR   ;DMA_SPI中断服务程序入口
                ORG                0193H
                LJMP        DMA_UR1T_ISR    ;DMA_UR1T中断服务程序入口
                ORG                019BH
                LJMP        DMA_UR1R_ISR    ;DMA_UR1R中断服务程序入口
                ORG                01A3H
                LJMP        DMA_UR2T_ISR    ;DMA_UR2T中断服务程序入口
                ORG                01ABH
                LJMP        DMA_UR2R_ISR    ;DMA_UR2R中断服务程序入口
                ORG                01B3H
                LJMP        DMA_UR3T_ISR    ;DMA_UR3T中断服务程序入口
                ORG                01BBH
                LJMP        DMA_UR3R_ISR    ;DMA_UR3R中断服务程序入口
                ORG                01C3H
                LJMP        DMA_UR4T_ISR    ;DMA_UR4T中断服务程序入口
                ORG                01CBH
                LJMP        DMA_UR4R_ISR    ;DMA_UR4R中断服务程序入口
                ORG                01D3H
                LJMP        DMA_LCM_ISR   ;DMA_LCM中断服务程序入口
                ORG                01DBH
                LJMP        LCM_ISR           ;LCM中断服务程序入口
//-------------------------------------------------------------------------------
        ORG        0200H
MAIN:
        MOV                SP,#80H                ;设置堆栈指针(可根据实际情况进行修改)
        ;初始化内存区域内容
        ;设置有关特殊功能寄存器(SFR)的控制字
        ;根据需要开放相应的中断控制
MAINLOOP:                                        ;主程序循环
       
        LJMP        MAINLOOP
//================================================================================
;下面是各个中断服务子程序
INT0_ISR:      ;外部中断0中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
T0_ISR:                        ;定时器0中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
INT1_ISR:                ;外部中断1中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
T1_ISR:                        ;定时器1中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
UART1_ISR:                ;串口1中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
ADC_ISR:                ;ADC中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
LVD_ISR:                ;低电压检测中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
PCA_ISR:                ;PCA中断服务子程序   
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
UART2_ISR:                ;串口2中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
SPI_ISR:                ;SPI中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
INT2_ISR:                ;INT2中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
INT3_ISR:                ;INT3中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
T2_ISR:                        ;定时器2中断服务子程序       
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
INT4_ISR:                ;INT4中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
UART3_ISR:                ;UART3中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
UART4_ISR:                ;UART4中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
T3_ISR:                        ;T3中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
T4_ISR:                        ;T4中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
CMP_ISR:                ;比较器中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
I2C_ISR:               ;I2C中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
USB_ISR:               ;USB中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
PWMA_ISR:              ;PWMA中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
PWMB_ISR:              ;PWMB中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
TKSU_ISR:              ;触摸按键中断服务子程序(STC8H8K64U单片机没有该中断)
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
RTC_ISR:              ;RTC中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P0_ISR:               ;P0中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P1_ISR:               ;P1中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P2_ISR:               ;P2中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P3_ISR:               ;P3中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P4_ISR:               ;P4中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P5_ISR:               ;P5中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P6_ISR:               ;P6中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
P7_ISR:               ;P7中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_M2M_ISR:    ;DMA_M2M中断服务子程序       
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_ADC_ISR:    ;DMA_ADC中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_SPI_ISR:    ;DMA_SPI中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR1T_ISR:   ;DMA_UR1T中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR1R_ISR:   ;DMA_UR1R中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR2T_ISR:   ;DMA_UR2T中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR2R_ISR:   ;DMA_UR2R中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR3T_ISR:   ;DMA_UR3T中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR3R_ISR:   ;DMA_UR3R中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR4T_ISR:   ;DMA_UR4T中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_UR4R_ISR:   ;DMA_UR4R中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
DMA_LCM_ISR:    ;DMA_LCM中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
LCM_ISR:           ;LCM中断服务子程序
        ;根据需要填入处理代码,若没有处理代码,可使用后面的一条语句让单片机复位
        MOV        IAP_CONTR,#20H             ;有其他处理程序时,不要使用该语句
        RETI
//--------------------------------------------------
;下面可以编写其他子程序或者定义程序中所用的常数               
       
        END

程序流程图在程序编制以前,先根据系统方案绘制程序流程图是一个很好的方法.
程序流程图可以简洁清晰地将程序的分支走向标示清楚,尤其是在程序复杂编写人员较多相互衔接容易出错的的情况下,利用流程图理顺各部分关系显得尤为重要。
画流程图有两个常用的结构:顺序执行的矩形框和条件分支的形框。
顺序执行:某个局部功能或者顺序执行的语句使用矩形方框表示,矩形方框内注明程序的功能,各方框之间用箭头表示执行顺序,一目了然。
条件分支:遇到需要根据条件判断是否转移时,使用萎形方框表示,菱形内注明分支条件,不同出口表明分支的去向。https://image.lceda.cn/oshwhub/6c44ed9cec124c2b89b680040c0b2e29.png典型汇编语言程序设计举例
[*]分支程序设计
程序分支是通过条件转移指令实现的,即根据条件进行判断后决定程序的走向。条件满足则进行程序转移,不满足就顺序执行程序。
[*]通过条件判断实现单分支程序转移的指令有J2、JNZ、CJINE和DJNZ等
[*]以位状态为条件,进行程序分支的指令JC、JNC、JB、INB和JBC等。
例:编程实现下面的比较函数。设变量x存放在R0,求得的y 值存入SIGN单元。
https://image.lceda.cn/oshwhub/3473d3e535a244418e0c7c688fbeb7c3.png
可以利用CJNE指令和进位位C状态控制转移(JC指令)来实现三分支转移。
   SIGN EQU 50H
      ORG 0000H
      LJMP MAIN
      ORG 0100H
MAIN:   SCINE RO,#37,NOTEQ         ;R0与37比较,不相等则转NOTEQ
      MOV SIGN,#00H                ;若比较相等,则SIGN←0
      LJMP ENDME
NOTEQ:JC                           ;两数不相等,若R0<37则转NEGA
      MOV SIGN,#01H                ;RO>37时,SIGN←+1
      LMPE NDME   
NEGA:   MOV SIGN,#OFFH               ;RO<37时,SIGN←-1
ENDME:NOP
      END


[*]查表程序设计
查表法就是把事先计算或测得的数据按一定顺序编制成表格,查表程序根据被测参数的值或者中间结果,查出最终所需要的结果。
查表法产生的背景
[*]参数的计算非常复杂;
[*]公式计算法计算程序长,难于计算;
[*]需要耗费大量时间;
[*]非线性参数,无法用一般算术运算就可以计算出来,如指数、对数、三角函数以及积分、微分等运算;
[*]数学计算无法建立相应的数学模型

[*]循环程序设计
延时程序是典型的循环程序。下面就以延时程序为例,说明循环程序的设计方法。延时程序是典型的循环程序。
https://image.lceda.cn/oshwhub/6a48db0f85cf415886f321ade05045b6.png
100uS延时,使用STC_ISP工具计算生成
DELAY100US:                        ;@11.0592MHz
        NOP
        NOP
        PUSH        30H
        PUSH        31H
        MOV                30H,#2
        MOV                31H,#107
NEXT:
        DJNZ        31H,NEXT
        DJNZ        30H,NEXT
        POP                31H
        POP                30H
        RET

[*]定点数运算子程序设计
多字节无符号加法子程序和减法子程序设计较简单,在此介绍有代表性的多字节BCD码减法程序和多字节乘法程序的设计。
[*]多字节十进制BCD码减法
由于指令系统中只有十进制加法调整指令DA A,也即该指令只有在加法指令(ADD、ADDC)后,才能得到正确的结果。为了用十进制加法调整指令对十进制减法进行调整,必须采用补码相加的办法,用9AH减去减数即得以十为模的减数的补码。
[*]多字节乘法程序
STC8H8K64U单片机指令系统中只有单字节的乘法指令MULAB,而在工程应用中常需8位乘16位、两个16位数相乘的运算。

[*]数据排序程序设计
数据排序是将数据块中的数据按升序或降序排列。下面以数据的升序排序为例,说明数据排序程序的设计方法.
数据升序排列常采用冒泡法。冒泡法是一种相邻数据互换的排列方法,同查找极大值的方法一样,一次冒泡即找到数据块的极大值放到数据块最后,再一次冒泡时,次大数排在倒数第二位置:多次冒泡实现升序排列。
https://image.lceda.cn/oshwhub/5a18fae167f8482ab9a6fab015037d0e.png
6. 代码转换程序设计
在汇编语言程序设计中,数据输入/输出、A/D、D/A转换等常采用BCD码,字符的存储用ASCII码,算术逻辑运算又采用二进制数。
除了用硬件逻辑实现转换外,可采用算法处理和查表方法软件实现
[*]4位二进制数转换为ASCII代码
从ASCI编码表可知,若4位二进制数小于10,则此二进制数加上30H即变为相应的ASCI码,若大于10(包括等于10),则应加37H。
[*]ASCI码转换为4位二进制数
入口:转换前ASCII码送R2。
出口:2转换后二进制数存R2中。
[*]BCD码转换为二进制码子程序
例:设有用BCD码表示的4位十进制数分别存于R1、R2中,其中R2存千位和百位数,R1存拾位和个位数,要把其转换成二进制码。
解决思路:可用由高位到低位逐位检查BCD码的数值,然后累加各十进制位对应的二进制数来实现。其中,1000-03E8H,100=0064H,10=000AH(个位数的BCD码与二进制码相同)

页: [1] 2
查看完整版本: 《STC最新8051单片机原理及应用-STC8H8K64U》学习打卡