这个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 return cra2 equ 0ah ; carriage return error_led equ p1.2 ; active low - clr to turn on load_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 80h main: clr EA lcall init ; init serial port
clr c mov c,load_en jc done lcall erase_flash call intro ; print welcome message call load1 done: mov dptr,#prompt8 ; end lcall outstr ljmp ram ; start running program
error: mov dptr,#prompt6 ; end lcall outstr stop: sjmp $
;******************************************************************** ; Receive hex file and write it to flash ;******************************************************************** load1: lcall inchar skip1: 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 XRAM erase_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
写给C8051F330的bootload、WIN32 API iap下载上位机
最新推荐文章于 2023-04-01 23:12:00 发布
这篇博客介绍了如何基于C8051F330微控制器编写一个简单的bootloader,该bootloader在上电后检查P1.3引脚,根据电平执行用户程序或启动HEX文件下载。程序主要用汇编语言编写,而上位机部分使用了WIN32 API。开发环境为Keil和VS2012。上位机每隔20ms发送HEX文件记录,并计划增加握手和校验功能。博主希望得到相关经验人士的建议。
摘要由CSDN通过智能技术生成