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

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

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 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 两次
           


         
      
     
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:217
  • 最近打卡:2024-11-15 09:12:27

29

主题

722

回帖

2790

积分

荣誉版主

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

2023/09/05 第三十五集

截图202309091442027956.jpg

一开始就有干货
看到浮点定义的过程
这个要配合以前讲浮点数的内容理解

去掉volatile
截图202309091445441539.jpg
就3行,被编译器优化了
编译器认为a b 没用
只记了结果

后面是个列表求和的例子

再次提到指令高速缓存概念   


汇编帮助DEBUG


auto register static extern

这几个都很好理解






回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-4 04:03 , Processed in 0.120188 second(s), 100 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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