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

第一次:环境的创立 | 送实验箱

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-15 14:55:11 | 显示全部楼层
接下来学习数组和for()的应用:


先定义一个全局变量i和数组16位数组Count_ms[3]

u16 Count_ms[3] = {0,0,0};     //3个记时变量
u8 i;




for(i =0;i<3;i++)
                {
               
                        Count_ms[i]++;
                        if( Count_ms[0]>=300)   //300ms到达!
                        {
               
                                Count_ms[0] = 0;
                                State1 = !State1;
                                P00 = State1;
                                               
                        }

                        if( Count_ms[1]>=600)   //600ms到达!
                        {
               
                                Count_ms[1] = 0;
                                State2 = !State2;
                                P01 = State2;
                                               
                        }

                        if( Count_ms[2]>=900)   //900ms到达!
                        {
               
                                Count_ms[2] = 0;
                                State3 = !State3;
                                P02 = State3;
                                               
                        }


                       
                }



这样写,就清爽很多!!!



回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-15 16:24:47 | 显示全部楼层
周期性任务介绍
任务2:数组点亮LED,实现流水灯

注意事项:
LED是0点亮,1熄灭。数组长度需要把握好流水灯移动的时间

/* 我想这样点亮8个LED,要求用数组
                b0     b7
      低位     高位
                01111111
                10111111
                11011111
                11101111
                11110111
                11111011
                11111101
                11111110


*/



#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //d调用头文件

#define u8  unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)       
       
u8 State1 = 0;                                        //LED1初始状态
u8 State2 = 0;                                        //LED2初始状态
u8 State3 = 0;                                        //LED3初始状态

u8 num = 0;
u8 State[8] = {0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80}; //定义一个数组且赋初值


u8 Run_State = 0;                                //运行状态




u16 Count_300 = 0 ;            //计数300ms变量
u16 Count_600 = 0 ;            //计数600ms变量
u16 Count_900 = 0 ;            //计数900ms变量

u16 Count_ms[3] = {0,0,0};     //3个记时变量
u8 i;

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";


void Timer0_Init(void);  //定时器函数声明

void main(void)
{
        int count=1;                                                                        //按键计数变量
       
    WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度
       
    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
       
        usb_init();                                     //USB CDC 接口配置

    IE2 |= 0x80;                                    //使能USB中断
       
        Timer0_Init();  //定时器初始化
               
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
       
        while(1)
        {
               
        if (bUsbOutReady)                                                        //如果接收到了数据
        {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            //printf("状态变量State1: %d  状态变量State2: %d 状态变量State3:  %d \r\n",State1,State2,State3);
                        //printf("State数值的第一个数值为: %d \r\n",(int)State[0]);
            State[0] = 15;
                        //printf("重新修改后State数值的第一个数值为: %d \r\n",(int)State[0]);
                       
                        for(i =0 ;i<3; i++)
                        {
                       
                                printf("当前变量i: %d  \r\n",i);

                          }       
                                       
                        usb_OUT_done();                                                        //
         }
               
                if( Count_ms[0]>=500)   //500ms执行一次
                        {
               
                                Count_ms[0] = 0;
                       
                                //P0 = State[num]; //2种不同亮法
                                P0 = ~State[num];
                               
                                num++;
                                        if(num>7)
                                        {
                                                num=0;
                                        }
                        }               
               
               

               
        }
}


void Timer0_Init(void)                //1毫秒@24.000MHz
{
        //TM0PS = 0x00;           //设置定时器时钟预分频
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x30;                                //设置定时初始值
        TH0 = 0xF8;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}




void Timer0_Isr(void) interrupt 1                //1毫秒执行一次
{
       
               
        Count_ms[0]++;
       
          

}


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-15 17:59:03 | 显示全部楼层
任务3:按键1按一下,LED通过数组移动一下;
注意事项:
按键不能在通过while判断是否按下松开了
可以通过按键按下计数


截图202508151758449068.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-15 18:54:31 | 显示全部楼层
解决按键不松开,程序就卡死在while这句上的方法如下:



/* 我想这样点亮8个LED,要求用数组
                b0     b7
      低位     高位
                01111111
                10111111
                11011111
                11101111
                11110111
                11111011
                11111101
                11111110
任务3:按键1按一下,LED通过数组移动一下;
注意事项:按键不能在通过while判断是否按下(不松手会一直死在那儿)
松开了可以通过按键P32按下计数,LED亮的灯循环向右移动

*/



#include "ai8051u.h"                        //调用头文件
#include "stc32_stc8_usb.h"                //调用头文件
#include "intrins.h"                        //d调用头文件

#define u8  unsigned char                //8位无符号变量(0-255)
#define u16 unsigned int                //16位无符号变量(0-65535)       
       
u8 State1 = 0;                                        //LED1初始状态
u8 State2 = 0;                                        //LED2初始状态
u8 State3 = 0;                                        //LED3初始状态

u8 num = 0;
u8 State[8] = {0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80}; //定义一个数组且赋初值


u8 Run_State = 0;                                //运行状态

u16 Key_Vol= 0;                                 //按键按下持续时间


u16 Count_300 = 0 ;            //计数300ms变量
u16 Count_600 = 0 ;            //计数600ms变量
u16 Count_900 = 0 ;            //计数900ms变量

u16 Count_ms[3] = {0,0,0};     //3个记时变量
u8 i;

char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";

void Delay10ms(void)        //@24.000MHz,延时10ms
{
        unsigned long edata i;

        _nop_();
        _nop_();
        _nop_();
        i = 59998UL;
        while (i) i--;
}




void Timer0_Init(void);  //定时器函数声明

void main(void)
{
        int count=1;                                                                        //按键计数变量
       
    WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度
       
    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
       
        usb_init();                                     //USB CDC 接口配置

    IE2 |= 0x80;                                    //使能USB中断
       
        Timer0_Init();  //定时器初始化
               
    EA = 1;                                                                                        //IE |= 0X80;
       
        P40 = 0;
       
        while (DeviceState != DEVSTATE_CONFIGURED);     //等待USB完成配置
       
        while(1)
        {
               
        if (bUsbOutReady)                                                        //如果接收到了数据
        {
            //USB_SendData(UsbOutBuffer,OutNumber);   //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
            //printf("状态变量State1: %d  状态变量State2: %d 状态变量State3:  %d \r\n",State1,State2,State3);
                        //printf("State数值的第一个数值为: %d \r\n",(int)State[0]);
            State[0] = 15;
                        //printf("重新修改后State数值的第一个数值为: %d \r\n",(int)State[0]);
                       
                        for(i =0 ;i<3; i++)
                        {
                       
                                printf("当前变量i: %d  \r\n",i);

                          }       
                                       
                        usb_OUT_done();                                                        //                 }
               
                 
                }       
               
               
                P0 = ~State[num];
//                if(P32 == 0 )
//                {
//                                Delay10ms();
//                                if(P32 == 0 )
//                                {
//                                        while( P32 == 0 );  //等他松开P32
//                                        //假如不松手,下面的程序就无法运行,好像
//                                        //死在这里了,接下来就是解决这个问题
//                                        num++;
//                                }
//                                if( num>7)
//                                {
//                                num = 0;
//                                }
//                               
//               
//                }
               
               
//下面的方法就可以解决卡死在按键的问题了

                if(Count_ms[1]>=1000)  //1000ms执行一次
                {
                        Count_ms[1] = 0;
                        printf("AI8051U\r\n");
               
                }
                if(Count_ms[2]>=10)  //10ms执行一次
                {
                                Count_ms[2] = 0;
                                if(P32 == 0)    //P32按键按下
                                {
                                        Key_Vol++;
                                        if( Key_Vol == 5)  //P32按键按下,消抖50ms
                                        {
                                                        num++;
                                                        if(num>=8)
                                                        {
                                                                num = 0;
               
                                                        }
                                        }
                                       
                                }
                                else
                                {
                                        Key_Vol = 0;
                                       
                                }
                }
               
               
        }
}

void Timer0_Init(void)                //1毫秒@24.000MHz
{
        //TM0PS = 0x00;           //设置定时器时钟预分频
        AUXR &= 0x7F;                        //定时器时钟12T模式
        TMOD &= 0xF0;                        //设置定时器模式
        TL0 = 0x30;                                //设置定时初始值
        TH0 = 0xF8;                                //设置定时初始值
        TF0 = 0;                                //清除TF0标志
        TR0 = 1;                                //定时器0开始计时
        ET0 = 1;                                //使能定时器0中断
}




void Timer0_Isr(void) interrupt 1                //1毫秒执行一次
{
       
               
        Count_ms[1]++;
        Count_ms[2]++;
          

}


这个其实不是太好理解,慢慢想一下.............
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-15 21:38:59 | 显示全部楼层
接下来冲哥介绍了文件架构,但我遇到一个问题:跟着冲哥开了user目录,把config.c config.h
建立起来,也能编译,没有报错,但是下载后,连USB_CDC都搞丢了,一开始我还以为硬件出来问题
马上换一台PC,表现一样,换冲哥的模版进去,又是可以的,不知道哪里有问题?



结构体数组的周期性任务调度
LED1  0.3秒闪一次;LED2  0.6秒闪一次,LED3  0.9秒闪一次
1都有定时器1ms加的变量
2都有一个设定的计数目标,
3都有需要执行的功能,
4.定时时间到了才能执行

typedef struct
{
u8 Run;  //任务状态:Run/Stop
u16 TIMCount;  //定时计数器
u6TRITime;    //重载计数器

void(*TaskHook)(void);//任务函数

}TASK_COMPONENTS;
看看官方的结构体:

//========================================================================
//                               本地变量声明
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{
//状态  计数  周期  函数
    {0, 1,   1,   Sample_Display},      /* task 1 Period: 1ms */
    {0, 10,  10,  Sample_MatrixKey},    /* task 2 Period: 10ms */
    {0, 10,  10,  Sample_adcKey},       /* task 3 Period: 10ms */
    {0, 300, 300, Sample_NTC},          /* task 4 Period: 300ms */
    {0, 500, 500, Sample_RTC},          /* task 5 Period: 500ms */
    /* Add new task here */
};





回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-16 13:08:42 | 显示全部楼层

先回滚一下:

冲哥介绍了文件架构,但我遇到一个问题:跟着冲哥开了user目录,把config.c config.h
建立起来,也能编译,没有报错,但是下载后,连USB_CDC都搞丢了,一开始我还以为硬件出来问题
马上换一台PC,表现一样,换冲哥的模版进去,又是可以的,不知道哪里有问题?


一开始以为我哪里搞错了,昨晚折腾到2点多,终于发现:


// void Sys_init();   //调用初始化函数
       
       
    WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度
       
    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
       
       


把系统初始化这段,还原回主程序,就OK了
但是把它写成 void Sys_init(); 再调用,也应该正常啊???很懵很懵很懵很懵很懵很懵




文件的创建(.c和.h)
创建程序文件三步,把硬件需要的初始化弄一个config.c新建文件并保存.
添加到工程.添加引用路径

一般一个.c和一个.h文件执行一个外设或者一个任务或功能。这样可以让代码看起来简洁明了

新建xxx.cxxx.h文件,代表一个功能块。
xxx.h格式
#ifndef  _XXX_H
#define  _ XXX_H
调用头文件
函数声明...
#endif
xxx.c格式
#include  "xxx.h"
函数定义
添加文件一定要记得引用路径和添加到工程里。

例如我们建立config.h

#ifndef  __CONFIG_H
#define  __CONFIG_H
#endif



回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-16 15:01:44 | 显示全部楼层
结构体数组的周期性任务调度



结构体数组的周期性任务调度
LED1  0.3秒闪一次;LED2  0.6秒闪一次,LED3  0.9秒闪一次
1都有定时器1ms加的变量
2都有一个设定的计数目标,
3都有需要执行的功能,
4.定时时间到了才能执行

这个任务,我仔细跟着冲哥做了一次:
首先是很多地方没有听懂,其次是IO口配置语句,还是要放置在main.c
才能顺利驱动。。。。。。。。

void main(void)
{
        int count=1;                                                                        //按键计数变量
       
//   void Sys_init();   //调用初始化函数
       
        WTST = 0;                                                                                  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1;                                                                                 //扩展寄存器(XFR)访问使能
    CKCON = 0;                                                                                 //提高访问XRAM速度
       
    P0M1 = 0x00;   P0M0 = 0x00;
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;
       
       
       
        usb_init();      //USB_CDC配置                                   //USB CDC 接口配置


    IE2 |= 0x80;                                    //使能USB中断

否则直接调用void Sys_init();   //调用初始化函数
可以顺利编译,下载后USB-CDC,CDC就消失了,还有一个,本来应该是双USB串口的,我试过4台不同的PC机(都是win10),都只有一个USB-CDC,CDC串口,好奇怪?

感觉自己能力不行,休息一下先!!!

截图202508161457367952.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 2025-8-16 16:04:38 | 显示全部楼层
重新看了冲哥的视频,第八集定时器周期性调度任务

总结一下,其实从1小时之后的结构体的任务开始,是真没看懂

不过,还是很老实的跟着冲哥做了实际操作,发现IO口初始化,好像真的只能放置在main.c









截图202508161602194060.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 7 天前 | 显示全部楼层
第十一次:《8051U深度入门到32位51大型实战教学视频》  第九集 数码管

第八集定时器周期性调度任务,有时间还要回去重新学习!

IO引脚的定义:

这样处理,以后修改就很方便! 仔细看图:

截图202508171629269998.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-08-22 10:12:58
已绑定手机

1

主题

158

回帖

407

积分

中级会员

积分
407
发表于 7 天前 | 显示全部楼层
怎么快速生成数码管数组?
STC的ISP是个宝藏,里面有工具!真是没想到!好方便

以前在学校还要要求学生自己用ABCDEF去自己搞,累死!!!

任务1..数码管静态的显示一个数字:先看74HC959芯片 ,这个我买过10片,挺好用的!

#define HC595_SER         P34
#define HC595_RCK         P35
#define HC595_SCK         P32

这个任务好完成!








截图202508171956057433.jpg
截图202508172110165575.jpg
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-8-24 15:41 , Processed in 0.154871 second(s), 92 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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