wuzhengmin
发表于 2025-8-15 14:55:11
接下来学习数组和for()的应用:
先定义一个全局变量i和数组16位数组Count_ms
u16 Count_ms = {0,0,0}; //3个记时变量
u8 i;
for(i =0;i<3;i++)
{
Count_ms++;
if( Count_ms>=300) //300ms到达!
{
Count_ms = 0;
State1 = !State1;
P00 = State1;
}
if( Count_ms>=600) //600ms到达!
{
Count_ms = 0;
State2 = !State2;
P01 = State2;
}
if( Count_ms>=900) //900ms到达!
{
Count_ms = 0;
State3 = !State3;
P02 = State3;
}
}
这样写,就清爽很多!!!
wuzhengmin
发表于 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 u8unsigned 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 = {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 = {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);
State = 15;
//printf("重新修改后State数值的第一个数值为: %d \r\n",(int)State);
for(i =0 ;i<3; i++)
{
printf("当前变量i: %d\r\n",i);
}
usb_OUT_done(); //
}
if( Count_ms>=500) //500ms执行一次
{
Count_ms = 0;
//P0 = State; //2种不同亮法
P0 = ~State;
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++;
}
wuzhengmin
发表于 2025-8-15 17:59:03
任务3:按键1按一下,LED通过数组移动一下; 注意事项:按键不能在通过while判断是否按下松开了可以通过按键按下计数
wuzhengmin
发表于 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 u8unsigned 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 = {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 = {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);
State = 15;
//printf("重新修改后State数值的第一个数值为: %d \r\n",(int)State);
for(i =0 ;i<3; i++)
{
printf("当前变量i: %d\r\n",i);
}
usb_OUT_done(); // }
}
P0 = ~State;
// if(P32 == 0 )
// {
// Delay10ms();
// if(P32 == 0 )
// {
// while( P32 == 0 );//等他松开P32
// //假如不松手,下面的程序就无法运行,好像
// //死在这里了,接下来就是解决这个问题
// num++;
// }
// if( num>7)
// {
// num = 0;
// }
//
//
// }
//下面的方法就可以解决卡死在按键的问题了
if(Count_ms>=1000)//1000ms执行一次
{
Count_ms = 0;
printf("AI8051U\r\n");
}
if(Count_ms>=10)//10ms执行一次
{
Count_ms = 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++;
Count_ms++;
}
这个其实不是太好理解,慢慢想一下.............
wuzhengmin
发表于 2025-8-15 21:38:59
接下来冲哥介绍了文件架构,但我遇到一个问题:跟着冲哥开了user目录,把config.c config.h
建立起来,也能编译,没有报错,但是下载后,连USB_CDC都搞丢了,一开始我还以为硬件出来问题
马上换一台PC,表现一样,换冲哥的模版进去,又是可以的,不知道哪里有问题?
结构体数组的周期性任务调度LED10.3秒闪一次;LED20.6秒闪一次,LED30.9秒闪一次1都有定时器1ms加的变量2都有一个设定的计数目标,3都有需要执行的功能,4.定时时间到了才能执行
typedef struct {u8 Run;//任务状态:Run/Stopu16 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 */};
wuzhengmin
发表于 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.c和xxx.h文件,代表一个功能块。xxx.h格式#ifndef_XXX_H #define_ XXX_H调用头文件函数声明...#endif xxx.c格式#include"xxx.h"函数定义添加文件一定要记得引用路径和添加到工程里。
例如我们建立config.h
#ifndef__CONFIG_H#define__CONFIG_H#endif
wuzhengmin
发表于 2025-8-16 15:01:44
结构体数组的周期性任务调度
结构体数组的周期性任务调度LED10.3秒闪一次;LED20.6秒闪一次,LED30.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串口,好奇怪?
感觉自己能力不行,休息一下先!!!
wuzhengmin
发表于 2025-8-16 16:04:38
重新看了冲哥的视频,第八集定时器周期性调度任务
总结一下,其实从1小时之后的结构体的任务开始,是真没看懂
不过,还是很老实的跟着冲哥做了实际操作,发现IO口初始化,好像真的只能放置在main.c
wuzhengmin
发表于 7 天前
第十一次:《8051U深度入门到32位51大型实战教学视频》第九集 数码管
第八集定时器周期性调度任务,有时间还要回去重新学习!
IO引脚的定义:
这样处理,以后修改就很方便! 仔细看图:
wuzhengmin
发表于 7 天前
怎么快速生成数码管数组?STC的ISP是个宝藏,里面有工具!真是没想到!好方便
以前在学校还要要求学生自己用ABCDEF去自己搞,累死!!!
任务1..数码管静态的显示一个数字:先看74HC959芯片 ,这个我买过10片,挺好用的!
#define HC595_SER P34#define HC595_RCK P35#define HC595_SCK P32
这个任务好完成!
页:
3
4
5
6
7
8
9
10
11
12
[13]
14
15
16
17