|
給你寫(xiě)了個(gè)程序,你想要的功能都有。已經(jīng)過(guò)TX-1C實(shí)驗(yàn)板驗(yàn)證通過(guò)。不合意處你自己更改。
/*************************************************************
程序功能:加電待機(jī),按鍵啟動(dòng),LED1~LED8依次點(diǎn)亮,按鍵間隔大于
0.5秒LED閃爍,最多閃爍三次后常亮,第9次按鍵進(jìn)入待機(jī)。每次操作
狀態(tài)數(shù)據(jù)保存在EEPROM,失電或關(guān)機(jī)后再次得電保持之前工作狀態(tài)。
*************************************************************/
#include <AT89X52.H> //單片機(jī)頭文件
#include <intrins.h> //庫(kù)頭文件
#define uint unsigned int //宏定義無(wú)符號(hào)整型數(shù)據(jù)(0-65535)
#define uchar unsigned char //宏定義無(wú)符號(hào)字符型數(shù)據(jù)(0-255)
/****定義ISP的操作命令*****/
#define RdCommand 0x01 //讀命令
#define PrgCommand 0x02 //寫(xiě)命令
#define EraseCommand 0x03 //擦除命令
#define WaitTime 0x01 //定義CPU的等待時(shí)間,寫(xiě)入硬件延時(shí)
/*STC89系列EEPROM寄存器聲明*/
sfr ISP_DATA=0xe2; //0000,0000 EEPROM數(shù)據(jù)寄存器
sfr ISP_ADDRH=0xe3; //0000,0000 EEPROM地址高字節(jié)
sfr ISP_ADDRL=0xe4; //0000,0000 EEPROM地址第字節(jié)
sfr ISP_CMD=0xe5; //xxxx,xx00 EEPROM命令寄存器
sfr ISP_TRIG=0xe6; //0000,0000 EEPRPM命令觸發(fā)寄存器
sfr ISP_CONTR=0xe7; //0000,x000 EEPROM控制寄存器
/********端口定義************/
sbit LED1=P1^0; //發(fā)光管端口定義
sbit LED2=P1^1;
sbit LED3=P1^2;
sbit LED4=P1^3;
sbit LED5=P1^4;
sbit LED6=P1^5;
sbit LED7=P1^6;
sbit LED8=P1^7;
sbit key=P3^6; //按鍵端口定義
/********變量及函數(shù)聲明************/
uchar num=0; //鍵值
uchar count1=0,count2=0; //中斷計(jì)數(shù)
bit Twinkle=0; //閃爍標(biāo)志
void keyscan(); //按鍵掃描程序
void display(); //顯示程序
void Timer0Init(); //初始化定時(shí)器
void ISP_IAP_enable(); //打開(kāi) ISP,IAP 功能
void ISP_IAP_disable(); //關(guān)閉 ISP,IAP 功能
void ISPgoon(); //公用的觸發(fā)代碼
uchar byte_read(uint byte_addr); //字節(jié)讀
void SectorErase(uint sector_addr); //扇區(qū)擦除
void byte_write(uint byte_addr, uchar original_data); //字節(jié)寫(xiě)
/********主函數(shù)************/
void main()
{
Timer0Init(); //定時(shí)器初始化
num=byte_read(0x2000); //程序開(kāi)始時(shí)讀取EEPROM中數(shù)據(jù)
if(num>=9) //如果num>=9
{
num=0; //num=0
}
while(1)
{
keyscan(); //按鍵識(shí)別子程序
display(); //顯示子程序
}
}
/**********按鍵掃描程序*********/
void keyscan()
{
static bit key_sign=0; //按鍵有效標(biāo)志
static uchar count=0; //計(jì)數(shù)變量
if(key==0) //檢測(cè)按鍵如果為0
{
count++; //消抖計(jì)數(shù)
if(count>=100) //100次檢測(cè)按鍵如果為0
{
count=100; //最大數(shù)限制
if(key_sign==0) //按鍵有效標(biāo)志為0
{
key_sign=1; //按鍵有效標(biāo)志置1
num++; //
if(num>=9)
num=0;
SectorErase(0x2000);//擦除EEPROM扇區(qū)中的數(shù)據(jù)
byte_write(0x2000,num); //重新寫(xiě)入數(shù)據(jù)
count1=0; //中斷計(jì)數(shù)1清0
count2=0; //中斷計(jì)數(shù)2清0
Twinkle=0; //閃爍標(biāo)志清0
}
}
}
else
{
if(key_sign==1)
{
if(num>0)
TR0 = 1; //開(kāi)定時(shí)器
else
TR0 = 0; //關(guān)定時(shí)器
key_sign=0; //按鍵有效標(biāo)志清0
}
count=0; //消抖計(jì)數(shù)清0
}
}
/**********顯示程序*********/
void display()
{
switch(num) //多重分支
{
case 0: P1=0XFF;
break;
case 1:
P1=0XFF;
if(Twinkle==1) LED1=1;
else LED1=0;
break;
case 2:
P1=0XFE;
if(Twinkle==1) LED2=1;
else LED2=0;
break;
case 3:
P1=0XFC;
if(Twinkle==1) LED3=1;
else LED3=0;
break;
case 4:
P1=0XF8;
if(Twinkle==1) LED4=1;
else LED4=0;
break;
case 5:
P1=0XF0;
if(Twinkle==1) LED5=1;
else LED5=0;
break;
case 6:
P1=0XE0;
if(Twinkle==1) LED6=1;
else LED6=0;
break;
case 7:
P1=0XC0;
if(Twinkle==1) LED7=1;
else LED7=0;
break;
case 8:
P1=0X80;
if(Twinkle==1) LED8=1;
else LED8=0;
break;
}
}
/*********定時(shí)器0初始化**************/
void Timer0Init(void) //50毫秒@12.000MHz
{
TMOD= 0x01; //設(shè)置定時(shí)器模式
TL0 = 0xB0; //設(shè)置定時(shí)初值
TH0 = 0x3C; //設(shè)置定時(shí)初值
// TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
EA=1; //開(kāi)總中斷
ET0=1; //開(kāi)定時(shí)器0中斷
}
/*********中斷服務(wù)程序**************/
void timer0() interrupt 1
{
TL0 = 0xB0; //設(shè)置定時(shí)初值
TH0 = 0x3C; //設(shè)置定時(shí)初值
count1++;
if(count1>=10) //0.5秒
{
count1=0;
Twinkle=~Twinkle; //閃爍標(biāo)志取反
count2++;
if(count2>=6) //閃爍三次
{
count2=0;
TR0 = 0; //關(guān)定時(shí)器
}
}
}
/* ================ 打開(kāi) ISP,IAP 功能 ================= */
void ISP_IAP_enable()
{
EA = 0; /* 關(guān)中斷 */
ISP_CONTR = ISP_CONTR & 0x18; /* 0001,1000 */
ISP_CONTR = ISP_CONTR | WaitTime; /* 寫(xiě)入硬件延時(shí) */
ISP_CONTR = ISP_CONTR | 0x80; /* ISPEN=1 */
}
/* =============== 關(guān)閉 ISP,IAP 功能 ================== */
void ISP_IAP_disable()
{
ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
ISP_TRIG = 0x00;
EA = 1; /* 開(kāi)中斷 */
}
/* ================ 公用的觸發(fā)代碼 ==================== */
void ISPgoon()
{
ISP_IAP_enable(); /* 打開(kāi) ISP,IAP 功能 */
ISP_TRIG = 0x46; /* 觸發(fā)ISP_IAP命令字節(jié)1 */
ISP_TRIG = 0xb9; /* 觸發(fā)ISP_IAP命令字節(jié)2 */
_nop_();
}
/* ==================== 字節(jié)讀 ======================== */
uchar byte_read(uint byte_addr)
{
ISP_ADDRH = (uchar)(byte_addr >> 8);/* 地址賦值 */
ISP_ADDRL = (uchar)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */
ISP_CMD = ISP_CMD | RdCommand; /* 寫(xiě)入讀命令 */
ISPgoon(); /* 觸發(fā)執(zhí)行 */
ISP_IAP_disable(); /* 關(guān)閉ISP,IAP功能 */
return (ISP_DATA); /* 返回讀到的數(shù)據(jù) */
}
/* ================== 扇區(qū)擦除 ======================== */
void SectorErase(uint sector_addr)
{
uint iSectorAddr;
iSectorAddr = (sector_addr & 0xfe00); /* 取扇區(qū)地址 */
ISP_ADDRH = (uchar)(iSectorAddr >> 8);
ISP_ADDRL = 0x00;
ISP_CMD = ISP_CMD & 0xf8; /* 清空低3位 */
ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3 */
ISPgoon(); /* 觸發(fā)執(zhí)行 */
ISP_IAP_disable(); /* 關(guān)閉ISP,IAP功能 */
}
/* ==================== 字節(jié)寫(xiě) ======================== */
void byte_write(uint byte_addr, uchar original_data)
{
ISP_ADDRH = (uchar)(byte_addr >> 8); /* 取地址 */
ISP_ADDRL = (uchar)(byte_addr & 0x00ff);
ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */
ISP_CMD = ISP_CMD | PrgCommand; /* 寫(xiě)命令2 */
ISP_DATA = original_data; /* 寫(xiě)入數(shù)據(jù)準(zhǔn)備 */
ISPgoon(); /* 觸發(fā)執(zhí)行 */
ISP_IAP_disable(); /* 關(guān)閉IAP功能 */
}
|
評(píng)分
-
查看全部評(píng)分
|