- 打卡等级:偶尔看看II
- 打卡总天数:22
- 最近打卡:2026-01-02 14:48:10
已绑定手机
中级会员
- 积分
- 221
|
发表于 2025-12-23 14:14:15
|
显示全部楼层
打卡擎天柱 第⑧集:周期性任务章节
代码:#include "config.h"
/*
流水灯采用8位
led0——————————led7
011111111
采用按位取反的模式
*/
#define u8 unsigned char //8未无符号字符(255)
#define u16 unsigned int //16位无符号字符(65586)
u8 state1 = 0; //初始状态
u8 state2 = 0; //初始状态
u8 state3 = 0; //LED3初始状态
u16 Count_300 = 0; //300毫秒的变量
u16 Count_600 = 0; //600毫秒的变量
u16 Count_900 = 0; //900毫秒的变量
//引入数组的概念
//变量名 [数量]={,,,,}第一个为索引值。
//eg
u8 State[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //即state中存入3个变量数据,分别为1,2,3
u16 Count_ms[3]= {0,0,0};//三个计时变量,不影响主函数的功能
u8 i;
u8 num = 0;
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
//char *USER_STCISPCMD = "@STCISP#"; //命令参数
//按键检测
//关于按键检测这一块,一般电源VDD如果是5v的输入,那么各个引脚的IO口的高电平最多为5.8v
//也就是相当于在原基础上多0.3.v
//常见的VDD为5或者3,各个引脚为5.3v--3.3v
//另外施密特触发,ai8051手册有介绍,有无打开会影响各个引脚的具体电压
//一般用 == 来检测按键的电平状态
void Delay20ms(void) //@11.0592MHz
{
unsigned long edata i;
_nop_();
_nop_();
_nop_();
i = 55294UL;
while (i) i--;
}
void Delay10us(void) //@24.000MHz
{
unsigned char data i;
_nop_();
_nop_();
i = 57;
while (--i);
}
void main(void)
{
//只执行一次的
P40 = 0; //灯的开关
Sys_init(); //函数的调用,系统初始化
usb_init(); //USB CDC 接口配置,初始化的过程
Timer0_Init(); //调用定时中断
IE2 |= 0x80 ;
EA = 1 ;
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
while(1) //Wwhile走一圈为一个循环,可以先试用查询函数Library-USB
{
if (bUsbOutReady)
{
//USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
// for(i=0;i<3;i++)
// {
// printf("当前state的值为:%d\r\n",(int)state);
// } //完成测试代码
// printf("state的第一个值为%d\r\n",(int)state[0]);
// printf("Count的一个值为%d\r\n",(int)Count[2]);//测试数据 的读
// printf("state的最后一个值为%d\r\n",(int)state[2]);//测试数据 的读取
//
usb_OUT_done();
}
//流水灯的实验效果
if(Count_ms[0] >= 200)
{
Count_ms[0] = 0;
P2= ~State[ num ]; //控制P0端口的所有灯,同时num的取值只有0-7
num ++;
if(num > 7)
num = 0;
//
}
}
// if(Count_300 >= 300)
// {
// state1 =! state1;
// P20 = state1;
// Count_300 = 0;
// //LED取反一次
// }
// if(Count_600 >= 600)
// {
// state2 =! state2;
// P21 = state2;
// Count_600 = 0;
// //LED2取反一次
// } if(Count_900 >= 900)
// {
// state3 =! state3;
// P22 = state3;
// Count_900 = 0;
// //LED3取反一次
// }
} //以中括号为准
void Timer0_Isr(void) interrupt 1 //1MS执行一次
{
for(i=0;i<3;i++)
Count_ms++;
// {
// if(Count_ms[0] >= 300)
// {
// state1 =! state1;
// Count_ms[0] = 0;
// P20 = state1;
// }
// if(Count_ms[0] >= 600)
// {
// state2 =! state2;
// Count_ms[1] = 0;
// P21 = state2;
// }if(Count_ms[0] >= 900)
// {
// state3 =! state3;
// Count_ms[2] = 0;
// P22 = state3;
// }
// }
// Count_300++; //周期型任务300ms变量启动,变量达到一定数值,执行某种命令
// Count_600++;
// Count_900++;
}
#include "config.h"
/*
函数定义一般放在.c文件当中,赋值什么的
*/
void Sys_init(void)
{
P_SW2 |= 0x80; //B7位写1,使能访问XFR,之所以写或,是确保P_SW2后面几位不会全部赋值为0
//相当于把XFR使能端口打开,相较于SFR
//简单来讲
//SFR:基础特殊功能寄存器(无需使能可直接访问)。(80H-ffH)
//XFR:扩展特殊功能寄存器(需要使能位打开才能访问)。(>FFH)
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;
}
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中断
}
成果i演示
|
|