STM8学习笔记1:CPU简介

STM8 汇编学习笔记1:CPU简介

 

写在前面

  最近项目中涉及到一些实时性要求很高的底层驱动设计,在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组通道,每一种外设都对应四组中的一组:
STM8学习笔记1:CPU简介
  Ch1-2具有外设->内存,内存->外设两种传输模式,Ch3具有 内存->内存和内存->外设两种传输模式。

5. 通讯外设

  USART,SPI,I2C,可以和具有相同通讯方式的单片机和外设通讯,如Flash,外置ADC,LCD和一些功能芯片(74HC595).

资料获取

  要学习一种单片机或计算机语言而又找不到教材时,最好的办法不是百度,而是直接到官网去找手册。经过翻译的东西,一方面没有经过验证,另一方面中文资料译者多是业余爱好,因此通过这类资料很容易获取错误 的知识,然后早期形成的固有思维模式很容易给今后的学习埋下看不见的雷。所以我觉得读英文原版的资料更准确,而且还可以顺便学学英语,多好。

STM8 参考手册和编程手册

STM8资料地址
  你可以在这里下载两个重要的东西:参考手册(RM0031 Reference manual)和编程手册(PM0044 Programming manual)。其中编程手册一定要把右上角的加号点开,看准文件编号,上面那个讲Flash存储器性能的,没什么卵用。
STM8学习笔记1:CPU简介

IAR帮助

  为了方便用户,在IAR的help菜单下具有开发向导,可以方便地查阅遇到的问题,几乎涉及IAR开发中的所有编程格式的问题,在这里都可以找到答案
STM8学习笔记1:CPU简介

今天先写到这里,接下来会记录下一些关于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)

  汇编中运用最多的寄存器,涉及到条件判断的时候都会用到它

V I1 H I0 N Z C
Overflow Interrupt mask level1 Half carry bit Interrupt mask level0 Negetive Zero Carry
溢出 中断屏蔽级别1 半字节进位标志 中断屏蔽级别0 负数标志 零标志 进位/借位标志

很简单,一目了然。

STM8存储器接口

  虽然是8位单片机,STM8却采用了冯·诺依曼结构,寻址方便了很多,不需要为区分RAM和ROM而采用不同的寻址指令。但是STM8没有ARM或51中的寄存器,所以使用IAR作为开发环境时,会生成16个(缺省值,可以设定)虚拟寄存器?b0-?b15(8bits)/?l0-?l15(16bits)。为啥开头用个问号,咱也不知道,咱也不敢问(估计是防止命名冲突)。一般是从0x00开始由低到高。
  32KB和64KB产品略有差别:

  1. Memory mapping of STM8L151x6/8 STM8L152x6/8:
    STM8学习笔记1:CPU简介

  2. Memory mapping of STM8L151x4, STM8L151x6,STM8L152x4, STM8L152x6:
    STM8学习笔记1:CPU简介
    具体信息请参阅
    DS6948_STM8L151x8,STM8L152x8,STM8L151R6,STM8L152R6单片机数据手册
    DS6372_STM8L151x4,STM8L151x6,STM8L152x4,STM8L152x6单片机数据手册
      32KB和64KB产品的不同块之间的起始地址都是相同的,但大容量产品Flash,RAM和EEPROM要大一倍。

指令流水线

  三级流水线标配,大部分指令(长转移指令和16位运算以及乘除法运算指令执行时间较长)可以在单周期内执行完成。
STM8学习笔记1:CPU简介
STM8学习笔记1:CPU简介
STM8学习笔记1:CPU简介
具体内容请参考:

PM0044_STM8单片机编程手册

寻址方式

  大部分MCU寻址可以概括为三种基本寻址方式:直接寻址,间接寻址和寄存器寻址。而STM8在此基础上衍生出了8种:

寻址方式 例子
固有寻址(Inherent) NOP
立即寻址(Immediate) LD A,#$55
直接寻址(Derect) LD A,$55
索引寻址(Indexed) LD A,($55,X)
堆栈索引寻址(SP Indexed) LD A,($55,SP)
间接寻址 LD A,([$55],X)
就近寻址(Relative) JRNE loop
位寻址(Bit operation) BSET byte,#5

  具体内容请参考上述文档(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. 除法指令
  除法指令能不用尽量不用,据我所知这个家伙是所有指令执行周期最长的了。用汇编的目的就是为了缩短指令执行时间,这玩意儿一加等于是一纳秒一纳秒抠出来的时间全扔了。
STM8学习笔记1:CPU简介
STM8学习笔记1:CPU简介
3. 位操作指令
  BSET和BRES可以对一个字节的数据的某个位进行操作,非常好用。但只能是RAM中的数据,CPU寄存器一个也不支持。不过这都无所谓,毕竟直接操作内存数据更方便。
STM8学习笔记1:CPU简介
STM8学习笔记1:CPU简介
  STM8内核的介绍就写这么多吧,具体的内容去看官方的参考手册,不仅内容详细,而且内容详细。。。
ps:新版****文本编辑器真坑,图片调不了大小,排版丑的。。。哎凑合写写吧,还要众筹出书咋地。。。
2019-09-13