STM8L052R8在线升级例程及步骤说明(3)

2019-04-23 14:53

place in FarFuncCode { ro section .far.rodata,

ro section .far_func.text };

place in HugeFuncCode { ro section .huge.rodata,

ro section .huge_func.text };

place in Eeprom { section .eeprom.noinit };

place in Eeprom { section .eeprom.data };

place in Eeprom { section .eeprom.rodata };

/////////////////////////////////////////////////////////////////

2、APP程序

(1)主函数

#include \

void Clk_Init(void) {

CLK_SWR = 0x01; //HSI selected as system clock source CLK_CKDIVR = 0x00; //System clock source/1 }

void Jump_To_App(void) {

asm(\ SP \ asm(\ A, $FF\ asm(\ XL, A \ asm(\, X \

asm(\ //9000是要跳转到偏移地址 }

void main(void) {

Clk_Init();

PC_DDR |= 0x80; //PC7输出口 PC_CR1 |= 0x80; //PC7推挽输出 PC_CR2 |= 0x80; //PC7输出速度最大为10MHZ PC_ODR &= ~0x80;//PC7输出低

Timer2_Init(200);

rim();

while(1) {

}

}

(2)定时器函数

TIM TimerCount; //定时器计数器

void Speak(void) { u8 i = 255; while(i > 0) { Buzzer_On(); Delayus(185); Buzeer_Off(); Delayus(185); i--; } }

void Buzzer(u8 speakcnt) //算了,把Buzzer函数也贴出来吧 { while(speakcnt > 0) { Speak(); Delayms(30); Delayms(30); Delayms(30); speakcnt--; } }

/*********************************************** * 文件名 :Timer2_Init

* 描述 :定时器4初始化 1ms定时周期 * 创建时间 :2017-05-17

************************************************/ void Timer2_Init(u8 ms) {

if(ms>254) ms = 254;

CLK_PCKENR1 |= 0x01; //Enable TIM2 clock TIM2_PSCR = 0x06; //prescaler:(2^6) = /64 TIM2_ARRH = ms; TIM2_ARRL = 250; //SYS_CLK_HSI_DIV1 Auto-Reload value: 16M / 64 = 1/4M, 1/4M / 1k = 250 TIM2_CNTRH = 0; TIM2_CNTRL = 0; //Counter value: 0, to compensate the initialization of TIMER TIM2_IER |= 0X01; //TIM2 Update interrupt enabled TIM2_SR1 &= ~0x01; //clear update flag TIM2_CR1 |= 0x01; //Enable Counter }

/*********************************************** * 文件名 :Timer2

* 描述 :定时器2中断入口函数 * 创建时间 :2017-05-17

************************************************/ #pragma vector = 0x15

__interrupt void Timer2_IRQhandle(void) {

TimerCount.T2++;

if(TimerCount.T2 == 5) {

TimerCount.T2 = 0; Buzzer(1); //Buzzer是蜂鸣器函数,大家板子上没有的可以随便写一个验证函数, //比如LED什么的,主要是为了验证升级成功了 }

TIM2_SR1 &= ~0x01; //clear }

(3)lnkstm8l052r8_App.icf

///////////////////////////////////////////////////////////////// // Example ILINK command file for

// STM8 IAR C/C++ Compiler and Assembler. //

// Copyright 2014 IAR Systems AB. //

/////////////////////////////////////////////////////////////////

define memory with size = 16M;

define region TinyData = [from 0x00 to 0xFF];

define region NearData = [from 0x0000 to 0x0FFF];

define region Eeprom = [from 0x1000 to 0x10FF];

define region BootROM = [from 0x6000 to 0x67FF];

define region NearFuncCode = [from 0xB800 to 0xDFFF];

define region FarFuncCode = [from 0xB800 to 0xDFFF];

define region HugeFuncCode = [from 0xB800 to 0xDFFF]; /*

define region NearFuncCode = [from 0x8000 to 0xFFFF];

define region FarFuncCode = [from 0x8000 to 0xFFFF]

| [from 0x10000 to 0x17FFF];

define region HugeFuncCode = [from 0x8000 to 0x17FFF]; */

/////////////////////////////////////////////////////////////////

define block CSTACK with size = _CSTACK_SIZE {};

define block HEAP with size = _HEAP_SIZE {};

define block INTVEC with size = 0x80 { ro section .intvec };

// Initialization

initialize by copy { rw section .far.bss,

rw section .far.data,

rw section .far_func.textrw, rw section .huge.bss, rw section .huge.data,

rw section .huge_func.textrw,

rw section .iar.dynexit, rw section .near.bss, rw section .near.data,

rw section .near_func.textrw, rw section .tiny.bss, rw section .tiny.data, ro section .tiny.rodata };

initialize by copy with packing = none {section __DLIB_PERTHREAD };

do not initialize { rw section .eeprom.noinit, rw section .far.noinit, rw section .huge.noinit, rw section .near.noinit, rw section .tiny.noinit, rw section .vregs };

// Placement

place at start of TinyData { rw section .vregs }; place in TinyData { rw section .tiny.bss,

rw section .tiny.data, rw section .tiny.noinit, rw section .tiny.rodata };

place at end of NearData { block CSTACK }; place in NearData { block HEAP,

rw section __DLIB_PERTHREAD, rw section .far.bss, rw section .far.data, rw section .far.noinit,

rw section .far_func.textrw, rw section .huge.bss, rw section .huge.data, rw section .huge.noinit,

rw section .huge_func.textrw, rw section .iar.dynexit, rw section .near.bss, rw section .near.data, rw section .near.noinit,

rw section .near_func.textrw };

place at start of NearFuncCode { block INTVEC };

place in NearFuncCode { ro section __DLIB_PERTHREAD_init, ro section .far.data_init,

ro section .far_func.textrw_init, ro section .huge.data_init,

ro section .huge_func.textrw_init, ro section .iar.init_table, ro section .init_array,

ro section .near.data_init, ro section .near.rodata, ro section .near_func.text, ro section .near_func.textrw_init,

ro section .tiny.data_init, ro section .tiny.rodata_init };

place in FarFuncCode { ro section .far.rodata,

ro section .far_func.text };

place in HugeFuncCode { ro section .huge.rodata,

ro section .huge_func.text };

place in Eeprom { section .eeprom.noinit };

place in Eeprom { section .eeprom.data };

place in Eeprom { section .eeprom.rodata };

/////////////////////////////////////////////////////////////////

二、STM8L052R8在线升级步骤

1、在bootloader程序中重新映射中断向量表(直接放在bootloader程序就行),其中0x8200B804中的B800是重新映射的起始地址, //中断向量重映射

__root const long reintvec[]@\{

0x82008080,0x8200B804,0x8200B808,0x8200B80c, 0x8200B810,0x8200B814,0x8200B818,0x8200B81c, 0x8200B820,0x8200B824,0x8200B828,0x8200B82c, 0x8200B830,0x8200B834,0x8200B838,0x8200B83c, 0x8200B840,0x8200B844,0x8200B848,0x8200B84c, 0x8200B850,0x8200B854,0x8200B858,0x8200B85c, 0x8200B860,0x8200B864,0x8200B868,0x8200B86c,

0x8200B870,0x8200B874,0x8200B878,0x8200B87c, };

2、重新分配bootloader工程的lnkstm8l052r8_boot.icf文件中定义的地址起始,定义bootloader文件占用空间的大小,例如:

更改后的地址分配 0x8000--0xD7FF bootloader工程被分配占用22K空间 define region NearFuncCode = [from 0x8000 to 0xD7FF]; define region FarFuncCode = [from 0x8000 to 0xD7FF]; define region HugeFuncCode = [from 0x8000 to 0xD7FF]; /*

原文件的空间分配

define region NearFuncCode = [from 0x8000 to 0xFFFF]; define region FarFuncCode = [from 0x8000 to 0xFFFF]

| [from 0x10000 to 0x17FFF]; define region HugeFuncCode = [from 0x8000 to 0x17FFF]; */

3、重新分配App工程的lnkstm8l052r8_App.icf文件中定义的地址起始,定义App文件占用空间的大小,例如:重新分配APP的起始地址, 0xB800 -- 0xDFFF App工程被分配占用10K空间

define region NearFuncCode = [from 0xB800 to 0xDFFF]; define region FarFuncCode = [from 0xB800 to 0xDFFF]; define region HugeFuncCode = [from 0xB800 to 0xDFFF]; /*

原文件的空间分配

define region NearFuncCode = [from 0x8000 to 0xFFFF]; define region FarFuncCode = [from 0x8000 to 0xFFFF]

| [from 0x10000 to 0x17FFF]; define region HugeFuncCode = [from 0x8000 to 0x17FFF];

*/ 4、将lnkstm8l052r8_boot.icf和lnkstm8l052r8_App.icf,放置在安装目录下的config文件夹下面,(“C:\\Program Files\\IAR Systems\\Embedded Workbench 7.0\\stm8\\config”),否则有些功能可能不能实现。

5、需要在Opition中的LINK选项下链接“$TOOLKIT_DIR$\\config\\lnkstm8l052r8_boot.icf”“$TOOLKIT_DIR$\\config\\lnkstm8l052r8_App.icf”,否则不能实现在线升级。不能运行App程序。 6、bootloader工程接收并向Flash中写完App工程的数据后,会向APP_Valid_address地址写入temp_Valid_flag数组的数据,然后软件复位,重新开始运行bootloader程序,检测到APP_Valid_address地址的数据有效后,就跳向App起始地址开始运行App程序。

7、 用串口助手(sscom3)发送升级命令7E 01 00 02 02 56 17 5B E7,其中02 56是要升级的总字节数(要根据自己的文件大小更改),17 58是16位的CRC校验(命令不同校验码不同),7E、E7分别是包头和包尾,01是命令,发送完升级命令后,bootloader程序会发送0x55到串口助手,然后再发送你要升级的文件(升级文件用的.bin格式),发送完成后蜂鸣器每隔一秒响一次。

8、因为百度文库不能上传压缩包,只能上传文档,所以大部分的程序只能都贴到word里了,看着有些费劲,但是大部分的程序都贴出来了,想学习在线升级的朋友就不要嫌麻烦,自己建立工程整理代码吧!


STM8L052R8在线升级例程及步骤说明(3).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:学生信息管理系统

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: