写在前面
最近项目中涉及到一些实时性要求很高的底层驱动设计,在IAR下用C语言写完后总是感觉响应不是足够快,平时在网上会看到很多嵌入式大牛直接通过汇编来写,效果超级明显。之前在学校里接触过51的汇编,感觉又low又难懂。随着时间的推移,越来越有一种潜意识,觉得高级程序虽然有着开发效率高的特点,但有一些地方的局限还是很多大的,如果想要继续深入地了解和运用一些单片机底层的资源,能且只能通过汇编来实现。现在工作中接触的MCU主要是STM8系列,所以就从他开始吧!
STM8 简介
意法半导体的这款8位单片机一直知名度不高,在上学时,一般耳熟能详的八位机都有PIC、51、AIR之类,STM系列也只听说过STM32,工作后接触到STM8,觉得这款芯片还是挺强大的,虽然是CISC架构,但大部分指令都能单周期内进行,更主要的是他丰富的外设,如果要求不高的话实用性完全超过了低价位的STM32芯片。
常用外设
从官网上了解到,STM8 系列有三个大类:S(mainstream MCUs,主流MCU),L(ultra-low-power MCUs,低功耗MCU),和AF/AL(automotive MCUs,车载嵌入式系统)。S系列以其价格优势占领了不少市场,但相比于后两者而言,功能较少,适用于一些功能简单的应用场合。A系列没接触过,L系列虽然号称低功耗,但它具有丰富的外设,并且具有1个多通道DMA,你可以灵活利用他们以节约系统资源去做更多的事情。比如利用SPI和595通讯以及AD采样,只需要合理设置,然后直接向定义的全局变量赋值或者读取数据就可以了,非常方便了可以说是。
1. ADC
高容量产品有4个高速通道(1us)和24个低速通道,低容量产品1个高速通道和24个低速通道,具有12位精度;
两个内部通道分别用于芯片温度和基准电压采集;
类似于STM32的规则组,可以采用扫描模式对选择的ADC端口扫描采样并通过DMA传输,并可以设置DMA中断立即对采样的数据进行处理。
2. DAC
一路DAC输出,12位精度。
3. TIMER
单片机的核心功能,STM8 具有5个定时器,高级定时器TIM1,通用定时器TIM2/TIM3/TIM5,和一个基本定时器。
其中TIM1具有DMA出发和捕获比较功能,可以生成单脉冲和PWM驱动,并能测量输入的脉冲宽度,具有多个中断事件(捕获中断、比较中断、溢出中断、触发中断),具有向上计数和向下计数的功能。
TIM4工作模式类似于TIMER1,但是好像只有定时器的基本功能,并具有更新中断和输入出发中断以及自动重装载功能。
TIM2/3/5通用定时器,具有捕获比较功能,但是有一点比较麻烦,就是定时器溢出后,产生更新标志,但是计数器不会复位,只能通过软件对其重新赋值。
4. DMA
DMA一共有4组通道,每一种外设都对应四组中的一组:
Ch1-2具有外设->内存,内存->外设两种传输模式,Ch3具有 内存->内存和内存->外设两种传输模式。
5. 通讯外设
USART,SPI,I2C,可以和具有相同通讯方式的单片机和外设通讯,如Flash,外置ADC,LCD和一些功能芯片(74HC595).
资料获取
要学习一种单片机或计算机语言而又找不到教材时,最好的办法不是百度,而是直接到官网去找手册。经过翻译的东西,一方面没有经过验证,另一方面中文资料译者多是业余爱好,因此通过这类资料很容易获取错误 的知识,然后早期形成的固有思维模式很容易给今后的学习埋下看不见的雷。所以我觉得读英文原版的资料更准确,而且还可以顺便学学英语,多好。
STM8 参考手册和编程手册
STM8资料地址
你可以在这里下载两个重要的东西:参考手册(RM0031 Reference manual)和编程手册(PM0044 Programming manual)。其中编程手册一定要把右上角的加号点开,看准文件编号,上面那个讲Flash存储器性能的,没什么卵用。
IAR帮助
为了方便用户,在IAR的help菜单下具有开发向导,可以方便地查阅遇到的问题,几乎涉及IAR开发中的所有编程格式的问题,在这里都可以找到答案
今天先写到这里,接下来会记录下一些关于STM8汇编语言方面的介绍和程序片段,作为自己的积累吧
STM8 内核
如其名称所示,STM8是一种8位单片机,可以高效地进行8位数据的操作,同时借助两个16位寄存器X和Y可以进行一些16位的运算,不过指令周期就有点长了。
CPU寄存器
1. 累加器(Accumulater, A)
&emdp;任何单片机不可或缺的寄存器,用于缓存操作数据以及逻辑或数学运算的操作结果;
2. 索引寄存器(Index registers, X and Y)
用于存放16位的地址或数据,可以存放乘法运算结果,并对其进行8位操作,即分成两部分:XH和XL,YH和YL.
3. 程序计数器(PC)
存放下一条指令的地址,具有16M的寻址空间。
4. 堆栈存储器(SP)
16位寄存器。和ARM架构不同,STM8的堆栈方向不可修改,总是采用向下生长的方式,并指向下一个空数据。但用户可以设定它的起始地址
以及终止地址。当压入堆栈的数据使SP越过了终止地址后,重新回到初始地址开始入栈。中断发生时,寄存器CC/X/Y/A/PC依次入栈,大概需要9个CPU时钟周期,9Byte数据被压入堆栈。
5. 全局控制寄存器(CFG_GCR)
用的不多,还是说说吧:
寄存器包括一个位:AL: Activation level
当该位为0时(main),中断返回指令IRET会将之前的堆栈数据出栈,继续进行之前的主程序,并且程序在WFI(wait for Interrupt)指令后不受影响,继续执行;
当该位为1时(Interruppt only active),IRET指令使CPU回到WFI或WFE模式,可以看做该模式使一种低功耗模式,在没有中断或事件触发的情况下处在空闲待机模式。这也是L系列的主要特色了。
6. 条件码寄存器(Condition Code Register CC)
汇编中运用最多的寄存器,涉及到条件判断的时候都会用到它
很简单,一目了然。
STM8存储器接口
虽然是8位单片机,STM8却采用了冯·诺依曼结构,寻址方便了很多,不需要为区分RAM和ROM而采用不同的寻址指令。但是STM8没有ARM或51中的寄存器,所以使用IAR作为开发环境时,会生成16个(缺省值,可以设定)虚拟寄存器?b0-?b15(8bits)/?l0-?l15(16bits)。为啥开头用个问号,咱也不知道,咱也不敢问(估计是防止命名冲突)。一般是从0x00开始由低到高。
32KB和64KB产品略有差别:
Memory mapping of STM8L151x6/8 STM8L152x6/8:
Memory mapping of STM8L151x4, STM8L151x6,STM8L152x4, STM8L152x6:
具体信息请参阅
DS6948_STM8L151x8,STM8L152x8,STM8L151R6,STM8L152R6单片机数据手册
DS6372_STM8L151x4,STM8L151x6,STM8L152x4,STM8L152x6单片机数据手册
32KB和64KB产品的不同块之间的起始地址都是相同的,但大容量产品Flash,RAM和EEPROM要大一倍。
指令流水线
三级流水线标配,大部分指令(长转移指令和16位运算以及乘除法运算指令执行时间较长)可以在单周期内执行完成。
具体内容请参考:
PM0044_STM8单片机编程手册
寻址方式
大部分MCU寻址可以概括为三种基本寻址方式:直接寻址,间接寻址和寄存器寻址。而STM8在此基础上衍生出了8种:
具体内容请参考上述文档(PM0044_STM8单片机编程手册).
指令集
同样,文档中解释的很详细。然后有几个地方需要注意下,这里简单说说。
1. 成对的指令
(a) 调用指令:
CALL label; 和RET; 是一对,CALLF label; 和RETF是一对。在C编程时调用汇编函数一定要看一下C语言的编译结果,在调用汇编的时候用的是CALL还是CALLF,他们的区别是:CALL执行时,PC的低位PCL和高位PCH被压入堆栈,同样RET将PC值的高位和低位出栈;而CALLF是将三字节数据压入堆栈: PC的低位PCL,PC位的高位PCH和PC的额外位PCE,同样RETF是将以上三字节数据出栈。如果没有搭配好,程序在返回调用位置时当然会出错了。如果有幸PC值的额外位没有用到,堆栈的顺序已经乱掉了,程序基本就没法运行了。对了,STM8没有中断返回指令RETI。
(b) 堆栈指令:
PUSH和POP是一对,PUSHW和POPW是一对,而且两者在同一段程序中顺序也要注意,先进后出。
2. 除法指令
除法指令能不用尽量不用,据我所知这个家伙是所有指令执行周期最长的了。用汇编的目的就是为了缩短指令执行时间,这玩意儿一加等于是一纳秒一纳秒抠出来的时间全扔了。
3. 位操作指令
BSET和BRES可以对一个字节的数据的某个位进行操作,非常好用。但只能是RAM中的数据,CPU寄存器一个也不支持。不过这都无所谓,毕竟直接操作内存数据更方便。
STM8内核的介绍就写这么多吧,具体的内容去看官方的参考手册,不仅内容详细,而且内容详细。。。
设计资源 培训 开发板 精华推荐
- 使用 ON Semiconductor 的 ILC6381 的参考设计
- LT1937 白光 LED 升压转换器的典型应用
- SiC438 3 至 28 V 输入、8A microBUCK DC/DC 转换器的典型应用
- LT3091HDE 连接以实现最佳负载调节的典型应用
- RT9284A微型封装、高性能、白光LED恒流开关稳压器驱动4串WLED的典型应用
- 使用 Analog Devices 的 LTC3701 的参考设计
- LT1934IS6 5V 降压转换器的典型应用电路
- LT1021BCN8-10 具有升压输出电流且无电流限制的电压基准的典型应用
- 具有关断功能的 TC1265 800 mA 固定输出 CMOS LDO 的典型应用
- 使用 Analog Devices 的 LT3020EMS8-1.8 的参考设计