STC12C5204AD AD E2PROM GSM 混合充电项目
#include<reg52.h> #include<stdio.h> #include<intrins.h> #define uchar unsigned char #define uint unsigned int /* 串口中断函数 信息内容数组 */ volatile char EFlag = -1; typedef unsigned char byte; typedef unsigned int word; unsigned char buff[5]; void delay(uint xms); sbit DQ = P1^2; //DS18B20 byte TPH; //存放温度值的高字节 byte TPL; uint temp; //整型温度数据 float f_temp; //浮点型温度数据 /* G S M */ sbit GsmPin = P1^7; unsigned char RxData; /*AT+CNMI=2,1 短信提示*/ code unsigned char ICMD1[13] = {0x41 ,0x54 ,0x2B ,0x43 ,0x4E ,0x4D ,0x49 ,0x3D ,0x32 ,0x2C ,0x31 ,0x0D ,0x0A}; /*AT+CMGF=1 英文方式发送*/ code unsigned char ICMD2[11] = {0x41 ,0x54 ,0x2B ,0x43 ,0x4D ,0x47 ,0x46 ,0x3D ,0x31 ,0x0D ,0x0A}; /*AT+CMGD=1,4 短信删除*/ code unsigned char DCMD[13] = {0x41 ,0x54 ,0x2B ,0x43 ,0x4D ,0x47 ,0x44 ,0x3D ,0x31 ,0x2C ,0x34 ,0x0D ,0x0A}; /* 短信读取 */ code unsigned char RCMD1[8] = {0x41 , 0x54 , 0x2B , 0x43 , 0x4D , 0x47 , 0x52 , 0x3D}; unsigned char RCMD2[5] = {0xff, 0xff, 0xff, 0xff, 0xff}; // 改回000 code unsigned char RCMD3[2] = {0x0D, 0x0A}; volatile unsigned char MsgAddBegin = 0; volatile unsigned char MsgAddEnd = 0; volatile unsigned char MsgAddSvCur = 0; volatile unsigned char MsgAdd[5]; volatile unsigned char MsgContentSvCur = 0; volatile unsigned char MsgContentBegin = 0; volatile unsigned char MsgContentEnd = 0; volatile unsigned char MsgContent[10]; //volatile unsigned char MsgContent[240]; code unsigned char Yes[8] = {'o', 'p', 'e', 'n', '3', '6','9'}; code unsigned char No[8] = {'c', 'l', 'o', 's', 'e', '4', '2'}; volatile unsigned char HeadCur = 0; #define HeadCnt 3 code volatile unsigned char Head[HeadCnt + 1] = {0x2B , 0x43 , 0x4D, 0xff}; // +CM volatile unsigned char AddHeadCur = 0; #define AddHeadCnt 9 code volatile unsigned char AddHead[AddHeadCnt + 1] = {0x54 ,0x49 ,0x3A ,0x20 ,0x22 ,0x53 ,0x4D ,0x22 ,0x2C, 0xff}; //TI: "SM", volatile unsigned char AddTailCur = 0; #define AddTailCnt 2 code volatile unsigned char AddTail[AddTailCnt] = {0x0D, 0x0A}; volatile unsigned char ContentHeadCur = 0; #define ContentHeadCnt 2 code volatile unsigned char ContentHead[ContentHeadCnt + 1] = {0x47 ,0x52 ,0xff}; //GR: 0x47 ,0x52 ,0x3A ,0x20, 0xff volatile unsigned char QuotationMarkCnt = 0; // 8 /* U S A R T */ void initSCI(void) { SM0 = 0; /*Step 1 : 确定串口通信方式*/ SM1 = 1; TMOD = 0x20; /*step 2: 根据串口通信方式 确定是否设置波特率*/ TH1 = 0xfd; TL1 = 0xfd; TR1 = 1; /*step 3 :启动*/ REN = 1; EA = 1; /*step 4: 是否启用中断函数*/ ES = 1; delay(100); } void putChar (unsigned char chr)//发送一个字符 { SBUF = chr; while(!TI); delay(3); TI=0; delay(3); } void putStr(char *s) { while(*s) { putChar(*s++); } } /* D S 1 8 B 2 0 */ void DelayXus(byte n) { while (n--) { _nop_(); _nop_(); } } /************************************** 复位DS18B20,并检测设备是否存在 **************************************/ void DS18B20_Reset() { CY = 1; while (CY) { DQ = 0; //送出低电平复位信号 DelayXus(240); //延时至少480us DelayXus(240); DQ = 1; //释放数据线 DelayXus(60); //等待60us CY = DQ; //检测存在脉冲 DelayXus(240); //等待设备释放数据线 DelayXus(180); } } /************************************** 从DS18B20读1字节数据 **************************************/ byte DS18B20_ReadByte() { byte i; byte dat = 0; for (i=0; i<8; i++) //8位计数器 { dat >>= 1; DQ = 0; //开始时间片 DelayXus(1); //延时等待 DQ = 1; //准备接收 DelayXus(4); //接收延时 if (DQ) dat |= 0x80; //读取数据 DelayXus(56); //等待时间片结束 } return dat; } /************************************** 向DS18B20写1字节数据 **************************************/ void DS18B20_WriteByte(byte dat) { char i; for (i=0; i<8; i++) //8位计数器 { DQ = 0; //开始时间片 DelayXus(1); //延时等待 dat >>= 1; //送出数据 DQ = CY; DelayXus(60); //等待时间片结束 DQ = 1; //恢复数据线 DelayXus(1); //恢复延时 } } uint DS18B20_GetTemp() { DS18B20_Reset(); //设备复位 DS18B20_WriteByte(0xCC); //跳过ROM命令 DS18B20_WriteByte(0x44); //开始转换命令 while (!DQ); //等待转换完成 DS18B20_Reset(); //设备复位 DS18B20_WriteByte(0xCC); //跳过ROM命令 DS18B20_WriteByte(0xBE); //读暂存存储器命令 TPL = DS18B20_ReadByte(); //读温度低字节 TPH = DS18B20_ReadByte(); //读温度高字节 temp = TPH; temp <<= 8; temp = temp | TPL; f_temp = temp * 0.0625; f_temp = f_temp + 0.5; if(f_temp > 4000.0) f_temp -= 4096.437; temp = f_temp + 0.05; return temp; } /* e e p r o m */ /* 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 STC12C5201AD series EEPROM #define IAP_ADDRESS 0x0000 void IapIdle() { IAP_CONTR = 0; //close IAP function IAP_CMD = 0; //clear command to standby IAP_TRIG = 0; //clear tirgger register IAP_ADDRH = 0x80; //data ptr point to non EEPROM area IAP_ADDRL = 0; //clear IAP address to prevent mususe } /* read one byte from isp/iap/eeprom area input:addr(isp iap eeprom address) output:flash data */ byte IapReadByte(word addr) { byte dat; IAP_CONTR = ENABLE_IAP; //Open IAP function and set wait time IAP_CMD = CMD_READ; //Set ISAP READ command IAP_ADDRL = addr; //Set ISP address low IAP_ADDRH = addr >> 8; //Set IAP address high IAP_TRIG = 0x5a; //Send trigger command1(0x5a) IAP_TRIG = 0xa5; //Send trigger command2(0xa5) _nop_(); //MCU will hold here until IAP operation complete dat = IAP_DATA; //Read IAP EEPROM data IapIdle(); //Close ISP function return dat; //Return Flash data } /* Program one byte to ISP area Input:addr (address) dat(data) Output:- */ void IapProgramByte(word addr, byte dat) { IAP_CONTR = ENABLE_IAP; //Open IAP function, and set wait time IAP_CMD = CMD_PROGRAM; //Set EEPROM PROGRAM command IAP_ADDRL = addr; IAP_ADDRH = addr >> 8; IAP_DATA = dat; IAP_TRIG = 0x5a; IAP_TRIG = 0xa5; _nop_(); IapIdle(); } /* Erase one sector area Input:addr */ void IapEraseSector(word addr) { IAP_CONTR = ENABLE_IAP; IAP_CMD = CMD_ERASE; IAP_ADDRL = addr; IAP_ADDRH = addr >> 8; IAP_TRIG = 0x5a; IAP_TRIG = 0xa5; _nop_(); IapIdle(); } unsigned char ReadE2Prom() { if(IapReadByte(IAP_ADDRESS) == 0xff) { IapEraseSector(IAP_ADDRESS); IapProgramByte(IAP_ADDRESS, 0x01); return 1; } if(IapReadByte(IAP_ADDRESS) == 0x01) { return 1; } return 0; } /* g s m */ void MsgRemindInit() //GSM模块来信提醒 { unsigned char i; for(i = 0; i < 13; ++i) { putChar( ICMD1[i] ); delay(10); } delay(100); for(i = 0; i < 11; ++i) { putChar( ICMD2[i] ); delay(10); } delay(100); delay(100); } unsigned char CheckMSG() { unsigned char i, Yctr = 0, Nctr = 0; for(i = 0; i < 7; ++i) { if(MsgContent[i] == Yes[i]) Yctr++; if(MsgContent[i] == No[i]) Nctr++; } if(Yctr >= 7) { EFlag = 1; while(ReadE2Prom() != 1) { IapEraseSector(IAP_ADDRESS); IapProgramByte(IAP_ADDRESS, 0x01); delay(300); } return 1; } else if(Nctr >= 7) { EFlag = 0; while(ReadE2Prom() != 0) { IapEraseSector(IAP_ADDRESS); IapProgramByte(IAP_ADDRESS, 0x00); delay(300); } return 0; } else { return 0; } } unsigned char ReadMSG() { unsigned char i; if (MsgAddEnd == 0) { delay(100); return 0; } for(i = 0; i < 5; ++i) { RCMD2[i] = MsgAdd[i]; if(MsgAdd[i] == 0xff) break; } MsgAddEnd = 0; for(i = 0; i < 5; ++i) MsgAdd[i] = 0xff; /*tx*/ for(i = 0; i < 8; ++i) { putChar( RCMD1[i] ); delay(10); } for(i = 0; i < 5; ++i) { if(RCMD2[i] != 0xff) { if(RCMD2[i] == 0x00) break; putChar( RCMD2[i] ); delay(10); } else break; } for(i = 0; i < 2; ++i) { putChar( RCMD3[i] ); delay(10); } /*waiting for msg content*/ while(MsgContentEnd == 0) delay(10); delay(100); MsgContentEnd = 0; /*删除短信*/ for(i = 0; i < 13; ++i) { putChar( DCMD[i] ); delay(10); } return CheckMSG(); // if(MsgContent[0] == '1') // { // EFlag = 1; // while(ReadE2Prom() != 1) // { // IapEraseSector(IAP_ADDRESS); // IapProgramByte(IAP_ADDRESS, 0x01); // delay(300); // } // return 1; // } // else if(MsgContent[0] == '0') // { // EFlag = 0; // while(ReadE2Prom() != 0) // { // IapEraseSector(IAP_ADDRESS); // IapProgramByte(IAP_ADDRESS, 0x00); // delay(300); // } // return 0; // } // else // { // return 0; // } } void ser() interrupt 4 //串口中断 { if( RI ) { RI = 0; RxData = SBUF; if(MsgAddBegin == 1) { if(RxData == 0x0D) { MsgAddEnd = 1; MsgAddBegin = 0; HeadCur = 0; AddHeadCur = 0; MsgAddSvCur = 0; return; } MsgAdd[MsgAddSvCur] = RxData; MsgAddSvCur++; return; } if(MsgContentBegin == 1) { if(RxData == 0x0D) { MsgContentEnd = 1; MsgContentBegin = 0; HeadCur = 0; ContentHeadCur = 0; MsgContentSvCur = 0; QuotationMarkCnt = 0; return; } MsgContent[MsgContentSvCur] = RxData; MsgContentSvCur++; return; } if(RxData == Head[HeadCur]) HeadCur++; else { if(HeadCur == HeadCnt) { if(RxData == AddHead[AddHeadCur]) AddHeadCur++; if(RxData == ContentHead[ContentHeadCur]) ContentHeadCur++; if(ContentHeadCur == ContentHeadCnt) { if(RxData == 0x22) QuotationMarkCnt++ ; if(QuotationMarkCnt == 8) { if(RxData == 0x0A) { MsgContentBegin = 1; MsgContentSvCur = 0; } } return; } else if(AddHeadCur == AddHeadCnt) { MsgAddBegin = 1; MsgAddSvCur = 0; return ; } } else HeadCur = 0; } } else if( TI ) { TI = 0; } return ; } void GSMCtrl() { if(ReadMSG() == 1 || EFlag == 1) { //putStr("\r\n GSM = 1"); GsmPin = 1; } else { GsmPin = 0; } } /* A D */ sfr ADC_CONTR = 0xBC; //ADC control register sfr ADC_RES = 0xBD; //ADC high 8-bit result register sfr ADC_LOW2 = 0xBE; //ADC low 2-bit result register sfr P1ASF = 0x9D; //P1 secondary function control register /* Define ADC operation const for ADC_CONTER */ #define ADC_POWER 0x80 //ADC power control bit #define ADC_FLAG 0x10 //ADC complete flag #define ADC_START 0x08 //ADC start control bit #define ADC_SPEEDLL 0x00 //420 clocks #define ADC_SPEEDL 0x20 //280 clocks #define ADC_SPEEDH 0x40 //140 clocks #define ADC_SPEEDHH 0x60 //70 clocks #define VEFF 6 #define VREF 5 unsigned char ADC_ch = 5; volatile int Veff, Vref; void Ddelay(word n) { word x; while (n--) { x = 5000; while (x--); } } void initADC() { P1ASF = 0x00 + (1 << VEFF) + (1 << VREF); //Set All P1 as analog input port ADC_RES = 0; //Clear previous result ADC_CONTR = ADC_POWER | ADC_SPEEDLL; Ddelay(2); } byte GetADCResult(byte ch) { ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START; _nop_(); //Must wait before inquiry _nop_(); _nop_(); _nop_(); while (!(ADC_CONTR & ADC_FLAG));//Wait complete flag ADC_CONTR &= ~ADC_FLAG; //Close ADC return ADC_RES; //Return ADC result } //void ShowResult(byte ch) //{ // putChar(ch); //Show Channel NO. // putChar(GetADCResult(ch)); //Show ADC high 8-bit result //} /* C o n t r o l P r o g r a m*/ /* Contral Val */ sbit CHARGE = P1^0; sbit DISCHARGE = P1^1; volatile int Voltage = 0; volatile int Temperature = 0; volatile int UnderV = 116, OverV = 144; int T_20 = -20, T_10 = -10, T45 = 50, T60 = 60; void GetPara() { Vref = GetADCResult(5); Veff = GetADCResult(6); Voltage = Veff; Voltage *= 25; Voltage /= Vref; Voltage = Voltage * 4; // putStr("\r\n VVV5 = "); // sprintf(buff,"%d",Vref); // putStr(buff); // // putStr("\r\n VVV6 = "); // sprintf(buff,"%d",Veff); // putStr(buff); DS18B20_GetTemp(); Temperature = f_temp + 0.05; // putStr("\r\nTemp = "); // sprintf(buff,"%d",Temperature); // putStr(buff); return; } void ChargeDischarge(unsigned char Charge, unsigned char Discharge) { CHARGE = Charge; DISCHARGE = Discharge; // putStr("\r\n Charge = "); // putChar(Charge + '0'); // putStr(" Disharge = "); // putChar(Discharge + '0'); //cout << (Charge ? "充电 " : "不充电 ") << (Discharge ? "放电" : "不放电") << endl; } void Changemode() { int V = Voltage; // putStr("\r\nVoltage = "); // sprintf(buff,"%d",V); // putStr(buff); // // putStr("\r\nTemperature = "); // sprintf(buff,"%d",Temperature); // putStr(buff); if(V < UnderV) { UnderV = 124; //UnderV = UnderV + 2; if(Temperature > T_10 && Temperature < T45) ChargeDischarge(1, 0); else ChargeDischarge(0, 0); } else if(V >= UnderV && V < OverV) { UnderV = 116; OverV = 144; //cout << "电压" << V << "温度" << Temperature << endl; if(Temperature < T_20) ChargeDischarge(0, 0); else if(Temperature > T_20 && Temperature < T_10) ChargeDischarge(0, 1); else if(Temperature >= T_10 && Temperature < T45) ChargeDischarge(1, 1); else if(Temperature >= T45 && Temperature < T60) ChargeDischarge(0, 1); else if(Temperature >= T60) ChargeDischarge(0, 0); } else if(V >= OverV) { UnderV = 116; OverV = 136; if(Temperature > T_20 && Temperature < T60) ChargeDischarge(0, 1); else ChargeDischarge(0, 0); } } void main() { unsigned char i; initSCI(); //串口初始化 for(i = 0; i < 100; ++i) delay(1000); // for(i = 0; i < 100; ++i) delay(1000); MsgRemindInit(); //GSM初始化 initADC(); // AD转换初始化 P0 = 0x00; while(EFlag == -1) EFlag = ReadE2Prom(); while (1) { delay(500); GetPara(); // 更新电压 及 温度参数 Changemode(); // 模式转换 GSMCtrl(); // GSM P1.7控制 } } void delay(uint xms) // 延时函数 { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); }