#include<reg51.h> //定義頭文件
#define uint unsigned int //定義字符uint
#define uchar unsigned char //定義字符uchar
#define TIME0H 0xff //定時器0計數器高位
#define TIME0L 0x9c //定時器0計數器低位
#define TIME1H 0x3c //定時器1計數器高位
#define TIME1L 0xb0 //定時器1計數器低位
#define MOTOR_COUNT 100 //PWM波輸出周期計數
#define sol 0x6c //將"so"宏定義為低音"5"的頻率 784Hz
#define Dol 0x44 //將"Do"宏定義為中音"1"的頻率 523Hz
#define Rel 0xac //將"Re"宏定義為中音"2"的頻率 587Hz
#define Mil 0x09 //將"Mi"宏定義為中音"3"的頻率 659Hz
#define Fal 0x34 //將"Fa"宏定義為中音"4"的頻率 698Hz
#define Sol 0x82 //將"So"宏定義為中音"5"的頻率 784Hz
#define Lal 0xc8 //將"La"宏定義為中音"6"的頻率 880Hz
#define Sil 0x05 //將"Si"宏定義為中音"7"的頻率 523H
#define soh 0xfc //將"so"宏定義為低音"5"的頻率 784Hz
#define Doh 0xfc //將"Do"宏定義為中音"1"的頻率 523Hz
#define Reh 0xfc //將"Re"宏定義為中音"2"的頻率 587Hz
#define Mih 0xfd //將"Mi"宏定義為中音"3"的頻率 659Hz
#define Fah 0xfd //將"Fa"宏定義為中音"4"的頻率 698Hz
#define Soh 0xfd //將"So"宏定義為中音"5"的頻率 784Hz
#define Lah 0xfd //將"La"宏定義為中音"6"的頻率 880Hz
#define Sih 0xfe //將"Si"宏定義為中音"7"的頻率 523H
//定義宏變量
sbit speaker =P2^6; //蜂鳴器控制引腳
sbit RS=P1^5; //LCD RS引腳
sbit R_W=P1^6; //LCD 讀寫信號
sbit EN=P1^7; //LCD 使能引腳
sbit motor_high=P1^0; //PWM輸出高電平引腳
sbit motor_low=P1^1; //PWM輸出低電平引腳
sbit motor_1_en=P1^2; //進水閥門引腳
sbit motor_2_en=P1^3; //出水閥門引腳
sbit motor_3_en=P1^4; //洗衣機電動使能引腳
sbit EOC=P2^4; //AD EOC
sbit START=P2^5; //AD START
sbit con=P3^5; //AD CON
sbit add_A=P3^0; //位選信號A
sbit lock_OE=P3^1; //74ls373鎖存控制引腳
//定義全局變量
uchar process; //當前洗衣機運行狀態全局變量
uchar method; //當前洗衣機運行方式全局變量
uchar speed; //當前電動機速度全局變量
uchar flag; //標志位
uchar state; //洗衣機運行狀態選擇
uint ad_level; //水位采樣全局變量
uint ad_voltage; //電壓采樣全局變量
uint time_count; //定時器0中斷次數全局變量
uint time_count1; //定時器1中斷次數全局變量
uint MOTOR_ON,MOTOR_NOW; //電動機pwm控制計數,高電平脈沖數和當前脈沖數
uchar st_pau; //當前洗衣機運行全局變量
uchar step; //當前洗衣機運行步驟全局變量
uint Cl=0; //
uint Ch=0; //
uchar close=0;
//聲明子函數
void init_LCM(); //lcd初始化函數
void clearLCD(); //lcd清屏函數
void write_data(char date); //lcd寫數據函數
void write_com(char command); //lcd寫指令函數
void display()reentrant; //lcd顯示函數
void check_BF(); //lcd檢查忙碌函數
void fangshi1(); //洗衣機運行方式1
void fangshi2(); //洗衣機運行方式2
void fangshi3(); //洗衣機運行方式3
void fangshi4(); //洗衣機運行方式4
void translate(int keycode); //按鍵值釋放函數
void clrpara(); //復位所有參數
void speaker_on(); //蜂鳴器
void delay(); //80ms延時程序
unsigned char f_TAB[][2]={ /**/{Sol,Soh},{Lal,Lah},{Sol,Soh},{Fal,Fah},{Mil,Mih},{Dol,Doh},//, //音調
/**/{Sol,Soh},{Lal,Lah},{Sol,Soh},{Fal,Fah},{Mil,Mih},{Dol,Doh},/**/{Dol,Doh},{sol,soh},{Dol,Doh},
/**/{Dol,Doh},{sol,soh},{Dol,Doh},/**/{0xff,0xff}};
uchar time_TAB[]={3,1,3,1,4,4,/**/3,1,3,1,4,4,/**/4,4,4,8,/**/4,4,4,8}; //節拍
/*****************************80ms延時*****************************/
void delay()
{
uchar i,j; //定義變量i,j
for(i=0;i<100;i++) //外循環
for(j=0;j<250;j++); //內循環
}
/***************************按鍵信息翻譯***************************/
void translate(int keycode)
{
int key; //定義臨時變量key,用來判斷(開始/暫停)按鍵次數
switch(keycode) //根據不同傳入的keycode值,進行全局變量賦值
{
case 0: //方式一
method = '1'; //將方式全局變量賦值為‘1’
//return '0'; //返回‘0’結果
break; //跳出分支判斷
case 1: //方式三
method = '3'; //將方式全局變量賦值為‘3’
//return '1'; //返回‘1’結果
break; //跳出分支判斷
case 2: //速度1/4
speed = '1'; //賦值速度全局變量為1
MOTOR_ON = 25; //設置PWM占空比為25/100
//return '2'; //返回‘2’結果
break; //跳出分支判斷
case 3: //速度3/4
speed = '3'; //賦值速度全局變量為3
MOTOR_ON = 75; //設置PWM占空比為75/100
//return '3'; //返回‘3’結果
break; //跳出分支判斷
case 4: //方式二
method = '2'; //將方式全局變量賦值為‘2’
//return '4'; //返回‘4’結果
break; //跳出分支判斷
case 5: //方式四
method = '4'; //將方式全局變量賦值為‘4’
//return '5'; //返回‘5’結果
break; //跳出分支判斷
case 6: //速度2/4
speed = '2'; //賦值速度全局變量為2
MOTOR_ON = 50; //設置PWM占空比為50/100
//return '6'; //返回‘6’結果
break; //跳出分支判斷
case 7: //速度4/4
speed = '4'; //賦值速度全局變量為4
MOTOR_ON = 100; //設置PWM占空比為100/100
//return '7'; //返回‘7’結果
break; //跳出分支判斷
case 8: //ON
state =1; //賦值洗衣機運行狀態選擇1
//return '8'; //返回‘8’結果
break; //跳出分支判斷
case 9: //OFF
state = 0; //賦值洗衣機運行狀態選擇0
//return '9'; //返回‘9’結果
break; //跳出分支判斷
case 10: //START/PAUSE
{
if(key==0) //判斷開始/暫停鍵是否按下,是繼續
{
st_pau=1; //賦值洗衣機運行全局變量為1
key++; //key自加1
}
else
{
st_pau=2; //當前洗衣機運行全局變量為2
key--; //key自減1
}
//return 'A'; //返回‘A’結果
break; //跳出分支判斷
}
}
}
/*****************************LCD顯示******************************/
void display()reentrant
{
int level_1,level_2,level_3,voltage_1,voltage_2,voltage_3;
//定義水位、電壓顯示百位、十位、各位。由于顯示直接采用返回AD轉換值,所以需要按照百、十、個位進行顯示
clearLCD(); //LCD清屏
//process: 1浸泡,2脫水,3洗滌,4進水,5漂洗,
//method:1方式一,2方式二,3方式三,4方式四
//speed:1速度1/4,2速度2/4,3速度3/4,4速度4/4
level_1 = ad_level / 100 + 48; //獲得水位檢測百位,同時轉化為ASCII碼
level_2 = (ad_level %100 ) /10 + 48; //獲得水位檢測值十位,同時轉化為ASCII碼
level_3 = (ad_level %10 ) + 48; //獲得水位檢測值個位,同時轉化為ASCII碼
voltage_1 = ad_voltage / 100 + 48; //獲得電壓轉換值百位,轉化為ASCII碼
voltage_2 = (ad_voltage %100 ) /10 + 48; //獲得電壓轉換值十位,轉化為ASCII碼
voltage_3 = (ad_voltage %10 ) + 48; //獲得電壓轉換值個位,轉化為ASCII碼
if (state == 1) //如果洗衣機當前運行狀態為on開啟狀態
{
switch(process) //根據不同的運行狀態,在LCD第一行顯示運行狀態信息
{
case '1': //進水
write_data('J'); //顯示字符‘J’
write_data('I'); //顯示字符‘I’
write_data('N'); //顯示字符‘N’
write_data('S'); //顯示字符‘S’
write_data('H'); //顯示字符‘H’
write_data('U'); //顯示字符‘U’
write_data('I'); //顯示字符‘I’
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data('L'); //顯示字符‘L’
write_data(level_1); //顯示水位檢測百位值
write_data(level_2); //顯示水位檢測十位值
write_data(level_3); //顯示水位檢測個位值
write_data(' '); //顯示空字符
write_data('V'); //顯示字符‘V’
write_data(voltage_1); //顯示電壓檢測百位值
write_data(voltage_2); //顯示電壓檢測十位值
write_data(voltage_3); //顯示電壓檢測個位值
motor_1_en = 1; //進水閥電動機驅動打開
motor_2_en = 0; //排水閥電動機驅動關閉
motor_3_en = 0; //洗衣機電動機驅動關閉
break; //跳出分支判斷
case '2': //浸泡
write_data('J'); //顯示字符‘J’
write_data('I'); //顯示字符‘I’
write_data('N'); //顯示字符‘N’
write_data('P'); //顯示字符‘P’
write_data('A'); //顯示字符‘A’
write_data('O'); //顯示字符‘O’
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data('L'); //顯示字符‘L’
write_data(level_1); //顯示水位檢測百位值
write_data(level_2); //顯示水位檢測十位值
write_data(level_3); //顯示水位檢測個位值
write_data(' '); //顯示空字符
write_data('V'); //顯示字符‘V’
write_data(voltage_1); //顯示電壓檢測百位值
write_data(voltage_2); //顯示電壓檢測十位值
write_data(voltage_3); //顯示電壓檢測個位值
motor_1_en = 0; //進水閥電動機驅動關閉
motor_2_en = 0; //排水閥電動機驅動關閉
motor_3_en = 0; //洗衣機電動機驅動關閉
break; //跳出分支判斷
case '3': //洗滌
write_data('X'); //顯示字符‘X’
write_data('I'); //顯示字符‘I’
write_data('D'); //顯示字符‘D’
write_data('I'); //顯示字符‘I’
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data('L'); //顯示字符‘’
write_data(level_1); //顯示水位檢測百位值
write_data(level_2); //顯示水位檢測十位值
write_data(level_3); //顯示水位檢測個位值
write_data(' '); //顯示空字符
write_data('V'); //顯示字符‘V’
write_data(voltage_1); //顯示電壓檢測百位值
write_data(voltage_2); //顯示電壓檢測十位值
write_data(voltage_3); //顯示電壓檢測個位值
motor_3_en = 1; //洗衣機電動機驅動打開
motor_1_en = 0; //進水閥電動機驅動關閉
motor_2_en = 0; //排水閥電動機驅動關閉
break; //跳出分支判斷
case '4': //漂洗
write_data('P'); //顯示字符‘P’
write_data('I'); //顯示字符‘I’
write_data('A'); //顯示字符‘A’
write_data('O'); //顯示字符‘O’
write_data('X'); //顯示字符‘X’
write_data('I'); //顯示字符‘I’
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data('L'); //顯示字符‘L’
write_data(level_1); //顯示水位檢測百位值
write_data(level_2); //顯示水位檢測十位值
write_data(level_3); //顯示水位檢測個位值
write_data(' '); //顯示空字符
write_data('V'); //顯示字符‘V’
write_data(voltage_1); //顯示電壓檢測百位值
write_data(voltage_2); //顯示電壓檢測十位值
write_data(voltage_3); //顯示電壓檢測個位值
motor_3_en = 1; //洗衣機電動機驅動打開
motor_1_en = 0; //進水閥電動機驅動關閉
motor_2_en = 0; //排水閥電動機驅動關閉
break; //跳出分支判斷
case '5': //脫水
write_data('T'); //顯示字符‘T’
write_data('U'); //顯示字符‘U’
write_data('O'); //顯示字符‘O’
write_data('S'); //顯示字符‘S’
write_data('H'); //顯示字符‘H’
write_data('U'); //顯示字符‘U’
write_data('I'); //顯示字符‘I’
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data('L'); //顯示字符‘L’
write_data(level_1); //顯示水位檢測百位值
write_data(level_2); //顯示水位檢測十位值
write_data(level_3); //顯示水位檢測個位值
write_data(' '); //顯示空字符
write_data('V'); //顯示字符‘V’
write_data(voltage_1); //顯示電壓檢測百位值
write_data(voltage_2); //顯示電壓檢測十位值
write_data(voltage_3); //顯示電壓檢測個位值
motor_1_en = 0; //進水閥電動機驅動關閉
motor_2_en = 1; //排水閥電動機驅動打開
motor_3_en = 0; //洗衣機電動機驅動關閉
break; //跳出分支判斷
}
if(st_pau==2) //當前洗衣機運行全局變量為2
{
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
write_data('P'); //顯示字符‘P’
write_data('A'); //顯示字符‘A’
write_data('U'); //顯示字符‘U’
write_data('S'); //顯示字符‘S’
write_data('E'); //顯示字符‘E’
}
else
{
switch(method) //判斷方式全局變量
{
case '1': //方式一
write_data('M'); //顯示字符‘M’
write_data('E'); //顯示字符‘E’
write_data('T'); //顯示字符‘T’
write_data('H'); //顯示字符‘H’
write_data('O'); //顯示字符‘O’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('1'); //顯示字符‘1’
write_data(' '); //顯示空字符
break; //跳出分支判斷
case '2': //方式二
write_data('M'); //顯示字符‘M’
write_data('E'); //顯示字符‘E’
write_data('T'); //顯示字符‘T’
write_data('H'); //顯示字符‘H’
write_data('O'); //顯示字符‘O’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('2'); //顯示字符‘2’
write_data(' '); //顯示空字符
break; //跳出分支判斷
case '3': //方式三
write_data('M'); //顯示字符‘M’
write_data('E'); //顯示字符‘E’
write_data('T'); //顯示字符‘T’
write_data('H'); //顯示字符‘H’
write_data('O'); //顯示字符‘O’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('3'); //顯示字符‘3’
write_data(' '); //顯示空字符
break; //跳出分支判斷
case '4': //方式四
write_data('M'); //顯示字符‘M’
write_data('E'); //顯示字符‘E’
write_data('T'); //顯示字符‘T’
write_data('H'); //顯示字符‘H’
write_data('O'); //顯示字符‘O’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('4'); //顯示字符‘4’
write_data(' '); //顯示空字符
break; //跳出分支判斷
}
switch(speed) //判斷速度全局變量
{
case '1': //速度一
write_data('S'); //顯示字符‘S’
write_data('P'); //顯示字符‘P’
write_data('E'); //顯示字符‘E’
write_data('E'); //顯示字符‘E’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('1'); //顯示字符‘1’
break; //跳出分支判斷
case '2': //速度二
write_data('S'); //顯示字符‘S’
write_data('P'); //顯示字符‘P’
write_data('E'); //顯示字符‘E’
write_data('E'); //顯示字符‘E’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('2'); //顯示字符‘2’
break; //跳出分支判斷
case '3': //速度三
write_data('S'); //顯示字符‘S’
write_data('P'); //顯示字符‘P’
write_data('E'); //顯示字符‘E’
write_data('E'); //顯示字符‘E’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('3'); //顯示字符‘3’
break; //跳出分支判斷
case '4': //速度四
write_data('S'); //顯示字符‘S’
write_data('P'); //顯示字符‘P’
write_data('E'); //顯示字符‘E’
write_data('E'); //顯示字符‘E’
write_data('D'); //顯示字符‘D’
write_data(':'); //顯示字符‘:’
write_data('4'); //顯示字符‘4’
break; //跳出分支判斷
}
}
}
else
{
write_data('N'); //顯示字符‘N’
write_data('O'); //顯示字符‘O’
write_data('W'); //顯示字符‘W’
write_data(' '); //顯示空字符
write_data('M'); //顯示字符‘M’
write_data('A'); //顯示字符‘A’
write_data('C'); //顯示字符‘C’
write_data('H'); //顯示字符‘H’
write_data('I'); //顯示字符‘I’
write_data('N'); //顯示字符‘N’
write_data('E'); //顯示字符‘E’
write_data(' '); //顯示空字符
write_data('I'); //顯示字符‘I’
write_data('S'); //顯示字符‘S’
write_data(' '); //顯示空字符
write_data('O'); //顯示字符‘O’
write_data('F'); //顯示字符‘F’
write_data('F'); //顯示字符‘F’
write_data(' '); //顯示空字符
write_data(' '); //顯示空字符
}
//P0 = 0XFF;
}
/****************************LCD初始化*****************************/
void init_LCM()
{
write_com(0x30); //發送控制命令0x30
write_com(0x30); //發送控制命令0x30
write_com(0x30); //發送控制命令0x30,做一個延時
write_com(0x38); //發送控制命令0x38
write_com(0x08); //發送控制命令0x08
write_com(0x01); //發送控制命令0x01
write_com(0x06); //發送控制命令0x06
write_com(0x0e); //發送控制命令0x0e
}
/***************************LCD寫數據函數**************************/
void write_data(char date)
{
RS=1; //寫指令電平置為高,進入寫數據狀態
R_W=0; //讀指令電平置為低,無效
EN=1; //使能信號開
P0=date; //將數據送入p0口
EN=0; //使能信號關
check_BF(); //等待LCD繁忙狀態結束
}
/***************************LCD寫指令函數**************************/
void write_com(char command)
{
RS=0; //寫指令電平置為低,進入寫指令狀態
R_W=0; //讀寫指令命令置為低電平
EN=1; //使能信號開
P0=command; //將數據送入p0口
EN=0; //使能信號關
check_BF(); //等待LCD繁忙狀態結束
}
/**************************LCD檢查忙碌函數*************************/
void check_BF()
{
char i,x=0x80; //定義字符變量i,x
P0=0xff; //P0口輸出高電平,使得P0口電平輸入允許
while(x&0x80) //當LCD還是處于繁忙狀態時,進入循環
{
RS=0; //寫指令置為1,讀取指令狀態
R_W=1; //讀引腳電平置為高,為讀取信息狀態
EN=1; //LCD使能信號開
P0=0XFF; //P0口輸出高電平,使得P0口電平輸入允許
x=P0; //將P0口電平信息賦給x
EN=0; //LCD使能信號關閉
for (i=0;i<10;i++); //循環等待
}
EN=0; //關閉使能信號
}
/****************************LCD清屏函數***************************/
void clearLCD()
{
write_com(0x01); //寫入LCD清屏指令
}
/******************************方式一******************************/
void fangshi1()
{
switch(step) //判斷洗衣機當前運行步驟
{
case 0: //步驟0
process = '1'; //進水
break; //跳出分支判斷
case 1: //步驟1
process = '2'; //浸泡
break; //跳出分支判斷
case 2: //步驟2
process = '3'; //洗滌
break; //跳出分支判斷
case 3: //步驟3
process = '5'; //脫水
break; //跳出分支判斷
case 4: //步驟4
process = '1'; //進水
break; //跳出分支判斷
case 5: //步驟5
process = '4'; //漂洗
break; //跳出分支判斷
case 6: //步驟6
process = '5'; //脫水
break; //跳出分支判斷
case 7: //步驟7
process = '1'; //進水
break; //跳出分支判斷
case 8: //步驟8
process = '4'; //漂洗
break; //跳出分支判斷
case 9: //步驟9
process = '5'; //脫水
break; //跳出分支判斷
case 10: //步驟10
clrpara(); //復位所有參數
break; //跳出分支判斷
}
}
/******************************方式二******************************/
void fangshi2()
{
switch(step) //判斷洗衣機當前運行步驟
{
case 0: //步驟0
process = '1'; //進水
break; //跳出分支判斷
case 1: //步驟1
process = '3'; //洗滌
break; //跳出分支判斷
case 2: //步驟2
process = '5'; //脫水
break; //跳出分支判斷
case 3: //步驟3
process = '1'; //進水
break; //跳出分支判斷
case 4: //步驟4
process = '4'; //漂洗
break; //跳出分支判斷
case 5: //步驟5
process = '5'; //脫水
break; //跳出分支判斷
case 6: //步驟6
process = '1'; //進水
break; //跳出分支判斷
case 7: //步驟7
process = '4'; //漂洗
break; //跳出分支判斷
case 8: //步驟8
process = '5'; //脫水
break; //跳出分支判斷
case 9: //步驟9
clrpara(); //復位所有參數
break; //跳出分支判斷
}
}
/******************************方式三******************************/
void fangshi3()
{
switch(step) //判斷洗衣機當前運行步驟
{
case 0: //步驟0
process = '1'; //進水
break; //跳出分支判斷
case 1: //步驟1
process = '3'; //洗滌
break; //跳出分支判斷
case 2: //步驟2
process = '5'; //脫水
break; //跳出分支判斷
case 3: //步驟3
process = '1'; //進水
break; //跳出分支判斷
case 4: //步驟4
process = '4'; //漂洗
break; //跳出分支判斷
case 5: //步驟5
process = '5'; //脫水
break; //跳出分支判斷
case 6: //步驟6
clrpara(); //復位所有參數
break; //跳出分支判斷
}
}
/******************************方式四******************************/
void fangshi4()
{
switch(step) //判斷洗衣機當前運行步驟
{
case 0: //步驟0
process = '5'; //脫水
break; //跳出分支判斷
case 1: //步驟1
clrpara(); //復位所有參數
break; //跳出分支判斷
}
}
/*******************************復位*******************************/
void clrpara()
{
EX0=0;
TR0=0;
st_pau=2; //洗衣機是否運行全局變量為2
step=0; //洗衣機運行步驟全局變量為0
//P2=0xff; //P0輸出0xff信息
state=0; //洗衣機運行狀態設置為OFF狀態
process='1'; //洗衣機過程全局變量為1
method='1'; //洗衣機方式全局變量為1
speed='1'; //電動機速度全局變量為1
ad_level=0; //水位AD監測值為0
ad_voltage=0; //電壓AD檢測值為0
motor_1_en = 0; //進水閥驅動機關閉
motor_2_en = 0; //排水閥驅動機關閉
motor_3_en = 0; //洗衣機電動機關閉
TR1=0;
flag=1; //標志位為1,開始播放音樂
//TR1=1; //啟動定時器0
init_LCM(); //LCD初始化程序
display(); //LCD刷新顯示
//speaker_on(); //音樂播放程序
}
/***************************音樂播放程序***************************/
void speaker_on()
{
uchar i,j; //定義變量i,j
i=0; //變量i賦值為0
while(f_TAB[i][0]!=0xff)//判斷
{
Ch=f_TAB[i][1]; //TH0賦值
Cl=f_TAB[i][0]; //TL0賦值
TH1=Ch; //TH0賦值
TL1=Cl; //TL0賦值
TR1=1;
for(j=0;j<time_TAB[i];j++) //控制節拍數
delay(); //延時 1 個節拍單位
TR1=0; //關閉定時器 T0
i++; //播放下一個音符
}
}
/****************************主程序入口****************************/
void main()
{
//中斷0按鍵
IT0 = 1; //中斷方式為下降沿
EX0 = 1; //開啟外部中斷
//定時器0、1,定時器0、1中斷,用于狀態改變計數,pwm調制計數
TMOD = 0x11; //定時器為定時中斷模式1
TH0 = TIME0H; //定時器0計數高位加載
TL0 = TIME0L; //定時器0計數低位加載
TH1 = TIME1H; //定時器1計數高位加載
TL1 = TIME1L; //定時器1計數低位加載
ET0 = 1; //定時器0中斷允許
ET1 = 1; //定時器1中斷允許
TR0 = 1; //定時器0計數器啟動
TR1 = 1; //定時器1計數器啟動
P2 = 0xff; //P0輸出0xff信息
state = 0; //洗衣機運行狀態設置為OFF狀態
process = '1'; //洗衣機過程全局變量為‘1’
method = '1'; //洗衣機方式全局變量為‘1’
speed = '1'; //電動機速度全局變量為‘1’
st_pau = '0'; //洗衣機是否運行全局變量為‘0’
step = 0 ; //洗衣機運行步驟全局變量為‘0’
MOTOR_ON = 25; //電動機PWM控制計數為25
ad_level = 0; //水位AD監測值為0
ad_voltage = 0; //電壓AD檢車值為0
time_count = 0; //定時0中斷計數器全局變量為0
time_count1 = 0; //定時1中斷計數器全局變量為0
flag=0; //標志位為0
speaker = 0; //蜂鳴器關閉
init_LCM(); //初始化LCD
display(); //刷新顯示
EA = 1; //開啟單片機中斷允許位,允許中斷開始
P0 = 0xff; //P0輸出高電平,使得可以進行外部電壓信號輸入
while(1)
{
//測試水位
while(flag==0)
{
con = 0; //AD轉換輸出關閉
add_A = 0; //選擇水位模擬信號進行AD轉換
START = 1; //設置START引腳為高電平
START = 0; //設置START引腳為低電平,得到下降沿,啟動AD檢測
while(!EOC); //等待AD轉換結束
lock_OE = 0; //74ls373鎖存信號為低,通道開啟
P0 = 0xff; //P0引腳輸出高電平,允許引腳電平的讀入
con = 1; //AD轉換芯片輸出使能
ad_level = P0; //將AD轉換賦值為AD_LEVEL全局變量
con = 0; //AD轉換芯片輸出禁止
lock_OE = 1; //74ls373鎖存信號開啟,進行電平鎖存
add_A = 1; //選擇AD模塊為1號通道信號進行模數轉換,即電壓信號
START = 1; //START引腳輸出高電平
START = 0; //START引腳輸出低電平,開始AD轉換
while(!EOC); //等待AD轉換結束
lock_OE = 0; //74ls373鎖存信號關閉,AD轉換信號可以輸出
P0 = 0xff; //P0輸出高電平,使得外部電壓可以進行輸入
con = 1; //AD轉換結果使能
ad_voltage = P0; //將P0引腳的AD轉換結果賦值給電壓檢測全局變量
con = 0; //AD轉化結果輸出關閉
lock_OE = 1; //74ls373鎖存信號開啟,使得P0口與AD轉換引腳隔離
}
if(flag==1)
{
speaker_on();
flag=0;
}
}
}
/**************************外部中斷0子程序*************************/
void int_0() interrupt 0
{
uint temp; //定義變量temp,用來讀取P2信息
temp = P2; //temp讀取P2信息
translate(temp&0x0f); //與0x0f相與,得到低四位電平信號,并傳入translate()函數
display(); //LCD顯示刷新
}
/***************************定時0中斷入口**************************/
void time_0() interrupt 1
{
time_count1 ++; //全局定時中斷計數自加1
if (time_count1 > 6) //如果全局定時中斷次數大于6,則
{
time_count1 = 0; //全局定時中斷次數置零
}
//只考慮正轉
if(st_pau==1) //如果洗衣機處于運行狀態,則
{
MOTOR_NOW++; //PWM計數次數自加1
if (MOTOR_NOW > MOTOR_ON) //如果PWM計數次數大于高電平計數值
{
motor_high = 0; //PWM高電平引腳輸出低電平
}
else
{
motor_high = 1; //PWM高電平輸出高電壓
}
if (MOTOR_NOW > MOTOR_COUNT) //如果PWM計數值大于PWM計數周期
{
MOTOR_NOW = 0; //PWM計數值置零
}
motor_low = 0; //PWM低電平輸出低電平
}
TH0=TIME0H; //定時器0高位計數載入
TL0=TIME0L; //定時器低位計數載入
}
/***************************定時1中斷入口**************************/
void vTimer0() interrupt 3
{
if(flag==0)
{
TR1=0;
if(st_pau==1)
{
time_count++;
if(time_count> 5)
{
time_count=0;
step++;
display();
}
}
switch(method)
{
case '1': //方式一
fangshi1();
break;
case '2': //方式二
fangshi2();
break;
case '3': //方式三
fangshi3();
break;
case '4': //方式四
fangshi4();
break;
}
TH1=TIME1H;
TL1=TIME1L;
TR1=1;
}
else
{
speaker=~speaker; //取反
TH1=Ch; //TH1賦值
TL1=Cl; //TL1賦值
}
}
|