单片机的实现多任务程序

更新时间:2023-07-17 17:52:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

在51单片机如何实现多任务的程序

/*************************************************

Copyright (C), 2010, Yuandian. Co., Ltd.

File name: pwm.c

Author: 幸

Version: 1.0

Date: 2010-8-6 // 作者、版本及完成日期

Description: 实现循环显示 按键显示的切换

Others: 学习标志位的应用 及多任务概念的复习

Function List:

1. 任何按键常按3秒进入按键显示

任何按键再次常按3秒进入循环显示循环显示0000--9999 History: 无

1. Date: 无

Author: 无

Modification: 无

2. ... 无

*************************************************/

#include "reg52.h" //定时器初始化程序

#define Shu_Ma_Data P1 //数码管送值

//子函数声明

void Timer_Initial(void);

void Scan_Key(void);

void Display_ShuM();

void Delay_Sub1(void);

void Clear_Key_Data(void);

void Xun_Dis(void);

//数码管列表

const unsigned char code Led_Byte[]={0x3F,0x06,0x5B,0x4F,

0x66,0x6D,0x7D,0x07, 0x7F,0x6F};

/* p0.0-->p0.1-->p0.2 代表三个按键 */

sbit First_Key = P0^0;

sbit Second_Key= P0^1;

sbit Third_Key = P0^2;

//数码管控制显示位

sbit Qian_bit = P2^0;

sbit Bai_bit = P2^1;

sbit Shi_bit = P2^2;

在51单片机如何实现多任务的程序

sbit Ge_bit = P2^3;

sbit XiSu_Dian = P1^7;

// 定时器累加时间

unsigned char Add_Ms; //1毫秒 加一次

unsigned int Accumul_Ms; //累加计数器 2秒钟灯顺序切换

unsigned char Key1_Delay1; //按键1防抖延迟时间

unsigned char Key2_Delay1; //按键2防抖延迟时间

unsigned char Key3_Delay1; //按键3防抖延迟时间

unsigned int Key1_Delay2; //按键1低电平延迟时间 unsigned int Key2_Delay2; //按键2低电平延迟时间 unsigned int Key3_Delay2; //按键3低电平延迟时间

unsigned char Move_Num; //数码管1的值

unsigned char SMG_Value[4]; //数码管1的值

//位操作区

unsigned char bdata Flag_Byte[1];

sbit Key1_Flag1 = Flag_Byte[0]^0; //加键按下标志

sbit Key1_Flag2 = Flag_Byte[0]^1; //加键弹起标志

sbit Key2_Flag1 = Flag_Byte[0]^2; //移动键按下标志

sbit Key2_Flag2 = Flag_Byte[0]^3; //移动键弹起标志

sbit Key3_Flag1 = Flag_Byte[0]^4; //减键按下标志

sbit Key3_Flag2 = Flag_Byte[0]^5; //减键弹起标志

sbit CDis_Flag = Flag_Byte[0]^6; //循环显示还是按键显示标志 sbit ShanS_Flag = Flag_Byte[0]^7; //被选中的按键闪烁标志

// 主程序

void main(void)

{

//定时器初始化

Timer_Initial();

while(1)

{

Scan_Key(); //按键扫描

Delay_Sub1(); //延迟时间减 循环时间

Xun_Dis(); //循环显示

在51单片机如何实现多任务的程序

Display_ShuM(); //调用数码管扫描显示程序

}

}

//循环显示

void Xun_Dis(void)

{

if (( Accumul_Ms >= 800 ) && ( !CDis_Flag ))

{

Accumul_Ms=0;

// 四个数码管数值累加

SMG_Value[0] +=1;

if( SMG_Value[0] >= 10)

{

SMG_Value[0]=0;

SMG_Value[1] += 1;

}

if( SMG_Value[1] >=10 )

{

SMG_Value[0] = 0;

SMG_Value[1] = 0;

SMG_Value[2] +=1;

}

if( SMG_Value[2] >=10 )

{

SMG_Value[0] = 0;

SMG_Value[1] = 0;

SMG_Value[2] = 0;

SMG_Value[3] +=1;

}

if (SMG_Value[3] >= 10 )

{

SMG_Value[0] = 0;

SMG_Value[1] = 0;

SMG_Value[2] = 0;

SMG_Value[3] = 0;

}

}

}

在51单片机如何实现多任务的程序

//键盘扫描子程序

void Scan_Key(void)

{

// 按键1扫描 //如果是一个抖动的话 下次按键没有防抖功能 if (( Key1_Flag1 == 0 ) //key1_flag1为按键按下标志; && ( Key1_Flag2 == 0 ) //key1_flag2为按键弹起标志; && ( First_Key == 0 ))//key1_delay1为按键一延计数; { //first_key为按键一是否按下; Key1_Delay1 = 10; //10毫秒延时时间

Key1_Flag1 = 1;

}

if (( Key1_Flag1 == 1 ) && (Key1_Delay1 == 0 ))

{

Key1_Flag1=0;

if( First_Key == 0 )

{

Key1_Flag2 = 1;

}

}

if (( Key1_Flag2 == 1 )

&& ( First_Key == 1 ))

{

//按键时间超过3秒表示进入按键显示状态

if ( Key1_Delay2 >= 1500 )

{

CDis_Flag = !CDis_Flag; //程序进入按键显示状态 Clear_Key_Data();

Key1_Delay2 = 0;

}

else

{

Key1_Delay2 = 0;

if( CDis_Flag )

{

SMG_Value[Move_Num] += 1;

if( SMG_Value[Move_Num] >= 10)

SMG_Value[Move_Num] = 0;

}

}

在51单片机如何实现多任务的程序

Key1_Flag2 = 0;

}

// 按键2扫描

if (( Key2_Flag1 == 0 )

&& ( Key2_Flag2 == 0 )

&& ( Second_Key == 0 ))

{

Key2_Delay1 = 10; //10毫秒延时时间

Key2_Flag1 = 1;

}

if (( Key2_Flag1 == 1 )

&& ( Second_Key == 0 )

&& (Key2_Delay1 == 0 ))

{

Key2_Flag1 = 0;

Key2_Flag2 = 1;

}

if (( Key1_Flag1 == 1 ) && (Key1_Delay1 == 0 )) Key1_Flag1=0;

if (( Key2_Flag2 == 1 )

&& ( Second_Key == 1 ))

{

//按键时间超过3秒表示进入按键显示状态

if ( Key2_Delay2 >= 1500 )

{

CDis_Flag = !CDis_Flag; //程序进入按键显示状态 Clear_Key_Data();

Key2_Delay2 = 0;

}

else

{

Key2_Delay2 = 0;

if( CDis_Flag )

{

Move_Num += 1;

if( Move_Num >= 4 )

Move_Num=0;

在51单片机如何实现多任务的程序

}

}

Key2_Flag2 = 0;

}

// 按键3扫描

if (( Key3_Flag1 == 0 )

&& ( Key3_Flag2 == 0 )

&& ( Third_Key == 0 ))

{

Key3_Delay1 = 10; //10毫秒延时时间

Key3_Flag1 = 1;

}

if (( Key3_Flag1 == 1 )

&& ( Third_Key == 0 )

&& (Key3_Delay1 == 0 ))

{

Key3_Flag1 = 0;

Key3_Flag2 = 1;

}

if (( Key1_Flag1 == 1 ) && (Key1_Delay1 == 0 )) Key1_Flag1=0;

if (( Key3_Flag2 == 1 )

&& ( Third_Key == 1 ))

{

//按键时间超过3秒表示进入按键显示状态

if ( Key3_Delay2 >= 1500 )

{

CDis_Flag = !CDis_Flag; //程序进入按键显示状态 Clear_Key_Data();

Key3_Delay2 = 0;

}

else

{

Key3_Delay2 = 0;

if( CDis_Flag )

{

if( SMG_Value[Move_Num] == 0)

在51单片机如何实现多任务的程序

SMG_Value[Move_Num] = 9;

else

SMG_Value[Move_Num] -= 1;

}

}

Key3_Flag2 = 0;

}

}

//进入循环显示后清键值单元

void Clear_Key_Data(void)

{

SMG_Value[3] = 0;

SMG_Value[2] = 0;

SMG_Value[1] = 0;

SMG_Value[0] = 0;

}

//数码管显示子程序

void Display_ShuM()

{

unsigned char i;

Qian_bit = 0;

Shu_Ma_Data = Led_Byte[SMG_Value[3]];

if (( Move_Num == 3 ) && ( CDis_Flag ))

XiSu_Dian = 1;

for ( i = 0;i < 20; i++);

Qian_bit = 1;

Bai_bit = 0;

Shu_Ma_Data = Led_Byte[SMG_Value[2]];

if (( Move_Num == 2 ) && ( CDis_Flag ))

XiSu_Dian = 1;

for ( i = 0;i < 20; i++);

Bai_bit = 1;

Shi_bit = 0;

Shu_Ma_Data = Led_Byte[SMG_Value[1]];

在51单片机如何实现多任务的程序

if (( Move_Num == 1 ) && ( CDis_Flag ))

XiSu_Dian = 1;

for ( i = 0;i < 20; i++);

Shi_bit = 1;

Ge_bit = 0;

Shu_Ma_Data = Led_Byte[SMG_Value[0]];

if (( Move_Num == 0 ) && ( CDis_Flag ))

XiSu_Dian = 1;

for ( i = 0;i < 20; i++);

Ge_bit = 1;

}

// 将主程序里面延迟时间在该子程序里面减去 循环时间 void Delay_Sub1(void)

{

if(Key1_Delay1 > Add_Ms)

Key1_Delay1 -= Add_Ms;

else

Key1_Delay1=0;

if(Key2_Delay1 > Add_Ms)

Key2_Delay1 -= Add_Ms;

else

Key2_Delay1=0;

if(Key3_Delay1 > Add_Ms)

Key3_Delay1 -= Add_Ms;

else

Key3_Delay1=0;

if( Key1_Flag2 == 1)

Key1_Delay2 += Add_Ms;

if( Key2_Flag2 == 1)

Key2_Delay2 += Add_Ms;

if( Key3_Flag2 == 1)

Key3_Delay2 += Add_Ms;

Add_Ms = 0;

}

在51单片机如何实现多任务的程序

//定时器初始化程序

void Timer_Initial(void)

{

TMOD = 0x01; //工作方式1 16位定时器

TH0 = 0xfc; //1毫秒定时 65536-1000=64536=0xFC18 TL0 = 0x18;

EA = 1; //开总中断

TR0 = 1; //启动定时器

ET0 = 1;

}

//中断子程序

void Timer_0() interrupt 1 using 1

{

TH0 = 0xfc;

TL0 = 0x18;

Add_Ms += 1;

Accumul_Ms++;

}

本文来源:https://www.bwwdw.com/article/8z81.html

Top