PIC单片机C语言程序设计(6)
接上文:单片机教程:PIC单片机C语言程序设计(5) 4.可预置起始时刻的倒计时程序 在《PIC 单片机C 语言程序(5)》一文中,我们介绍了可预置起始时刻的时钟的硬件电路并给出了C 语言程序。下面要介绍的可预置起始时刻的倒计时程序,是作为日常生活中对某事件的定时之用:只要某事件由人工设置的计时时间到,倒计时电路便会发出报警声。倒计时的特点是,计时一旦达到预定值,其值就归零。利用归零条件,即可实现任意倒计时达到时的报警功能,提示人们定时已到。 本倒计时器可在0~99 分钟内任意设置计时值。 例如在厨房中,蒸大米饭(8 两米),定时33 分钟,烧开水(一壶)为20 分钟,煮胡罗卜(红色)为30 分钟等,只要设定时间一到,倒计时器即报警,使用十分方便。当然,上述倒计时值,均是事先用普通时钟确定每个事件所要花费的时间,列出相应定时标准,才能用倒记时器进行定时。
(1)硬件电路。 图6 是0~99 分钟可预置的倒计时电路。
图6 0~99分钟的倒计时电路 PIC16F84A 单片机④脚为手动复位端,外接R1、D0、C6、K0(微动开关)组成复位电路;③脚RA4 外接上电阻R2 和倒计时人工预置开关K1 ;⒄脚RAO 外接R0、V3 和蜂鸣器,组成倒计时值达到(归零)时的自动报警信号。电路中的两位LED 数码管和V1、V2 组成0~99 分钟可预置LED 数码显示电路,其电路原理与《PIC 单片机C 语言程序(3)》一文中图3 的起始两位计数电路相似。
( 2) 程序流程图。 图7、图8、图9 分别为0~99 分钟可预置的倒计时程序的主程序、显示函数和键值扫描程序流程图。通过流程图,读者可以加深对于倒计时程序设计原理和对2010 年第2 期《PIC 单片机C 语言程序(5)》一文中可预置时钟电路程序的理解。
图7 倒计定时主程序流程图
图8 倒计时显示函数流程图
图9 倒计时键值扫描流程图
(3)倒计时的C 程序。 根据图7~ 图9 编写的的倒计时C 程序(命名为pic06.c)清单如下: #include<pic.h> #define PORTAIT(add,bit)((unsigned)(&add)*8+(bit)) static bit PORTA_0 @PORTAIT(PORTA,0); //pic16F84A static bit PORTA_1 @PORTAIT(PORTA,1); static bit PORTA_2 @PORTAIT(PORTA,2); //A 口的位定义 static bit PORTA_3 @PORTAIT(PORTA,3); static bit PORTA_4 @PORTAIT(PORTA,4); unsigned int ttr=0; // 无符号整形变量ttr,并赋值0 unsigned char x=0,sign_a=0; // 字符变量X,标志位并赋值0 void key_server(); // 键值服务函数 void display(unsigned int x); // 带形参X 的显示函数 void display_set(unsigned int x); // 带形参X 的键值显示函数 void delay_1m(); // 按键延时函数 void delay(unsigned long int k ) // 延时函数 { unsigned long int i; // 无符号整形变量i for(i=0;i<=k;i++) // for 语句 continue; // 继续循环 } void display(unsigned int x) // 显示函数开始 { unsigned int d=5800,unit_bit,ten_bit, // 整型变量d 并赋值,个、十位 unsigned char SEG7[10]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; // 引用数组字符段码 unit_bit=x%10; //picc 编译器可识别的个位 ten_bit=x/10%10; // picc 可识别的十位 while(d>0) // while 语句 { PORTA|=0x1E; // 关显示 PORTB=SEG7[unit_bit]; // 个位字段码送B 口 RA3=0; // 显示个位 delay(200); // 延时以便观察 RA3=1; // 关个位显示 delay(2); // 延时 PORTB=SEG7[ten_bit]; // 十位字段码送B 口 RA2=0; // 显示十位 delay(200); // 延时以便观察 RA2=1; // 关十位显示 delay(2); // 延时 d--; // d 从5800 开始自减量 if( PORTA_4==0) // K1 未按下 { while(1) // 执行while 语句 { if( PORTA_4==1) // K1 按下,执行以下程序 { sign_a=1; x=0; d=0; RA0=0; break; // 跳出循环 } } } } } void main( ) // 主程序开始 { TRISB=0x00; // 16F84A 口初始化,B 为输入 TRISA=0x10; // A4 输入,其余输出 PORTB=0xFF; INTCON=0x00; PORTA=0xFF; 关显示 RA0=0; 关报警 x=0; // 给整型变量X 赋值0 while(1) // while 循环语句开始 { while(x>0) { display(x); // 调显示函数 key_server(); // 调键值服务函数 x--; // 分自减量(倒计时) } if (x==0) // 如果X=0 RA0=1; // RA0 赋值1(报警信号) display_set(x); // 调键值显示函数 key_server(); // 调键值服务函数 } } void key_server()// 键值服务程序开始 { unsigned int value=0; // 给存储显示值赋0 display_set(x); // 调键值显示函数 if( PORTA_4==0 ) // 如果RA4 为0 { while(1) { x++; // 键值X 自增 if(x > 99) // 如果键值X > 99 x=0; // 给X 赋值0 display_set(x); // 调键值显示函数 delay_1m(); // 按键延时,以便观察 if(PORTA_4==1) // 如果RA4 为高电平 { sign_a=0; // 清零设定时间标志位 RA0=0; // 给RA0 赋值0 break; // 跳出循环返回 } } } } void display_set(unsigned int x) // 键值显示函数开始 { unsigned int d=20,unit_bit,ten_bit,unsigned char SEG7[10]={0xc0,0xf9,0xa4, 0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; unit_bit=x%10; // 这里的注释与display 的函数相似 ten_bit=x/10%10; while(d > 0) { PORTA=0x1e; PORTB=SEG7[unit_bit]; RA3=0; // 显示个位 delay(200); RA3=1; delay(2); PORTB=SEG7[ten_bit]; RA2=0; // 显示十位 delay(200); RA2=1; delay(2); d--; } } void delay_1m() // 按键(图6 的K1)延时函数开始 { unsigned long int k; // 说明语句 for(k=0;k < 4;k++) // for 语句 { display_set(x); // 调用键值显示函数 } } 说明: 上述C 程序经picc 编译后生成。hex,即可用PIC 单片机编程器将。hex 烧写到pic16F84A芯片中,再按图6 电路制成倒计时器,即可按需要使用。
|