📄 main_new_5_test.c
字号:
/******************************************************************************************************
All Rights Reserved
作者: 史永杰
修改时间:2006年4月15日
功能说明:定时器0作为系统时间发生器,定时器1控制波形输出频率,由于波形高电平持续时间很短,因此将输出高电平
放在定时器1中断程序钟;系统要求输出两路脉冲,由于频率都不高,因此都放在中断中处理。两路脉冲并不同步
但是由于两路脉冲是独立的,相位的差别没有什么 意义,因此这样做是可行的
基于第二块板子
******************************************************************************************************/
#include<AT89X52.h>
#define unchar unsigned char
#define unint unsigned int
#define LED_1 P1_1 //定时指示灯
#define LED_2 P1_3 //功能一指示灯
#define LED_3 P1_2 //功能二指示灯
#define BUZZER P1_4 //蜂鸣器
#define DOTE P1_0 //小数点显示位
#define OUT1 P2_7 //波形一输出io口
#define OUT2 P2_6 //波形二输出io
#define GATE1 P2_5 //波形二输出控制1
#define GATE2 P2_4 //波形二输出控制2
//全局变量
unchar TEMP;
unchar KEYNUM; //键值
unchar SYS_STATE; //系统当前设置状态
unint COUNT0; //记录定时器0中断次数
unint COUNT1; //记录定时器1中断次数
unint SECOND;
unint BACKTIME;
char SET_MINUTE; //定时分钟数
unchar WAVE_TYPE_1; //功能一输出波形
unchar WAVE_TYPE_2; //功能二输出波形
int DISP_INTENSE_1; //波形一显示设定输出强度
int DISP_INTENSE_2; //波形二显示设定输出强度
int INTENSE_1; //波形一实际设定输出强度
int INTENSE_2; //波形二实际设定输出强度
bit FLAG2;
unchar COUNT2; //波形1_2计时变量
unchar COUNT3; //波形1_3计时变量
unint COUNT4; //波形1_4计时变量
unint COUNT1_5;
unint COUNT2_1;
unint COUNT[3];
unint COUNT2_5;
unint COUNT2_6;
unint COUNT2_7;
unint COUNT2_9;
unint COUNT2_10;
unint COUNT2_11;
unint COUNT2_12;
unchar COUNT2_4;
unint TEMP2_5;
unint COUNT1_3;
bit FLAG4;
bit FLAG5;
unchar FLAG2_7;
unchar DISBUFFER[6]={0,2,0,0,0,0}; //显示缓冲区
const unchar LED7Code[]={ //共阳的,编码顺序:A,B,C,D,E,F,G(7,6,5,4,3,2,1),H为小数点,单独编码
0x03, // 0
0x9F, // 1
0x25, // 2
0x0D, // 3
0x99, // 4
0x49, // 5
0x41, // 6
0x1F, // 7
0x01, // 8
0x09, // 9
0xff
}; //编码表
//函数声明
void SystemInitial(); //系统初始化函数
void Display(); //显示函数
void KeyProg(unchar keynum); //根据按键值执行响应的功能
void DelayShort(unchar delay); //延时程序,延时0-255us
void Timer0Interrupt(); //定时器0中断处理函数
//void Stop(); //治疗时间到,停止工作函数
void DisplayChar(unchar j, unchar offset); //显示一个0-99的数
void wave2_1();
void wave_sine(unint t,unint high,unchar type,unchar func);
/******************************************************************************************************
200ms延时子程序
******************************************************************************************************/
void delay200ms(void)
{
unsigned char i,j,k;
for(i=5;i>0;i--)
for(j=132;j>0;j--)
for(k=150;k>0;k--);
}
/******************************************************************************************************
键盘说明
键盘:键盘采用74148(8-3优先编码器),输出接到P2.0,P2.1,P2.2,有键按下时候给出中断信号,接到单片机INT0
注意:有键按下后148给出得中断信号是一个低电平,一直保持到键弹起为止
按键功能分布:
key0:功能一强度调节(+)
key1:功能一强度调节(-)
key2:功能二强度调节(+)
key3:功能二强度调节(-)
key4:功能选择(+)
key5:功能选择(-)
key6:时间设定
key7:功能选择
******************************************************************************************************/
/******************************************************************************************************
按键中断处理函数
中断类型:外部中断0
******************************************************************************************************/
void KeyInterrupt(void) interrupt 0
{
EX0 = 0; //禁止键盘,不在响应其他按键;但是定时器中断同样还是响应
KEYNUM = P2 & 0x07; //p2低3位作为键值
while(P3_2 == 0) //每隔200ms判断按键是否还是按下,如果继续按下,则当成第二次按键处理
{
KeyProg(KEYNUM); //转向键值处理函数
delay200ms();
}
//DISBUFFER[0] = KEYNUM;
Display();
EX0 = 1;
}
/******************************************************************************************************
按键处理函数
作用:更具按键值执行响应的操作
参数:按键值
参数类型:unchar
******************************************************************************************************/
void KeyProg(unchar keynum)
{
switch (keynum)
{
case 0: //波形一(+)
BACKTIME = 0;
DISP_INTENSE_1 ++;
if(DISP_INTENSE_1 >=99)
DISP_INTENSE_1 = 99;
DisplayChar(DISP_INTENSE_1,4);
break;
case 1: //波形一(-)
BACKTIME = 0;
DISP_INTENSE_1 --;
if(DISP_INTENSE_1 <=0)
DISP_INTENSE_1 = 0;
DisplayChar(DISP_INTENSE_1,4);
break;
case 2: //波形二(+)
BACKTIME = 0;
DISP_INTENSE_2 ++;
if(DISP_INTENSE_2 >=99)
DISP_INTENSE_2 = 99;
DisplayChar(DISP_INTENSE_2,2);
break;
case 3: //波形二(-)
BACKTIME = 0;
DISP_INTENSE_2 --;
if(DISP_INTENSE_2 <=0)
DISP_INTENSE_2 = 0;
DisplayChar(DISP_INTENSE_2,2);
break;
case 4: //定时按键(+)
//
{
switch (SYS_STATE)
{
case 0: //时间设定
{
SET_MINUTE ++;
if(SET_MINUTE>99)
SET_MINUTE = 99;
DisplayChar(SET_MINUTE,0);
}
break;
case 1: //功能一波形选择
{
BACKTIME = 0;
DISP_INTENSE_1 = 0;
DisplayChar(DISP_INTENSE_1,4);
WAVE_TYPE_1 ++;
if(WAVE_TYPE_1>6)
WAVE_TYPE_1 = 1;
DisplayChar(WAVE_TYPE_1,0);
}
break;
case 2: //功能二波形选择
{
BACKTIME = 0;
DISP_INTENSE_2 = 0;
DisplayChar(DISP_INTENSE_2,2);
WAVE_TYPE_2 ++;
if(WAVE_TYPE_2>9)
WAVE_TYPE_2 = 1;
DisplayChar(WAVE_TYPE_2,0);
}
break;
}
break;
}
case 5: //定时按键(一)
//
{
switch (SYS_STATE)
{
case 0: //时间设定
{
SET_MINUTE --;
if(SET_MINUTE<= 0)
SET_MINUTE = 0;
DisplayChar(SET_MINUTE,0);
}
break;
case 1: //功能一波形选择
{
BACKTIME = 0;
DISP_INTENSE_1 = 0;
DisplayChar(DISP_INTENSE_1,4);
WAVE_TYPE_1 --;
if(WAVE_TYPE_1 < 1)
WAVE_TYPE_1= 6;
DisplayChar(WAVE_TYPE_1,0);
}
break;
case 2: //功能二波形选择
{
BACKTIME = 0;
DISP_INTENSE_2 = 0;
DisplayChar(DISP_INTENSE_2,2);
WAVE_TYPE_2 --;
if(WAVE_TYPE_2 <1)
WAVE_TYPE_2 = 9;
DisplayChar(WAVE_TYPE_2,0);
}
break;
}
break;
}
case 6: //时间设定
//
SYS_STATE ++;
SYS_STATE %=3;
if(SYS_STATE == 0)
{
LED_1 = 1;
LED_2 = 0;
LED_3 = 0;
DisplayChar(SET_MINUTE,0);
}
if(SYS_STATE == 1)
{
LED_1 = 0;
LED_2 = 1;
LED_3 = 0;
BACKTIME = 0;
DisplayChar(WAVE_TYPE_1,0);
}
if(SYS_STATE == 2)
{
LED_1 = 0;
LED_2 = 0;
LED_3 = 1;
BACKTIME = 0;
DisplayChar(WAVE_TYPE_2,0);
}
break;
case 7: //功能选择(复位键盘)
//
SystemInitial();
break;
}
//强度调整
// INTENSE_1 =INTENSE_1*4+1;
// INTENSE_1/=5;
//INTENSE_2 =(DISP_INTENSE_2*4)/5+1;
}
/******************************************************************************************************
数码管显示说明
数码管皆为共阳型,1,2显示时间和功能选项;数码管3,4显示功能一的强度,数码管5,6显示功能二的强度
数码管采用串行驱动方式,只有LED2上的小数点由P1.0 控制,其余小数点都不能使用
另外还有三个LED指示灯,L1,L2,L3分别作为时间,功能一,功能二的指示灯。L1,L2,L3受到P1.2,P1.3,P1.4的控制
均为高电平点亮
注意:由于采用串行移位显示,最先送入的的
******************************************************************************************************/
/******************************************************************************************************
显示函数
作用: 将显示缓冲区的内容译码后送LED显示
参数: 无
******************************************************************************************************/
void Display()
{
unchar i;
for(i =0;i<6;i++)
{
SBUF = LED7Code[ DISBUFFER[5-i] ];
while(TI == 0) ;
TI = 0;
}
}
//显示一个0-99的数,offset指定显示偏移量
void DisplayChar(unchar j, unchar offset)
{
unchar i;
i = j;
i %= 100;
//if(i/10 == 0)
//DISBUFFER[1+offset] = 11; //灭
//else
DISBUFFER[1+offset] = i/10;
i %= 10;
DISBUFFER[0+offset] = i;
Display();
}
/***************************************************************************************
定时器0中断处理
作用:将定时器0作为系统时钟,没50ms发生一次中断
****************************************************************************************/
void Timer0Interrupt() interrupt 1
{
//P2_5 =!P2_5;
ET0 = 0;
COUNT0++;
BACKTIME++;
if( BACKTIME == 100)
{
SYS_STATE = 0;
DisplayChar(SET_MINUTE,0);
BACKTIME = 0;
LED_1 = 1;
LED_2 = 0;
LED_3 = 0;
}
if((COUNT0%10) == 0) //0.5秒到
{
DOTE = ! DOTE; //小数点交替亮灭
//INTENSE_1 +=10;
//if(INTENSE_1 >100)
//INTENSE_1 = 10;
//P1_6 = ! P1_6;
// DISBUFFER[0]++;
//DISBUFFER[0] =DISBUFFER[0] % 10;
//P1_1 = ! P1_1;
Display();
}
if(COUNT0 == 1200 ) //1分钟到
{
SET_MINUTE--;
if(SET_MINUTE == 0)
{
BUZZER = 1;
TR0 = 0;
}
DisplayChar(SET_MINUTE,0); //显示设置分钟
COUNT0 = 0;
//
}
TH0 = 0x3C;
TL0 = 0xB0;
ET0 = 1;
}
/******************************************************************************************************
治疗时间到,停止工作函数
******************************************************************************************************/
//void Stop(){}
void wave2_1()
{
unchar i,j;
//强度调整
INTENSE_2 =(DISP_INTENSE_2*3)/4+1;
COUNT2_1++;
COUNT2_1= COUNT2_1%200;
i =INTENSE_2;
j =INTENSE_2/20+1;
if(COUNT2_1 <25) //1s的脉冲
{
// for (k=0;k<j;k++)
// {
OUT2 =0;
while(--i); //宽度可调的高电平
OUT2 = 1;
i =INTENSE_2;
while(--i); //宽度可调的高电平
// }
OUT2 =0;
}
if((COUNT2_1 >=25)&&(COUNT2_1<=100)) //1s 的低电平
{
OUT2 = 0;
}
if((COUNT2_1 >=100)&&(COUNT2_1<=150)) //2s的脉冲
{
// for (k=0;k<j;k++)
// {
OUT2 =0;
while(--i); //宽度可调的高电平
OUT2 = 1;
i =INTENSE_2;
while(--i); //宽度可调的高电平
// }
OUT2 =0;
}
if((COUNT2_1 >=150)&&(COUNT2_1<=200)) //1s 的低电平
{
OUT2 = 0;
}
}
/*
void wave_sine(unint t,unint high,unchar type,unchar func)
{
unchar temp,i;
unchar intense;
if(func == 1)
{
intense =INTENSE_1;
}
if(func == 2)
{
intense =INTENSE_2;
}
COUNT[type]++;
COUNT[type]=COUNT[type]%t; //t为一周期,t以20ms为单位
//i =INTENSE_1;
//TH1 = (65536-25000)/256; //25ms中断一次(38hz)
//TL1 = (65536-25000)%256;
temp = high/10; //将高电平分为20段
i++;
i =i% intense;
if(COUNT[type] <=high/2) //脉冲前半段
{
if(COUNT[type]%temp == 0)
{
//if(intense<10)
// i = intense;
// else
// {
// i = (intense/5)*(COUNT[type]/temp);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -