scpcw 发表于 2025-2-20 09:11:56

tianjing818 发表于 2025-2-20 08:26
必须点赞

一定把AI8051这个小可爱搞好

scpcw 发表于 2025-2-20 09:13:02

tianjing818 发表于 2025-2-20 08:26
必须点赞

认真学习这个小可爱,把她搞透彻。

zhaoye818 发表于 2025-2-20 09:34:42

scpcw 发表于 2025-2-20 09:10
有了大神的肯定,必须加油

我不是大神,一起学习一起加油。

scpcw 发表于 2025-2-20 21:57:49

               我总结的ISP虚拟 数码管 LED函数使用
                        //SEG7_ShowString("a%d b%d", (char)single_double+1,GongDe); //用printf的格式化参数
                        //SEG7_ShowLong(GongDe,16);                              //用16进制显示
                        //SEG7_ShowFloat(3.14159);                              //显示小数
                        //------------------------------------------
//                        byte cod
//                        cod = 0x3f|0x80;                        //或0x80加小数点
//                        cod = 0x06;
//                        cod = 0x5b;
//                        cod = 0x0;                              //0x00空格
//                        cod = 0x66;
//                        cod = 0x6d;
//                        cod = 0x71;
//                        cod = 0x71;
//                        SEG7_ShowCode(cod);                        //用段码显示
                        //--------------------------------------
                        
//                        LCD12864_DisplayClear();                //清屏
//                        LCD12864_AutoWrapOn();                        //自动换行
/*/----------------------------------------------------                        
                        cod = 0x4c;                        //LCD所有命令前4字节都是LCD+0x80
                        cod = 0x43;                        //LCD所有命令前4字节都是LCD+0x80
                        cod = 0x44;                        //LCD所有命令前4字节都是LCD+0x80
                        cod = 0x80;                        //LCD所有命令前4字节都是LCD+0x80
                        cod = 0x01;                        //LCD所有命令第5字节都是后面字节数
                        cod = 0xa6;                        //0xa6:清屏 (0xa7):显示ASCII字符( 0xa7 0x0 0x0)X,Y坐标
                        USB_SendData(cod,0x06);//测试直接用命令字体清屏LCD12864_DisplayClear();
*/      


                        
/*/----------------------------------------------------------------                        
      任务1,发送123到缓存
                        功能17: 上传数据到缓冲区
                                                命令格式: 4CH 43H 44H 80H x1 AFH ah al xx ...
                                       
                        
                        功能15:显示字符在LCD12864上显示ASCII码和简体中文字符
                              命令格式: 4CH 43H 44H 80H 03H A7H x y
                        
-----------------------------------------------------------------------*/

//----------用命令发送------------------------------------
//                        LCD12864_DisplayClear();                //清屏
//                        LCD12864_AutoWrapOn();                        //自动换行
//                        cod= 0x4c;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod= 0x43;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod= 0x44;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod= 0x80;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod= 7;                        //LCD所有命令第11字节都是后面字节数7
//                        cod= 0xaf;                        //0xaf:发送数据到缓存
//                        cod= 0x00;                        //发送地址高位
//                        cod= 0x00;                        //发送地址低位
//                        cod= 0x31;                        //发送'1'
//                        cod= 0x32;                        //发送'2'
//                        cod = 0x33;                        //发送'3'
//                        cod = 0x00;                        //发送00结束符
//                        USB_SendData(cod,12);//测试直接用命令字体清屏LCD12864_DisplayClear();
//                        
//                        cod= 0x03;                        //LCD所有命令第5字节都是后面字节数8
//                        cod= 0xa7;                        //0xaf:发送数据到缓存
//                        cod= 0x0;                        //第2列
//                        cod= 0x0;                        //第0行
//                        USB_SendData(cod,0x8);//显示字符
                        


//----------用数组发字符串
                        cod= '1';                        //LCD所有命令前4字节都是LCD+0x80
                        cod= 'a';                        //LCD所有命令前4字节都是LCD+0x80
                        cod= GongDe+0x30;                        //LCD所有命令前4字节都是LCD+0x80
                        cod= 00;      
                        LCD12864_ShowString(0, 0, cod);

scpcw 发表于 2025-2-21 16:45:52



第八集 定时器周期性调度任务
官方给了一个利用定时器周期性调度度任务的模板
我把模板裁减最小化,分析了一下:
#include "config.h"
#include "io.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
//----------以上为USB参数赋值----






typedef struct
{
      u8 Run;               //任务是否运行:Run/Stop
      u16 TIMCount;         //运行的时间片
      u16 TRITime;          //重载值,前面减完从这里又复制去
      void (*TaskHook) (void); //任务函数 用指针指向函数,不能带参数.
} TASK_COMPONENTS;


static TASK_COMPONENTS Task_Comps[]=
{
//状态计数周期函数
      
{0, 500,   500,   LED0_Blink},      /* task 1 Period: 300ms */
{0, 1000,   1000,   LED1_Blink},      /* task 1 Period: 600ms */
{0, 2000,   2000,   LED2_Blink},      /* task 1 Period: 600ms */
{0, 10,    10,    KEY_Task},      /* task 1 Period: 600ms */         
};


u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);








void main(void)
{
      //-----------------------------------------------------------------------------
      Sys_init();                                                                              //系统初始化
      //----------------------------------------------------------------


      
      
      
      //----------1毫秒@24.000MHz------定时器初始化--
      TM0PS = 0x00;                        //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
      AUXR &= 0x7F;                        //定时器时钟12T模式
      TMOD &= 0xF0;                        //设置定时器模式
      TL0 = 0x30;                              //设置定时初始值
      TH0 = 0xF8;                              //设置定时初始值
      TF0 = 0;                              //清除TF0标志
      TR0 = 1;                              //定时器0开始计时
      ET0 = 1;                              //使能定时器0中断






      
      
      while(1)
      {
                u8 i;      
                for(i=0; i<Tasks_Max; i++)
                {
                        if(Task_Comps.Run) /* If task can be run */
                        {
                              Task_Comps.Run = 0;      /* Flag clear 0 */
                              Task_Comps.TaskHook();   /* Run task */
                        }
                }
      }
}






void Timer0_Isr(void) interrupt 1                //1MS执行一次
{
      u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }


}

scpcw 发表于 2025-2-21 22:05:08

第九集 数码管
第十集 虚拟键盘LED和数码管
第十一集 矩阵按键
这几集放在一起学习,一起练习吧。它们都是为了单机的调试服务。也是简单常用的输入输出设备。


如果需要按从高到低位发送1字节数据的情况
可以用如下算法,最高效率,主要用于串行方式通讯,I2C是这样。
u8 i;
u8 Dat=0xFF;
for(i=0,i<8,i++)
      Dat += Dat;          //等同Dat=Dat<<1 ,位移比加法多一条汇编指令,最高位进入CY(程序状态字寄存器)PSW进位标志位
      HC595_SER=CY;    //引脚只要发送CY标志就可以了,但要注意后面其它操作不能影响进位标志
         HC595_SRCLK=1;
         HC595_SRCLK=0;

}

下面是易读版
u8 i;
u8 Dat;
for (i = 0; i < 8; i++) {
    HC595_SER = (Dat & 0x80) ? 1 : 0;// 直接输出最高位
    Dat <<= 1;                         // 左移一位
}

下面是入门版,效率最低。
u8 i;
u8 Dat;
for (i = 0; i < 8; i++) {
   
    HC595_SER = (Dat&0x80)>>7;      //不解释
   HC595_SRCLK=1;
   HC595_SRCLK=0;
   Dat = Dat<<1;                  // 左移一位
}




scpcw 发表于 2025-2-23 09:58:49

还在等实验箱,今天把我的STC8也拿出来,也为9,10,11集的练习做一下准备。两套系统都做一下。
之前的STC8核心开发板,用的一个USB转ttl下载数据。核心板上P30 P31没有二极管和电阻。下发数据复位时,只能四条线一起怼。
后来我在GND上接了一个开关,好象可以下载了。但有40%概率会不成功。
今天我按芯片手册找了一个二级管和电阻,想按规矩改一下。


开始找了一个1N1007二极管,但是压降太大了,不能识别到。
后来又找了一个FR107,我看参数应该能代替1N5819。、


不知道是哪里的原因,我在3v3上接了一个开关,不能下载。我只能不用这个电源。只保留GND,RXD,TXD三根线。
然后在核心板用面包板上面的3.3V供电。通过对面包板上的电源开关,下载就很顺了。

也研究了一下USB下载


STC8支持USB下载,不支持USB仿真,就没有去实现这个功能了。

scpcw 发表于 2025-2-23 10:35:44

今天把《第8集定时器周期性调渡任务》移植到STC8上面,还要把串口也要初始化出来。
先把后面的串口通讯预习一下.后面好象有这个课.



void UartInit() //115200bps@11.0592MHz 串口1   定时器1
{
        /*顺序:   SCON(串口控制器)                //后面都是定时器控制
                        ->AUXR(定时器辅助寄存器)控制是否分频1T 12T
                        ->TMOD(定时器模式)
                        ->TL0,TL1定时器计数寄存器计算波特率
                        ->定时器开始计时TCON 里的TR1 第6位
                        ->串口使能ES=1;
       
        */
               
        SCON = 0x50;                //串口控制寄存器, 串口1:SCON 串口2:S2COM
                                        //b7 b6 0 1 可变波特率8位数据方式 b4 1充许接收 01010000 后面4位设0,细节后面再研究.
       
        //---------------------------------------------------------------       
       
        AUXR |= 0x40;                //定时器时钟1T模式
                                        // b7位,定时器0 12T模式0 不分频1 //b6位定时器0 12T模式0 不分频1
       
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器 //最后1位0使用定时器1 最后1位1使用定时器2
                                        //上面一句可以直接用40或41
                        //AUXR = 0x40; // 0x41为使用定时器2               
       
       
        TMOD &= 0x0F;                     //设置 对高4位定时器1全设0,低4位定时器0不改动;
       
        TL1 = BRT;                        //使用此变量可以让系统主频与串口频率无关.
        TH1 = BRT >> 8;                //#define FOSC 11059200UL
                                                //#define BRT (65536 - FOSC / 115200 / 4) 这个公式用于1T模式
                                                //#define BRT (65536 - FOSC / 12 / 115200 / 32) 这个公式用于12T模式
                                               
               
        TR1 = 1;                             //定时器1开始计时 TCON 定时器控制器,T1举出中断标志和定时器运行控制位
                                                //TF1和TR1是TCON最高7,6位 TF0和TR0是5,4位
        //----------------------------------------------               
               
        ES = 1;                          //串口中断使能,如果不用串口中断可以不用使能
        EA = 1;                        //全局中断使能


        busy = 0;                        //例程添加的一个变量,可忽略
               
}


scpcw 发表于 2025-2-23 21:37:16

数码管代码敲好了.

scpcw 发表于 2025-2-24 07:30:13

矩阵键盘
我的矩阵键盘模块,请指正!




#include "MatrixKey.h"
u8 key_num=0xff;
void MatrixKey(void)
{
      bit m,n,o,p;
      ROW1 = 1;                //先判断横,所以先置高电平先让她稳定
      ROW2 = 1;
      COL1 = 0;
      COL2 = 0;
      COL3 = 0;
      COL4 = 0;

      m=ROW1;                                                //添加中间变量是为了稳定性
      n=ROW2;                                                //实测没有中间变量,再切换电平后,电平未稳定,下面的按键扫描有误
      if( m != n)
      {
               
                if( m )      key_num = 4;                //如果1行高电平,就是按了2行,所以为2行第一个键码4
                if( n)key_num = 0;               

               
      
                COL1 = 1;                //下面是扫描纵列,所以先改纵列电平
                COL2 = 1;
                COL3 = 1;
                COL4 = 1;
                ROW1 = 0;
                ROW2 = 0;
                m=COL1;
                n=COL2;
                o=COL3;
                p=COL4;
                //if( m==0 )key_num=key_num;
                if( n == 0 ) key_num = key_num + 1;
                if( o == 0 ) key_num = key_num + 2;
                if( p == 0 ) key_num = key_num + 3;
               

      }else key_num=0xff;
}      


页: 1 2 [3] 4 5
查看完整版本: 我学AI8051