擎天柱学习记录,第8集:定时器周期性调度任务
程序如下:
- #include "ai8051u.h" //调用头文件
- #include "AI_usb.h"
- #include "intrins.h"
-
- #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 State[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
- u8 i;
-
- u8 Run_State = 0; //运行状态
- u8 num = 0;
-
- //u16 Count_300 = 0; //计数300ms变量
- //u16 Count_600 = 0; //计数600ms变量
- //u16 Count_900 = 0; //计数900ms变量
-
- u16 Count_ms[3] = {0,0,0};
- u16 Key_Vol = 0;
-
- char *USER_DEVICEDESC = NULL;
- char *USER_PRODUCTDESC = NULL;
- char *USER_STCISPCMD = "@STCISP#";
-
- void Delay10ms(void) //@24.000MHz
- {
- unsigned long edata i;
-
- _nop_();
- _nop_();
- _nop_();
- i = 59998UL;
- while (i) i--;
- }
-
- void Timer0_Init(void); //3秒@24.000MHz //函数声明
-
- 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;
-
- while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
-
- while(1)
- {
- if (bUsbOutReady)
- {
- // USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
-
- usb_OUT_done();
- }
- /*任务1:用一个定时器实现这个任务。LED1实现0.3秒取反一次,LED2实现0.6秒取反一次,LED30.9秒取反一次
- if(Count_300 >= 300)
- {
- Count_300 = 0;
- State1 = !State1;
- P20 = State1; //led1取反
- }
- if(Count_600 >= 600)
- {
- Count_600 = 0;
- State2 = !State2;
- P21 = State2; //led2取反
- }
- if(Count_900 >= 900)
- {
- Count_900 = 0;
- State3 = !State3;
- P22 = State3; //led3取反
- }
- */
-
- /*任务2:数组点亮LED,实现流水灯
- if(Count_ms[0]>=500)
- {
- Count_ms[0]=0;
- P2 = ~State[num];
- num++;
- if(num>7)
- num = 0;
- }
- */
-
- /*---------任务3:按键1按一下,LED通过数组移动一下---------*/
- P2 = ~State[num];
- if(P32==0)
- {
- Delay10ms();
- if(P32==0)
- {
- while(P32==0);
- num++;
- }
- }
- if(Count_ms[1]>=1000)
- {
- Count_ms[1]=0;
- printf("AI8051U\r\n");
- }
- if(Count_ms[2]>=10)
- {
- Count_ms[2]=0;
- if(P32==0)
- {
- Key_Vol++;
- if(Key_Vol==5)
- {
- num++;
- }
- }
- 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_300++;
- // Count_600++;
- // Count_900++;
-
- /*数组定义+for循环实现任务1
- for(i=0;i<3;i++)
- {
- Count_ms[i]++;
- if(Count_ms[0]>=300)
- {
- Count_ms[0]=0;
- State1 = !State1;
- P20 = State1;
- }
- if(Count_ms[1]>=600)
- {
- Count_ms[1]=0;
- State2 = !State2;
- P21 = State2;
- }
- if(Count_ms[2]>=900)
- {
- Count_ms[2]=0;
- State3 = !State3;
- P22 = State3;
- }
- }
- */
-
- // Count_ms[0]++;
-
- for(i=0;i<3;i++)
- {
- Count_ms[i]++;
- }
- }
复制代码
任务1:用一个定时器实现这个任务。LED1实现0.3秒取反一次,LED2实现0.6秒取反一次,LED30.9秒取反一次
任务2:数组点亮LED,实现流水灯
任务3:按键1按一下,LED通过数组移动一下,每隔1秒串口打印AI8051U
|