?? 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 + -