- 打卡等级:偶尔看看II
- 打卡总天数:20
- 最近打卡:2025-06-16 07:09:04
已绑定手机
注册会员
- 积分
- 119
|
发表于 2025-5-30 15:00:53
|
显示全部楼层
第八集 定时器周期性调度任务
(前1-7集感觉就是带小白入门,从本集开始难度飙升,半吊子的我学起来有一丢丢吃力了 )
本集主要内容如下:
1.常见的错误介绍
2.周期性任务介绍
3.数组
4.按键不再用while检测按键抬起,防止冲突其他任务,改用定时器计数
5.多文件的建立
6.用结构体去创建多任务
任务1:用一个定时器实现这个任务。LED1实现0.3秒取反一次,LED2实现0.6 秒取反一次,LED3 0.9秒取反一次
周期性任务代码:
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#define MAIN_Fosc 24000000L //定义主时钟
#define u8 unsigned char
#define u16 unsigned int
void usb_callback();
u8 interrupt_count = 0;
u16 LED1_count = 0;
u16 LED2_count = 0;
u16 LED3_count = 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 main(void)
{
EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
WTST = 0; //设置取程序代码等待时间,
//赋值为0表示不等待,程序以最快速度运行
CKCON = 0; //设置访问片内的xdata速度,
//赋值为 0表示用最快速度访问,
//不增加额外的等待时间
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 接口配置
set_usb_OUT_callback(usb_callback); //设置中断回调回调函数
Timer0_Init();
EA = 1;
while(1)
{
if(LED1_count == 300)
{
LED1_count = 0;
P20 = !P20;
}
if(LED2_count == 600)
{
LED2_count = 0;
P21 = !P21;
}
if(LED3_count == 900)
{
LED3_count = 0;
P22 = !P22;
}
}
}
void Timer0_Isr(void) interrupt 1
{
LED1_count++;
LED2_count++;
LED3_count++;
}
void usb_callback()
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
}
数组方式实现:
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#define MAIN_Fosc 24000000L //定义主时钟
#define u8 unsigned char
#define u16 unsigned int
void usb_callback();
u8 interrupt_count = 0;
//u16 LED1_count = 0;
//u16 LED2_count = 0;
//u16 LED3_count = 0;
u16 count[3]={0,0,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 main(void)
{
EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
WTST = 0; //设置取程序代码等待时间,
//赋值为0表示不等待,程序以最快速度运行
CKCON = 0; //设置访问片内的xdata速度,
//赋值为 0表示用最快速度访问,
//不增加额外的等待时间
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 接口配置
set_usb_OUT_callback(usb_callback); //设置中断回调回调函数
Timer0_Init();
EA = 1;
while(1)
{
}
}
void Timer0_Isr(void) interrupt 1
{
u8 i;
for( i=0;i<3;i++)
{
count++;
if(count[0] == 300)
{
count[0] = 0;
P20 = !P20;
}
if(count[1] == 600)
{
count[1] = 0;
P21 = !P21;
}
if(count[2] == 900)
{
count[2] = 0;
P22 = !P22;
}
}
}
void usb_callback()
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
}
任务2:数组点亮LED,实现流水灯
实现代码:
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#define MAIN_Fosc 24000000L //定义主时钟
#define u8 unsigned char
#define u16 unsigned int
void usb_callback();
u8 interrupt_count = 0;
u16 count[3]={0,0,0};
u16 led[14]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x04,0x02};
u8 j=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 main(void)
{
EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
WTST = 0; //设置取程序代码等待时间,
//赋值为0表示不等待,程序以最快速度运行
CKCON = 0; //设置访问片内的xdata速度,
//赋值为 0表示用最快速度访问,
//不增加额外的等待时间
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 接口配置
set_usb_OUT_callback(usb_callback); //设置中断回调回调函数
Timer0_Init();
EA = 1;
while(1)
{
}
}
void Timer0_Isr(void) interrupt 1
{
u8 i;
for( i=0;i<3;i++)
{
count++;
if(count[0] == 300)
{
count[0] = 0;
P2 = ~led[j];
j++;
if(j > 13){j =0;}
}
}
}
void usb_callback()
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
}
任务3:按键1按一下,LED通过数组移动一下
实现代码:
#include "ai8051u.h"
#include "stc32_stc8_usb.h"
#define MAIN_Fosc 24000000L //定义主时钟
#define u8 unsigned char
#define u16 unsigned int
void usb_callback();
u8 interrupt_count = 0;
u16 count[3]={0,0,0};
u16 led[14]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x04,0x02};
u8 j = 0,key_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 main(void)
{
EAXFR = 1; //允许访问扩展的特殊寄存器,XFR
WTST = 0; //设置取程序代码等待时间,
//赋值为0表示不等待,程序以最快速度运行
CKCON = 0; //设置访问片内的xdata速度,
//赋值为 0表示用最快速度访问,
//不增加额外的等待时间
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 接口配置
set_usb_OUT_callback(usb_callback); //设置中断回调回调函数
Timer0_Init();
EA = 1;
while(1)
{
P2 = ~led[j];
if(count[0] == 1000)
{
count[0] = 0;
printf("AI8051U\r\n");
}
if(count[1] == 10)
{
count[1] = 0;
if(P32 == 0)
{
key_num++;
if(key_num == 5)
{
j++;
if(j > 13){j =0;}
}
}
else
{
key_num = 0;
}
}
}
}
void Timer0_Isr(void) interrupt 1
{
u8 i;
for( i=0;i<3;i++)
{
count++;
}
}
void usb_callback()
{
USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
}
多文件
多任务
AI8051_2_8.7z
(35.5 KB, 下载次数: 5)
--哪怕梦想让我们拼的遍体鳞伤,这一次我们也要勇往直前
|
|