找回密码
 立即注册
楼主: gentleman

【实验箱已收到】何老师 《STC32位8051单片机原理及应用-STC32G12K128》,打卡

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-8-30 08:11:18 | 显示全部楼层
2023/08/22 第二十二集

     控制指令
            1.png
           
           RETI  是中断中返回  ,RET 是 子程序返回
           如果在终端中写RET  中断只能执行一次

           对比一下

         2.png        3.png


        跳转

          4.png

         CALL 需要回来
         JMP 不需要回来
         所以一个叫调用 一个叫跳转

         AJMP JMPADR            跳到标号jmpadr 存的地址
         
       EJMP 能跳刀整个16M 空间的任意位置

       LJMP 只能64k  间接寻址

      SJMP rel   rel 编译器编译完了是相对地址  
                                   根据下一条指令算偏移量

     
            MOV   DPTR,#JMP_TBL
            JMP   @A+DPTR
     JMP_TBL: AJMP   LABEL0
                    AJMP   LABEL1
                    AJMP   LABEL2
                       
           查表

    5.png


      
   JC  CY=1 跳转
        像ADD 后就可能有 进位
     
   JNC  CY =0 跳转

         这俩不影响标志位 只判断  
         
     JNC  LABEL1
     CPL   CY
     JNC LABEL2

     跳进来 CY清楚  从LABEL2 开始

   
    JB/JNB  判断位的
     
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-8-30 08:41:59 | 显示全部楼层
2023/08/22 第二十三集

   
1.png


   2.png

     跳转太多了不好,会占用指令周期
     占用流水线
         
     JLE/JSL  等  判断Z或CY  

     CJNE  DJNE 这种是老朋友了 8051汇编就很常用的
     
     DJNZ 40H,LABEL1
     DJNZ 50H,LABEL2
     DJNZ 60H,LABEL

    RAM  0X40  0X01
             0X50  0X70
             0X60  0X15
    执行后
            0X40 0X00
            0X50 0X6F
            0X60 0X14
        
     其实一般都用这两条做循环

                 MOV R2,#8
     TOGGLE:CPL P1.7
                  DJNZ R2,TOGGLE

      NOP 空指令
             机器码 0
             1个时钟
             PC 指针+1

            有些库通过内嵌汇编 打到精准操作,给出精准的NOP

            
   汇编语言的程序设计
          3.png
         keil的帮助手册可以去看看

         A251  编译器          相对地址  
         L251  链接器           链接到绝对地址
         LIB251  库,看不见         
         OH251   生成HEX文件的
                       

  

      

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-8-30 09:17:22 | 显示全部楼层
2023/08/22 第二十四集

    汇编语言程序设计
           汇编注重逻辑
           
           汇编程序是啥
                  是汇编语言助记符 + 汇编器助记符命令
           谁家的汇编都是这两部分
         
           汇编器助记符不翻译成机器指令

           例子1:
                  
              code 中的四个 立即数  搬到  edata里面

              用C来说 (应该对吧,自己是这样理解的)
            
              short code a[4] = {0x13,0x0,0x2,0x4};
              short b[4];

              for(i = 0;i<4;i++)
              {
                      b[i] = a[i];
               }

              汇编代码
           
              data_seg1 SEGMENT CODE                         ;声明个代码段
                             RSG         data_seg1                   ;用这个代码段
              
              TABLE:     DW          0x0123,0x4567,0x89ab,0xcdef           ;用DW 建个表 地址由链接器分频


              data_seg2 SEGMENT EDATA                         ;声明个edata段
                             RSG         data_seg2                   ;用这个edata段
              
              STORE:     DSW          4         ;整4个空间  8个字节

            
              prog_seg SEGMENT CODE         ;    代码段
                     RSEG  porg_seg                ;用代码段
                     LJMP  main                     ;跳主程序
                    ORG 0x0220                    ;跳过中断的区域
          main:
                   MOV             DPTR,#TABLE       ;指向表首地址
                   MOV             WR0,#STORE       ;把整个地址给寄存器
                   MOV              R4,#0x4             ;要循环的次数
           CON:
                   MOV            A,#0x0              ;      给累加器 0
                   MOVC        A,@A+DPTR         ;    开始指向第一个数据
                   MOV           R2,A                 ;        放寄存器R2
                  INC               DPTR              ;          DPTR+1
                  MOV              A,#0X0         ;         又清0
                   MOV          A,@A+DPTR     ;              指向后8位
                   MOV           R3,A               ;     后8位放R3              由于R2 R3组成WR2
                   MOV          @WR0,WR2       ;    把WR2中 数据给WR0 中对应的地址
                   INC            DPTR             ;    指向code中下一个数据的地址
                   ADD           WR0,#0x2       ;    指向edata放下个放数据的地址
                   MOV            A,R4              ;  R4是循环的次数
                   SUBB           A,#0x1           ;   A-1
                   MOV           R4,A                ;     A 放R4   
                   JNZ           CON                   ; 不为零就 跳CON里       这就相当于for循环
                  NOP                                  ;空指令

         为便于理解,给程序添加了逐行注释  。

         segment  段
                 同名合并
                 code  data 等
         
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-1 07:34:45 | 显示全部楼层
2023/08/25  第二十五集
      何老师带着大家复习了一下上节课的汇编程序

      code ->  edata

      查看c的反汇编语言

      数据先放到DR8 中
       由于不能操作32位
       分别放到WR8 WR10
       组成32位

       1.png

       MOV  WR6,@DR8+0x0006
       这里吧DR8 偏移6 搬到WR6寄存器
   
      2.png


    MOV  WR4,@DR8+0x0004
    MOV  WR2,@DR8+0x0002

    MOV  WR0,@DR8


3.png     4.png   这是code区


    继续搬,可以看到把数据搬到了 这4个寄存器

   MOV  @WR10+0x0010,WR4
   搬了最高的  循环从4开始


    5.png
   在监视窗口看到 搬了1个最高的数据到 STROE 中

  DEC 给R7 -1
  然后  比较CMP R7 是否0
  JNC 判断标志位 来决定是否跳转

  后面3次循环与这次类似
  
  这是  这个搬移的过程 的反汇编分析


  补充一下用到的几个指令

  SEGMENT
      能用 下面这些段

      6.png

   RSEG  声明段
      
   DW  初始化存储器

   前面都一样,后面用了32位拓展汇编指令

   MAIN:
            MOV DPTR,#TABLE
            MOV DPXL,#0FFH
            MOV WR0,#STROE
           MOV  R4,#0x04
    CON:
              MOV  WR6,@DR56
              MOV  @WR0,WR6
              INC  DR56,#2
              INC  WR0,#2
              DEC  R4,#1
              JNE CON

      可看到 32位拓展的汇编指令能极大的 增加程序的简洁性
                 8位的汇编要搬到A  B  来处理,A  B 还只有有8位,增加了程序的复杂度
                 
                 

      

  






回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-1 08:46:13 | 显示全部楼层
本帖最后由 gentleman 于 2023-9-1 08:53 编辑

2023/08/25 第二十六集
   MOV DPXL ,#01
          这条可以指向xdata区域

          开始时edta 区域

   EBIT
         扩展位可寻址

    EDATA HDATA
         这两个等效

   符号
        不能数字开头
        EQU  SET
        LABEL:
   标号
         定义位置   作用  跳转或提升可读性
         只能定义一次

   汇编器标号
          1.png
   表达式与操作数
       vvv  EQU 3
   数字
        记得字母前面加0
        可加$
   
         可用决定地址 (不完全可用,编译器不让,让用EDATA)
   字符
      不能超过2个
   字符串
        KEYMSG: DB 'SDFKLJSDLFKJSLDKFJ SDLJFL'
        EOLMSG: DB 'End of line', 00h
   位置计数器
        ORG 改初值
        $ 当前位置计数器
        JMP $
    优先级
       2.png

   类操作符
     讲过好几次了

   类运算符
       3.png
      
     
   
      
   
   
     

回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-1 10:36:56 | 显示全部楼层
2023/08/25 第二十七集


控制语句
     不产生代码
      
     ALIGN  位置计数器  设置为  下一个地址模2^表达式
                 确保2^n 边界对齐
                 51 不用 arm 得用  用了有缝隙

    EVEN  位置计数器指向下一个偶数

    ORG   这个太熟了   更改当前段 位置计数器  为后续设置原点
            
              ORG 0200H
  
  USING  选用哪个寄存器组  R0~R7  3组
            
             PUSH PSW
             MOV PSW,#(2 SHL 3)
             POP PSW

   EQU 定义AR0 要谨慎


  DB  
          MSG: DB 'PRESS A KEY',0
          TAB: DB  2,3,4,5,6,7,';'

  DD  32位双字

  DW  2个字节
           
  DBIT    段保留 几个位

  DS /DSB   保留字节

  DSD          32位双字(double)

  DSW        16位
  
  PROC  ENDP
                 子程序
  LABEL  标号  位置

EXTRN/EXTERN     多文件?  必须public

PUBLIC      公共符号

  CSEG  CODE 绝对段

   CSEG AT  0300H   我说这么眼熟  中断号拓展用的这个指令  
  
   ISEG  IDATA段


   RSEG  声明可重定义段 上节课的例子用了


  SEGMENT  
          1.png
         
  XSEG


  BIT    指定位地址
            
  CODE/DATA   定义地址
   
  EQU   只能定义一次

  sbit   能用再A251中         

  SET  创建新符号
         不能PUBLIC
   sfr    定义SFR

  _ERROR_  指定错误信息

   END       结束

   汇编接近尾声,c语言即将开始
  
      
  
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-2 08:47:41 | 显示全部楼层
2023/08/29 第二十八集


     条件汇编
           单个源文件   不同版本
     
     $
       截图202309020831589743.jpg
     
    有个例子   在编译器SET AA = 10

     使用$IF
            ...
            $ELSE
             ..
            $ENDIF
           
      通过keil调试 进行测试


       不带$
       直接使用AA SET 10 指令设置


    宏定义
          注意宏定义与子程序的区别
          宏适合做表  不跳转,直接复制一份到下一行, 多次调用增加代码长度
          子程序  跳转  不增加代码长度


           A251 3种宏
                 macro-name MACRO <[> parmeter-list <]
           <[> LOCAL local-labels <]>                     
          ... ...
           macro-body
          ... ...
          ENDM


           不调用 不展开


         例子
                截图202309020846551738.jpg

         


           
                 


回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-2 10:10:15 | 显示全部楼层
2023/08/29 第二十九集

      汇编实例 -点灯

            截图202309020942415007.jpg
  
          外设复用理念
                解决io不够用的问题
                传统跳线          麻烦
                晶体管 电压      好用

          I/O 寄存器
               端口寄存器
                      PXM0 PXM1
                      4种模式
                       上下设置,不是左右组合设置

               数据寄存器
                   PX.Y =0 低电平
                   PX.Y = 1 高电平
               
            
              程序要点
                   DATA 定义寄存器地址
                  
                    ORG 0x200  前面给中断留着

                   MOV 寄存器复制

                   用 A 放循环移位初值

                   ACALL  延时子程序

                   RL 移位

                   MOV 吧A 搬到 端口数据寄存器

                   延时子程序
                          SUB  JNE 实现延时
                    
                   掌握这些,应该就可以独立完成流水灯的程序了。

                    配合调试可以更清晰的看到程序运行的过程。
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-2 10:23:12 | 显示全部楼层
2023/08/29 第三十集
       汇编实例-中断
  
        按下按键 灯移动一位

             截图202309021011361856.jpg

        按键按下  io被拉低
  
        得出结论

            TCON.0=1
            TCON.2 =1
            EX0 = 1
            EX1 = 1
            EA = 1

        程序新增要点
            EQU 定义寄存器位

            ORG  放中断入口

            中断子程序 实现  RL/RR

           硬件/软件调试 判断是否进入中断

          这两节课的代码比较简单,在论坛上都有,就没有抄。

          到此mcs-251汇编就已经结束了,刚刚接触大量新增指令集的时候,确实很吃力。
          后面结合程序看,就好多了。
          当然现在也仅仅能看懂汇编,并不能完成汇编的程序设计。
          现阶段的目标也是能看懂汇编,配合c调试时生成的反汇编可以分析错误,分析底层逻辑。
          后面学习操作系统时,再来加强对汇编的理解。

            
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:230
  • 最近打卡:2025-12-04 10:06:16

36

主题

741

回帖

3131

积分

荣誉版主

积分
3131
发表于 2023-9-9 14:39:57 | 显示全部楼层
本帖最后由 gentleman 于 2023-9-23 09:00 编辑



发现09/01 的课没有打卡,后面补上了

2023/09/05 第三十四集   
     C251 限定符
       const   运行未修改
       volatile   可能会被修改
            通常是硬件
      
        const 声明 的  可以用xdata/code 指定存储位置 ,定义直接初始化

         const 指针 不能改他指向的常数
         普通指针 指向常数,改指向的值,不报错,也没效果

        特殊用法  定义一个不可更改的指针

         截图202309091428382592.jpg   

         volatile 不让编译器优化
              硬件寄存器不能给优化,优化了寄存器就没配置成功


        使用keil 调试,可以直观的看到这些变量定义与运算的过程


       截图202309091438331081.jpg
     
     单字 双字 直接MOV

      4字节 要MOV 两次
           


         
      
     
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-12-17 10:56 , Processed in 0.132054 second(s), 78 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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