历史上的今天
返回首页

历史上的今天

今天是:2024年09月05日(星期四)

正在发生

2018年09月05日 | STM8S:Debug调试正常,烧录程序运行不正常

2018-09-05 来源:eefocus

最近有一个项目需要用到STM8S103F3单片机。在开始之前以为会很容易,可是实际操作起来,却遇到不少问题 。其中最令我感到困惑的一个问题是:我在调试程序的时候程序可以运行正常,但当我把程序烧录进去断电重启后却运行不正常。


试了很多方法,都没有找到问题所在。最后,我把Start-up file 选择默认的就可以。之前不知道在哪里看到过可以不使用系统的默认启动文件,可以直接在stm8_interrupt_vector.c中将_stext()改为main();现在看来真的是害死个让人。

关于STM8S的启动过程:

1)首先bootloader(ROM中)从0x6000地址启动。

2)从bootloader跳转到0x8000(内部FLASH起始地址),0x8000后面才是软件设计可以控制的。很多人不明白的是stm8库里面提供的相关代码,具体流程如下:

a)中断向量表:大家都知道0x8000地址放的是中断函数的地址,而‘0x82’则是stm8内部的中断指令。程序执行到这会自动跳转到中断向量地址所在函数。

b)mian函数到底从哪开始?

这也许是大家最纳闷的了,起始原来很简单:关键是stm8有个复位中断,定义在

stm8_interrupt_vector.c中:

"(void @near (*)())0x8200,"

"_stext, /* RESET */”"

extern void @near _stext(); /* startup routine */

void @near (* const _vectab[])() =

{



"(void @near (*)())0x8200,"

"_stext, /* RESET */"



"(void @near (*)())0x8200,"

"TRAP_IRQHandler, /* TRAP - Software interrupt */"



"(void @near (*)())0x8200,"

"TLI_IRQHandler, /* irq0 - External Top Level interrupt (TLI) */"



"(void @near (*)())0x8200,"

"AWU_IRQHandler, /* irq1 - Auto Wake Up from Halt interrupt */"

"(void @near (*)())0x8200,"

"CLK_IRQHandler, /* irq2 - Clock Controller interrupt */"

"(void @near (*)())0x8200,"

"EXTI_PORTA_IRQHandler, /* irq3 - External interrupt 0 (GPIOA) */"

"(void @near (*)())0x8200,"

"EXTI_PORTB_IRQHandler, /* irq4 - External interrupt 1 (GPIOB) */"

"(void @near (*)())0x8200,"

"EXTI_PORTC_IRQHandler, /* irq5 - External interrupt 2 (GPIOC) */"

"(void @near (*)())0x8200,"

"EXTI_PORTD_IRQHandler, /* irq6 - External interrupt 3 (GPIOD) */"

"(void @near (*)())0x8200,"

"EXTI_PORTE_IRQHandler, /* irq7 - External interrupt 4 (GPIOE) */"



#ifdef STM8S208

"(void @near (*)())0x8200,"

"CAN_RX_IRQHandler, /* irq8 - CAN Rx interrupt */"

"(void @near (*)())0x8200,"

"CAN_TX_IRQHandler, /* irq9 - CAN Tx/ER/SC interrupt */"



#elif defined (STM8S903)

"(void @near (*)())0x8200,"

"EXTI_PORTF_IRQHandler, /* irq8 - External interrupt 5 (GPIOF) */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq9 - Reserved */"

"#else /*STM8S207, STM8S105 or STM8S103*/"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq8 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq9 - Reserved */"

#endif /*STM8S208*/

"(void @near (*)())0x8200,"

"SPI_IRQHandler, /* irq10 - SPI End of transfer interrupt */"

"(void @near (*)())0x8200,"

"TIM1_UPD_OVF_TRG_BRK_IRQHandler, /* irq11 - TIM1 Update/Overflow/Trigger/Break interrupt */"

"(void @near (*)())0x8200,"

"TIM1_CAP_COM_IRQHandler, /* irq12 - TIM1 Capture/Compare interrupt */"



#ifdef STM8S903

"(void @near (*)())0x8200,"

"TIM5_UPD_OVF_BRK_TRG_IRQHandler, /* irq13 - TIM5 Update/Overflow/Break/Trigger interrupt */"

"(void @near (*)())0x8200,"

"TIM5_CAP_COM_IRQHandler, /* irq14 - TIM5 Capture/Compare interrupt */"



"#else /*STM8S208, STM8S207, STM8S105 or STM8S103*/"

"(void @near (*)())0x8200,"

"TIM2_UPD_OVF_BRK_IRQHandler, /* irq13 - TIM2 Update/Overflow/Break interrupt */"

"(void @near (*)())0x8200,"

"TIM2_CAP_COM_IRQHandler, /* irq14 - TIM2 Capture/Compare interrupt */"

#endif /*STM8S903*/



#if defined (STM8S208) || defined(STM8S207) || defined(STM8S105)

"(void @near (*)())0x8200,"

"TIM3_UPD_OVF_BRK_IRQHandler, /* irq15 - TIM3 Update/Overflow/Break interrupt */"

"(void @near (*)())0x8200,"

"TIM3_CAP_COM_IRQHandler, /* irq16 - TIM3 Capture/Compare interrupt */"

#else

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq15 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq16 - Reserved */"

"#endif /*STM8S208, STM8S207 or STM8S105*/"



#ifdef STM8S105

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq17 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq18 - Reserved */"

#else

"(void @near (*)())0x8200,"

"UART1_TX_IRQHandler, /* irq17 - UART1 Tx complete interrupt */"

"(void @near (*)())0x8200,"

"UART1_RX_IRQHandler, /* irq18 - UART1 Rx interrupt */"

#endif /*STM8S105*/

"(void @near (*)())0x8200,"

"I2C_IRQHandler, /* irq19 - I2C interrupt */"

#if defined(STM8S208) || defined(STM8S207)

"(void @near (*)())0x8200,"

"UART3_TX_IRQHandler, /* irq20 - UART3 Tx interrupt */"

"(void @near (*)())0x8200,"

"UART3_RX_IRQHandler, /* irq21 - UART3 Rx interrupt */"

#elif defined (STM8S105)

"(void @near (*)())0x8200,"

"UART2_TX_IRQHandler, /* irq20 - UART2 Tx interrupt */"

"(void @near (*)())0x8200,"

"UART2_RX_IRQHandler, /* irq21 - UART2 Rx interrupt */"

"#else /* STM8S103, STM8S903 */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq20 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq21 - Reserved */"

"#endif /* STM8S208, STM8S207 */"

#if defined(STM8S208) || defined(STM8S207)

"(void @near (*)())0x8200,"

"ADC2_IRQHandler, /* irq22 - ADC2 end of conversion interrupt */"

"#else /* STM8S105, STM8S103, STM8S903 */"

"(void @near (*)())0x8200,"

"ADC1_IRQHandler, /* irq22 - ADC1 end of conversion/Analog watchdog interrupts */"

"#endif /* STM8S208, STM8S207 */"

#ifdef STM8S903

"(void @near (*)())0x8200,"

"TIM6_UPD_OVF_TRG_IRQHandler, /* irq23 - TIM6 Update/Overflow/Trigger interrupt */"

#else

"(void @near (*)())0x8200,"

"TIM4_UPD_OVF_IRQHandler, /* irq23 - TIM4 Update/Overflow interrupt */"

#endif /*STM8S903*/

"(void @near (*)())0x8200,"

"EEPROM_EEC_IRQHandler, /* irq24 - FLASH interrupt */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq25 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq26 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq27 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq28 - Reserved */"

"(void @near (*)())0x8200,"

"NonHandledInterrupt, /* irq29 - Reserved */"

};


复位中断的地址就是0x8000后面的第一个跳转地址,复位后程序自然会跳转到‘_stext’所在地址。‘_stext’在哪里?从‘extern void @near _stext(); /* startup routine */’可以知道它定义在别的文件中,这个文件就是stm8的启动文件,用汇编写的crtsi0.sm8,在cosmic安装目录下可以找到:

; C STARTUP FOR STM8

; WITH AUTOMATIC DATA INITIALISATION

; Copyright (c) 2006 by COSMIC Software

;

"xref _main, __memory, __idesc__, __stack"

"xref.b c_x, c_y, __endzp"

"xdef _exit, __stext"

;

; start address of zpage

;

switch .ubsct

__suzp:

;

; start address of bss

;

switch .bss

__sbss:

;

; startup routine from reset vector

;

switch .text

__stext:

;

; initialize stack pointer

;

"ldw x,#__stack ; stack pointer"

"ldw sp,x ; in place"

;

; setup initialized data

;

"ldw y,__idesc__ ; data start address"

"ldw x,#__idesc__+2 ; descriptor address"

ibcl:

"ld a,(x) ; test flag byte"

jreq zero ; no more segment

"bcp a,#$60 ; test for moveable code segment"

"jreq qbcl ; yes, skip it"

"ldw c_x,x ; save pointer"

"ldw x,(3,x) ; move end address"

"ldw c_y,x ; in memory"

"ldw x,c_x ; reload pointer"

"ldw x,(1,x) ; start address"

dbcl:

"ld a,(y) ; transfer"

"ld (x),a ; byte"

incw x ; increment

incw y ; pointers

"cpw y,c_y ; last byte ?"

"jrne dbcl ; no, loop again"

"ldw x,c_x ; reload pointer"

qbcl:

"addw x,#5 ; next descriptor"

jra ibcl ; and loop

;

; reset uninitialized data in zero page

; 将zero page中未初始化的变量区域清0

zero:

"ldw x,#__suzp ; start of uninitialized zpage ;__suzp为未初始化区域的首地址,也就是.ubsct的起始地址"

jra loop ; test segment end first

zbcl:

"ld (x),a ; clear byte ;清0"

incw x ; next byte;地址加1

loop:

"cpw x,#__endzp ; end of zpage ;__endzp为zeropage内未初始化变量的结束地址,也就是.ubsct的结束地址,"

;_endzp定义在.lkf(链接文件里),这句的意思是比较现地址是否为.ubsct的结束地址。

"jrne zbcl ; no, continue ;如果.ubsct未初始化完成跳转到abcl继续进行,jrne:不等于则跳转"

;

; reset uninitialized data in bss

"; 将ram中的未初始化变量区域清0,也就是清零.bss段所在区域"

"ldw x,#__sbss ; start address"

jra ok ; test segment end first

bbcl:

"ld (x),a ; clear byte"

incw x ; next byte

ok:

"cpw x,#__memory ; compare end"

"jrne bbcl ; not equal, continue"

; execute main() function

; may be called by a 'jp' instruction if no return expected

;

call _main ; execute main

_exit:

jra _exit ; and stay here

;

end


从启动代码中自然会找到call _main入口。


推荐阅读

史海拾趣

Goldstar Electron Co Ltd公司的发展小趣事

对于27MHz晶体振荡器电路,网友可能会提出多种问题,以下是一些常见问题及其详细回答:

一、电路设计相关问题

  1. 如何设计一个简单的27MHz晶体振荡器电路?
    • 回答:设计一个简单的27MHz晶体振荡器电路通常包括晶体本身、两个反馈电容、一个或多个电阻以及可能的放大元件(如晶体管或集成电路中的振荡器部分)。例如,可以使用一个并联型晶体振荡器电路,其中晶体与两个电容形成谐振电路,并通过一个放大元件(如CMOS反相器)提供正反馈以维持振荡。具体设计可参考技术资料(如华强电子网)提供的电路图,并根据实际需要进行调整。
  2. 如何选择合适的反馈电容和电阻值?
    • 回答:反馈电容和电阻的选择对振荡器的稳定性和频率精度至关重要。电容值通常根据晶体的规格和所需的振荡频率来确定,而电阻值则用于限制放大器的增益,以防止振荡器过度放大并产生不稳定现象。选择时,建议参考晶体振荡器的数据手册或相关设计指南,并结合实验测试来找到最佳值。

二、电路性能相关问题

  1. 如何减少27MHz晶体振荡器的谐波失真?
    • 回答:谐波失真通常是由于电路中的非线性元件或设计不当引起的。为了减少谐波失真,可以采取以下措施:
      • 选择低谐波失真的晶体振荡器。
      • 在电路中添加低通滤波器以滤除高频谐波。
      • 优化电路设计,减少非线性元件的使用,并确保电路元件的匹配性。
  2. 如何提高27MHz晶体振荡器的频率稳定性?
    • 回答:频率稳定性受多种因素影响,包括晶体的物理特性、环境温度、电源电压波动等。提高频率稳定性的方法包括:
      • 选择高质量的晶体振荡器,确保其具有较低的频率漂移和温度系数。
      • 在电路中添加温度补偿电路,以抵消温度变化对频率的影响。
      • 使用稳定的电源电压,并在必要时添加电压稳压器。
      • 优化电路布局和接地设计,减少电磁干扰和噪声。

三、电路调试与测试相关问题

  1. 如何调试27MHz晶体振荡器电路以确保其正常工作?
    • 回答:调试晶体振荡器电路时,可以按照以下步骤进行:
      • 检查电路连接是否正确,确保所有元件都已正确安装。
      • 使用示波器观察振荡波形,确认其频率和幅度是否符合要求。
      • 调整反馈电容和电阻值,以优化振荡器的性能和稳定性。
      • 检查电源电压和电流是否稳定,并调整至推荐值。
      • 如果发现谐波失真或其他问题,根据具体情况采取相应的解决措施。
  2. 如何测试27MHz晶体振荡器的输出频率和相位噪声?
    • 回答:测试晶体振荡器的输出频率和相位噪声通常需要使用专业的测试设备,如频率计和相位噪声分析仪。测试时,将振荡器的输出连接到测试设备的输入端,并设置适当的测试参数。通过测试设备可以准确测量振荡器的输出频率和相位噪声水平,从而评估其性能是否符合要求。

四、其他常见问题

  1. 27MHz晶体振荡器适用于哪些应用场景?
    • 回答:27MHz晶体振荡器由于其较高的频率和较好的稳定性,广泛应用于无线通信、雷达系统、电子测量仪器等领域。在这些应用场景中,晶体振荡器作为时钟源或频率基准,为系统提供稳定的频率信号。
  2. 如何延长27MHz晶体振荡器的使用寿命?
    • 回答:延长晶体振荡器的使用寿命需要注意以下几点:
      • 避免在极端温度或湿度条件下使用。
      • 保持电源电压稳定,避免频繁波动。
      • 定期检查电路连接和元件状态,及时更换损坏的元件。
      • 避免机械冲击和振动对晶体振荡器的影响。
      • 选择质量可靠、性能稳定的晶体振荡器产品。
Amphenol RF公司的发展小趣事

Amphenol RF 是 Amphenol 公司的一个子公司,专注于设计、制造和销售射频连接器和组件,在电子行业中占据重要地位。以下是关于 Amphenol RF 公司发展的五个相关故事:

  1. 创立与早期发展:Amphenol RF 公司的历史可以追溯到20世纪40年代,当时被称为RF Connector Division。最初,公司主要致力于生产射频连接器和组件,为通信、航空航天、军事和工业市场提供射频连接解决方案。随着射频技术的发展和市场需求的增长,Amphenol RF 逐渐壮大成为射频连接器领域的重要参与者。

  2. 技术创新与产品多样化:Amphenol RF 公司在射频领域持续进行技术创新,并不断推出新型的射频连接器和组件产品。公司致力于提升产品的性能、可靠性和适应性,满足客户对高频射频应用的需求。除了传统的射频连接器,Amphenol RF 还推出了一系列新型产品,如微波连接器、同轴连接器、板对板连接器等,拓展了产品线的多样性。

  3. 客户合作与定制化解决方案:Amphenol RF 公司与客户建立了紧密的合作关系,共同开发定制化的射频连接器和组件解决方案。公司的工程团队与客户密切合作,根据客户的需求和应用场景,设计和制造符合特定要求的产品。这种定制化解决方案能够满足客户个性化的需求,为客户提供更加专业和完善的服务。

  4. 质量控制与认证标准:Amphenol RF 公司高度重视产品质量控制,并严格遵循国际质量管理体系标准。公司的生产工艺和质量管理体系符合ISO 9001质量管理体系认证标准,以确保产品质量的稳定性和可靠性。此外,Amphenol RF 公司的产品还通过了各种行业和应用领域的认证标准,如航空航天领域的MIL-SPEC标准等,确保产品符合行业标准和规定。

  5. 全球市场拓展与合作伙伴关系:除了在美国的生产基地外,Amphenol RF 公司还在全球范围内设有多个销售办事处和代理商网络,拓展了国际市场份额。公司与全球各种行业领先企业建立了长期稳定的合作关系,共同推动产品的创新和市场拓展。通过全球市场拓展和合作伙伴关系,Amphenol RF 公司不断扩大业务规模,增强了在射频连接器领域的市场竞争力。

这些故事展示了 Amphenol RF 公司从成立初期到如今在技术创新、产品多样化、客户合作与定制化解决方案、质量控制与认证标准以及全球市场拓展与合作伙伴关系等方面取得的重要进展。

HIT(日立)公司的发展小趣事
对于可能产生热量的元件(如可控硅),应采取适当的散热措施,防止元件过热损坏。
ADATA公司的发展小趣事
对于可能产生热量的元件(如可控硅),应采取适当的散热措施,防止元件过热损坏。
雅特力(Artery)公司的发展小趣事

在发展过程中,雅特力积极寻求与其他企业的战略合作,以实现共赢发展。通过与上下游企业建立紧密的合作关系,雅特力不仅确保了供应链的稳定性和高效性,还获得了更多的技术支持和市场资源。同时,雅特力还注重与同行业企业的交流与合作,共同推动电子行业的进步与发展。这些战略合作不仅增强了雅特力的综合实力和市场竞争力,也为整个电子行业的繁荣做出了积极贡献。

综上所述,雅特力公司通过技术创新、全球市场布局、企业社会责任、人才培养和战略合作等多个方面的努力,实现了从初创企业到行业领军者的华丽转身。这些故事不仅展现了雅特力的发展历程和成就,也揭示了其在电子行业中的重要地位和影响力。

Galaxy ( Bel )公司的发展小趣事

随着公司实力的不断增强,雅特力开始将目光投向全球市场。公司积极参与国际电子展会和论坛,与全球各地的客户和合作伙伴建立了广泛的联系。同时,雅特力还通过设立海外分支机构、开展跨国合作等方式,进一步拓展其全球市场。这些举措不仅提升了雅特力的品牌知名度和影响力,也为公司的长远发展奠定了坚实的基础。

问答坊 | AI 解惑

平板电视中的开关电源发展趋势

消费电子应用的电源设计一直都存在着外型、成本和能效目标等方面的困难挑战。电视终端市场已经从阴极射线管(CRT)技术转向等离子、液晶显示(LCD)和背投多种数字电视显示技术。其中,LCD已经确立了明显的领先优势,据预测,2008年液晶电视(LCD TV)的 ...…

查看全部问答>

wince6.0 OSDesigns目录下的两个子目录

wince6.0 OSDesigns目录下的两个子目录 RelDir和Wince600目录作用是什么,或者说里面装了些什么,关键是WinCe600目录里的内容…

查看全部问答>

WinCE下如何读取SD卡信息?包括SD卡大小,剩余容量等?

WinCE下如何读取SD卡信息?包括SD卡大小,剩余容量等? 是否得用IO口去读? 得用哪个函数? 另外,同时问一下如何读取RAM内存信息,包括总大小以及已经使用的大小? …

查看全部问答>

MSP430 ADC10中断进不去,帮帮忙看看程序

我的程序如下 void main() {     ADC10CTL0 &= ~ ENC;                                //在改变设置前停止转换 & ...…

查看全部问答>

杭州 家和智能控制公司 怎么样 啊

这家公司说是搞什么传感网的,不知道待遇如何?以及公司内部氛围如何,麻烦相关人士解答啊…

查看全部问答>

易电源学习心得

易电源最本质的特点就是容易。易电源的游戏设计的非常好,通过看电源管理模块的原理图,已经知道器件的放置位置了。游戏过程中只要分析一下芯片的工作原理,其实就可以很轻易分析到器件使用场合。这个比原来单独设计,计算参数方便很多了…

查看全部问答>

基于stm32的PLC译码程序设计及优化怎么做!!!!

在KEIL中用C语言编程,实现对PLC指令的解释。不会做啊!!…

查看全部问答>

【求助】初学FPGA,有几个与verilog相关的问题请教各位高人:

1.verilog里的$display系统函数是否能被quartusII9.0支持,在哪里能看到运行的结果? 2.一个半加器的verilog文件如下 `timescale 1ns/100ps module abc(a,b,sum,c);         input a,b;         outp ...…

查看全部问答>

了解一下AC-DC LED照明的方案

安森美半导体在AC-DC电源供电的LED照明应用中,提供各种离线控制器及功率因数校正(PFC)控制器,并配合隔离及非隔离要求提供不同的LED应用方案。在交流线路电压与LED之间没有物理电气连接的隔离应用中,常见的拓扑结构有反激(Flyback)及双电感加单电 ...…

查看全部问答>

话说半导体的长尾效应

在上周举办的第三届光伏逆变器关键元器件技术与应用研讨会上,听了一场富士通半导体公司市场部蔡经理的富士通FRAM(铁电存储器)在太阳能逆变器中的应用演讲,让我认识了真正的半导体行业中的长尾效应产品。 演讲内容本身其实并没有太多技术性,F ...…

查看全部问答>