- #include <reg52.h>
- #include <intrins.h>
- typedef unsigned char BYTE;
- typedef unsigned int WORD;
- //unsigned char table[8]={0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55};
- /*Declare SFR associated with the IAP */
- sfr IAP_DATA = 0xC2; //Flash data register
- sfr IAP_ADDRH = 0xC3; //Flash address HIGH
- sfr IAP_ADDRL = 0xC4; //Flash address LOW
- sfr IAP_CMD = 0xC5; //Flash command register
- sfr IAP_TRIG = 0xC6; //Flash command trigger
- sfr IAP_CONTR = 0xC7; //Flash control register
- /*Define ISP/IAP/EEPROM command*/
- #define CMD_IDLE 0 //Stand-By
- #define CMD_READ 1 //Byte-Read
- #define CMD_PROGRAM 2 //Byte-Program
- #define CMD_ERASE 3 //Sector-Erase
- /*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
- //#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
- //#define ENABLE_IAP 0x81 //if SYSCLK<24MHz
- //#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
- #define ENABLE_IAP 0x83 //if SYSCLK<12MHz
- //#define ENABLE_IAP 0x84 //if SYSCLK<6MHz
- //#define ENABLE_IAP 0x85 //if SYSCLK<3MHz
- //#define ENABLE_IAP 0x86 //if SYSCLK<2MHz
- //#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
- //Start address for STC12C5A60S2 series EEPROM
- #define IAP_ADDRESS 0x2000
- void Delay(BYTE n);
- void IapIdle();
- BYTE IapReadByte(WORD addr);
- void IapProgramByte(WORD addr, BYTE dat);
- void IapEraseSector(WORD addr);
- /*
- WORD i;
- void Delay(BYTE n)
- {
- WORD x;
- while (n--)
- {
- x = 0;
- while (++x);
- }
- }*/
- unsigned char RunMode;
- //**********************************System Fuction*************************************************
- void Delay1ms(unsigned int count)
- {
- unsigned int i,j;
- for(i=0;i<count;i++)
- for(j=0;j<120;j++);
- }
- unsigned char GetKey(void)
- {
- unsigned char KeyTemp,CheckValue,Key = 0x00;
- CheckValue = P3&0x32;
- if(CheckValue==0x32)
- return 0x00;
- Delay1ms(10);
- KeyTemp = P3&0x32;
- if(KeyTemp==CheckValue)
- return 0x00;
-
- if(!(CheckValue&0x02))
- Key|=0x01;
- if(!(CheckValue&0x10))
- Key|=0x02;
- if(!(CheckValue&0x20))
- Key|=0x04;
- return Key;
- }
- unsigned int TimerCount,SystemSpeed,SystemSpeedIndex;
- void InitialTimer2(void)
- {
- TMOD=0X01;
- TH0=(65536-5000)/256;
- TL0=(65536-5000)%256;
- ET0=1;
- TR0=1;
- EA=1;
- }
- unsigned int code SpeedCode[]={5, 8, 10, 14, 17, 20, 30,
- 40, 50, 60, 70, 80, 90, 100, 120, 140, 160,
- 180, 200, 300, 400, 500, 600, 700, 800, 900,1000};//27
- void SetSpeed(unsigned char Speed)
- {
- SystemSpeed =SpeedCode[Speed];
- }
- void LEDShow(unsigned int LEDStatus)
- {
- P1 = ~(LEDStatus&0xff);
- }
- void InitialCPU(void)
- {
- RunMode = 0x00;
- TimerCount = 0;
- SystemSpeedIndex =10;
- P3 = 0xff;
- Delay1ms(500);
- P1 = 0xFF;
- P3 = 0xFF;
- SetSpeed(SystemSpeedIndex);
- }
- //Mode 0
- unsigned int LEDIndex = 0;
- bit LEDDirection = 1,LEDFlag = 1;
- void Mode_0(void)
- {
- LEDShow(0x01<<LEDIndex);
- LEDIndex = (LEDIndex+1)%8;
- }
- //Mode 1
- void Mode_1(void)
- {
- LEDShow(0x80>>LEDIndex);
- LEDIndex = (LEDIndex+1)%8;
- }
- //Mode 2
- void Mode_2(void)
- {
- if(LEDDirection)
- LEDShow(0x01<<LEDIndex);
- else
- LEDShow(0x80>>LEDIndex);
- if(LEDIndex==7)
- LEDDirection = !LEDDirection;
- LEDIndex = (LEDIndex+1)%8;
- }
- //Mode 3
- void Mode_3(void)
- {
- if(LEDDirection)
- LEDShow(~(0xff<<LEDIndex));
- /*else
- LEDShow(~(0x80>>LEDIndex));*/
- if(LEDIndex==8)
- LEDDirection = !LEDDirection;
- LEDIndex = (LEDIndex+1)%9;
- }
- void TimerEventRun(void)
- {
- if(RunMode==0x00)
- {
- Mode_0();
- }
- else if(RunMode ==0x01)
- {
- Mode_1();
- }
- else if(RunMode ==0x02)
- {
- Mode_2();
- }
- else if(RunMode ==0x03)
- {
- Mode_3();
- }
- }
- void Timer2(void) interrupt 1 using 1
- {
- TF0 = 0; //中斷標志清除( Timer2 必須軟件清標志!)
- TH0=(65536-2500)/256;
- TL0=(65536-2500)%256;
- if(++TimerCount>=SystemSpeed)
- {
- TimerCount = 0;
- TimerEventRun();
- }
- }
- unsigned char MusicIndex = 0;
- void KeyDispose(unsigned char Key)
- {
- // WORD i;
- if(Key&0x01)
- {
- LEDDirection = 1;
- LEDIndex = 0;
- //LEDFlag = 1;
- RunMode = (RunMode+1)%4;
- }
- if(Key&0x02)
- {
- if(SystemSpeedIndex>0)
- {
- --SystemSpeedIndex;
- SetSpeed(SystemSpeedIndex);
- }
- }
- if(Key&0x04)
- {
- if(SystemSpeedIndex<26)
- {
- ++SystemSpeedIndex;
- SetSpeed(SystemSpeedIndex);
- }
- }
- }
- //***********************************************************************************
- void main()
- {
- unsigned char Key,Key1;
- InitialCPU();
- InitialTimer2();
- Key1=IapReadByte(IAP_ADDRESS);
- while(1)
- {
- Key = GetKey();
- if(Key!=0x00 && Key!=Key1)
- {
- Key1=Key;
- IapEraseSector(IAP_ADDRESS);
- IapProgramByte(IAP_ADDRESS, Key1);
- }
- if(Key!=0x00)
- {
- KeyDispose(Key);
- }
- }
- }
- void IapIdle()//關閉ISP,IAP功能
- {
- IAP_CONTR = 0; //Close IAP function
- IAP_CMD = 0; //Clear command to standby
- IAP_TRIG = 0; //Clear trigger register
- IAP_ADDRH = 0x80; //Data ptr point to non-EEPROM area
- IAP_ADDRL = 0; //Clear IAP address to prevent misuse
- }
- /*----------------------------Read one byte from ISP/IAP/EEPROM area
- Input: addr (ISP/IAP/EEPROM address)
- Output:Flash data
- ----------------------------*/
- BYTE IapReadByte(WORD addr)//讀字節
- {
- BYTE dat; //Data buffer
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
- IAP_CMD = CMD_READ; //Set ISP/IAP/EEPROM READ command
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
- IAP_TRIG = 0x46; //Send trigger command1 (0x5a)
- IAP_TRIG = 0xb9; //Send trigger command2 (0xa5)
- _nop_(); //MCU will hold here until ISP/IAP/EEPROM
- //operation complete
- dat = IAP_DATA; //Read ISP/IAP/EEPROM data
- IapIdle(); //Close ISP/IAP/EEPROM function
- return dat; //Return Flash data
- }
- /*----------------------------Program one byte to ISP/IAP/EEPROM area
- Input: addr (ISP/IAP/EEPROM address)
- dat (ISP/IAP/EEPROM data)
- Output:-----------------------------*/
- void IapProgramByte(WORD addr, BYTE dat)//寫字節
- {
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
- IAP_CMD = CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM command
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
- IAP_DATA = dat; //Write ISP/IAP/EEPROM data
- IAP_TRIG = 0x46; //Send trigger command1 (0x5a)
- IAP_TRIG = 0xb9; //Send trigger command2 (0xa5)
- _nop_(); //MCU will hold here until ISP/IAP/EEPROM
- //operation complete
- IapIdle();
- }
- /*----------------------------Erase one sector area
- Input: addr (ISP/IAP/EEPROM address)
- Output:-----------------------------*/
- void IapEraseSector(WORD addr)//擦除扇區
- {
- IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time
- IAP_CMD = CMD_ERASE; //Set ISP/IAP/EEPROM ERASE command
- IAP_ADDRL = addr; //Set ISP/IAP/EEPROM address low
- IAP_ADDRH = addr >> 8; //Set ISP/IAP/EEPROM address high
- IAP_TRIG = 0x46; //Send trigger command1 (0x5a)
- IAP_TRIG = 0xb9; //Send trigger command2 (0xa5)
- _nop_(); //MCU will hold here until ISP/IAP/EEPROM
- //operation complete
- IapIdle();
- }
復制代碼 |