1. 程式人生 > >UART燒寫FLASH

UART燒寫FLASH

/************************************************************
  Copyright (C), 20XX-20XX, SZREC Tech. Co., Ltd.
  FileName: LedArray.c
  Author:        Version :          Date:
  Description:     // 接收並存儲來自通訊裝置下發的串列埠資訊,根據相應的資訊設定相應的標誌位,
                        並將這些資料送入點陣屏顯示模組進行處理  
  Version:         // 1.0
  Function List:   // 主要函式及其功能
    1. -------
  History:         // 歷史修改記錄
      <author>  <time>   <version >   <desc>
      David    1/22/14     1.0       
***********************************************************/
#include "uart.h" #include "string.h" #include "flash.h" #include <stdio.h> #include "main.h" unsigned char UartBuf[256]={0};//串列埠資料快取陣列 unsigned char CopyBuf[256]={0}; //unsigned char code DownLoad_Complete[]={"SPI Flash DownLoad CompLete"}; unsigned char UartWaitTime=0,UartStart=FALSE,UartComp=FALSE; unsigned int
UartCount=0; unsigned int FlashAddrCount=5152; unsigned long Count=1; bit FullFlag=0; bit CountFlag=0; bit PerFlag=0; unsigned long Capacity; unsigned int Sector; unsigned int Per=0; unsigned char Temp1[5]; void Receive_Process(); /********************************************************************/ /* 函式名稱:void Uart_Send_Byte(unsigned char SendData)*/
/* 函式功能:串列埠傳送一位元組資料*/ /* 輸入引數:SenData:要傳送的資料*/ /* 輸出引數:*/ /* 全域性變數:*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ void Uart_Send_Byte(unsigned char SendData) { ES=0; TI=0; SBUF=SendData; while(TI==0); TI=0; ES=1; } /********************************************************************/ /* 函式名稱:void Uart_Send_Bytes(unsigned char *Buf,unsigned char Len)*/ /* 函式功能:串列埠傳送多位元組資料*/ /* 輸入引數:Buf:指向傳送資料的指標,Len:傳送的資料長度*/ /* 輸出引數:*/ /* 全域性變數:*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ void Uart_Send_Bytes(unsigned char *Buf) { while(*Buf!='\0') { Uart_Send_Byte(*Buf++); } } //void uart_over() //{ // UartCount = 0; // UartComp = FALSE; //} ///********************************************************************/ ///* 函式名稱:void uart_interrput_receive() interrupt 4*/ ///* 函式功能:串列埠接收函式(中斷接收),接收完成之後進入串列埠資料處理*/ ///* 輸入引數:*/ ///* 輸出引數:UartBuf[]:串列埠資料快取*/ ///* 全域性變數:UartBuf[]*/ ///* 返 回 值:*/ ///* 呼叫前提:有串列埠中斷產生*/ ///* 副 作 用:*/ ///* 修改記錄:*/ ///* 說 明:*/ ///********************************************************************/ void uart_interrput_receive() interrupt 4 { unsigned char ReByte; unsigned int i; unsigned char n=0; unsigned char Temp[60]; //unsigned char Temp1[5]; PDownConfig UartDownConfig; RI=0; ReByte=SBUF; UartBuf[UartCount]=ReByte; if(ConfigFlag) { if(UartCount>=5)//首先接收配置引數 { ConfigFlag=0; UartCount=0; RevFlag=1; UartDownConfig=(PDownConfig)UartBuf; Capacity=UartDownConfig->Capacity; Sector=UartDownConfig->Sector*16; sprintf(Temp,"The total capacity is %6ld,The starting Sector is %4d \n\n",Capacity,Sector/16); Uart_Send_Bytes(Temp); } else UartCount++; } else if(RevFlag) { CountFlag=1; // Uart_Send_Byte(UartCount); if((UartCount>=255)&&(Count<=Capacity-Capacity%256)) { UartCount = 0; UartComp=TRUE; for(i=0;i<=255;i++) { CopyBuf[i]=UartBuf[i]; } // Uart_Send_Byte(UartBuf[0]); //FlashAddrCount+=2;//一次寫倆頁 } else if((UartCount>=Capacity%256-1)&&(Count>Capacity-Capacity%256)) { Uart_Send_Bytes("SPI Flash DownLoad CompLete \n \n"); Count=0; FullFlag=1; UartCount=0; UartComp=TRUE; // for(i=128;i<=255;i++) // CopyBuf[i]=0; for(n=0;n<=127;n++) { CopyBuf[n]=UartBuf[n]; //Uart_Send_Byte(UartCount); } } else { UartCount++; } if(Count-1==(Capacity/100)*Per) { PerFlag=1; //Uart_Send_Bytes("\n"); Per++; } // if(Count-1==0) // Uart_Send_Bytes("Has been completed:\n0%\n"); Count++; } } // // /********************************************************************/ ///* 函式名稱:void Receive_Process()*/ ///* 函式功能:串列埠資料處理*/ ///* 輸入引數:*/ ///* 輸出引數: ///* 全域性變數:*/ ///* 返 回 值:*/ ///* 呼叫前提:必須等串列埠資料接收完畢*/ ///* 副 作 用:*/ ///* 修改記錄:*/ ///* 說 明:每次寫入256個位元組及一頁內容,最後在寫入剩餘不足一頁的內容*/ ///********************************************************************/ // void Receive_Process() { if(UartComp==TRUE) { UartComp=0; if(!FullFlag) { SPI_Flash_Write_Page(&CopyBuf[0],(unsigned long)(Sector++)*256,256); } else { //FullFlag=0; SPI_Flash_Write_Page(&CopyBuf[0],(unsigned long)(Sector++)*256,Capacity%256);//最後寫不足一頁的 } if(PerFlag==1)//每寫完1%輸出下,不能輸出太多內容以免和串列埠中斷衝突 { PerFlag=0; Temp1[0]=Per/100+0x30; Temp1[1]=Per/10+0x30; Temp1[2]=Per%10+0x30; Temp1[3]='%'; Temp1[4]='\0'; if(Temp1[0]==0X30)Temp1[0]=' '; if(Temp1[1]==0X30)Temp1[1]=' '; if(Per<=99) Uart_Send_Bytes(Temp1); Uart_Send_Byte('\n'); } } } /********************************************************************/ /* 函式名稱:void uart_init()*/ /* 函式功能:串列埠初始化,頻率22.1184M波特率19200*/ /* 輸入引數:*/ /* 輸出引數:*/ /* 全域性變數:*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ void uart_init() { SCON=0x50; AUXR|=0x40; AUXR &= 0xFE; TMOD&=0x0f; TL1=(65535-(FOSC/4/BAUD)); TH1=(65535-(FOSC/4/BAUD))>>8; TR1=1; ET1 = 0; ES=1; } /********************************************************************/ /* 函式名稱:void init_timer0()*/ /* 函式功能:定時器0初始化*/ /* 輸入引數:*/ /* 輸出引數:*/ /* 全域性變數:*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ //void init_timer0() //{ // TMOD|=0x01; // // TH0=(65535-20000)/256; // TH1=(65535-20000)%256; // ET0=1; // TR0=1; // // // //} /********************************************************************/ /* 函式名稱:void init_timer2(void)*/ /* 函式功能:定時器2初始化25毫秒*/ /* 輸入引數:*/ /* 輸出引數:*/ /* 全域性變數:*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ void init_timer2(void) //25毫秒@22.1184MHz { //AUXR |= 0x04; //定時器2為1T模式 AUXR &= ~0x04; //定時器2為12T模式 T2L = T1MS%256; //設定定時初值 T2H = T1MS/256; AUXR |= 0x10; //定時器2開始計時 IE2 |= 0x04; //開定時器2中斷 } /********************************************************************/ /* 函式名稱:void time2() interrupt 12*/ /* 函式功能:定時器2中斷,計時下載字型檔時間*/ /* 輸入引數:*/ /* 輸出引數: /* 全域性變數:Count:中斷計時*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ void time2() interrupt 12 { static unsigned char Minute=0,Second=0,MS=0; unsigned char Time[20]; if(CountFlag) { //Uart_Send_Bytes("Using Time:",11); //Uart_Send_Byte(Minute); if((MS++)>=40) { MS=0; if((Second++)>=60) { Second=0; Minute++; } } } if(FullFlag) { FullFlag=0; CountFlag=0; sprintf(Time,"%2d Minute %2d Second",(int)Minute,(int)Second); Uart_Send_Bytes("Using Time:"); Uart_Send_Bytes(Time); Minute=0; Second=0; MS=0; //Uart_Send_Bytes(Minute) } } /********************************************************************/ /* 函式名稱:void time0() interrupt 1*/ /* 函式功能:定時器0中斷,判斷串列埠是否接收超時*/ /* 輸入引數:*/ /* 輸出引數:UartWaitTime:串列埠接收計時,UartStart:串列埠是否開始接受資料標誌*/ /* 全域性變數:*/ /* 返 回 值:*/ /* 呼叫前提:*/ /* 副 作 用:*/ /* 修改記錄:*/ /* 說 明:*/ /********************************************************************/ //void time0() interrupt 1 //{ // TH0=(65535-20000)/256; // TL0=(65535-20000)%256; // //Uart_Send_Byte(DispStayFlag); // if(((UartWaitTime++)>=4)&&(UartStart==TRUE)) // { // UartWaitTime=0; // uart_over(); // } // //}

前段時間買的一個開發板,有個例程是將SD卡里的GBK點陣字型檔寫入SPI FLASH中的,速度很快,半分鐘就能搞定,字型檔檔案766080位元組的,但是我正好有個專案需要用到[size=14.3999996185303px]GBK點陣字型檔又沒SD介面,研究了下用串列埠傳送的形式,38400的波特率,3分12秒寫完

[size=14.3999996185303px]燒寫SPI FLASH步驟如下
1首先燒寫玩程式之後需要等待幾十秒擦除完整片FLASH

2傳送燒寫配置,主要是傳送檔案總位元組數(4位元組)和寫入的起始扇區(2位元組)16進位制的,如00 0B B0 80 01 42,就是檔案總大小766080,從322扇區開始寫起
3傳送GBK字型檔的二進位制檔案,傳送過程中有提示寫入百分比進度的,寫完之後會顯示總共用時的