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

【实验箱已收到】陈老师《单片机原理及应用-STC8H8K64U》打卡 | 实验箱已收到

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-14 10:22:57 | 显示全部楼层
本帖最后由 gentleman 于 2023-8-14 10:24 编辑

2023/08/08 第十集

       汇编一般步骤和基本框架
             规范 有序  正确
       一般步骤
             分析 确定算法
             画流程图
             分配资源   RAM  TIMER  UART等
                   目前主要时外设资源/IO分配问题 ,最好列个表  
             写程序
                   .asm  
              调试
                   软件模拟  
                   在线调试
                          有些问题必须要硬件仿真才能展现
                           软仿永远跟不上硬件的发展  
                    
               模块化编程
         框架
          1.jpeg

             2.jpeg
             3.jpeg

           建议不用的中断放复位
           可以提高系统的可靠性
       程序流程图
             4.jpeg          5.jpeg

         典型的例子
              分支
                    JZ  JNZ  CJNE  DJNZ
                    JC  JNC  JB  JNB  JBC
                    
                    自己尝试写一下
  

                                $NOMOD51
                                $INCLUDE (STC8H.H)
                                       
                                ORG       0000H
                                LJMP      MAIN
                                ORG       0003H

                                MAIN:
                                   MOV SP,#80H
                                   MOV R0,#10; 给R0赋值20H
                                   CLR C
                                   CJNE R0,#37,CMP
                                   MOV R1,0
                                 
                                CMP:
                                   JNC BIG
                                   MOV R1,#0FFH; -1补码0xff
                                   RET

                                BIG:
                                   MOV R1,#1
                                   END



                      6.png


                    

                 给R0 赋值10 10<37 得出结果为+1 存入寄存器R1中   
                 
                 老师的例程中使用EQU 定义了SIGN 这个我没有考虑到   
                  老师的例程
                   7.jpeg
              

              查表
                  MOVC  A,  @A+DPTR  查找

                 MOV  DPTR,#SEGTAB       ;移动倒字模表首地址
                 MOV  A,@A+DPTR           ;查表

                SEGTAB:  DB   0C0H         ;子模表
                              DB    0F9H
                                    .
                                    .
                                    .
                               DB     90H
                                   
              循环
                          延时
                             参考stc-isp 生成
                              8.jpeg
                             PUSH/POP 保护/释放 30H/31H
                             DJNZ  双重循环

              定点数
                      BCD 减法  9AH(100)减去 减数
              
                      9.jpeg
                   多字节乘法
                           10.jpeg 11.jpeg

              数据排序
                     冒泡排序

              代码转换
                     A/D  D/A BCD 转ascii
                    4BIT二进制转ASCII
                    <10  + 30H
                    >10  + 37H
                 
                   12.jpeg

                bcd 转二进制
                低位   R1        个/十   
                高位   R2        百/千
              

                13.jpeg
                  14.jpeg
                   15.jpeg
             16.jpeg

             汇编的课程到此应该结束了
             正如老师所说,目前只是掌握了如何去学汇编,而不是掌握了汇编。后面复杂的例程,目前我是无法完成编写的。
             汇编语言的重要性老师都强调过。不管以后是否会用到,感觉还是有必要掌握的。
             汇编的价值不仅仅在程序设计上,更多的是对于底层原理的理解。
             想用单片机,可以不学汇编。想懂单片机,汇编是不可或缺的。
             不管是兼容8051 还是80251 还是arm 指令集(或者哪一天国人搞了一套自研的指令集)单片机的学习,你使用汇编对其底层进行分析,都可以加快对其的理解于掌握。
            
            
回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-16 07:18:02 | 显示全部楼层
本帖最后由 gentleman 于 2023-8-16 10:30 编辑

2023/08/14  第十一集

       c的内容就轻松多了,相信各位都是c语言大神

      C51 对ANSI C的扩展
            加了19个关键字 常用的有_at_          (这个常用吗?)
                                                sbit            常用于定义引脚
                                                sfr             特殊功能寄存器
                                                bit             位变量
                                                xdata         拓展RAM
                                                code          code FLASH 区域
                                                interrupt     中断

            变量类型
                          新增  bit        位型           1bit           0/1
                                  sbit                         1               0/1
                                  sfr                          8               0x80~0xff
                                  sfr16                       8               0x80~0xff


                          bit 不能声明指针 不能做数组
                          sbit 在可独立访问位寻址的位  
                          sfr 用来控制定时/计数器 串口 io
                               sfr P0=0x80;
                               sbit cy=psw^7
            内存区域的制定
                      code  常数,可用于保存数码管码表
                      RAM
                             data   直接寻址  低 128 BYTE
                             idata  间接寻址  RAM 256 BYTE
                             bdata  位寻址     20H~FH
            外部数据存储器
                             xdata  外部RAM 大数组可用,
                             pdata    别用!!! 8032时代选页的,pdata与xdata有冲突
            指针
                     一般和ANSI C一样
                     很重要,很灵活        
                     硬件相关寄存器指针需要使用volatile 保证不被优化  
                       例
  1. #define P0PU (*(unsigned char volatile xdata *)0xfe10)
复制代码

            中断
                  声明
                       
  1. void UART_ISR(void) interrupt 4
  2. {
  3.        //中断服务程序代码
  4. }
复制代码
                    使用中断号 说明哪个中断

                 加using 指定工作寄存器区
                 加small/large 说明存储模式            

      c的运算
                     算数运算
             1.jpeg
                  逻辑运算
                      &&  ||  !
                   不太认同老师说的 !不常用,感觉!还是很常用的,我经常写 if(!a) 而不是 if(a==0);  
                  位运算符
                    & |  ^  ~ << >>
                    &  类似 ANL
                    |   常用于 给莫一位置1  psw2 |=0x80  最高位置1
                    <<      RLC
                    >>      RRC

      STC8H C51 框架
            
  1. #inlcude "stc8h.h"
  2. void delay(long delaytime)
  3. void main(void)
  4. {
  5.       while(1)
  6.      {
  7.           delay(100);
  8.       }
  9. }
复制代码




      

回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-16 10:29:39 | 显示全部楼层
2023/08/14 第十二集

      c语言程序设计实例
      例1 闪灯程序
            stc8h.h 没必要拷贝  


                        #include <stc8h.h>


                        void Delay500ms();
                        void main(void)
                        {
                                P4M0= 0x00;
                                P4M1= 0x00;
                                P6M0= 0x00;
                                P6M1= 0x00;
                                P4 = 0;
                                while(1)
                                {
                                        P60=1;
                                        Delay500ms();
                                        P60=1;
                                        Delay500ms();
                                }
                        }


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


                                i = 29;
                                j = 14;
                                k = 54;
                                do
                                {
                                        do
                                        {
                                                while (--k);
                                        } while (--j);
                                } while (--i);
                        }
         

              注意 这里do while  在编译器被翻译为DJNE 便于计算循环次数
                            while 被翻译为 CJNE  于 SJMP     由于存在 是否跳转的问题  不容易计算
                     
                           使用 data 强制定义数据区域,避免编译器设为large 等影响延时时间  
      
                使用移位可以简单的实现流水灯/跑马灯  
                定义变量
                       LEDdata = 0x01;
                 在主循环中左移
                       LEDdata <<= 1;
                 判断
                       if(!LEDdata)
                           LEDdata = 0x01;
                 给IO赋值   
                       P6 = LEDdata;
               
          例2 flash操作

                                #include <stc8h.h>
                                #include "intrins.h"


                                void IapIdle()
                                {
                                        IAP_CONTR = 0;
                                        IAP_CMD = 0;
                                        IAP_TRIG = 0;
                                        IAP_ADDRH = 0x80;
                                        IAP_ADDRL = 0;
                                       
                                }


                                char IapRead(int addr)
                                {
                                                char dat;                       


                                                IAP_CONTR = 0x80;               //使能IAP
                                                IAP_CMD = 1;                    //设置IAP命令
                                                IAP_ADDRL = addr;               //设置IAP低地址
                                                IAP_ADDRH = addr >> 8;          //设置IAP高地址
                                                IAP_TRIG = 0x5a;                //写触发命令(0x5a)
                                                IAP_TRIG = 0xa5;                //写触发命令(0xa5)
                                                _nop_();                        //等待ISP/IAP/EEPROM操作完成
                                                dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
                                                IapIdle();                      //关闭IAP功能


                                                return dat;                     //返回
                                }


                                void IapProgram(int addr, char dat)
                                {
                                                IAP_CONTR = 0x80;               //使能IAP
                                                IAP_CMD = 2;                    //设置IAP命令
                                                IAP_ADDRL = addr;               //设置IAP低地址
                                                IAP_ADDRH = addr >> 8;          //设置IAP高地址
                                                IAP_DATA = dat;                 //写ISP/IAP/EEPROM数据
                                                IAP_TRIG = 0x5a;                //写触发命令(0x5a)
                                                IAP_TRIG = 0xa5;                //写触发命令(0xa5)
                                                _nop_();                        //等待ISP/IAP/EEPROM操作完成
                                                IapIdle();
                                }


                                void IapErase(int addr)
                                {
                                                IAP_CONTR = 0x80;               //使能IAP
                                                IAP_CMD = 3;                    //设置IAP命令
                                                IAP_ADDRL = addr;               //设置IAP低地址
                                                IAP_ADDRH = addr >> 8;          //设置IAP高地址
                                                IAP_TRIG = 0x5a;                //写触发命令(0x5a)
                                                IAP_TRIG = 0xa5;                //写触发命令(0xa5)
                                                _nop_();                        //等待ISP/IAP/EEPROM操作完成
                                                IapIdle();
                                }


                                void main()
                                {
                                        unsigned char dataread=0,datawrite=0;
                                       
                                        IapErase(0x0400);
                                        dataread = IapRead(0x400);
                                        IapProgram(0x400,0x12);
                                        datawrite = IapRead(0x400);
                                       
                                        while(1);
                                }   
               
  

                      基本的eeprom 操作,在需要掉电存储的场合下很常用。 而且不需要外挂24/25系列存储器,易用性于安全性都有很大提升     
                 放在这里应该是让大家熟悉一下寄存器的操作。
                        记得写eeprom之前要先擦除,每次擦一个扇区。
                        这里没有判断LVDS,有些场合需要判断,保证低压时不要进行eeprom操作。


                                

回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-21 06:56:18 | 显示全部楼层
2023/08/16 第十三集
        中断
              单片机执行其他程序 , 出现某些异常事件或请求,cpu 中止,转去执行异常事件,执行完毕,返回继续执行。
        中断源
              cpu中断请求源
        中断响应
              cpu暂停工作转去处理中断源事件
        中断服务
               处理工程
         中断返回
               处理完返回中断的地方
         中断优先级
                  1.jpeg
                低优先级会挂起  LCALL
           保护现场
                 PUSH  POP 指令 堆栈操作实现
           堆栈
                 先进后出
                 SP 指向栈顶
            中断撤除
                中断请求标志位擦除,有的会自己擦除
            中断源
                 stc8h  44个
                  2.png

           
                3.png

             4.png

             注意 中断号是keil 的c51
                     查询次序是8051的 先有查询次序
      中断标志位
             TCON
                  IT0       触发方式   0  上升/下降沿触发      
                                             1   仅下降沿触发
                  IE0        INT0 请求标志
                  IT1        INT1 触发方式
                  IE1        INT1请求标志
            AUXINTIF
                  管定时器2~4的
                   所有定时器外部中断标志位自动清0
            串口
                 TI/(SX)TI    RI/(SX)RI
                 不能自动请0
                 
                 可以直接写TI=0 ,因为地址可以被8整除
   
                 
回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-21 07:16:49 | 显示全部楼层
本帖最后由 gentleman 于 2023-8-21 07:48 编辑

2023/08/16 第十四集
         中断标志位
               PCON
                   LVDF   低电压检测 不开中断也可以读
               SPI
                   SPSTAT 传输完成置位
               ADC
                   ADC_CONTR   A/D转换结束标志位
                                        需要软件清0
          中断允许,禁止,优先级
          IE 0A8H
       1.png
               EA  总中断
                     0  关闭
                     1  开放
                ELVD 低压检测
                EADC A/D
                ES     串口1
                ET1    定时器1
                EX1    INT1
                ET0    T0
                EX0    INT0
           优先级
                1.png
                  00 01 10  11  对应1234 级
                  先高后低 停低转高 高不睬低
               
                  即使关闭EA/分中断开关 标志位也改变,只是不响应,可以查  
           
                  RETI 不能写成RET 结果只执行一


           不响应中断的情况
                 EA/   不开不响应
                  cpu执行更高一级的中断
                  执行的机器周期不是指令周期的最后一个机器周期
                  执行的是RETI 或 访问IP/IP  cpu再执行一条指令才响应中断
          终端服务
                入口 到 RETI

                 保护现场   终端服务  恢复现场  中断返回

                 中断可以临时关。避免高优先级中断     

                实例:通过INT0 改变灯状态

                        基于原来的点灯程序修改


                        IT0 =1;
                       EX0 =1;
                        EA=1;
                        
                      这样中断1和总中断就打开了

                       再写个中断函数,把引脚取反

                       void INT0_ISR interrupt  中断号忘了,好像是0
                       {
                             P60=~P60;
                       }

                        INT0 放个小电阻 100R或者300R 保护一下


                        用汇编写要在头部写好外部中断的跳转地址
                        ORG 0003H
                        LJMP INT0_ISR
                        
                         给开关置0,选触发模式
                         SETB IT0
                         SETB EX0
                         SETB EA
                          
                        在最后写上中断子程序

                          INT0_ISR:
                                  CPI P6.0
                                  RETI
                                  END


          中断在程序设计中是很常用的。基本稍微复杂一点的程序就会用到。
          如果没有中断,cpu就只能靠轮询。对程序设计的影响还是很大的。
          stc8/32 相对于传统8051添加了很多中断,更加简化了对程序的设计。
          比如原来的定时器就经常不够用,要用其他的方式去处理,stc的有4~5个,还能自动重载,随便用。
回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-27 08:38:40 | 显示全部楼层
2023/08/27 第 15 集
        定时器结构
               功能 : 定时或计数
                           分频
                           可编程输出
                           串口波特率发生器

             一般结构     

              系统/外部来的时钟 让计数器加1 加满了就中断      

                1.png

               

                2.png

               工作模式 4种
                         常用16位自动重载/不可中断的16位自动重载


               下图是模式0 16位自动重载
                非常清晰,图看懂了,就会用定时器了。
                3.png


                T2 模式固定 16位自动重载
                        
                寄存器不用背 会查就行   

        定时器寄存器
              TMOD  
                         GATE  C/T  M1  M0    GATE  C/T   M1  M0
                    
                            M1  M0   
                            0      0          模式0 16位自动重载
                            1      1          模式3 最高中断优先级的16位自动重载
        
                                   记住这两个模式就行

                            C/T      1 计数器
                                       0 定时器
                            GATE   1  ~INTn搞 且 TRn置位 启动
                                      0   TRn 置位 启动
            TCON

                         TF1  TR1 TF0  TR0  IE1  IT1  IE0  IT0

                         TF1/0       中断标志位 自动清
                          
                         TR1/0      开关 置1启动

                         后面4位是外部中断的
            
            AUXR
                         T0x12  T1x12  UART_M0x6  T2R  T2_C/T  T2x12  EXTRAM  S1T2
                        
                         T0x12/T1x12   0 12分频
                                               1 不分频
                          TR2                定时器 2开关 置1启动
                          T2_C/T            0  T2 12个时钟计数1次
                                                1   T2  1个时钟计数1次
                          UART_M0x6     串口速度
                           S1ST2            波特率发生器选择位
             T4T3M
                         T4R  T4_C/T    T4x12  T4CLKO  T3R  T3_C/T  T3x12  T3CLKO
                        
                          T4/T3CLKO  时钟输出开关  置1开启
                          其他参考上面
                        
                        
回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-8-27 08:58:43 | 显示全部楼层
2023/08/21  第16集
         定时器应用

              最大能力
                    fosc = 11.0592m
                    12分频

                     1计数周期 = 12/晶振频率  -12/110592 =1us

                     N = M-TC/TP

                     TC/TP = 1000;

                     T = 71.111ms

               T2/T4
                    T = 18s

          量程拓展
                一般用软件  
                       多次中断后处理一次时间就行
            
          例程
                    汇编例程看的懂就好,也不太复杂
                    后面再尝试写。

                    c:

void Timer0_Isr(void) interrupt 1


{
       i--;
       if(!i)
        {
                P60 = ~P60;
                i = 0;
         }
}

void Timer0_Init(void)                //50微秒@11.0592MHz
{
        AUXR |= 0x80;                        //定时器时钟1T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0xD7;                                //设置定时初始值
        TH0 = 0xFD;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
        EA = 1;
}


     然后再main 调用初始化函数 就行了

     记得设置
                 PXMX = 0x00;
                 P40 =0;

     运行程序就会看到 试验箱的灯在闪 500ms 亮一次

    后面还有操作其他定时器的例程
  
    注意T2 T3 T4 的许多寄存器都不能位寻址

    定时器是很常用的应用,大家一定要多多练习

                        
            

回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-9-3 11:49:30 | 显示全部楼层
2023/08/23  第十七集

       STC8H8K64U
           4 UART
           1 SPI
           1 I2C
           1 USB
      
       并行 -同时传送
       串行 -一位移位传  脉冲
               截图202309031141434291.jpg
    TTL  <10M
    RS232 15M
    RS485 100M  多机

    异步通讯  0/1 作为字符标志
            截图202309031144313032.jpg

           约定编码形式 奇偶校验 起始位停止位
                  通讯速率  9600,n,8,1

  
            单工/  半双工 / 全双工

      串行接口的内部结构
       截图202309031147094126.jpg

      截图202309031147372104.jpg

    时序图

      截图202309031148217254.jpg
  
    stc补充多机通信
                截图202309031149194913.jpg




回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-9-3 11:58:19 | 显示全部楼层
2023/08/23 第十八集
         STC8H8K64U  
           4个串口  全双工 支持DMA
            
           两个SBUF独立  


         SFR


       截图202309031153302344.jpg

      SCON
         截图202309031154119388.jpg

       常用模式1 3

    工作模式1示意图
       截图202309031155254060.jpg
      

    可以由定时器作为波特率发生器
   
     



     
回复 支持 反对

使用道具 举报 送花

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

29

主题

722

回帖

2790

积分

荣誉版主

积分
2790
发表于 2023-9-3 12:09:11 | 显示全部楼层
2023/08/28 第十九集

       使用定时器作为波特率发生器时要 TR1/TR2=1
       中断不用开

      截图202309031200424289.jpg

   常用stc-isp 工具计算定时器初值

    实时任务需要 中断

     编程要点
         SCON 设置
         TMOD/SMOD 设置
         ES/EA 设置
         data -> SBUF
          清TR/RI 编程序

          其他串口类似,注意寄存器不同

    流程图

        发送
         截图202309031204403236.jpg


       接收

      
      截图202309031205375864.jpg


      注意波特率要相同,才能进行通信

  多机通信

                SM2 标志位区分

     流程图
          截图202309031207101502.jpg

      注意TB8=1     发地址
           发完清TB8

     

   
         
        
截图202309031204349958.jpg
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

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

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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