写给C8051F330的bootload、WIN32 API iap下载上位机

来源:互联网 发布:js 页面后退 编辑:程序博客网 时间:2024/05/18 02:09

这个bootload非常简陋,源码是在silicon 官网例程和在网上找的一个汇编例程的基础上修改的,经过几天的努力实现了基本功能。

程序主体是用汇编写的,因为感觉用C重定位中断向量比较麻烦。发送HEX文件的上位机使用 win32 API 写的,也相当的简单。

 

用户程序模板测试了串口中断ADC中断,测试过程中未发现问题。

 

bootload 在芯片上电后会检测P1.3脚,低电平直接跳转至用户程序,若为高电平则调用flash擦除代码,擦除地址400H之后的10页flash空间,然后等待接收HEX文件,程序下载成功后跳转至用户程序。

 

C8051F330 bootload 源代码:

开发环境:keil

;iap for c8051f330;data:2013-11-29 ;zxx

$INCLUDE(C8051F330.INC)    ; Register definition file.

cra1            equ 0dh             ; carriage returncra2            equ 0ah             ; carriage returnerror_led       equ p1.2           ; active low - clr to turn onload_en      equ p1.3           ; active low - clr to turn on

ram    set 400h   ; programs into          

;********************************************************************; Interrupt vector table;********************************************************************    org 0               ; System reset      RST    ljmp main    org 3               ; External 0        IE0    ljmp (ram+3)    org 0bh             ; Timer 0           TF0    ljmp (ram+0bh)    org 13h             ; External 1        IE1    ljmp (ram+13h)    org 1bh             ; Timer 1           TF1    ljmp (ram+1bh)    org 23h             ; Serial port       TI or RI    ljmp (ram+23h)    org 2bh             ; Timer 2           TF2 or EXF2    ljmp (ram+2bh)    org 33h    ljmp (ram+33h)  ;spi    org 3bh    ljmp (ram+3bh)  ;smb0       org 4bh    ljmp (ram+4bh)  ;adc0 windows    org 53h    ljmp (ram+53h)  ;adc0 convert over        org 5bh    ljmp (ram+5bh)  ;pca    org 63h    ljmp (ram+63h)  ;comparator    org 73h    ljmp (ram+73h)  ;timer3 overflow    ;********************************************************************; Main program starts here;;********************************************************************    org 80hmain:    clr EA       lcall init          ; init serial port

    clr c    mov c,load_en    jc   done    lcall erase_flash             call  intro         ; print welcome message     call  load1done:     mov dptr,#prompt8   ; end    lcall outstr              ljmp ram            ; start running program

error:   mov dptr,#prompt6   ; end    lcall outstrstop:   sjmp $

;********************************************************************; Receive hex file and write it to flash;********************************************************************load1:   lcall incharskip1:   cjne a,#':',load1   ; each record begins with ':'    mov r1,#0           ; init checksum to zero

length:   lcall gethex        ; get byte from serial port    mov b,a             ; use b as byte counter    jz done             ; if b = 0      address:  lcall gethex        ; get address high byte    mov dph,a    lcall gethex        ; get address low byte    mov dpl,a

record_type: lcall gethex        ; get record type (ignore this)    cjne a,#01h,check1    sjmp done   ; if record type is 01h hex file reach the end check1:   jz  load4   ; if record type is zero then perpare to write to flash    sjmp error

load4:   acall gethex        ;get data byte    mov PSCTL,#01H  ;MOVX writes to FLASH             mov FLKEY,#0A5H    mov FLKEY,#0F1H    movx @dptr,a        ; store in FLASH    inc dptr    mov PSCTL,#00H       ; MOVX writes target XRAM    dec b               ; repeat until count = 0    mov a,b    jnz load4

 checksum:  acall gethex        ; get the HEX record checksum field               mov a,r1            ; checksum should be zero

    jnz error           ;if not, stop download

    mov dptr,#prompt4      lcall outstr                     sjmp load1   ; if so, then get next record

;********************************************************************;  erase_flash ; ;********************************************************************erase_flash:                             mov  r3,#08h    mov  dptr,#ram  ;MOVX writes target XRAMerase_all:      mov  PSCTL,#03h   ;MOVX erases FLASH    mov  FLKEY,#0A5h  ;FLASH lock and key sequence 1    mov  FLKEY,#0F1h;  ;FLASH lock and key sequence 2              clr  a    movx @dptr,a    mov  PSCTL,#00h     mov  a,dph    add  a,#02h    mov  dph,a    djnz r3,erase_all

    clr  a    mov dptr,#prompt7           lcall outstr     ret

;********************************************************************;  Get two characters from serial port and form a hex byte. ;  Also add byte to checksum in r1.;********************************************************************gethex:   lcall inchar        ; get first character    lcall atoh          ; convert to hex    swap a              ; put in upper nibble    mov r0,a            ; save it    lcall inchar        ; get second character    lcall atoh          ; convert to hex    orl a,r0            ; or with first nibble    mov r2,a            ; save byte    add a,r1            ; add byte to checksum    mov r1,a            ; restore checkum in r1    mov a,r2            ; retrieve byte    ret

;********************************************************************; Wait until a char is received from the serial port, and return; that char in the accumulator.;********************************************************************inchar:   jnb ri0,inchar       ; wait until ri is set    clr ri0              ; clear interrupt    mov a,sbuf0          ; get character    ret

;********************************************************************; ASCII to hex - enter with ascii code in acc. (assume hex char 0-F); exit with hex nibble in A.0-A.3;********************************************************************atoh:   clr acc.7           ; ensure parity bit is off    cjne a,#3ah,next    ; ?? this just sets carry bit ??next:   jc atoh2    add a,#9            ; no, adjust for range A-Fatoh2:   anl a,#0fh          ; yes, convert directly    ret

;********************************************************************; Print welcome message;********************************************************************intro:   mov dptr,#prompt1    lcall outstr    mov dptr,#prompt2    lcall outstr    mov dptr,#prompt5    lcall outstr    ret

;********************************************************************; Wait until tx ready, then send a char out serial port;********************************************************************outchar:  nb ti0,outchar      ; wait until ti is set    clr ti0             ; clear it    mov sbuf0,a         ; send acc to serial buffer    ret

;********************************************************************; Send a null terminated string out serial port;********************************************************************outstr:   clr a    movc a,@a+dptr      ; get character    jz exit             ; stop if char == null    lcall outchar       ; else send it    inc dptr            ; point to next char    sjmp outstrexit:   ret

;********************************************************************; Init serial port;********************************************************************init:      mov OSCICN,#083h    mov RSTSRC,#0x04   ;Enable missing clock detector

    anl PCA0MD,#0BFh    mov PCA0MD,#000h   ;disable watchdog

    mov CKCON,#08h    mov TCON,#040h    mov TMOD,#020h    mov TH1,#96h    ;115200    mov SCON0,#013h    ;enable UART  ; 8 bit UART mode    mov  P0MDOUT,   #010h    mov  XBR0,      #001h    mov  XBR1,      #040h    ret           

prompt1:        db cra1,cra2,'zxx''s C8051F330 bootloader - 18 NOV 2013',cra1,cra2,0prompt2:        db cra1,cra2,'Download Intel hex files to address 1000h',cra1,cra2,0prompt3:        db cra1,cra2,'*** Cannot decode HEX file.',cra1,cra2,0prompt4:        db cra1,cra2,'Received OK.',cra1,cra2,0prompt5:        db cra1,cra2,'Ready to receive hex file..',cra1,cra2,0prompt6:        db cra1,cra2,'Error Load!',cra1,cra2,0 prompt7:        db cra1,cra2,'Flash erase OK...',cra1,cra2,0 prompt8:        db cra1,cra2,'Received end.',cra1,cra2,0

                end

 


hex文件发送:上位机读取hex文件,每间隔20ms 发送一条记录。测试通过。后续要加上上下位机握手,以及校验。

上位机源代码:

开发环境:vs2012

#include "stdafx.h"#include "hex_win.h"#include<windows.h>#include<math.h>#include<stdio.h>#include <Commdlg.h>#include <winbase.h>#define MAX_LOADSTRING 100// 全局变量:HINSTANCE hInst;             // 当前实例TCHAR szTitle[MAX_LOADSTRING];       // 标题栏文本TCHAR szWindowClass[MAX_LOADSTRING];   // 主窗口类名const double dboffset = 0.000001 ;TCHAR str[80]; static  HWND hwndSlectPortButton ,hwndPortNum ,hwnlistbox,hwndpath,hwnSlectbutton,hwnDownloadbutton,hwndList;DWORD dwCommEvent;#define ID_LIST 1#define hex_file_size  0x1e00char hex_file_buffer[hex_file_size];DWORD hex_file_real_size;BOOL Read_hex_file_ok;HANDLE hCom;  //全局变量,串口句柄char ReadComstr[64];DWORD ReadCount;//读取的字节数//函数声明ATOM MyRegisterClass(HINSTANCE hInstance);BOOL  InitInstance(HINSTANCE, int);LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);void Hex_Fiel_Open_Init(void);BOOL Read_Com(void);void Com_handle(void);BYTE hex2char(char *pBuffer);BOOL Read_Com_Synchronous(void);//////////////////////////////////////////////////////////////////int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine, _In_ int nCmdShow){ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); MSG msg; HACCEL hAccelTable; WNDCLASSEX wcex; HWND hWnd; // 初始化全局字符串 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance,  IDC_HEX_WIN, szWindowClass, MAX_LOADSTRING); wcex.cbSize = sizeof(WNDCLASSEX); wcex.style   = CS_HREDRAW | CS_VREDRAW|CS_CLASSDC; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra  = 0; wcex.cbWndExtra  = 0; wcex.hInstance  = hInstance; wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE( IDC_HEX_WIN)); wcex.hCursor  = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = MAKEINTRESOURCE( IDC_HEX_WIN); wcex.lpszClassName = szWindowClass; wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); RegisterClassEx(&wcex); //注册主窗口 hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,400,200,600,400,NULL, NULL, hInstance, NULL); if (!hWnd)      return FALSE; ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE( IDC_HEX_WIN)); //加载快捷键 while (GetMessage(&msg, NULL, 0, 0))   // 主消息循环 {   if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))   {    TranslateMessage(&msg);    DispatchMessage(&msg);   }                      } return (int) msg.wParam;} //设置串口基本参数BOOL SetComm(void){ hCom = CreateFile( "COM1",                   //COM1口         GENERIC_READ|GENERIC_WRITE,          //允许读和写         0,                      //独占方式         NULL,         OPEN_EXISTING,                //打开而不是创建         //FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,  //重叠方式         0,                       // 同步方式         NULL); if(hCom == INVALID_HANDLE_VALUE) {   MessageBox( NULL,"打开COM失败!" ,"Error",MB_OK);    return FALSE; }  SetWindowText(hwndPortNum,"COM1");  MessageBox( NULL,"打开COM成功" ,"ok",MB_OK);       SetupComm(hCom,0x2000,0x2000); //输入缓冲区和输出缓冲区的大小都是1024  COMMTIMEOUTS TimeOuts;  //设定读超时  TimeOuts.ReadIntervalTimeout = 1000;  TimeOuts.ReadTotalTimeoutMultiplier = 500;  TimeOuts.ReadTotalTimeoutConstant = 5000;  //设定写超时  TimeOuts.WriteTotalTimeoutMultiplier = 500;  TimeOuts.WriteTotalTimeoutConstant = 2000;  SetCommTimeouts(hCom, &TimeOuts); //设置超时  DCB dcb;  GetCommState(hCom, &dcb);  dcb.BaudRate =  CBR_115200;   //波特率  dcb.ByteSize = 8;      //每个字节有8位  dcb.Parity = NOPARITY;   //无奇偶校验位  dcb.StopBits = ONESTOPBIT ; //一个停止位  dcb.fBinary = TRUE;  dcb.fParity = TRUE;  SetCommState(hCom, &dcb);  PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);//-------------------------------------------------------------------------------  DWORD dwStoredFlags;  dwStoredFlags = EV_BREAK | EV_CTS   | EV_DSR | EV_ERR | EV_RING |EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;    if (!SetCommMask(hCom, dwStoredFlags))    return FALSE;// error setting communications mask//-------------------------------------------------------------------------------//  CloseHandle(hCom); // 一定注意在函数退出之前对句柄进行释放。     return TRUE;}// dwStoredFlags = EV_BREAK | EV_CTS   | EV_DSR | EV_ERR | EV_RING |EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY ;void Com_handle(void){ switch (dwCommEvent) {  case EV_RXCHAR:       Read_Com();  break;  default:  break; }}BYTE hex2char(char *pBuffer){ BYTE  byte_l,byte; if(*pBuffer=':')  pBuffer++; byte=*pBuffer; pBuffer++; byte_l=*pBuffer; pBuffer++; if(byte<0x3a)  byte=(byte&0x0F)<<4; else  byte=((byte&0x0F)+9)<<4; if(byte_l<0x3a)  byte_l=byte_l&0x0F; else  byte_l=(byte_l&0x0F)+9; byte+=byte_l; return byte;} BOOL Write_Hex_File(char *pBuffer) {  COMSTAT ComStat;  DWORD dwErrorFlags;  BOOL bWriteStat;  BOOL bReadStat; // DWORD NumberOfBytesWritten;//  DWORD dwBytesWrite; BYTE  record_lenght;//HEX 文件数校验// UINT load_address;// BYTE  load_address_l;// BYTE  record_type;// BYTE  record_data;// BYTE  check_sum; char  *send_data_pBuffer; DWORD send_data_length;   do  {   if(*pBuffer==':')   {      send_data_pBuffer=pBuffer;    record_lenght=hex2char(pBuffer);    send_data_length=1+2+4+2+(record_lenght*2)+2;    ClearCommError(hCom,&dwErrorFlags,&ComStat);    bWriteStat = WriteFile(hCom, send_data_pBuffer, send_data_length, &send_data_length, NULL);    if (!bWriteStat)    {     MessageBox( NULL,"写串口失败!" ,"Error",MB_OK);     return FALSE;    }    Sleep(20);// delay 20ms   // bReadStat= Read_Com_Synchronous();    bReadStat= Read_Com();    if (!bReadStat)    {    }   }    pBuffer++;  } while (record_lenght!=0);  if (!bWriteStat)  {   MessageBox( NULL,"写串口失败!" ,"Error",MB_OK);   return FALSE;  }  else   return TRUE;}/*    load_address=hex2char(pBuffer);    load_address_l=hex2char(pBuffer);    load_address=(load_address<<8)+load_address_l;        record_type=hex2char(pBuffer);    */////void Read_Hex_File(char* str) //读取HEX文件,转换为十六进制数据,保存到缓存 hex_buffer,长度为 HexBufferSize/*BlpOverlapped     OOL ReadFile(     HANDLE hFile, //文件的句柄     LPVOID lpBuffer, //用于保存读入数据的一个缓冲区     DWORD nNumberOfBytesToRead, //要读入的字节数     LPDWORD lpNumberOfBytesRead, //指向实际读取字节数的指针     LPOVERLAPPED //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。     //该结构定义了一次异步读取操作。否则,应将这个参数设为NULL );BOOL ReadFile( HANDLE hFile,          //文件的句柄            PVOID lpBuffer,                DWORD nNumberOfBytesToRead,             LPDWORD lpNumberOfBytesRead,  //指向实际读取字节数的指针            LPOVERLAPPED lpOverlapped                         );*/BOOL Read_Com_Synchronous(void){  BOOL bReadStat;  bReadStat=ReadFile(hCom,ReadComstr,64,&ReadCount,NULL);  if(!bReadStat)  {      MessageBox( NULL,"读串口失败!" ,"Error",MB_OK);               return FALSE;  }    return TRUE;}//异步读串口BOOL Read_Com(void){ char lpInBuffer[1024];      //用于保存读入数据的一个缓冲区      DWORD dwBytesRead=1024;   //要读入的字节数  COMSTAT ComStat; DWORD dwErrorFlags; OVERLAPPED m_osRead;     //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。                  //该结构定义了一次异步读取操作。否则,应将这个参数设为NULL  memset(&m_osRead,0,sizeof(OVERLAPPED)); m_osRead.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL); ClearCommError(hCom,&dwErrorFlags,&ComStat); dwBytesRead=min(dwBytesRead,(DWORD)ComStat.cbInQue);  if(!dwBytesRead)  return FALSE;  BOOL bReadStatus;  bReadStatus=ReadFile(hCom,lpInBuffer,dwBytesRead,&dwBytesRead,&m_osRead); if(!bReadStatus)                //如果ReadFile函数返回FALSE {  if(GetLastError()==ERROR_IO_PENDING)      //GetLastError()函数返回ERROR_IO_PENDING,表明串口正在进行读操作    {   WaitForSingleObject(m_osRead.hEvent,2000);   //使用WaitForSingleObject函数等待,直到读操作完成或延时已达到2秒钟    PurgeComm(hCom, PURGE_TXABORT| PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); //当串口读操作进行完毕后,m_osRead的hEvent事件会变为有信号   return dwBytesRead;  } return 0; } PurgeComm(hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); return dwBytesRead;}//读取HEX文件并将其转换成HEX格式,存入缓存;void Read_File(char* str) {      HANDLE pfile;      pfile =CreateFile(str,GENERIC_READ,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//用这个函数比OpenFile好      if ( pfile == INVALID_HANDLE_VALUE)      {          // MessageBox( NULL,"打开文件失败" ,"Error",MB_OK);           CloseHandle(pfile);           // 一定注意在函数退出之前对句柄进行释放。   Read_hex_file_ok=0;  return;  }  DWORD filesize=GetFileSize(pfile,NULL);  ReadFile(pfile,hex_file_buffer,filesize,&hex_file_real_size,NULL);//保存hex文件至缓存  Read_hex_file_ok=1;// char* buffer=new char[filesize+1];      // 最后一位为 '/0',C-Style 字符串的结束符。 // DWORD readsize; // ReadFile(pfile,buffer,filesize,&readsize,NULL);  // buffer[filesize]=0;  MessageBox(NULL,hex_file_buffer,"hex file",MB_OK); // /* BYTE  record_lenght;//HEX 文件数校验 BYTE  load_address; BYTE  record_type; BYTE  record_data; BYTE  check_sum;*/// delete[] buffer;     // 注意是delete[] 而不是 delete  CloseHandle(pfile);   // 关闭句柄。 }//  函数: void Hex_Fiel_Open(void)//HEX文件打开// lStructSize   // 指定这个结构的大小,以字节为单位。   // Windows 95/98和Windows NT 4.0:特意为Windows 95/98或Windows NT 4.0,及带有WINVER和_WIN32_WINNT >= 0x0500编译时,  //  为这个成员使用OPENFILENAME_SIZE_VERSION_400。   // Windows 2000及更高版本:这个参数使用sizeof (OPENFILENAME) 。  #define     MAX_FILE_FOR_SEL 20 //最大允许选择的文件数   OPENFILENAME ofn = { OPENFILENAME_SIZE_VERSION_400 };//or  {sizeof (OPENFILENAME)} TCHAR szPathName[MAX_PATH *MAX_FILE_FOR_SEL];  //获取文件路径//文件选择对话框void Hex_Fiel_Open_Init(void){ ofn.hwndOwner =GetForegroundWindow();              // 打开OR保存文件对话框的父窗口        ofn.lpstrFilter = "hex文件(*.hex)\0*.hex\0All Files(*.*)\0*.*\0\0";       //过滤器 如果为 NULL 不使用过滤器   //具体用法看上面  注意 \0 ofn.nFilterIndex = 1;  lstrcpy(szPathName, TEXT(""));   ofn.lpstrFile = szPathName;   ofn.nMaxFile = sizeof(szPathName);                 //存放用户选择文件的 路径及文件名 缓冲区    ofn.lpstrTitle = TEXT("选择要下载的hex文件");             //选择文件对话框标题   TCHAR szCurDir[MAX_PATH];   GetCurrentDirectory(sizeof(szCurDir),szCurDir);   ofn.lpstrInitialDir=szCurDir;                    //设置对话框显示的初始目录   // ofn.Flags = OFN_EXPLORER |OFN_ALLOWMULTISELECT| OFN_FILEMUSTEXIST;                               //如果需要选择多个文件 则必须带有  OFN_ALLOWMULTISELECT标志    ofn.Flags = OFN_EXPLORER;}  ////  函数: WndProc(HWND, UINT, WPARAM, LPARAM)////  目的: 处理主窗口的消息。////  WM_COMMAND - 处理应用程序菜单//  WM_PAINT - 绘制主窗口//  WM_DESTROY - 发送退出消息并返回//LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; switch (message) {  case WM_COMMAND:     //按钮处理    wmId    = LOWORD(wParam);    wmEvent = HIWORD(wParam);     if(((HWND)lParam ==hwndSlectPortButton) && (HIWORD(wParam) ==BN_CLICKED))   //搜索串口 按钮处理     {       SetComm( );     }        if(((HWND)lParam ==hwnSlectbutton) && (HIWORD(wParam) ==BN_CLICKED))      //文件选择按钮处理     {      Hex_Fiel_Open_Init();      GetOpenFileName(&ofn);      SetWindowText(hwndpath,szPathName);      Read_File(szPathName) ;     }     if(((HWND)lParam ==hwnDownloadbutton) && (HIWORD(wParam) ==BN_CLICKED))   //文件选择按钮处理     {      if(Read_hex_file_ok)      {       Write_Hex_File(hex_file_buffer);        //Read_hex_file_ok=0;      }      else      MessageBox( NULL,"选择要下载的hex文件" ,NULL,MB_OK);              }  break;  // 分析菜单选择:  switch (wmId)  {   case IDM_ABOUT:    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);    break;   case IDM_EXIT:    DestroyWindow(hWnd);    break;   default:    return DefWindowProc(hWnd, message, wParam, lParam);  }  break; case WM_PAINT://绘图代码...  hdc = BeginPaint(hWnd, &ps);     TextOut(hdc,10,10,"串口号 ",6);  EndPaint(hWnd, &ps);  break;/*BUTTON :按钮COMBOBOX :复合框 EDIT :编辑 LISTBOX :列表 RichEdit :Rich Edit version 1.0RICHEDIT_CLASS :Rich Edit version 2.0SCROLLBAR :滚动条STATIC :静态"\r\n" 来表示一个换行  //创建编辑框“edit”是windows内部定义的编辑框的窗口类名,系统内部定义类名,不须再注册;*/ case WM_CREATE:    hwndPortNum= CreateWindow("edit",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL,10,40,100,25,hWnd,NULL,NULL,NULL);   hwndSlectPortButton = CreateWindow("button","打开串口",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,120,40,100,25,hWnd,NULL,NULL,NULL);   hwndpath =CreateWindow("edit",NULL,WS_CHILD|WS_VISIBLE|WS_BORDER|ES_AUTOHSCROLL,10,70,320,25,hWnd,NULL,NULL,NULL);                                     hwnSlectbutton=CreateWindow("button","选择文件",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,340,70,100,25,hWnd,NULL,NULL,NULL);   hwnDownloadbutton=CreateWindow("button","下载程序",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,10,105,100,25,hWnd,NULL,NULL,NULL); //  hwnlistbox =CreateWindow( "edit", NULL,WS_VISIBLE|WS_CHILD|WS_BORDER|WS_VSCROLL|ES_MULTILINE|ES_WANTRETURN|ES_AUTOHSCROLL|ES_AUTOVSCROLL,10, 140, 570,190 ,hWnd, NULL, NULL, NULL);   hwndList = CreateWindow ("listbox", NULL,WS_CHILD | WS_VISIBLE | LBS_STANDARD,10, 140,100,25,hWnd, (HMENU) ID_LIST,(HINSTANCE) GetWindowLong (hWnd, GWL_HINSTANCE),NULL) ;   return 0 ; case WM_DESTROY:  PostQuitMessage(0);  break; default:  return DefWindowProc(hWnd, message, wParam, lParam); } return 0;}// “关于”框的消息处理程序。INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){ UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG:  return (INT_PTR)TRUE; case WM_COMMAND:  if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  {   EndDialog(hDlg, LOWORD(wParam));   return (INT_PTR)TRUE;  }  break; } return (INT_PTR)FALSE;}


 

芯片的中断入口已重定位。

程序模板:

;P1.2口 LED 闪烁$INCLUDE(C8051F330.INC); Register definition file.ledequ p1.2VECTOREQU400H;================中断向量地址=======================ORGVECTOR+00H;复位向量LJMPMAINORGVECTOR+03H;外部中断0 (INT0)LJMPMAINORGVECTOR+0BH;定时器0溢出LJMPMAINORGVECTOR+13H;外部中断1 (INT1)LJMPMAINORGVECTOR+1BH;定时器1溢出LJMPMAINORGVECTOR+23H;UART0LJMPUART_ISRORGVECTOR+2BH;定时器2溢出LJMPMAINORGVECTOR+33H;SPI0LJMPMAINORGVECTOR+3BH;SMB0LJMPMAINORGVECTOR+4BH;ADC0窗口比较LJMPMAINORGVECTOR+53H;ADC0转换结束LJMPADC_ISRORGVECTOR+5BH;可编程计数器阵列LJMPMAINORGVECTOR+63H;比较器0LJMPMAINORGVECTOR+73H;定时器3溢出LJMPMAIN;================程序入口=======================ORGVECTOR+80H;程序入口地址MAIN:MOV SP,#30HMOV PSW,#00H;-----------------------------------------------------MOV  OSCICN,#083h   MOV  RSTSRC,#0x04;              ;Enable missing clock detector    ANL  PCA0MD,#0BFh    MOV  PCA0MD,#000h;disable watch dog;    mov  P1MDOUT,#004h    mov  XBR1, #040h;-----------------------------------------------------MAIN_LOOP:movr2,#010hdelay1:movr1,#0ffhdelay:movr0,#0ffhdjnzr0,$djnzr1,delaydjnzr2,delay1cplledSJMPMAIN_LOOPRETEND


 

 

 这个bootload 做的比较简单,不管怎样这一套东西总算弄齐了,后续再在此基础上完善。

希望做过这方面工作的朋友给些建议,谢谢... O(∩_∩)O~

 

 

 

原创粉丝点击