久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11438|回復: 8
收起左側

STM32之智能家居

[復制鏈接]
ID:51024 發表于 2014-8-3 01:07 | 顯示全部樓層 |閱讀模式


#include "stm32f10x.h"
#include "usart.h"
#include "rtc.h"
#include "IO.h"
#include "ds18b20.h"
#include "adc.h"
#include "exti.h"
#include "timer.h"
//#include "uart2.h"
#include "control.h"
#define Phz (u32)3*Pmax        //功率頻率值上限實際為3*Pmax/100;為了減少誤差,放大100倍 此計算為500微歐采樣電阻值
#define USART_IAP_LEN          10*1024+3 //定義最大接收字節數 10K+3字節        固件更新分3次接收
//IO方向設置
//#define DS18B20_IO_IN()  {GPIOB->CRL&=0XFFFFFF0F;GPIOB->CRL|=0x00000080;}        //PB1 CRL控制的是低8位 CRH控制的是高8位
//#define DS18B20_IO_OUT() {GPIOB->CRL&=0XFFFFFF0F;GPIOB->CRL|=0x00000030;}
//////////////////////////////////////////////////////////////////////////////////         
//XXXX智能插座主程序
//author:WEN BO RUI        (WEN K)
//Q:406650447
//修改日期:2014/5/16
//版本:V1.0
//Copyright(C) 沈陽XXXX公司 2014-2024
//All rights reserved         
//////////////////////////////////////////////////////////////////////////////////
//u8 USART1_RX_BUF[USART_IAP_LEN] __attribute__ ((at(0X20001000)));//接收緩沖,最大USART_IAP_LEN個字節,起始地址為0X20001000.
u8  USART1_RX_BUF[USART_IAP_LEN]; //串口1數據接收緩沖字節
u8  rtcbuffer[8]={0};        //實時時鐘數組
u16        flashBUF[512];          //定義FLASH存儲參數緩存;共512*2=1024個字節,1K字節存儲。因為STM32內部FLASH存取為半字(u16)讀寫,參數為功率和定時組合
u8  Param[204];        //204定義一個8位的參數數組,用于讀取、寫入參數到FLASH的轉化;
u8 TEMPBUF[206];        //臨時緩沖區數組
u8  T50F=0,T1000F=0,VDIF=0; //定時器T3定時100毫秒和1秒標志位,語音按鍵標志位
u8 t3count=0;        //T3定時器計數器
u8 SREF=0,NREFLAG=0,GettimeF=0;        //SREF串口接收服務器數據標志位;NREFLAG為恢復出廠狀態標志位;GettimeF校時功能位
u8 overload = 0;          //overload過載標志位,當等于1時表示過載,斷繼電器電源
u8 CRCF,HELLOF =0;;        //數據累加和
u32 PSUM;        //累積功率
u32 Pmax;        //最大使用功率設置上限
u32 Pvio;        //用于語音播放時時功率轉換
u16 ADCValue;
u16 j1=0,pj=0;
u16 m,n;
u16 flashCN;
//u16 aplen1,iaplen2,iaplen3;   //三段IAP長度
float ADtemp,ADJDQ;        //檢測繼電器狀態變量
u8 TEMH,TEML,TEM,V5H,V5L;        //溫度 電壓檢測值

struct  
{
vu8 powstaF;                 //開關狀態位,增加此變量可以用于服務器對繼電器狀態查詢時返回開關狀態,開關工作方式(off auto on)
vu8 runF;
vu8 pv1;                 //u8 pv1,pv2,pv3,pv4;        //32位的功率變為4個8位的
vu8 pv2;
vu8 pv3;
vu8 pv4;
//        vu8 yearTH;          //上次清零功率時的時間
//        vu8 yearTL;        
//        vu8 monT;          //        
//        vu8 dateT;        
//        vu8 hourT;        
//        vu8 minT;
//        vu8 secT;
//        vu8 timT;        //時區         
}sta;
struct  
{
u8 Time1;u8 Time2;u8 Time3;u8 Time4;
u8 Time5;u8 Time6;u8 Time7;u8 Time8;         
}work;          //定時操作結構體
void COM1SEND (u8 com1)
{
USART_SendData(USART1,com1);
while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);        
}
void send1()
{
COM1SEND(0x1e);
COM1SEND(0xba);
COM1SEND(0x00);
COM1SEND(0x00);
COM1SEND(CRCF);        
}
//向串口發送一個字符串,strlen為該字符串長度
//void send_string_com1(u8 *str,u8 strlen)
//{
//    u8 k=0;
//    for(k=0;k<strlen;k++)
//        {
//        COM1SEND(*(str + k));
//        }
//}
//CRC8校驗函數
#define POLY 0xB2
unsigned crc8_slow(unsigned crc, unsigned char *data, size_t len)
{
    unsigned char *end;

    if (len == 0)
        return crc;
    crc ^= 0xff;
    end = data + len;
    do {
        crc ^= *data++;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
    } while (data < end);
    return crc ^ 0xff;
}
void HELLO(void)                 //WIFI上電準備完成后發送消息給服務器
{
u8 i;
u8 inbuf1[32]={"hahahahahahahahahahahahahah00000"};        
CRCF = 0;
TEMPBUF[0] = 0x24;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa1;
for(i=3;i<35;i++)
    {
             TEMPBUF=inbuf1[i-3];
    }
TEMPBUF[35] = 0x00;
TEMPBUF[36] = 0x10;
TEMPBUF[37] = 0x00;
TEMPBUF[38] = 0x11;
CRCF=crc8_slow(CRCF,TEMPBUF,39);
send1();        //發送1e ba 00 00  crc
for(i=0;i<39;i++)
    {
             COM1SEND(TEMPBUF);
    }
CRCF = 0;        
}
void IDEL(void)                 //WIFI每分鐘發送一次給服務器,防止鏈接斷開
{
u8 i;
u8 idel1[7]  = {0x04,0x00,0xa2,0x00,0x00,0x00,0x00}; //鏈接數據        
CRCF = 0;
CRCF=crc8_slow(CRCF,idel1,7);        //CRC8校驗
send1();
for(i=0;i<7;i++)
{
COM1SEND (idel1);
}        
}
void SHUTDOWN(void)                 //發送斷電信息給服務器
{
u8 i;
u8 shut1[7]  = {0x04,0x00,0xa3,0x00,0x00,0x00,0x00};          //斷電數據        
CRCF = 0;
CRCF=crc8_slow(CRCF,shut1,7);        //CRC8校驗
send1();
for(i=0;i<7;i++)        
{
COM1SEND (shut1);
}        
}
//*********************************************
//函數名: ONE_LINE(U16 COM_data)  
//功能說明:發送一個一線串口命令
//入口參數:COM_data 為語音地址或者命令
//出口參數:無
//*********************************************
void ONE_LINE(u16 COM_data)
{
u8    i;
u8    high_data; //高八位
u8    low_data;          //低八位
low_data        =   COM_data &0x00ff;
high_data          =  (COM_data>>8) & 0x00ff;
//while(!BUSY)        //判斷非忙,再發地址數據
{
DATA = 0;
delay_ms(5);                          //拉低數據線5毫秒
for(i=0;i<8;i++)                    //發送高八位
{
if(high_data &0x80)             //數據位為 1
{
DATA = 1;
delay_us(600);              //延時 600us
DATA = 0;
delay_us(200);              //延時 200us
}
else                            //數據位為 0
{
DATA = 1;                       
delay_us(200);              //延時 200us
DATA = 0;
delay_us(600);              //延時 600us
}
high_data <<=1;              //循環左移一位
}
for(i=0;i<8;i++)                    //發送低八位
{
if(low_data &0x80)              //數據位為 1
{
DATA = 1;
delay_us(600);                  //延時 600us
DATA = 0;
delay_us(200);                  //延時 200us
}
else                            //數據位為 0
{
DATA = 1;
delay_us(200);              //延時 200us
DATA = 0;
delay_us(600);                  //延時 600us
}
low_data <<=1;        //循環左移一位
}
DATA =1;
}
}
//*************寫參數到內部FLASH函數**************/
void FLASHWR()
{
u8 i,j = 0;
for(i=0;i<193;i+=2)        //串口接收的數據存入16位的數組,準備寫入FLASH
{
flashBUF[j] = ((Param&&0xff)<<8)+Param[i+1];        
j++;
}
j = 0;
flashBUF[101] = PSUM;          //當前功率累加值送入FLASH緩存,準備保存        小端在前
flashBUF[102] = PSUM>>16;                 //當前功率累加值送入FLASH緩存,準備保存        
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(0x800fc00);          //先擦后寫,FLASH存參數地址為從0x800fc00開始的1K字節;
for(flashCN=0;flashCN<128;flashCN++)          //256字節數據         
{
FLASH_ProgramHalfWord((0x800fc00 +flashCN*2),flashBUF[flashCN]);          //flash  為一個字節存儲,16位數據必須地址加2
}
FLASH_Lock();
}
//**************返回服務器全部參數設置狀態函數*********************/
void STAall()
{
u8 i;
TEMPBUF[0]  = 0xcb;
TEMPBUF[1]  = 0x00;
TEMPBUF[2]  = 0xa4;
TEMPBUF[3]  = 0xff;
TEMPBUF[4]  = 0xff;
TEMPBUF[5]  = sta.powstaF;        //開關狀態位
TEMPBUF[6]  = sta.runF;        //運行方式位
TEMPBUF[7]  = Param[10];        //虛擬值
TEMPBUF[8]  = Param[4];        //限制使用功率上限值
TEMPBUF[9]  = Param[5];
TEMPBUF[10] = Param[6];
TEMPBUF[11] = Param[7];
TEMPBUF[12] = PSUM;                 //數據封裝小端模式,低位在前
TEMPBUF[13] = PSUM>>8;
TEMPBUF[14] = PSUM>>16;
TEMPBUF[15] = PSUM>>24;
TEMPBUF[16] = Param[193];        //上次功率清零時間
TEMPBUF[17] = Param[194];
TEMPBUF[18] = Param[195];
TEMPBUF[19] = Param[196];
TEMPBUF[20] = Param[197];
TEMPBUF[21] = Param[198];
TEMPBUF[22] = Param[199];
for(i=11;i<193;i++)        //本次設定值返回
{
TEMPBUF[i+12] = Param;        
}
TEMPBUF[205] = Param[8];        //最后一個字節聲音提示與否
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,206); //CRC8校驗
send1();        //
for(i=0;i<206;i++)        //本次設定值返回
{
COM1SEND(TEMPBUF);        
}        
CRCF = 0;
}
//**************軟復位程序,用于固件更新重啟單片機**********************/
void SoftReset(void) //軟復位程序
{  
__set_FAULTMASK(1);              // 關閉所有中端
         NVIC_SystemReset();        // 復位        以上兩個函數位于 core_cm3.h 文件中
}
//********************主函數開始**********************/
int main(void)
{
//u8 inbuf1[10]={"opencloner"};
//u8 inbuf1[22]={"感謝使用XXXX智能插座\n"};
u8 i,j,Tchange,WifiF;        
u8 FproV=0x78; //掉電時FLASH 寫保護標識,防止多次寫入
u8 FproT=0x78; //每天時間到了寫次Flash,寫保護標識,防止多次寫入
u16 COM1F;        //接收服務器數據狀態查詢字節
short TEM18B20;
u8 vdio[10];        //語音播報功率值時各個位置上的數值
//SCB->VTOR = FLASH_BASE | 0x1400; //使用IAP更新功能,        VTOR寄存器存放的是新的中斷向量表的起始地址復位從0x8001400開始
delay_init();                   //延時函數初始化
IO_Init();          //GPIO初始化
NVIC_Configuration(); //設置NVIC中斷分組2:2位搶占優先級,2位響應優先級
//uart2_Init(115200);                 //串口2初始化
RTC_Init();                 //RTC初始化
EXTIX_Init();          //外部中斷初始化
Adc_Init();          //ADC初始化
uart_init(115200);
DS18B20_Init();
TIM3_Init(249,7199);        //10Khz的計數頻率,計數到250為25ms   Tout= ((249+1)*( 7199+1))/72=25000us=25ms
//        RTC_Set(2014,6,10,10,36,10);        //測試用,實際代碼中要去掉
for(flashCN=0;flashCN<128;flashCN++) //上電后讀取參數
    {
         flashBUF[flashCN]= *(u16*)(0x800f800 + flashCN*2);   //讀取FLASH數據
    }
if(flashBUF[102] == 0xffff)                 //第一次上電讀出,累積置零
{
flashBUF[101] = 0;        
flashBUF[102] = 0;        
}
j = 0;
PSUM =(flashBUF[102]<<16)+flashBUF[101];        //累積功率送PSUM  小端在前(低位在前)
for(i=0;i<102;i++)
{
Param[j] = flashBUF>>8; //高8位在前
Param[j+1] = flashBUF;
j+=2;
}
j = 0;                 //清j
if((Param[7]==0xff)||(Param[6]==0xff)||(Param[5]==0xff))
{
//        Pmax = 1100;        //如果功率使用上限為0XFF。認為沒有設置,自動設置為默認為1100W(美國功率限制)
//        Pmax = 2200;        //自動設置為默認為2200W(中國功率限制)
Pmax = 2500;        //考慮用戶使用心理,設置可稍高些
Param[7] = 0;          //功率設定值送給對應數組,留保存
Param[6] = 0;
Param[5] = Pmax>>8;
Param[4] = Pmax;        //最低位在前
}
else
{
Pmax = (Param[7]<<24)+(Param[6]<<16)+(Param[5]<<8)+Param[4];//最大使用上限讀出來        
}
//        Pmax = 300;        //測試用,實際代碼中要去掉
//        Param[192]=0x08;        //測試用,實際代碼中要去掉
//        Param[131]=0x07;        //測試用,實際代碼中要去掉
//        Param[183]=0x06;        //測試用,實際代碼中要去掉
//        Param[11]=0x05;        //測試用,實際代碼中要去掉        
while(1)
{
//****************以下WiFi模塊初始化完成程序*****暫時可以不用,上電一直循環發送HELLO給服務器*****************************************
//        if((WifiRDY==0)&&(WifiF==0))        //WifiRDY為wifi模塊的READY引腳,接STM32 IO引腳 ,上拉輸入
//        {        //當為低電平時WIFI模塊上電正常
//        WifiF = 1;        //發送一次后不再發送
//        HELLO();        //發送給服務器進行握手,        
//        }
//        if(WifiRDY)        //WifiRDY=1表示高電平;表示WIFI模塊斷了;這時清WifiF,為了下一次握手
//        {
//        WifiF = 0;        //清WifiF        
//        }
//****************以下恢復出廠狀態處理程序*************************************************
if(NREFLAG)          //如果恢復出廠狀態標志位被置高了
{
NREFLAG = 0;
TEMPBUF[0] = 0x01;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa5;
TEMPBUF[3] = 0x03;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,4); //CRC8校驗
send1();        
for(i=0;i<4;i++)
{
COM1SEND(TEMPBUF);        //過載信息發給服務器
}
for(i=0;i<128;i++)        //將0xffff,準備寫入FLASH
{
flashBUF = 0xffff;        
}
flashBUF[101] = 0;        //功率參數直接清零        
flashBUF[102] = 0;        
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
FLASH_ErasePage(0x800fc00);          //先擦后寫,FLASH存參數起始地址
for(flashCN=0;flashCN<128;flashCN++)          //256字節數據         
{
FLASH_ProgramHalfWord((0x800fc00 +flashCN*2),flashBUF[flashCN]);          //flash  為一個字節存儲,16位數據必須地址加2
}
FLASH_Lock();
delay_ms(10);
for(flashCN=0;flashCN<128;flashCN++) //延時一段時間后讀取參數
    {
         flashBUF[flashCN]= *(u16*)(0x800f800 + flashCN*2);   //讀取FLASH數據
    }        
j = 0;
for(i=0;i<102;i++)
{
Param[j] = flashBUF>>8; //高8位在前
Param[j+1] = flashBUF;
j+=2;
}
j = 0;                 
}
//****************以下接收服務器指令處理程序***********************************************
switch(SREF)
{
case 0xB1:                 //SERVER_WELCOME 服務器歡迎數據 當前固定為 "opencloner"+時間
{
SREF = 0;        //暫無內容返回(PLUG主動發HELLO給服務器,服務器返回這個數據包,PLUG不在發送數據)
HELLOF = 1;                 //服務器收到插座的HELLO,返回相應值,職位HELLOF,插座不再發HELLO函數
STAall(); //返回所有狀態
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
break;
case 0xB2:                 //SERVER_INQUIRY狀態查詢(PLUG收到查詢請求后需要根據數據位標識碼返回PLUG_STATUS)
{
SREF = 0;
COM1F = (USART1_RX_BUF[3]<<8)+USART1_RX_BUF[2];          //兩個字節的Mask標志位,低位在前高位在后;如0x01;接收的位01,00
switch(COM1F)
{
case 0xffff:        //所有狀態查詢 (已OK)
{
STAall(); //返回所有狀態
}break;        
case 0x01:        //開關狀態查詢,開還是關(已OK)
{
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x01;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = sta.powstaF;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x02:        //開關運行方式查詢,一直開。自動,一直關
{
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x02;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = sta.runF;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x03:        //開關狀態和運行方式查詢,一直開。自動,一直關(已OK)
{
TEMPBUF[0] = 0x04;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x03;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = sta.powstaF;
TEMPBUF[6] = sta.runF;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,7); //CRC8校驗
send1();
for(i=0;i<7;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x04:        //虛擬設定值        (已OK)
{
  //位于flashBUF[5]的高8位--->Param[10]
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x04;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = Param[10];
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x08:          //限制功率上限值 (具體值及相應功能程序未完成)
{
TEMPBUF[0] = 0x06;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x08;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = Param[4];
TEMPBUF[6] = Param[5];
TEMPBUF[7] = Param[6];
TEMPBUF[8] = Param[7];
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,9); //CRC8校驗
send1();        
for(i=0;i<9;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x10:          //當前累積電量查詢        (已OK)
{
TEMPBUF[0] = 0x06;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x10;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = PSUM;
TEMPBUF[6] = PSUM>>8;
TEMPBUF[7] = PSUM>>16;
TEMPBUF[8] = PSUM>>24;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,9); //CRC8校驗        需加上數據長度兩字節和標志位1字節
send1();
for(i=0;i<9;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x20:        //定時數據狀態        (具體值及相應功能程序也已經完成)
{        
TEMPBUF[0] = 0x7b;        //123個字節
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x20;
TEMPBUF[4] = 0x00;
for(i=11;i<132;i++)        //定時數據從Param[11]到Param[131]
{
TEMPBUF[i-6]=        Param;
}
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,126); //CRC8校驗需加上數據長度兩字節和標志位1字節
send1();        
for(i=0;i<126;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x40:                 //溫度設定狀態返回是否有效位+溫控數據 (已OK)
{
TEMPBUF[0] = 0x33;        //51個字節
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x40;
TEMPBUF[4] = 0x00;
for(i=132;i<184;i++)        //定時數據從Param[11]到Param[131]
{
TEMPBUF[i-127]=        Param;
}
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,54); //CRC8校驗 需加上數據長度兩字節和標志位1字節
send1();        
for(i=0;i<54;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x80:                 //???沒明白是什么意思時間設定有效否,返回是否有效位
{
//位于flashBUF[92]的高8位字節--->Param[184] 暫定時區設定
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x80;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = Param[184];
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x100:                 //聲音設定有效否 (已完成)
{
//位于flashBUF[4]的高8位字節--->Param[8]
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x00;
TEMPBUF[4] = 0x10;
TEMPBUF[5] = Param[8];
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;
case 0x200:                 //是否時間自動校正
{
//時間自動校正位于flashBUF[97]的高8位字節--->Param[192]
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x00;
TEMPBUF[4] = 0x20;
TEMPBUF[5] = Param[192];
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}break;        
}
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
break;
case 0xB3:        //SERVER_SWITCH(服務器發送此指令進行開關操作, plug收到后返回PLUG_STATUS(數據位mask=01))
{
SREF = 0;
if(USART1_RX_BUF[2]==1)
{
sta.powstaF = 1;        //繼電器狀態查詢時返回開關狀態 1表示吸合 0斷開
AUTO = 1;                 //開繼電器
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x01;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = sta.powstaF;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}
if(!USART1_RX_BUF[2])
{
sta.powstaF = 0;        //繼電器狀態查詢時返回開關狀態 1表示吸合 0斷開
AUTO =0;        //關繼電器
TEMPBUF[0] = 0x03;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa4;
TEMPBUF[3] = 0x01;
TEMPBUF[4] = 0x00;
TEMPBUF[5] = sta.powstaF;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,6); //CRC8校驗
send1();        
for(i=0;i<6;i++)
{
COM1SEND(TEMPBUF);        
}        
}
USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);
}
break;
case 0xB4:        //SERVER_SETUP(參數設置)
{
SREF = 0;
for(i=0;i<193;i++)        //串口接收的數據存入16位的數組,準備寫入FLASH
{
Param = USART1_RX_BUF;        
}
STAall();        //發送所有參數給服務器
Pmax = (Param[7]<<24)+(Param[6]<<16)+(Param[5]<<8)+Param[4];//最大使用上限讀出來
//FLASHWR();        //參數寫入FLASH
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        //開啟串口中斷
}
break;
case 0xB5:        //SERVER_UPGRADE(固件升級,暫未調試)
{        
SREF = 0;
if(USART1_RX_BUF[2]==0x01)        //第一段升級程序,一共三段
{
//        USART1_RX_BUF[1023]=0x01;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[1024]=0x02;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[1025]=0x03;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[1026]=0x04;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[2049]=0x05;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[2050]=0x06;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[3073]=0x09;        //測試用,正常程序屏蔽掉
//        USART1_RX_BUF[3074]=0x0a;        //測試用,正常程序屏蔽掉
//iaplen1 = USART1_RX_BUF[0];        //長度取過來,暫時未用
//第一段寫入地址為0x08008800~0x0800afff(10k字節)
for(i=0;i<10;i++)        //寫10次
{
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
m=0;
FLASH_ErasePage(0x8008800+i*1024);        //先擦后寫,每次擦除一頁地址(1K);擦10K;FLASH存參數起始地址
for(n=0;n<1024;n+=2)        //串口接收的數據存入16位的數組,準備寫入FLASH
{
flashBUF[m] = (USART1_RX_BUF[n+4+i*1024]<<8)+USART1_RX_BUF[n+3+i*1024];        
m++;
}
m = 0;
for(flashCN=0;flashCN<512;flashCN++)        //10k字節數據,分10次寫入,每次寫1K,因為RAM不夠         
{
FLASH_ProgramHalfWord((0x8008800 +flashCN*2+i*1024),flashBUF[flashCN]);//flash  為一個字節存儲,16位數據必須地址加2
}
FLASH_Lock();
}        
}
if(USART1_RX_BUF[2]==0x02)        //第二段升級程序,一共三段
{
//iaplen2 = USART1_RX_BUF[0];        //長度取過來
//第二段寫入地址為0x0800b000~0x0800d7ff(10k字節)
for(i=0;i<10;i++)        //寫10次
{
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
m=0;
FLASH_ErasePage(0x800b000+i*1024);        //先擦后寫,每次擦除一頁地址(1K);擦10K;FLASH存參數起始地址
for(n=0;n<1024;n+=2)        //串口接收的數據存入16位的數組,準備寫入FLASH
{
flashBUF[m] = (USART1_RX_BUF[n+4+i*1024]<<8)+USART1_RX_BUF[n+3+i*1024];        
m++;
}
m = 0;
for(flashCN=0;flashCN<512;flashCN++)        //10k字節數據,分10次寫入,每次寫1K,因為RAM不夠         
{
FLASH_ProgramHalfWord((0x800b000 +flashCN*2+i*1024),flashBUF[flashCN]);//flash  為一個字節存儲,16位數據必須地址加2
}
FLASH_Lock();
}
for(m=0;m<USART_IAP_LEN;m++)        //第二次接收完后把串口緩存全部置為0xff,防止第三次接收后
{        //接收的不是整K的長度,寫到FLASH的值不定
USART1_RX_BUF[m]=0xff;
}        
}
if(USART1_RX_BUF[2]==0x03)        //第三段升級程序,一共三段
{
//iaplen3 = USART1_RX_BUF[0];        //長度送過來
//第3段寫入地址為0x0800d800~0x0800fbff(9k字節)
for(i=0;i<9;i++)        //寫9次
{
FLASH_Unlock();
FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_PGERR|FLASH_FLAG_WRPRTERR);
m=0;
FLASH_ErasePage(0x800d800+i*1024);        //先擦后寫,每次擦除一頁地址(1K);擦10K;FLASH存參數起始地址
for(n=0;n<1024;n+=2)        //串口接收的數據存入16位的數組,準備寫入FLASH
{
flashBUF[m] = (USART1_RX_BUF[n+4+i*1024]<<8)+USART1_RX_BUF[n+3+i*1024];        
m++;
}
m = 0;
if(i==8)          //最后一次寫入時,置一個更新標志位存到FLASH
{
flashBUF[511]=0x7777;        //地址0x0800fbff存入0x77,以便IAP判斷
}
for(flashCN=0;flashCN<512;flashCN++)        //9k字節數據,分9次寫入,每次寫1K,因為RAM不夠         
{
FLASH_ProgramHalfWord((0x800d800 +flashCN*2+i*1024),flashBUF[flashCN]);//flash  為一個字節存儲,16位數據必須地址加2
}
FLASH_Lock();
}
TEMPBUF[0] = 0x01;        //第三次寫完后發送準備固件更新消息
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa5;
TEMPBUF[3] = 0x04;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,4); //CRC8校驗
send1();        
for(i=0;i<4;i++)                 //準備固件更新信息返回服務器
{
COM1SEND(TEMPBUF);        
}
SoftReset(); //接收和存儲完固件更新文件后軟復位程序,轉IAP程序開始更新,        
}
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
break;
case 0xB6:        //SERVER_TIME,用于回應plug的PLUG_TIME指令。
{
SREF = 0;
COM1F = (USART1_RX_BUF[4]<<8)+USART1_RX_BUF[3];        //USART1_RX_BUF[1]是標志位0XB6;USART1_RX_BUF[2]接收的是時區,
//所以時間從USART1_RX_BUF[3]開始 3,4為年份需合并成16位的格式
GettimeF = 1;        //低字節在前,高字節在后,如2014年=07DE,接收順序為DE 07        
RTC_Set(COM1F,USART1_RX_BUF[5],USART1_RX_BUF[6],USART1_RX_BUF[7],USART1_RX_BUF[8],USART1_RX_BUF[9]);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        
}
break;
case 0xB7:        //SERVER_IDLE,用于回應plug的PLUG_IDLE,無實際意義。
{
SREF = 0;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        
}
break;
case 0xB8:        //用于接收手機端設置的一些定時參數。
{        
SREF = 0;
for(i=0;i<193;i++)        //串口接收的數據存入16位的數組,準備寫入FLASH
{
Param = USART1_RX_BUF;        
}
STAall();        //發送所有參數給服務器
Pmax = (Param[7]<<24)+(Param[6]<<16)+(Param[5]<<8)+Param[4];//最大使用上限讀出來
TEMPBUF[0] = 0x01;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa5;
TEMPBUF[3] = 0x05;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,4); //CRC8校驗
send1();        
COM1SEND(0x01);
COM1SEND(0x00);
COM1SEND(0xa5);        //返回服務器PLUG_ALERM 返回05 告知本地設置改變
COM1SEND(0x05);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);        
}
break;
default:
{
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}break;
}
//****************以下過載報警程序********************************************        
if(overload)        //過載標志
{        
overload = 0;
AUTO = 0; //關掉繼電器
TEMPBUF[0] = 0x01;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa5;
TEMPBUF[3] = 0x01;
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,4); //CRC8校驗
send1();        
COM1SEND(0x01);
COM1SEND(0x00);
COM1SEND(0xa5);        //返回服務器PLUG_ALERM 返回01 告知過載
COM1SEND(0x01);        
}
//****************以下語音模塊處理程序,地址1~9存放的數字1~9語音,地址10存放“0”語音,*******************************************        
if(VDIF == 1)        //語音按鍵標志位等于1播放當前時刻
{        //
//        ONE_LINE(0x0B);        //地址11存放的”當前時刻“語句
//        delay_ms(180);        //經驗時間,等待BUSY變成1
//        while(BUSY);        //一直等待上個語句播放完成
ONE_LINE(0x02);                 //播放下一條語句
delay_ms(180);
while(BUSY);        //一直等待上個語句播放完成
ONE_LINE(0x01);        
VDIF = 0;        
}
if(VDIF == 2)        //語音按鍵標志位等于2播放當前已消耗功率
{
vdio[0] = PSUM/1000000000;        //最高位(第10位)數值
Pvio = PSUM-vdio[0]*1000000000;
vdio[1] = Pvio/100000000;        //(第9位)數值
Pvio = Pvio-vdio[1]*100000000;
vdio[2] =       Pvio/10000000;        //(第8位)數值
Pvio = Pvio-vdio[2]*10000000;
vdio[3] =       Pvio/1000000;        //(第7位)數值
Pvio = Pvio-vdio[3]*1000000;
vdio[4] =       Pvio/100000;        //(第6位)數值
Pvio = Pvio-vdio[4]*100000;
vdio[5] =       Pvio/10000;        //(第5位)數值
Pvio = Pvio-vdio[5]*10000;
vdio[6] =       Pvio/1000;        //(第4位)數值
Pvio = Pvio-vdio[6]*1000;
vdio[7] =       Pvio/100;        //(第3位)數值
Pvio = Pvio-vdio[7]*100;
vdio[8] =       Pvio/10;        //(第2位)數值
Pvio = Pvio-vdio[8]*10;        
vdio[9] =       Pvio%10;        //(第1位)數值
ONE_LINE(0x0c);        //地址12存放的“已使用功率“語音
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
if(vdio[0])        //最高位不為0;從最高位播放
{
for(i=0;i<10;i++)
{
ONE_LINE(vdio);        //播放最高位
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else        //最高位為0,判斷第9位,以此類推
{
if(vdio[1])        //最9位不為0;從9位播放
{
for(i=1;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[2])        //最8位不為0;從8位播放
{
for(i=2;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[3])        //最7位不為0;從7位播放
{
for(i=3;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[4])        //最6位不為0;從6位播放
{
for(i=4;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[5])        //最5位不為0;從5位播放
{
for(i=5;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[6])        //最4位不為0;從4位播放
{
for(i=6;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[7])        //最3位不為0;從3位播放
{
for(i=7;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
if(vdio[8])        //最2位不為0;從2位播放
{
for(i=8;i<10;i++)
{
ONE_LINE(vdio);        //播放
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);
}
}
else
{
ONE_LINE(vdio[9]);        //播放第一位
delay_ms(180);        //經驗時間,等待BUSY變成1
while(BUSY);        
}        
}        
}        
}        
}        
}        
}        
}        
}
VDIF = 0;        //清播放標志位
}
//***************以下電壓采集及斷電處理程序25毫秒檢測一次***********************************************
if(T50F)                 //目前25毫米取一次AD采樣值,用以判斷是否斷電
{          //小于4.75V認為出現斷電或異常,保存參數,送出警告
T50F = 0;
ADCValue = Get_Adc_Average(ADC_Channel_1 ,3); //采集3次取平均值 為了減少損耗時間
ADtemp = (float)ADCValue*(3.3/4096);
V5H = ADtemp;
V5L = (ADtemp-V5H)*100;
if(ADtemp<=1.87)        //小于4.75V認為出現斷電或異常,保存參數,送出警告
{        //正常時1.90,差0.03V
SHUTDOWN();                 //發送斷電信息給服務器        
if(FproV==0x78)        //Fprotect==0x78,才寫入一次FLASH,
{        //防止斷電延遲時間過長,多次寫入FLASH        
//        FLASHWR();        //參數寫入FLASH
FproV = 0;        //寫入一次后不再寫入,重上電后恢復。
}
}
}
//***************以下讀取時間,溫度,繼電器工作狀態檢測,定時處理及發送程序********************************************
if(T1000F)        //定時1秒時間讀次時間,溫度并發送給服務器
{        //清除標志位
T1000F = 0;
//****************以下開啟校時模式程序**********************************************
if((Param[192]==1)&&(GettimeF==0))        //是否需要校時,接收到服務器的校時數據后,置位GettimeF ,不再發送申請命令
{        //
TEMPBUF[0] = 0x01;
TEMPBUF[1] = 0x00;
TEMPBUF[2] = 0xa6;
TEMPBUF[3] = Param[184];
CRCF = 0;
CRCF=crc8_slow(CRCF,TEMPBUF,4); //CRC8校驗
send1();
COM1SEND(0x01);
COM1SEND(0x00);
COM1SEND(0xa6);
COM1SEND(Param[184]);        
}
//****************以下獲取溫度程序**********************************************
TEM18B20=DS18B20_Get_Temp();          //獲取溫度
if(TEM18B20<0)
{
TEM18B20=-TEM18B20;        //轉為正數
TEM = 1;        //表示負溫度
}
else
{
TEM = 0;
}
TEMH = TEM18B20/10;        //顯示正數部分           
  TEML = TEM18B20%10;        //顯示小數部
//******繼電器工作方式檢測
ADCValue = Get_Adc_Average(ADC_Channel_7 ,5); //ADC 7通道采集5次繼電器控制端電壓
ADJDQ = (float)ADCValue*(3.3/4096);
if(ADJDQ>3.2)        //大于3.2V工作在自動運行的吸合狀態
{
if(WifiRDY==0)        //WiFi正常
{
LEDR = 0;        //wifi正常且繼電器有輸出,紅燈亮
LEDG = 1;
}
if(WifiRDY)        //WiFi異常
{
LEDR = ~LEDR;        //wifi異常且繼電器有輸出,紅燈閃
LEDG = 1;
}
sta.powstaF = 1;        //繼電器狀態查詢時返回開關狀態 1表示吸合 0斷開
sta.runF = 1;        //繼電器運行方式  1表示自動運行
}
if(ADJDQ<0.2)        //小于0.2V工作在自動運行的斷開狀態
{
if(WifiRDY==0)        //WiFi正常
{
LEDR = 1;        //wifi正常且繼電器無輸出,綠燈亮
LEDG = 0;
}
if(WifiRDY)        //WiFi異常
{
LEDR = 1;        //wifi異常且繼電器無輸出,綠燈閃
LEDG = ~LEDG;
}
sta.powstaF = 0;        //增加此變量可以用于服務器對繼電器狀態查詢時返回開關狀態
sta.runF = 1;        //繼電器運行方式  1表示自動運行        
}
if((ADJDQ>2.8)&&(ADJDQ<3.1))        //工作在一直吸合狀態  LED指示燈為橙色
{
LEDR=LEDG=0;        //橙色
sta.powstaF = 1;        //增加此變量可以用于服務器對繼電器狀態查詢時返回開關狀態
sta.runF = 0;        //繼電器運行方式  0常閉狀態
}
if((ADJDQ>0.3)&&(ADJDQ<0.6))        //工作在一直斷開狀態
{
sta.powstaF = 0;        //增加此變量可以用于服務器對繼電器狀態查詢時返回開關狀態
sta.runF = 2;        //繼電器運行方式  2表示常開狀態
}
//RTC讀取及處理
RTC_Get();        //獲取時間
rtcbuffer[0]=calendar.w_year/0xff;        //年份的高8位        
rtcbuffer[1]=calendar.w_year;          //年份的低8位
rtcbuffer[2]=calendar.w_month;
rtcbuffer[3]=calendar.w_date;
rtcbuffer[4]=calendar.hour;
if(calendar.min!=rtcbuffer[5])        //如果分鐘變了;
{        
Tchange = 1;        //每分鐘發次IDEL();給服務器,防止鏈接斷開        
}
rtcbuffer[5]=calendar.min;
rtcbuffer[6]=calendar.sec;
rtcbuffer[7]=calendar.week;
if((rtcbuffer[4]==0x13)&&(FproT==0x78))        //每天19點寫一次FLASH,保護參數。
{
FLASHWR();
FproT = 0;        
}        
if(Tchange)        //每分鐘發次IDEL();給服務器,防止鏈接斷開        
{
Tchange = 0;
IDEL();        
}
//**********定時開關檢測***************************        
if(Param[11]==1)        //定時開關使能
{
timeJC(work.Time1,12);        //Param[12]~Param[26]        
timeJC(work.Time2,27);        //Param[27]~Param[41]
timeJC(work.Time3,42);        //Param[42]~Param[56]
timeJC(work.Time4,57);        //Param[57]~Param[71]
timeJC(work.Time5,72);        //Param[72]~Param[86]
timeJC(work.Time6,87);        //Param[87]~Param[101]
timeJC(work.Time7,102);        //Param[102]~Param[116]
timeJC(work.Time8,117);                 //Param[117]~Param[131]        
}        
//**********溫度開關簡單模式使能********************
if(Param[132]==1)
{
Tsimple(133);
}
//**********溫度開關編程模式使能********************
if(Param[132]==2)
{
Tprog(136);
Tprog(142);
Tprog(148);
Tprog(154);
Tprog(160);
Tprog(166);
Tprog(172);
Tprog(178);
}
//        sta.pv4 = PSUM;        //低8位
//        sta.pv3 = PSUM>>8;
//        sta.pv2 = PSUM>>16;
//        sta.pv1 = PSUM>>24;
//        for(i=0;i<8;i++)
//        {
//        COM1SEND (rtcbuffer);
//        }
//        COM1SEND(V5H);
//        COM1SEND(V5L);
//        COM1SEND((j1>>8));
//        COM1SEND(j1);
//        COM1SEND(PSUM>>24);
//        COM1SEND(PSUM>>16);
//        COM1SEND(PSUM>>8);
//        COM1SEND(PSUM);
if(!HELLOF)        //如果服務器未返回值一直發送HELLO函數
{
HELLO();
}
COM1SEND((j1>>8));
COM1SEND(j1);
COM1SEND(PSUM>>24);
COM1SEND(PSUM>>16);
COM1SEND(PSUM>>8);
COM1SEND(PSUM);
//        COM1SEND (PSUM);
//        COM1SEND (PJ);
//        COM1SEND (overload);
//        COM1SEND (FproV);                 //讀Flash,用于測試
//        COM1SEND (FproT);                 //讀Flash,用于測試
//        COM1SEND (aj);                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x8008800));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x8008801));
COM1SEND (*(u8*)(0x8008bfc));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x8008bfd));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x8008bfe));
COM1SEND (*(u8*)(0x8008bff));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x8008ffe));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x8008fff));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x80093fe));                 //讀Flash,用于測試
COM1SEND (*(u8*)(0x80093ff));
COM1SEND (*(u8*)(0x800fbfe));
COM1SEND (*(u8*)(0x800fbff));
}
}
}         
void USART1_IRQHandler(void)                        //串口1中斷服務程序
{
static u8 receY=0,i=0;
static u16 j=0,LEN = 0;
static u8 Rav[7];
//static u8 k=0;        
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)          //接收中斷
{
   USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中斷標志
if((i<7)&&(receY==0))                 //接受完數據包頭1E BA 00 00 和CRC 和數據長度(7個字節)
{
Rav=USART_ReceiveData(USART1);        //讀取接收到的首字節數據
if((Rav[0]==0x1E))        //首字節為0X00;
{
i++;        //
if((Rav[1]==0xBA))
{
if((Rav[2]==0x00))
{
if((Rav[3]==0x00))
{
if(i == 7)
{
i = 0;
receY = 1;          //是要接收的數據包
LEN = Rav[6];
LEN=(LEN<<8)+Rav[5]+2;        //獲得數據長度值 數據包長度需加2,因為緊跟著的標識位沒算數據長度而且后續接收j先加1了
//LEN = ((Rav[5]&0x00ff)<<8)+Rav[6]+2;        //而且數據長度的低字節當receY有效時,緊接著又送一遍到USART_RX_BUF[0]
//                     for(k=0;k<7;k++)
//        {
//        Rav = 0xaf;        
//        }
}
}
}
}   
if(i==7){i = 0;}        //i加到5,確沒有被清零,表明接收到錯誤數據,自動清零
}
         }
if(receY)        //開始接收數據包
{
USART1_RX_BUF[j]=USART_ReceiveData(USART1);
if(j<LEN)
{
j++;
}
  if(j==LEN)        //接收完成,開始處理數據        
  {
SREF = USART1_RX_BUF[1];        //標識位送REVF
USART1_RX_BUF[0] = LEN-3;        //為了得到固件更新時每次的數據長度 減去開頭重復接收的一個數據,標識位及包標識位
j = 0;        //這樣USART1_RX_BUF[0]為數據長度,USART1_RX_BUF[1]為標識
receY = 0;        //USART1_RX_BUF[2]為第幾包,后面為更新的數據
LEN = 0;
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);        //關閉接收中斷
  }
}
}   
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET) //溢出      
{               
USART_ClearFlag(USART1,USART_FLAG_ORE); //讀SR              
USART_ReceiveData(USART1); //讀DR
}
           USART_ReceiveData(USART1);
}
//外部中斷5-9服務程序
void EXTI9_5_IRQHandler(void)
{
//static u16 j1;
j1++;
pj++;
if(j1==130)          //1300個脈沖對應1W        6毫歐時為1300;500微歐為110個脈沖
{
j1 = 0;
PSUM++;        //一個脈沖到來時1W功率
}
EXTI_ClearITPendingBit(EXTI_Line9); //清除LINE9上的中斷標志位  
}

//外部中斷10-15服務程序
void EXTI15_10_IRQHandler(void)
{
static u8  av;
av++;
if(av == 1)
{
VDIF = 1;
}
if(av == 2)
{
av = 0;
VDIF = 2;
}
EXTI_ClearITPendingBit(EXTI_Line13);          //清除LINE13上的中斷標志位  
}
//定時器3中斷服務程序
void TIM3_IRQHandler(void)   //TIM3中斷 25毫秒中斷
{
static u8 Pcount,nrecount;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //檢查TIM3更新中斷發生與否
{
T50F = 1;                 
t3count++;
Pcount++;          //功率判斷開始計時,1秒
LEDG = ~LEDG;
if(Pcount==39)        //1秒到了
{
Pcount = 0;
if((pj*100) >Phz)        //判斷PJ的計數值是否超過預設功率上限對應的參數
{
overload = 1;        //超過則認為過載
}
pj = 0;        //清除該計數為了下一次判斷
}
if(NRE==0) //出廠設置鍵被按下
{
nrecount++;
if(nrecount>121)
{
nrecount = 0;
NREFLAG = 1;        //置高恢復出廠狀態標志位        
}        
}
else  nrecount = 0;          //按鍵未按下或時間不到抬起了,清計數器
if(t3count==200)        //5秒時間
{
t3count = 0;
T1000F = 1;
LEDR = ~LEDR;
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); //清除TIMx更新中斷標志
}
}

回復

使用道具 舉報

ID:25762 發表于 2014-12-2 16:09 | 顯示全部樓層
功能說明都沒有,只發了一篇代碼,看得很費勁。
回復

使用道具 舉報

ID:70042 發表于 2014-12-22 22:46 | 顯示全部樓層
樓主怎么沒有敘述啊??
回復

使用道具 舉報

ID:70971 發表于 2014-12-23 18:53 | 顯示全部樓層
zenme doushi 程序呢?
回復

使用道具 舉報

ID:56678 發表于 2015-1-17 00:09 | 顯示全部樓層
樓主很厲害啊,最好多介紹介紹。
回復

使用道具 舉報

ID:72495 發表于 2015-1-20 08:36 | 顯示全部樓層
學習了
回復

使用道具 舉報

ID:116399 發表于 2016-4-24 19:28 | 顯示全部樓層
放了大段的代碼,可惜沒有解釋上面
回復

使用道具 舉報

ID:236814 發表于 2017-10-1 11:59 | 顯示全部樓層
厲害,學習下
回復

使用道具 舉報

ID:191195 發表于 2017-10-13 10:57 | 顯示全部樓層
看不懂上面的代碼。。。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品一区二区在线观看 | 欧美日韩精品在线一区 | 一区二区三区国产好 | 欧美久久久久 | 亚洲国产一区在线 | 国产一区二区精品在线 | 亚洲精品高清视频在线观看 | 国产一区二区三区免费 | 日本精品视频一区二区三区四区 | 999久久久 | 91婷婷韩国欧美一区二区 | 国产成人高清 | 午夜寂寞影院在线观看 | 二区成人| 欧美午夜激情在线 | 99视频在线免费观看 | 久草网站 | 国产精品永久免费观看 | 国产男人的天堂 | 成人午夜免费视频 | 国产乱码久久久久久 | 久久久精| 九九热精品视频 | 久久免费精品视频 | 成人二区三区 | 中文字幕一区二区三区精彩视频 | 99中文字幕| 中文字幕精品一区二区三区精品 | 国产激情在线看 | 午夜精品久久久久久久久久久久 | jizz18国产 | 综合色婷婷 | 亚洲一区二区成人 | 在线播放中文字幕 | 成人3d动漫一区二区三区91 | 一区二区三区视频在线观看 | 性生生活大片免费看视频 | 国产精品嫩草影院精东 | 久久久久国产一区二区三区四区 | 中文字幕视频在线观看 | 久久久国产一区 |