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

我学AI8051

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 2025-2-20 09:11:56 | 显示全部楼层

一定把AI8051这个小可爱搞好
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 2025-2-20 09:13:02 | 显示全部楼层

认真学习这个小可爱,把她搞透彻。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:381
  • 最近打卡:2025-05-01 08:27:28
已绑定手机

10

主题

146

回帖

458

积分

中级会员

积分
458
发表于 2025-2-20 09:34:42 | 显示全部楼层
scp*** 发表于 2025-2-20 09:10
有了大神的肯定,必须加油

我不是大神,一起学习一起加油。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 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[0] = 0x3f|0x80;                        //或0x80加小数点
//                        cod[1] = 0x06;
//                        cod[2] = 0x5b;
//                        cod[3] = 0x0;                                //0x00空格
//                        cod[4] = 0x66;
//                        cod[5] = 0x6d;
//                        cod[6] = 0x71;
//                        cod[7] = 0x71;
//                        SEG7_ShowCode(cod);                        //用段码显示
                        //--------------------------------------
                        
//                        LCD12864_DisplayClear();                //清屏
//                        LCD12864_AutoWrapOn();                        //自动换行
/*/----------------------------------------------------                        
                        cod[0] = 0x4c;                        //LCD所有命令前4字节都是LCD+0x80
                        cod[1] = 0x43;                        //LCD所有命令前4字节都是LCD+0x80
                        cod[2] = 0x44;                        //LCD所有命令前4字节都是LCD+0x80
                        cod[3] = 0x80;                        //LCD所有命令前4字节都是LCD+0x80
                        cod[4] = 0x01;                        //LCD所有命令第5字节都是后面字节数
                        cod[5] = 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[0]  = 0x4c;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod[1]  = 0x43;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod[2]  = 0x44;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod[3]  = 0x80;                        //LCD所有命令前4字节都是LCD+0x80
//                        cod[4]  = 7;                        //LCD所有命令第11字节都是后面字节数7
//                        cod[5]  = 0xaf;                        //0xaf:发送数据到缓存
//                        cod[6]  = 0x00;                        //发送地址高位
//                        cod[7]  = 0x00;                        //发送地址低位
//                        cod[8]  = 0x31;                        //发送'1'
//                        cod[9]  = 0x32;                        //发送'2'
//                        cod[10] = 0x33;                        //发送'3'
//                        cod[11] = 0x00;                        //发送00结束符
//                        USB_SendData(cod,12);  //测试直接用命令字体清屏  LCD12864_DisplayClear();
//                        
//                        cod[4]  = 0x03;                        //LCD所有命令第5字节都是后面字节数8
//                        cod[5]  = 0xa7;                        //0xaf:发送数据到缓存
//                        cod[6]  = 0x0;                        //第2列
//                        cod[7]  = 0x0;                        //第0行
//                        USB_SendData(cod,0x8);  //显示字符
                        


//----------用数组发字符串
                        cod[0]  = '1';                        //LCD所有命令前4字节都是LCD+0x80
                        cod[1]  = 'a';                        //LCD所有命令前4字节都是LCD+0x80
                        cod[2]  = GongDe+0x30;                        //LCD所有命令前4字节都是LCD+0x80
                        cod[3]  = 00;        
                        LCD12864_ShowString(0, 0, cod);
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 2025-2-21 16:45:52 | 显示全部楼层
pcw 第八集 定时器周期性调度任务.zip (3.97 MB, 下载次数: 25)

第八集 定时器周期性调度任务
官方给了一个利用定时器周期性调度度任务的模板
我把模板裁减最小化,分析了一下:
#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[0]);








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 */
            }
        }
    }


}

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 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;                    // 左移一位
}




回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

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

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

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

也研究了一下USB下载
截图202502231010203484.jpg

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

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 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;                        //例程添加的一个变量,可忽略
               
}


回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 2025-2-23 21:37:16 | 显示全部楼层
数码管代码敲好了.

pcw 第9集 shu码管.zip

10.15 MB, 下载次数: 29

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:16
  • 最近打卡:2025-05-01 07:09:37
已绑定手机

1

主题

43

回帖

233

积分

中级会员

积分
233
发表于 2025-2-24 07:30:13 | 显示全部楼层
矩阵键盘
我的矩阵键盘模块,请指正!
pcw 第11集 矩阵键盘.zip (64.17 KB, 下载次数: 19)



#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;
}        


回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-2 04:16 , Processed in 0.139511 second(s), 106 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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