STM8基础

STM8是ST意法半导体针对工业应用和消费电子开发而推出的8位单片机。

每种MCU都有自身的优点与缺点,与其它8-bit MCU相比,STM8 8-bit MCU最大的特点是:

  • 内核:
    • 最高fcpu频率,可达24MHz,当fcpu≤16MHz时0等待的存储器访问
    • 高级STM8内核,基于哈佛结构并带有3级流水线
    • 扩展指令集
    • 最高20 MIPS @ 24 MHz
  • 时钟、复位和电源管理:
    • 2.95V到5.5V工作电压
    • 灵活的时钟控制,4个主时钟源
    • 带有时钟监控的时钟安全保障系统
  • 电源管理:
    • 低功耗模式(等待、活跃停机、停机)
    • 外设的时钟可单独关闭
    • 永远打开的低功耗上电和掉电复位
  • 通信接口:
    • 高速1Mbit/s CAN 2.0B接口
    • 带有同步时钟输出的UART — LIN主模式
    • UART兼容LIN2.1协议,主/从模式和自动重新同步
    • SPI接口最高到10Mbit/s
    • I2C接口最高到400Kbit/s
  • I/O端口:
    • 带有高吸收电流输出的GPIO脚
    • 非常强健的GPIO设计,对倒灌电流有非常强的承受能力
  • 开发支持:
    • 单线接口模块(SWIM)和调试模块(DM),可以方便地进行在线编程和非侵入式调试
  • 性价比:
    • 相对于现在众多的8位单片机,STM8的价格与性能比例是比较高。    


SWIM接口是STM8的调试系统的调试和编程接口,它提供非侵入式读/写内存和外设,从而可以对STM8实现仿真和编程。 

其实STM8可以不需要晶振跟复位电路,但是为了最小系统能够稳定运行,所以最好增加外部电路。 
  ● STM8复位电路设计
  STM8单片机内置上电复位(POR),所以,STM8单片机可以不设外部上电复位电路,依然可以正常复位,稳定工作。 若是系统需要设置按键复位电路,那么注意,STM8单片机是低电平复位,如下图,设计按键复位电路:

  ● STM8震荡电路设计

  STM8单片机内置RC振荡电路。出厂时,未进行时钟源设置的STM8,其时钟源使用的是内部16M高速RC振荡器,然后经过8分频则是2M频率。
  通过程序对寄存器的设置,可以设置MCU的内部RC振荡频率。例如:4M、8M等。不过,内置RC振荡,在一致性方面存在差异,它因生产的批次有所差异,亦与温度等 因素有较大的相关性。所以,在一些对时钟要求较高的场合,如:精确定时,RS232通信等,这些场合,建议使用外部的晶振线路。

     ● 仿真与编程电路设计

  一般来说,STM8所有系列的单片机都是通过SWIM接口仿真与编程的。
  而SWIM接口只需要4根连接线就够了,所以设计的时候非常简便,只要引出单片机的SWIM接口跟RESET接口,再连上供电电路,然后按照下图的排序标准就OK了!


  ● 注意事项
  (1).VCAP电容引脚: STM8S的VCAP电容是一个很特别的电容。它是STM8S的内核的工作电压。需要在外 部加一个外部的电容,以保证内核工作电压的稳定。一般推荐1uF的瓷片电容。。而且 1uF的瓷片电容在进行PCB布线时,必须要尽可能地靠近VCAP引脚,一直靠近到不 能再靠近为止。这一点非常非常重要,切记!切记!(STM8L系列上没有此电容)
  (2).电源 VDD和VSS电源引脚上,建议加上退耦电容(10uF点解电容和0.1uF瓷片电容) 在用电源对VDDIO_x 和VSSIO_x 的引脚上,建议加上退耦电容(10uF 点解电容和 0.1uF瓷片电容),或者至少加上一个0.1uF瓷片电容。
  若在电路中,有用到外部的设备(如FLASH, 24C02等),建议在其电源上加上退耦电 容(10uF点解电容和0.1uF瓷片电容)。或者至少加上一个1uF瓷片电容。最好不要 使其与MCU共地。


软件编写注意事项:

  • 时钟分配
       主时钟是否正常起振并稳定,各个外设时钟是否开启
  • 选项字节配置(option bytes)
       I/O重映射功能状态是否与实际项目相符合
       如果看门狗使用硬件方法使能,则看门狗在复位后立即有效,主程序必须喂狗。
       如果MCU主频高于16MHz,则需要配置选项字节的MCU等待周期为1
  • 有一些状态寄存器的位的清零是通过读该寄存器来实现的,所以对这样的寄存器操作要清楚其后果。
  • 建议将常用的变量分配在Zero page中,这样可以提高这些变量的访问速度。对于不常用的变量可以用@near定义在0xFF以外区域(相对来说,访问速度略慢)。用户可以根据实际情况决定。

进一步掌握STVD/COSMIC

如何分配变量到指定的地址

举例:
unsigned char temp_A@0x00; //定义无符号变量temp_A,强制其地址为0x00
unsigned char temp_B@0x100; //定义无符号变量temp_B,强制其地址为0x100
@tiny unsigned char temp_C; //定义无符号变量temp_C,由编译器自动在地址小于0x100的RAM中为其分配一个地址
@near unsigned char temp_D; //定义无符号变量temp_D,由编译器自动在地址大于0xFF的RAM中为其分配一个地址
另外也可以采用伪指令"pragma"将函数或者变量定义到指定的section中,例如:
#pragma section [name] // 将下面定义的未初始化变量定义到.name section中
Unsigned char data1;
Unsigned int data2;
……(任何需要定义在.name section中的变量)
……
#pragma section [] // 返回到正常的section.
注意:pragma伪指令可以用来定位函数,初始化变量或者未初始化变量。这三者用不同的括号区分。
(name):代码
[name] :未初始化变量
{name}:初始化变量

如何在COSMIC C文件中使用汇编语言
在COSMIC C文件中使用汇编语言常见的方法有如下两种:使用#asm …#endasm组合格式
或_asm("…"); 单行格式。
举例1:
unsigned char temp_A;
Void func1(void)
{
...
#asm
PUSH A
LD A,(X)
LD _temp_A,A
POP A
#endasm
...
}
注:在C嵌汇编环境下使用全局变量,要在该全局变量名称前加下划线"_"。
举例2:
Void func1(void)
{
...
_asm("rim");
_asm("nop");
...
}

如何观察RAM/FLASH/EEPROM的最终分配情况

在Project->settings->linker选项页中,将Category选为Output,再勾选Generate Map File。 
点击OK按键后,再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:\STM8_NewProject1\debug 目录下)生成 .map 文件。该文件详细地列出RAM/FLASH/EEPROM的分配使用情况。

如何生成hex格式的输出文件
在Project->settings->PostBuild选项页中,在commands栏内加入下行命令:
chex –fi -o $(OutputPath)$(TargetSName).hex $(OutputPath)$(TargetSName).sm8
再次编译链接该项目,如果成功则会在项目输出目录中(本例是在C:\STM8_NewProject1\debug 目录下)生成 .hex 文件。

什么是MEMORY MODEL
STM8的C编译器支持多种存储器模式。用户可以根据应用的需要选择最适合的配置。可以根据需要选择采用2个字节的寻址方式(仅适用于64k以内的程序)或者3字节的寻址方式。也可以规定将变量默认为定义在存储器的哪一区域:zero page内,还是zero page 外。下面对几种供选择的MEMORY MODEL做简单说明。
在Project->settings->C Complier选项页中,将Category选为General,里面有一个Memory Models选项栏如下:
 
在下拉菜单中共有4种MEMORY MODEL可供选择:

  • 程序地址空间在64K以内(即程序容量小于32K)
    mods0,
    modsl0
  • 程序地址哦那个键在64K以上(即程序容量大于32K)
    mods
    modsl

MODS0MODSL0MODSMODSL
名称Stack Short
短堆栈模式
Stack Long
长堆栈模式
Stack Short
短堆栈模式
Stack Long
长堆栈模式
程序地址空间程序所用到的地址空间在64K范围内程序所用到的地址空间超出64K范围
指针默认类型函数指针和数据指针默认为@near (2 bytes)函数指针默认为@far(地址为3字节);
数据指针默认为@near
全局变量默认类型所有全局变量的地址默认为1个字节。对于地址超出1个字节的变量,必须用@near定义所有全局变量默认为Long型。若要将变量地址定义为1个字节,必须用@tiny定义所有全局变量的地址默认为1个字节。对于地址超出1个字节的变量,必须用@near定义所有全局变量默认为Long型。若要将变量地址定义为1个字节,必须用@tiny定义

.lkf 文件的作用
.lkf文件在程序链接时决定如何具体分配RAM/ROM的空间。在Project Settings – Linker – Category(Input)选项页中,当"Auto"选择框被选中时,由系统自动生成.LKF文件,否则由用户指定。 
当"Auto"选择框被勾选时,.lkf文件会自动生成在项目主目录下的 debug/ 和 release/ 目录中。下面以上图所示 at45DBXX Project的 lkf 文件为例,来进一步理解.lkf 。
在.lkf中,以"#"开头的行是注释行,为方便用户理解,将原注释删除,代之以中文注释如下:
# 定义(+seg)一个常量段(.const),开始(b)于0x8080,最大分配(m)0x1ff80个字节(即不超过
# 0x27FFF),为该段起名(n)为.const(和常量段的保留字同名),需要初始化的变量的初始值存
# 放于此段(-it)
+seg .const -b 0x8080 -m 0x1ff80 -n .const -it
# 定义(+seg)一个程序段(.text),紧跟(-a)在.const段后面(和.const 共同位于0x8080 –
# 0x27FFF),为该段起名(n)为. text (和程序段的保留字同名)。
+seg .text -a .const -n .text
# 定义(+seg)一个EEPROM段(.eeprom),开始(b)于0x4000,最大分配(m)0x800个字节(即不超
#过0x47FF),为该段起名(n)为. eeprom (和EEPROM段的保留字同名)。
+seg .eeprom -b 0x4000 -m 0x800 -n .eeprom
# .bsct段服务于定义在0页(地址小于0x100)以内需要初始化的全局变量(如@tiny char a = 9;)
+seg .bsct -b 0x0 -m 0x100 -n .bsct
# .ubsct段服务于定义在0页(地址小于0x100)以内不需要初始化的全局变量(如@tiny char b;)
+seg .ubsct -a .bsct -n .ubsct 
# .bit表示位域段,定义后即可在程序中使用_Bool变量(如_Bool c = 1;),-id表示该段需要初始化。
+seg .bit -a .ubsct -n .bit -id
# 这是ST7时代(STM8是基于ST7发展而来的)由于物理堆栈小,速度慢,使用内存来模拟堆栈的变通手段。
+seg .share -a .bit -n .share -is
# .data段服务于定义在0页(地址大于0xFF)以外需要初始化的全局变量(如@near char d = 8;)
+seg .data -b 0x100 -m 0x1300 -n .data
# .bss段服务于定义在0页(地址大于0xFF)以内不需要初始化的全局变量(如@ near char e;)
+seg .bss -a .data -n .bss
# 段定义结束,下面放置的库及Obj文件中的变量、常量、程序就按照上面的规定进行分配。
#初始化程序
crtsi0.sm8
#用户程序
Debug\main.o

# 一些必要的cosmic库
libis0.sm8
libm0.sm8
# 重定义常量段,开始于0x8000,用于放置中断向量表(STM8硬件决定此位置)
# –k 用于程序冗余代码优化,详情可参考cosmic用户手册。
+seg .const -b 0x8000 –k
# 中断向量
Debug\stm8_interrupt_vector.o
#定义了三个变量,用于系统初始化
+def __endzp=@.ubsct # end of uninitialized zpage
+def __memory=@.bss # end of bss segment
+def __stack=0x17ff # 不同的芯片__stack内容不同,由系统自动生成

如何实现位操作
Cosmic C 编译器支持位变量的操作,可以将其定义成 _Bool类型。_Bool类型的变量只包含两种值true(1)或者false(0)。若将一个表达式赋值给_Bool变量,则编译器会将表达式与0做比较,然后将布尔值赋给_Bool变量。因此,任何整型或者表达式的值都可以赋给_Bool变量。但是,布尔变量不能定义位数组,只能定义成结构体或者联合。而且,_Bool变量会被打包成字节的形式。
编译器会将所有的全局_Bool变量打包成字节形式,存放在.bit section中。局部_Bool变量也会被打包成字节形式。但是_Bool类型的参数会被扩展成一个单字节。

具体的关于位变量的定义和使用可参考如下例子:
定义位变量:
_Bool in_range;
_Bool p_valid;
char *ptr;
使用位变量:
in_range = (value >= 10) && (value <= 20);
p_valid = ptr; /* p_valid is true if ptr not 0 */
if (p_valid && in_

在使用位变量时,若程序编译时提示如下错误:
#error clnk Debug\example.lkf:1 no default placement for segment .bit
The command: "clnk -l"C:\Program Files\COSMIC\CXSTM8_16K_4.2.10\Lib" -o Debug\example.sm8 -mDebug\example.map -sa Debug\example.lkf " has failed, the returned value is: 1
exit code=1.
实际上是由于,在项目中没有定义.bit section。可按照如下步骤,手工添加.bit section:
打开项目链接配置窗口:Project - Settings - Linker,选择 Input 目录项

在Zero page 或者 Ram 里面定义一个.bit section.

然后重新编译一下就可以了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值