当前位置:文档之家› Lua 5.0 参考手册

Lua 5.0 参考手册

Lua 5.0 参考手册
Lua 5.0 参考手册

Lua 5.0 参考手册

作者: Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes Copyright ? 2003 Tecgraf, PUC-Rio. All rights reserved.

译者:ShiningRay Nicholas @ NirvanaStudio

给予支持

1 - 绪论

Lua是一种为支持有数据描述机制的一般过程式编程语言而设计的扩展编程语言。它同样可以对面向对象语言、函数式程序设计(Functional Programming,如Lisp)以及数据驱动编程(data-driven programming)提供很好的支持。它的目标是被用作一种强大的、轻型的配置语言。Lua目前已经被实现为一个扩展库,是用clean C (ANSI C/C++的一个通用子集)编写的。

作为一个扩展语言,Lua没有"Main"函数的概念:它仅仅是嵌入一个宿主程序进行工作,可以称之为嵌入式编程或者简单的说是宿主编程。这个宿主程序可以调用函数来执行Lua的代码片断,可以设置和读取Lua的变量,可以注册C

函数让Lua代码调用。Lua的能力可以扩展到更大范围,在不同的领域内,这样就在同样的语法框架下创建了你自定义的编程语言。

Lua的发行版包括一个独立的嵌入式程序,lua,他使用Lua的扩展库来提供一

个完全的Lua解释器。

Lua是自由软件,通常不提供任何担保,如它的版权说明中叙述的那样。手册

中描述的实现在Lua的官方网站可以找到,https://www.doczj.com/doc/be1815984.html,。

如果需要知道Lua设计背后的一些决定和讨论,可以参考以下论文,它们都可以在Lua的网站上找到。

R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. Lua---an extensible extension language. Software: Practice & Experience26

#6 (1996) 635-652.

?L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. The design and implementation of a language for extending applications.

Proceedings of XXI Brazilian Seminar on Software and Hardware(1994) 273-283.

?L. H. de Figueiredo, R. Ierusalimschy, and W. Celes. Lua: an extensible embedded language. Dr. Dobb's Journal21#12 (Dec 1996) 26-33.

?R. Ierusalimschy, L. H. de Figueiredo, and W. Celes. The evolution of an extension language: a history of Lua, Proceedings of V Brazilian Symposium on Programming Languages(2001) B-14-B-28. Lua在葡萄牙语中的意思是“月亮”,发音是 LOO-ah。

2 - 语言

这一章将描述Lua的词法、语法和语义结构。换句话说,这一章会讲什么标记是合法的,他们是如何组合的,以及他们的组合是什么含义。

语言结构会使用常用的扩展BNF范式来解释,如{a} 表示0或多个a, [a] 表示a是可选的(0个或1个)。非终端字体(不能显示的)用斜体表示,关键

字是粗体,其他终端符号用typewriter(等宽)字体,并用单引号引出。

2.1 - 词法约定

Lua中的标识符(Identifiers)可以是任意的数字、字符和下划线“_”,但不能以数字开头。这条规则符合大多数编程语言中的标识符的定义。(字符的具体定义要根据系统的地区设置:任何区域设置可以认同的字母表中的字母都可以用在标识符中。)

下面的关键字(keywords)为保留关键字不可以作为标识符出现:

and break do else elseif

end false for function if

in local nil not or

repeat return then true until while

Lua对大小写敏感:and是一个保留字,但是 And 和 AND 是两个不一样的、但都合法的标识符。习惯上来说,以下划线开始且后面跟着大写字母的标识符 (例如 _VERSION) 是为Lua内部变量所保留的。

下面的字符(串)是其他的一些标记:

+ - * / ^ =

~= <= >= < > ==

( ) { } [ ]

; : , . .. ...

字符串(Literal strings)以单引号或者双引号定界,同时可以包含以下C 语言风格的转义字符:

?\a --- 铃声(bell)

?\b --- 回退(backspace)

?\f --- form feed

?\n --- 新行(newline)

?\r --- 回车(carriage return)

?\t --- 水平制表符(horizontal tab)

?\v --- 垂直制表符(vertical tab)

?\\ --- 反斜杠(backslash)

?\" --- 双引号(quotation mark)

?\' --- 单引号(apostrophe)

?\[ --- 左方括号(left square bracket)

?\] --- 右方括号(right square bracket)

另外,一个 `\newline′(一个反斜杠加上一个真正的换行符)会导致字符串内的分行。字符串中的字符也可以使用转义字符`\ddd′通过数字值来指定。ddd是最多为3个十进制数字的序列。Lua中的字符串也可以包含8进制数字,包括嵌入零,它可以表示为 `\0′。

字符串也可以用双方括号来定界[[ ··· ]]。这种括号方式的语法,字符串可以跨越多行,也可以包含嵌套的,同时不会转义任何序列。方便起见,当开始的 `[[′后面紧跟着一个换行符的话,这个换行符不会包括在字符串内。举个例子:在一个使用ASCII编码(其中`a′的编码是97,换行符是10,字符`1′是49)的系统中,以下四种格式得到的都是同一个字符串:

(1) "alo\n123\""

(2) '\97lo\10\04923"'

(3) [[alo

123"]]

(4) [[

alo

123"]]

数值常量(Numerical constants)可以有一个可选的底数部分和一个可选的指数部分。以下是有效的数值常量:

3 3.0 3.1416 314.16e-2 0.31416E1

注释(Comments)可以在任何地方出现,必须在最前面加上双减号 (--)。如果紧接着 -- 的文本不是 [[,那么会认为是一个短注释(short comment),这一行往后到行尾都是注释。否则,会认为是一个常注释(long comment),注释直到相应的 ]]结束。长注释可以跨越多行,同时可以包含嵌套的[[ ··· ]] 括号对。

为了方便起见,文件的第一行如果是以#开始,这个机制允许Lua在Unix系统中用做一个脚本解释器(见 6)。

2.2 - 值和类型

Lua是一种动态类型语言(dynamically typed language)。这意味着变量是没有类型的;只有值才有。语言中没有类型定义。所有的值都包含他自身的类型。Lua中有八种基本类型:nil, boolean, number, string, function, userdata,

thread和table。Nil空类型只对应nil值,他的属性和其他任何值都有区别;通常它代表没有有效的值。Boolean布尔类型有两种不同的值false and true。在Lua中,nil and false代表成假条件;其他任何值都代表成真条件。Number数字类型表示实数(双精度浮点数)。(构建Lua解释器时也可以很容易地用其他内部的表示方式表示数字,如单精度浮点数或者长整型)。String字符串类型表示一个字符的序列。Lua 字符串可以包含8位字符,包括嵌入的('\0') (见 2.1)。

函数是Lua中的第一类值(first-class values)。也就是说函数可以保存在变量中,当作参数传递给其他函数,或者被当作结果返回。Lua可以调用(和处理)Lua写的函数和C写的函数(见 2.5.7)。

用户数据类型(userdata)提供了让任意C数据储存在Lua变量中的功能。这种类型直接对应着一块内存,Lua中也没有任何预先定义的操作,除了赋值和一致性比较。然而,通过使用元表(metatables),程序员可以定义处理userdata 的操作。(见 2.8)。 Userdata 值不能在Lua中建立或者修改,只能通过

C API。这保证了宿主程序的数据完整性。

线程(thread)类型代表了相互独立的执行线程,用来实现同步程序。

表(table)类型实现了联合数组,也就是说,数组不仅可以使用数字,还能使用其他的值(除了nil)。而且,tables 可以是互异的(heterogeneous),他们可以保存任何类型的值(除了nil)。 Tables 是Lua中唯一的数据结构机制;他们可以用来表示一般数组,特征表,集合,记录,图,树等等。如果要表示记录,Lua使用字段名作为索引。语言支持 https://www.doczj.com/doc/be1815984.html, 这种比较优美的表示方式,还有 a["name"]。在Lua中有几种建立表的简便方法(见 2.5.6)。

就像索引一样,表字段的值也可以是任何类型(除了nil)。特别需要注意地是,由于函数是第一型的值,表字段也可以包含函数。这样表也可以支持方法(methods)(见 2.5.8)。

表,函数,和用户数据类型的值都是对象(objects):变量不会包含他们的实际值,只是一个他们的引用(references)。赋值,参数传递和函数返回只是操作这些值的引用,这些操作不会暗含任何拷贝。

库函数 type 返回一个字符串描述给出值所表示的类型(见 5.1)。

2.2.1 - 类型转换

Lua提供运行时的数字和字符串值得自动转换。任何对字符串的算术操作都会现尝试把字符串转换成数字,使用一般规则转换。反过来,当一个数值用在需要字符串的地方时,数字会自动转换成字符串,遵循一种合理的格式。如果要指定数值如何转换成字符串,请使用字符串库中的 format 函数(见 5.3)。

2.3 - 变量

变量是储存值的地方。Lua中有三种不同的变量:全局变量,局部变量和表字段。

一个名称可以表示全局变量或局部变量(或者一个函数的正式参数,一种局部变量的特殊形式):

var ::= Name

Lua假设变量是全局变量,除非明确地用local进行声明(见 2.4.7)。局部变量有词义范围(lexically scoped):局部变量可以被在它们范围内的函数自由访问(见 2.6)。

在变量第一次赋值之前,它的值是nil。

方括号用于对表进行检索:

var ::= prefixexp `[′ exp `]′

第一个表达式 (prefixexp)结果必须是表;第二个表达式 (exp) 识别表中一个特定条目。给出表的表达式有一个限制语法;详细见 2.5。

https://www.doczj.com/doc/be1815984.html, 语法是 var["NAME"] 的较好形式:

var ::= prefixexp `.′ Name

访问全局变量和表字段的实质可以通过元表进行改变。对索引变量 t[i] 的访问等同于调用 gettable_event(t,i)。(关于 gettable_event 的完整描述见

2.8。这个函数并没有在Lua中定义,也无法调用。我们在这里仅仅用来解释原理)。

所有的全局变量存在一个普?ǖ腖ua表中,称之为环境变量表(environment tables)或简称环境(environments)。由C写的并导入到Lua中的函数 (C 函数) 全部共享一个通用全局环境(global environment)。Lua写的每个函数 (a Lua 函数) 都有一个它自己的环境的引用,这样这个函数中的所有的全局变量都会指向这个环境变量表。当新创建一个函数时,它会继承创建它的函数的环境。要改变或者获得Lua函数的环境表,可以调用 setfenv or getfenv (见 5.1)。

访问全局变量 x 等同于 _env.x,又等同于

gettable_event(_env, "x")

_env 是运行的函数的环境。(_env 变量并没有在Lua中定义。我们这里仅仅用来解释原理)

2.4 - 语句

Lua支持一种很通俗的语句集,和Pascal或者C中的很相似。他包括赋值,控制结构,过程调用,表构造和变量声明。

2.4.1 - 语句段

Lua执行的最小单元称之为一个段(chunk)。一段语句就是简单的语句的序列,以顺序执行。每一个语句后面都可以加上一个分号(可选):

chunk ::= {stat [`;′]}

Lua将语句段作为一个匿名函数(见 2.5.8)的本体进行处理。这样,语句段可以定义局部变量或者返回值。

一段语句可以储存在文件内或者宿主程序的一个字符串中。当语句段被执行时,他首先被预编译成虚拟机使用的字节码,然后虚拟机用一个解释器执行被编译的代码。

语句段也可以被预编译为二进制代码;详情参看 luac 程序。源代码和编译形态可以互相转换;Lua自动监测文件类型然后作相应操作。

2.4.2 - 语句块

一个语句块是一系列语句;从语句构成上来看,语句块等同于语句段:block ::= chunk

一个语句块可以明确定界来替换单个语句:

stat ::= do block end

显式语句块可以很好地控制变量的声明范围。显示语句块有时也常会在另一个语句块的中间添加return或break语句(见 2.4.4)。

2.4.3 - 赋值

Lua允许多重赋值。因此,赋值的语法定义为:等号左边是一个变量表,右边是一个表达式表。两边的表中的元素都用逗号分隔开来:

stat ::= varlist1 `=′ explist1

varlist1 ::= var {`,′ var}

explist1 ::= exp {`,′ exp}

我们将在 2.5 讨论表达式。

在赋值之前,值的表长度会被调整为和变量的表一样。如果值比需要的多,多出的值就会被扔掉。如果值的数量不够,就会用足够多的nil来填充表直到满足数量要求。如果表达式表以一个函数调用结束,那么在赋值之前,函数返回的所有的值都会添加到值的表中(除非把函数调用放在括号里面;见 2.5)。

赋值语句首先计算出所有的表达式,然后才会执行赋值,所以代码:

i = 3

i, a[i] = i+1, 20

设置 a[3] 为 20,但不影响 a[4]。因为在 a[i] 中的 i 在赋值为4之前是等于3。同样的,下面这行:

x, y = y, x

可以交换 x 和 y 的值。

对全局变量和表字段的赋值可以看作是通过元表进行的。对一个索引变量的赋值t[i] = val 等同于 settable_event(t,i,val)。(settable_event详细介绍参看 2.8 ,Lua中并未定义该函数,他也无法直接调用。我们这里只是用它来进行解释。)

对全局变量的赋值 x = val 等同于赋值语句 _env.x = val,像前面也等同于: settable_event(_env, "x", val)

_env 是运行函数的环境。(_env 变量并未在Lua中定义。我们这里只是用来进行解释。)

2.4.4 - 控制结构

控制结构if, while和repeat具有通用的含义和类似的语法:

stat ::= while exp do block end

stat ::= repeat block until exp

stat ::= if exp then block {elseif exp then block} [else block] end

Lua也有for语句,有两种格式(见 2.4.5)。

控制结构的条件表达式exp可以返回任意值。false和nil都表示假。所有其他的值都认为是真(特别要说明的:数字0和空字符串也表示真)。

语句return用来从函数或者是语句段中返回一个值。函数和语句段都可以返回多个值,所以return语句的语法为:

stat ::= return [explist1]

break语句可以用来终止while, repeat或者for循环的执行,直接跳到循环后面的语句。

stat ::= break

break结束最里面的一个循环。

由于语法的原因,return和break语句只能作为语句块的最后一个语句。如果确实需要在语句块的中间使用return或者break,需要使用一个显示语句块: `do return end′和 `do break end′,这样现在return和break就成为他们(内部)语句块中的最后一个语句了。实际上,这两种用法一般只用在调试中。

2.4.5 - For 语句

for语句有两种形式:数值形式和一般形式。

数值形式的for循环根据一个控制变量用算术过程重复一语句块。语法如下:

stat ::= for Name `=′ exp `,′ exp [`,′ exp] do block end

block语句块根据name以第一个exp的值开始,直到他以第三个exp为步长达到了第二个exp。一个这样的for语句:

for var = e1, e2, e3 do block end

等价于一下代码:

do

local var, _limit, _step = tonumber(e1), tonumber(e2), tonumber(e3)

if not (var and _limit and _step) then error() end

while (_step>0 and var<=_limit) or (_step<=0 and var>=_limit) do

block

var = var + _step

end

end

注意:

?三种控制表达式只会被计算一次,在循环开始之前。他们的结果必须是数值。

?_limit 和 _step 是不可见的变量。这里只是为了进行解释。

?如果你在程序块内给 var 赋值,结果行为将会不确定。

?如果没有给出第三个表达式(步长),那么默认为1。

?你可以使用break来退出for循环。

?循环变量 var 是局部变量;你不可以在for循环结束之后继续使用。如果你需要使用这个值,请在退出循环之前把它们传给其他变量。

for的语句的一般形式是操作于函数之上的,称之为迭代器(iterators)。每一个迭代过程,它调用迭代函数来产生新的值,直到新的值是nil。一般形式for循环有如下语法:

stat ::= for Name {`,′ Name} in explist1 do block end

一个这样的for语句

for var_1, ..., var_n in explist do block end

等同于以下代码:

do

local _f, _s, var_1 = explist

local var_2, ... , var_n

while true do

var_1, ..., var_n = _f(_s, var_1)

if var_1 == nil then break end

block

end

end

注意:

?explist 只会计算一次。他的结果是一个迭代函数,一个状态,和给第一个迭代变量的一个初始值。

?_f 和 _s 是不可见的变量。这里只是用来进行解释说明。

?如果你在语句块中给 var_1 赋值,那么行为就会变得不确定。

?你可以使用break来退出for循环。

?循环变量 var_i 是局部变量;你不可以在for循环结束之后继续使用。

如果你需要使用这个值,请在退出循环之前把它们传给其他变量。

2.4.6 - 语句式函数调用

如果要忽略可能的影响,函数调用可以按照语句执行:

stat ::= functioncall

I在这里,所有的返回值都会被忽略。函数调用将在 2.5.7 详细解释。

2.4.7 - 局部变量声明

局部变量可以在语句块中任何地方声明。声明时也可以添加一个初始赋值:

stat ::= local namelist [`=′ explist1]

namelist ::= Name {`,′ Name}

如果出现初始赋值,他的语法和多重赋值语句一样(见 2.4.3)。否则,所有的变量都会初始化为nil。

一个语句段也是一个语句块(见 2.4.1),所以语句段之内的任何显式语句块之外也可以声明局部变量。这种局部变量在语句段结束就会销毁。

局部变量的可见规则会在 2.6解释。

2.5 - 表达式

Lua中有以下几种基本表达式:

exp ::= prefixexp

exp ::= nil | false | true

exp ::= Number

exp ::= Literal

exp ::= function

exp ::= tableconstructor

prefixexp ::= var | functioncall | `(′ exp `)′

数字和字符串已经在 2.1 中解释;变量在 2.3 中解释;函数定义在 2.5.8;函数调用在 2.5.7;表构造器在 2.5.6。

一个用括号括起的表达式只会返回一个值。这样,(f(x,y,z)) 将只会返回单一的一个值,即使 f 可以返回多个值,((f(x,y,z)) 的值将是 f 返回的第一个值或者如果 f 没有返回任何值就是nil)。

表达式也可以使用各种算术运算符,关系运算符和逻辑运算符,下面几节就会讲到。

2.5.1 - 算术运算符

Lua支持常见的几种运算符:二元 + (加), - (减), * (乘), / (除),以及 ^ (指数运算);一元 - (负号)。如果操作数是数字,或者是可以转换成数字的字符串(见 2.2.1),那么所有的操作都和算术意义上的运算一致(除了指数)。指数运算其实是调用一个全局函数 __pow,否则一个合适的元方法将会被调用(见 2.8)。标准数学库定义了函数 __pow,给出了指数运算的定义(见5.5)。

2.5.2 - 关系运算符

Lua中的关系运算符有

== ~= < > <= >=

这些运算只会产生false或true值。

等于 (==) 先比较操作数的类型。如果类型不一样,结果便是false。否则,再比较操作数的值。对象(表,用户数据,线程,和函数)是按照引用进行比较:

只有两个对象是同一个对象的时候,才认为是相等。每次你创建一个新的对象(表,用户数据,或者是函数)。这个新的对象将不同于前面存在的任何对象。

你可以用"eq"元方法改变Lua比较表的方式(见 2.8)。

2.2.1 的转换规则不适用于相等比较。这样," "0"==0 结果是false,同样t[0] 和 t["0"] 给出的是表中不同的字段。

而操作符 ~= 是等于 (==) 的相反的操作。

T操作符的执行顺序如下。如果两个参数都是数字,那么它们就直接进行比较。如果,两个参数都是字符串,那么它们的值会根据当前的区域设置进行比较。否则,Lua尝试调用"lt"或者 "le" 元方法(见 2.8)。

2.5.3 - 逻辑运算符

Lua中的逻辑运算符是:

and or not

和控制结构一样(见 2.4.4),所有的逻辑操作符认为false和nil都?羌伲 渌 闹刀际钦妗?

not操作符总是返回false或true。

合取运算and如果第一个参数是false或者nil则返回第一个参数;否则and返回第二个参数。析取运算or如果第一个参数不是nil或false则返回第一个参数,否则or返回第二个参数。and和or都使用截取计算,也就是,只有有必要的情况下才计算第二个参数。例如:

10 or error() -> 10

nil or "a" -> "a"

nil and 10 -> nil

false and error() -> false

false and nil -> false

false or nil -> nil

10 and 20 -> 20

2.5.4 - 串联接

在Lua中字符串连接操作符是两个点 (`..′)。如果两边的操作数都是字符或者数字,他们就都会按照 2.2.1的规则被转换成字符串。否则,将调用 "concat" 元方法(见 2.8)。

2.5.5 - 优先级

Lua中的操作符的优先级如下表所示,从低到高优先级:

or

and

< > <= >= ~= ==

..

+ -

* /

not - (unary)

^

表达式中,你可以使用括号来改变优先顺序。串联接符 (`..′) 和指数符 (`^′) 都是右结合的。其他二元操作都是左结合的。

2.5.6 - 表构造器

表构造器是创建表的表达式。当计算构造器的时候,就会创建一个新的表。构造器可以用来创建空的表,或者创建表并初始化一些字段。一般的语法如下:

tableconstructor ::= `{′ [fieldlist] `}′

fieldlist ::= field {fieldsep field} [fieldsep]

field ::= `[′ exp `]′ `=′ exp | Name `=′ exp | exp

fieldsep ::= `,′ | `;′

[exp1] = exp2 形式的每一个添加到新表中的字段条目以 exp1 为键并以 exp2 为值。name = exp 形式的字段,等同于 ["name"] = exp。最后,exp 形式的字段等同于 [i] = exp 其中 i 是连续的整数,从1开始。其它格式的字段不会影响它的计数。例如:

a = {[f(1)] = g; "x", "y"; x = 1, f(x), [30] = 23; 45}

等同于:

do

local temp = {}

temp[f(1)] = g

temp[1] = "x" -- 1st exp

temp[2] = "y" -- 2nd exp

temp.x = 1 -- temp["x"] = 1

temp[3] = f(x) -- 3rd exp

temp[30] = 23

temp[4] = 45 -- 4th exp

a = temp

end

如果列表中最后一个字段的形式是 exp 同时表达式又是一个函数调用,那么调用返回的所有值会依次进入列表(见 2.5.7)。如果要避免这种情况,在函数调用两边加上括号(见 2.5)。

字段列表可以有一个结尾的分隔符,这个对由机器生成的列表十分方便。

2.5.7 - 函数调用

Lua中的一个函数调用有如下语法:

functioncall ::= prefixexp args

在函数调用中,首先会计算prefixexp和args。如果prefixexp的值是function类型,那么那个函数就会被调用,同时使用给出的参数。否则,他的"call" 元方法就会被调用,第一个参数是prefixexp的值,接下来是原来的调用参数(见 2.8)。

形式

functioncall ::= prefixexp `:′ Name args

可以用来调用“方法”("methods")。调用 v:name(...) 语法上比

https://www.doczj.com/doc/be1815984.html,(v,...),要好一些,除非表达式 v 只计算一次。

参数可以有以下几种语法:

args ::= `(′ [explist1] `)′

args ::= tableconstructor

args ::= Literal

所有的参数表达式都会在实际调用之前进行计算。f{...} 的调用形式在语法上较 f({...}) 要好,是因为,参数列表示一个单独的新表。 f'...' (或者 f"..." 或者 f[[...]])较 f('...') 要好,是因为参数列表是一个单独的字符串。

因为函数可以返回任意个结果(见 2.4.4),结果的数量必须在使用它们前进行调整。如果函数按照语句进行调用(见 2.4.6),那么它的返回列表就会被调整

为零个元素,这样就舍弃了所有的返回值。如果调用函数时,他是一个表达式列表的最后一个元素,那么不会做调整(除非调用时加了括号)。

以下是一些例子:

f() -- 调整为0个结果

g(f(), x) -- f() 被调整成1个结果

g(x, f()) -- g 获得 x 加上f()返回的所有值

a,b,c = f(), x -- f() 被调整成1个结果(此时c获得nil值) a,b,c = x, f() -- f() 被调整为两个结果

a,b,c = f() -- f() 被调整为3个结果

return f() -- 返回所有 f() 返回的值

return x,y,f() -- 建立一个表包含所有 f() 返回的值

{f()} -- creates a list with all values returned by f()

{f(), nil} -- f() 被调整为一个结果

如果你用括号括起调用的函数,那么它就会被调整为返回一个值。

return x,y,(f()) -- returns x, y, and the first value from f() {(f())} -- creates a table with exactly one element

作为Lua语法自由格式的一个例外,你不能在函数调用的 `(′前面加入一个换行。这个限制可以避免语言中的一些二义性。如果你写:

a = f

(g).x(a)

Lua会读作 a = f(g).x(a)。这样,如果你想执行为两条语句,你必须在中间加分号。如果你实际上想调用 f,你就必须删除 (g) 前面的换行。

return functioncall的调用格式称之为尾部调用(tail call)。Lua实现了proper tail calls;在一个尾部调用中,被调用的函数将会重新使用调用程序的栈。因此,程序执行对嵌套尾部调用的次数没有任何限制。然而,尾部调用会清楚调用函数的调试信息。注意尾部调用只有在特殊的语法中才能出现,也就是return只有一个函数调用作为参数,这种语法保证了调用函数确切返回被调用函数的返回值。所以,下面的例子都不是尾部调用:

return (f(x)) -- results adjusted to 1

return 2 * f(x)

return x, f(x) -- additional results

f(x); return -- results discarded

return x or f(x) -- results adjusted to 1

2.5.8 - 函数定义

函数定义的语法是:

function ::= function funcbody

funcbody ::= `(′ [parlist1] `)′ block end

下面较好的语法简化了函数定义:

stat ::= function funcname funcbody

stat ::= local function Name funcbody

funcname ::= Name {`.′ Name} [`:′ Name]

语句

function f () ... end

会被翻译为

f = function () ... end

语句

function t.a.b.c.f () ... end

会被翻译为

t.a.b.c.f = function () ... end

语句

local function f () ... end

会被翻译为

local f; f = function () ... end

一个函数定义是一个可执行的表达式,他的类型为函数(function)。当Lua 预编译语句段的时候,他的函数体也会被预编译。这样,当Lua执行函数定义的时候,函数被实例化(封装 closed)。这个函数实例(或闭包 closure)是表达式的最终结果。同一个函数的不同的实例可以引用不同的外部局部变量也可以有不同的环境表。

形式参数(代表参数的变量,简称形参)就像用实际参数值(简称实参)初始化的局部变量一样。

parlist1 ::= namelist [`,′ `...′]

parlist1 ::= `...′

当调用一个函数时,实参表会调整为和形参一样的长度,除非函数是 variadic 或者变长参数函数(vararg function)。变长参数函数在其参数列表最后有三个点 (`...′)。变长参数函数不会对参数列表进行调整;而是,它把所有的额外实参放到一个隐含的形参 arg中。 arg 的值是一个表,包含一个字段`n′表示额外参数的个数,位置 1, 2, ..., n是额外的参数。

请思考以下函数定义的例子:

function f(a, b) end

function g(a, b, ...) end

function r() return 1,2,3 end

然后,我们有以下实参到形参的对应关系:

CALL PARAMETERS

f(3) a=3, b=nil

f(3, 4) a=3, b=4

f(3, 4, 5) a=3, b=4

f(r(), 10) a=1, b=10

f(r()) a=1, b=2

g(3) a=3, b=nil, arg={n=0}

g(3, 4) a=3, b=4, arg={n=0}

g(3, 4, 5, 8) a=3, b=4, arg={5, 8; n=2}

g(5, r()) a=5, b=1, arg={2, 3; n=2}

结果使用return语句返回(见 2.4.4)。如果控制到达了函数尾部而没有遇到return语句,那么函数没有返回值。

冒号(:)语法是用来定义methods的,也就是,函数有一个隐含的额外参数self. 。这样,语句:

function t.a.b.c:f (...) ... end

相对以下是较好的形式:

t.a.b.c.f = function (self, ...) ... end

2.6 - 可见性规则

Lua是一个有词法范围的语言。变量的范围从声明语句后的第一个语句开始到包含声明的最内部的语句块为止。例如:

x = 10 -- global variable

do -- new block

local x = x -- new `x', with value 10

print(x) --> 10

x = x+1

do -- another block

local x = x+1 -- another `x'

print(x) --> 12

end

print(x) --> 11

end

print(x) --> 10 (the global one)

注意:在类似 local x = x,正在声明的新的 x 尚未进入范围,所以第二个 x 指代的是外面的变量。

由于词法范围的规则,在局部变量的范围内定义的函数可以任意访问这些变量。例如:

local counter = 0

function inc (x)

counter = counter + x

return counter

end

内部函数使用的局部变量在函数内部称之为上值(upvalue),或者外局部变量(external local variable)。

注意每个local语句执行时会定义一个新的局部变量。看以下例子:

a = {}

local x = 20

for i=1,10 do

local y = 0

a[i] = function () y=y+1; return x+y end

end

循环产生了十个闭包(也就是,十个匿名函数的实例)。每个闭包使用不同的 y 变量,但他们共享同一个 x 变量。

2.7 - 错误处理

因为Lua是一个扩展语言,所有的Lua动作都是从宿主程序中调用Lua库中函数的C代码开始的(见 3.15)。无论错误发生在Lua编译过程时或执行时,控制返回C,然后可以做相应的处理(比如打印一个错误)。

Lua代码可以通过调用error函数来产生一个错误(见 5.1)。如果你要在Lua 中捕获错误,你可以使用 pcall 函数(见 5.1)。

2.8 - 元表(Metatables)

Lua中的每一个表和用户数据都可以拥有一个元表(metatable)。这个元表是一个普通的Lua表,定义了在特定操作下原始表和用户数据的行为。你可以通过设置一个对象的元表中的特定字段来更改它某些方面的行为。例如,当一个对象是一个加法的操作数时,Lua检查它的元表中的 "__add" 字段是不是一个函数。如果是,Lua调用它来执行加法。

我们称元表中的键(字段名,key)为事件(events),值为元方法(metamethods)。在上一个例子中, "add" 是事件,执行加法的函数是元方法。你可以通过 set/getmetatable 函数来查询和更改一个对象的元表(见 5.1)。

元表可以控制对象在算术操作、比较、串连接、索引取值中如何运行。元表也可以定义一个函数当收集内存垃圾时调用。每一个操作这里Lua都用一个特定的键关联,称之为事件。当Lua对一个表或是一个用户数据执行上面中的一个操作时,它先检查元表控制的操作已经罗列在下面。每个操作有一个相应的名称,代表了他的含义。他们在元表中的键是由名称前加上两条下划线;如,操作 "add" 的键是 "__add"。这些操作的语义

这里给出的Lua代码仅仅是说明性的;真正的行为是硬编码在解释器中的,比下面的的模拟的效率要高很多。描述中用到的函数 (rawget, tonumber, 等等) 在5.1 中会对他们进行描述。特别地,要获得一个给定对象的元方法,我们使用这个表达式:

metatable(obj)[event]

这个要读作:

rawget(metatable(obj) or {}, event)

也就是,访问元方法时不会调用其它元方法,同时调用没有元表的对象不会出错(它返回一个nil值)。

?"add": + 加法操作。

下面的 getbinhandler 函数定义了Lua如何给一个二元操作选择一个处理器。首先,Lua尝试第一个操作数。如果它的类型没有定义这个操作的处理器,那么然后Lua尝试第二个操作数。

function getbinhandler (op1, op2, event)

return metatable(op1)[event] or metatable(op2)[event]

end

利用该函数,op1 + op2 的行为方式可看作是

function add_event (op1, op2)

local o1, o2 = tonumber(op1), tonumber(op2)

if o1 and o2 then -- both operands are numeric?

return o1 + o2 -- `+' here is the primitive `add'

else -- at least one of the operands is not numeric

local h = getbinhandler(op1, op2, "__add")

if h then

-- call the handler with both operands

return h(op1, op2)

else -- no handler available: default behavior

error("...")

end

end

end

?"sub": - 操作。行为方式类似 "add" 操作。

?"mul": * 操作。行为方式类似 "add" 操作。

?"div": / 操作。行为方式类似 "add" 操作。

?"pow": ^ (指数)操作

? function pow_event (op1, op2)

? local o1, o2 = tonumber(op1), tonumber(op2)

? if o1 and o2 then -- both operands are numeric?

? return __pow(o1, o2) -- call global `__pow'

? else -- at least one of the operands is not numeric

? local h = getbinhandler(op1, op2, "__pow")

? if h then

? -- call the handler with both operands

? return h(op1, op2)

? else -- no handler available: default behavior

? error("...")

最新STM8L15X中文参考手册资料

本参考手册的目标应用程序开发人员。它提供了完整的信息如何使用stm8l05xx,stm8l15xx 和stm8l16xx微控制器的存储器和外围设备。 该stm8l05xx / stm8l15xx / stm8l16xx是一个家庭的不同存储密度的微控制器和外围设备。这些产品是专为超低功耗应用。可用的外设的完整列表,请参阅产品数据表。 订购信息,引脚说明,机械和电气设备的特点,请参阅产品数据表。 关于STM8 SWIM通信协议信息和调试模块,请参阅用户手册(um0470)。 在STM8的核心信息,请参阅STM8的CPU编程手册(pm0044)。关于编程,擦除和保护的内部快闪记忆体,请参阅STM8L闪存编程手册(pm0054)。

1 中央处理单元(CPU)。30。 1.1 引言30 1.2 CPU的寄存器。30。 1.2.1 描述CPU寄存器。..。30 1.2.2 STM8 CPU寄存器图。..。34 1.3 全球配置寄存器(cfg_gcr)。34。 1.3.1 激活水平。..。34 1.3.2 游泳禁用。..。35 1.3.3 描述全局配置寄存器(cfg_gcr)。..。35 1.3.4 全局配置寄存器图及复位值。..。35 2 启动ROM . . . 36 3程序存储器和数据存储器。37。 3.1引言37 3.2术语。37。 3.3个主要的快闪存储器的特点。38。 3.4记忆的组织。39。 3.4.1低密度设备的存储器组织。39 3.4.2介质密度的装置记忆的组织。..。40 3.4.3介质+密度装置记忆的组织。..。41 3.4.4高密度存储器组织。..。42 3.4.5专有代码区(译)。43 3.4.6用户区(UBC)。43 3.4.7数据的EEPROM(数据)。..。46 3.4.8主程序区。46 3.4.9选项字节。..。46 3.5内存保护。47。 3.5.1读出保护。47 3.5.2内存访问安全系统(质量)。47 3.5.3使写访问选项字节。49 3.6内存编程49 3.6.1同时读写(读写网)。..。49 2 / 573文档ID 15226转9 rm0031内容 3.6.2字节编程。..。49 3.6.3字编程。50 3.6.4块编程。50 3.6.5选项字节编程。52 Flash 3.7的低功耗模式。52。 3.8例ICP和IAP。52。 3.9闪光寄存器57 3.9.1闪光控制寄存器1(flash_cr1)。57 3.9.2闪光控制寄存器2(flash_cr2)。58

STM8L152中文介绍

STM8L152介绍 8位超低功耗单片机,高达64 + 2字节数据的闪存EE PROM,EEPROM (Electrically Erasable Programmable ), 实时时钟,液晶显示器,定时器,USART,C,SPI,模数转换器,数模转换器,比较器特点:操作条件:工作电源:1.65v~ 3.6v 温度范围:40 to 85, 105 or 125 低功耗的特点:5个低功耗模式:等,低功率运行 (5.9|ì一),低功耗等(3|ì一),active-halt 全实时时钟(1.4|ì一),停止(400) 动态功率消耗:200UA/兆赫+ 330UA,快速唤醒从停止模式(4.7us) 超低漏 I/ O:50nA 先进的stm8核心: 哈佛结构和三级流水线

最大频率:16条16mhz,相关峰 最多40个外部中断源 复位和供应管理: 低功率,超安全欠压复位5可编程阈值 超低功率POR /PDR(通电复位/Protection(保护)、Detection(检测)、Response(响应)) 可编程电压检测器(Programmable voltage detector (PVD)) 时钟管理 32kHz和1-16MHz晶体振荡器 工厂校准的内部16MHz RC和 38kHz的低功耗RC 时钟安全系统

低功耗RTC BCD日历,闹钟中断, 数字校准+ / - 0.5ppm的准确度 先进的防篡改检测 DMA 4个通道。 ADC,DAC的,SPIS,我 2C,USART接口,定时器,1路。存储器到存储器的 LCD:8x40或4x44瓦特/升压转换器 12位ADC1 Msps/28渠道 温度。传感器和内部参考。电压 记忆

STM8L051低功耗模式实现说明文档

STM8L051低功耗模式测试文档 STM8L051的五种低功耗模式wait ,low power run mode,low power wait mode,Ative-Halt mode,Halt mode。 1、WAIT mode 在等待模式,CPU的时钟是停止的,被选择的外设继续运行。W AIT mode 分为两种方式:WFE,WFI。WFE是等待事件发生,才从等待模式中唤醒。WFI是等待中断发生,才从等待模式中唤醒。 2、low power run mode 在低功耗运行模式下,CPU和被选择的外设在工作,程序执行在LSI或者LSE下,从RAM 中执行程序,Flash和EEPROM都要停止运行。电压被配置成Ultra Low Power模式。进入此模式可以通过软件配置,退出此模式可以软件配置或者是复位。 3、low power wait mode 这种模式进入是在low power run mode下,执行wfe。在此模式下CPU时钟会被停止,其他的外设运行情况和low power run mode类似。在此模式下可以被内部或外部事件、中断和复位唤醒。当被事件唤醒后,系统恢复到low power run mode。 4、Active-Halt mode 在此模式下,除了RTC外,CPU和其他外设的时钟被停止。系统唤醒是通过RTC中断、外部中断或是复位。 5、Halt mode 在此模式下,CPU和外设的时钟都被停止。系统唤醒是通过外部中断或复位。关闭内部的参考电压可以进一步降低功耗。通过配置ULP位和FWU位,也可以6us的快速唤醒,不用等待内部的参考电压启动。 一、各个低功耗模式的代码实现 1、WAIT mode 等待模式分为两种:WFI和WFE。 1.1 WFI mode 当执行“wfi”语句时,系统就进入WFI模式,当中断发生时,CPU被从WFI模式唤醒,执行中断服务程序和继续向下执行程序。 通过置位CFG_GCR的AL位,使主程序服务完中断服务程序后,重新返回到WFI 模式。 程序如下: void Mcuwfi() { PWR_UltraLowPowerCmd(ENABLE); //开启电源的低功耗模式 CLK_HSEConfig(CLK_HSE_OFF); //关闭HSE时钟(16MHz) #ifdef USE_LSE CLK_SYSCLKSourceConfig(CLK_SYSCLKSource_LSE);

2021年STM8L中文参考手册-1

简介 欧阳光明(2021.03.07) 本参考手册的目标应用程序开发人员。它提供了完整的信息如何使用stm8l05xx,stm8l15xx和stm8l16xx微控制器的存储器和外围设备。 该stm8l05xx / stm8l15xx / stm8l16xx是一个家庭的不同存储密度的微控制器和外围设备。 这些产品是专为超低功耗应用。可用的外设的完整列表,请参阅产品数据表。 订购信息,引脚说明,机械和电气设备的特点,请参阅产品数据表。 关于STM8 SWIM通信协议信息和调试模块,请参阅用户手册(um0470)。 在STM8的核心信息,请参阅STM8的CPU编程手册(pm0044)。关于编程,擦除和保护的内部快闪记忆体,请参阅STM8L闪存编程手册(pm0054)。 表一、 类型零件号 控制器价值线低密度stm8l05xx设备:stm8l051x3 8KB Flash微控制器 价值线中密度stm8l05xx设备:stm8l052x6微控制器与32闪光 价值线高密度stm8l05xx设备:stm8l052x8 64-KB闪存微控制器 低密度stm8l15x设备:stm8l151c2 / K2 / G2/F2, stm8l151c3 / K3 / G3 / F3微控制器与4KB或8KB Flash 中密度stm8l15xx设备:stm8l151c4 / K4 / G4, 微控制器stm8l151c6 / K6 / G6,stm8l152c4 / K4和stm8l152c6 / K6 微控制器与16-KB或32闪光 培养基+密度stm8l15xx设备:stm8l151r6和 stm8l152r6微控制器与闪存(32比中密度器件广泛的外设范围) 高密度stm8l15xx设备:stm8l151x8和stm8l152x8 随着64-KB闪存微控制器(相同的外周设置为中等+) 高密度stm8l16xx设备:stm8l162x8微控制器与闪存(相同的外周设置为 64-KB高密度stm8l152设备加AES硬件加速器 目录 1中央处理单元(CPU)。30。 1.1引言30 1.2 CPU的寄存器。30。 1.2.1描述CPU寄存器。..。30 1.2.2STM8 CPU寄存器图。..。34 1.3全球配置寄存器(cfg_gcr)。34。 1.3.1激活水平。..。34

STM8L中文参考手册(4)-

STM8L中文参考手册(4)- 20 16位通用定时器(TIM2、TIM3、tim5) 20.1简介 本章介绍TIM2、TIM3和tim5是相同的定时器 每个定时器包括一个由可编程分频器驱动的16位上下自动重载计数器它可以用于多种目的,包括:●定时产生●测量输入信号的脉冲长度(输入捕获) ●产生输出波形(输出比较、脉宽调制和脉冲模式)●各种中断能力事件(捕获、比较、溢出) ●与其他定时器或外部信号(外部时钟、复位、触发使能)同步 定时器时钟可以来自内部时钟,也可以来自配置寄存器或外部源本章仅介绍通用定时器的主要特性。它参考了与19:16高级控制定时器(TIM1)相对应的部分中的每个功能的更详细的信息页28320.2 TIMx 主要功能 通用TIMx TIM2/TIM3功能包括: ●16位向上、向下、向上/向下自动刷新计数器●3位可编程分频器允许将计数器的时钟频率分成1至128的任意2次方两个独立的低电平通道:输入捕获输出比较 脉冲宽度调制产生(边沿对齐)-一个脉冲输出模式 低电平中断输入,用于复位定时器输出信号,或处于已知状态●输入捕捉2可通过来自comp2比较器 :

更新的中断和DMA请求产生以下事件:当计数器溢出时,计数器初始化(软件)输入捕捉输出比较中断输入 触发事件(开始、停止、内部/外部触发初始化或计数) 20.3.1时间单元 定时器时基单元包括:●16位可逆计数器 时钟源是内部时钟(fsysclk)它由预分频器计数器的时钟ck_cnt驱动,预分频器计数器直接连接到ck_psc时钟馈送 分频器 分频器的实现如下:7位计数器(在timx_pscr寄存器中)由基于 低预分频器的3位寄存器控制它可以控制飞行中寄存器缓冲区的变化。它可以将计数器的时钟频率转换为1、2、4、8、16、32、64或128计数器的时钟频率计算如下: fCk _ CNT = fck _ PSC/2(PSCR[2:0)计数器操作 请参考第19.3.4页:上部288,模式部分19.3.5:在第290页向下计数,模式19.3.6:中心对齐(向上/向下计数)29220.3.2时钟/触发控制器 参见第296页第19.4节:TIM1时钟/触发控制器20.3.3采集/比较通道输入级 参见第310页第19.5节:TIM1采集/比较通道 有两个输入通道,如图122:输入级框图通道2内部连接到比较器

stm8l中文参考手册(下)

手动开关 手动开关没有自动切换为直接的但它提供给用户的切换事件时间的精确控制。参照图20中的流程图。 1。写使用系统时钟开关选择目标时钟源的8位值寄存器(clk_swr)。然后swbsy位是由硬件,和目标源振荡器开始。古老的时钟源继续驱动CPU和外设。 2。该软件具有等到目标时钟源准备(稳定的)。这是在clk_swcr寄存器和快捷旗由中断如果swien位设置显示。 3。最终软件的作用是设置,在所选择的时间,在clk_swcr的赛文点寄存器来执行开关。在手动和自动切换模式,旧的系统时钟源不会自动关闭的情况下是由其他模块(LSI混凝土可用于例如独立的看门狗驱动)。时钟源可以关机使用在内部时钟寄存器的位(clk_ickcr)和外部时钟寄存器(clk_eckcr)。如果时钟开关不因任何原因的工作,软件可以通过清除swbsy 标志复位电流开关操作。这将恢复clk_swr注册到其以前的内容(旧的系统时钟)。注意:在清理swbsy标志具有复位时钟主开关的程序,应用程序必须等到后产生新的主时钟切换请求之前有一段至少两个时钟周期。

9.7周门控时钟(PCG) 外周时钟门控(PCG)模式选择性地启用或禁用系统时钟(SYSCLK)连接到外围设备在运行或慢速模式的任何时间来优化功耗。 设备复位后,所有的外设时钟被禁用。唯一的一点是在复位状态是默认启用pcken27因为它用于启动。软件已被正确地写入关掉ROM Bootloader执行后的时钟。 您可以启用时钟的任何外围设置在clk_pckenrx周围门控时钟寄存器的相应pcken点。 ●使周围,首先使在clk_pckenr相应的pcken点 寄存器然后设置使点周围的外围控制寄存器。 ●禁用适当的外围,先禁用在周边的适当位 控制寄存器,然后停止相应的时钟。

stm8L051F3

This is information on a product in full production. March 2014 DocID023465 Rev 21/93 STM8L051F3 Value Line, 8-bit ultralow power MCU, 8-KB Flash, 256-byte data EEPROM, RTC, timers, USART, I2C, SPI, ADC Datasheet production data Features ?Operating conditions –Operating power supply: 1.8 V to 3.6 V Temperature range: ?40 °C to 85 °C ?Low power features – 5 low power modes: Wait, Low power run (5.1 μA), Low power wait (3 μA), Active-halt with RTC (1.3 μA), Halt (350 nA)–Ultra-low leakage per I/0: 50 nA –Fast wakeup from Halt: 5 μs ?Advanced STM8 core –Harvard architecture and 3-stage pipeline –Max freq: 16 MHz, 16 CISC MIPS peak –Up to 40 external interrupt sources ?Reset and supply management –Low power, ultra-safe BOR reset with 5 selectable thresholds –Ultra low power POR/PDR –Programmable voltage detector (PVD)?Clock management –32 kHz and 1 to 16 MHz crystal oscillators –Internal 16 MHz factory-trimmed RC –Internal 38 kHz low consumption RC –Clock security system ?Low power RTC –BCD calendar with alarm interrupt –Digital calibration with +/- 0.5 ppm accuracy –LSE security system –Auto-wakeup from Halt w/ periodic interrupt ?Memories –8 Kbytes of Flash program memory and 256 bytes of data EEPROM with ECC –Flexible write and read protection modes – 1 Kbyte of RAM ?DMA – 4 channels supporting ADC, SPI, I2C, USART, timers – 1 channel for memory-to-memory ?12-bit ADC up to 1 Msps/28 channels –Internal reference voltage ?Timers –Two 16-bit timers with 2 channels (used as IC, OC, PWM), quadrature encoder –One 8-bit timer with 7-bit prescaler – 2 watchdogs: 1 Window, 1 Independent –Beeper timer with 1, 2 or 4 kHz frequencies ?Communication interfaces –Synchronous serial interface (SPI)–Fast I 2C 400 kHz SMBus and PMBus –USART ?Up to 18 I/Os, all mappable on interrupt vectors ?Development support –Fast on-chip programming and non-intrusive debugging with SWIM –Bootloader using USART https://www.doczj.com/doc/be1815984.html,

STM8L入门手册

STM8L单片机入门手册 注:本教程以STM8L052R8和IAR开发环境为例1、IAR环境安装与注意事项: 安装时按照一般软件安装即可,提示需要输入License时请使用IAR kegen PartC软件进行破解,注意Product选择STM8项,如下图示: 另外:机器上本身安装过MSP430平台的IAR环境,安装STM8平台的IAR是可以兼容的

2、IAR环境创建STM8工程: 2.1、创建工程 如下图示,打开IAR环境for STM8 选择project->Create New Project,选择C语言开发,点击“OK” 选择保存路径后输入工程名点击“保存”即可。

按上图示,添加文件分组,并命名“SRC”和“Lib”,类似方法在分组中添加文件。 2.2工程重要设置: 右击工程名,选择“Options…” 在General Options项中,Target选项卡中按照下图设置: 在C/C++ Compiler项中,Preprocessor选项卡中添加头文件路径,如下图示:

红色圈内容直接输入(不能选???) $PROJ_DIR$\..\Lib\inc 解释:$PROJ_DIR$->表示当前工程目录(.eww文件所在目录); ..->表示上层目录; 在Debugger项中,设置仿真调试器与入口函数,如下图示:

main 上图中,Run to:写main 这里是设置入口函数2.3设置生成HEX文件: 右击工程名,选择“Options…”

该设置不会影响调试器在线仿真功能,可以一直勾选上,这点和MSP430不同。 3、IAR环境常见问题及解决方法 3.1、Couldn’t go to ‘M52Li’ 进入调试模式是会有下图警告,并且不能调试 找不到入口函数,入口函数应该是main 3.2、“The debugging session could not be started.” 由于脱机烧录或者其他原因写了保护,造成连接不上目标板。 解决方法: 打开STVP软件,点击读取按钮,会出现以下报错: 此时,进入到OPTION BYTE页面,将ROP写为OFF模式,如下图示

STM8L05X入门学习笔记

1、工程新建 首先新建文件夹,在文件夹下建立四个文件(这个看个人喜好),我喜欢建立一个工程文件夹Project用于存放工程文件,Library文件用于存放库文件,App用于存放用户程序,Doc 用于存放说明文档,如图1所示。 图1 二:将官方的库文件Libraries文件下STM8S_StdPeriph_Driver这个文件下的内容复制到自己新建的Library文件下,把官方Project文件下Template文件夹下main.c stm8s_conf.h stm8s_it.c 和stm8s_it.h复制到App文件夹下。如图2,图3。 图2 图3 三:打开IAR 选择Project-> Create New Project –>ok,将文件保存到Project下,

这时工程已经建好,右击工程选择Add Group,然后依次添加文件App,Libraries,Doc,BSP_CFG 配置好如图所示 四:给工程下APP添加App文件下的文件如图

给Libraries添加Library文件下src文件下的所有文件、 五配置Options,包括如下,1选择型号这里选STM8S903K3 2C++选项卡配置路经,和型号的宏定义。

六编译工程,这事会提醒对工程的保存,进行保存即可,这时会发现很多错误,这是因为这个库包含了所有的型号,有些这个单片机没有,将它移除即可。再次编译就会发现没有错误了。 7HEX文件输出

2、系统时钟 四种不同的时钟源可以用来驱动系统时钟: ●16 MHz 高速内部(HSI)工厂调整RC 时钟 ●1 到16 MHz 高速外(HSE)振荡器时钟 ●32.768 千赫低速外(LSE)振荡器时钟 ●38 千赫低速内部(LSI)低功耗时钟 每个时钟源可以开启或关闭独立不使用时的功耗,优化。 这四个时钟可以用一个可编程分频器(因素1 至128)驱动 系统时钟(系统时钟)。该系统时钟用于时钟的核心,内存和外设。复位后,该设备重新启动与HSI 时钟除以8 的违约。该分频器分频比时钟源可以改变应用程序尽快执行代码起点。

stm8L 数据手册

October 2010Doc ID 15275 Rev 111/81 STM8L101xx 8-bit ultralow power microcontroller with up to 8 Kbytes Flash, multifunction timers, comparators, USART , SPI, I2C Features ■ Main microcontroller features –Supply voltage range 1.65 V to 3.6 V –Low power consumption (Halt: 0.3μA, Active-halt: 0.8μA, Dynamic Run: 150μA/MHz) –STM8 Core with up to 16 CISC MIPS throughput –Temp. range: -40 to 85°C and 125 °C ■ Memories –Up to 8 Kbytes of Flash program including up to 2 Kbytes of data EEPROM –Error correction code (ECC) –Flexible write and read protection modes –In-application and in-circuit programming –Data EEPROM capability – 1.5 Kbytes of static RAM ■ Clock management –Internal 16 MHz RC with fast wakeup time (typ. 4μs) –Internal low consumption 38kHz RC driving both the IWDG and the AWU ■ Reset and supply management –Ultralow power, ultrasafe power-on-reset /power down reset –Three low power modes: Wait, Active-halt, Halt ■ Interrupt management –Nested interrupt controller with software priority control –Up to 29 external interrupt sources ■ I/Os –Up to 30 I/Os, all mappable on external interrupt vectors –I/Os with prog. input pull-ups, high sink/source capability and one LED driver infrared output ■ Peripherals –Two 16-bit general purpose timers (TIM2 and TIM3) with up and down counter and 2 channels (used as IC, OC, PWM) –One 8-bit timer (TIM4) with 7-bit prescaler –Infrared remote control (IR)–Independent watchdog –Auto-wakeup unit –Beeper timer with 1, 2 or 4 kHz frequencies –SPI synchronous serial interface –Fast I2C Multimaster/slave 400 kHz –USART with fractional baud rate generator – 2 comparators with 4 inputs each ■Development support –Hardware single wire interface module (SWIM) for fast on-chip programming and non intrusive debugging –In-circuit emulation (ICE)■ 96-bit unique ID Table 1. Device summary Reference Part number STM8L101xx STM8L101F1, STM8L101F2, STM8L101F3, STM8L101G2, STM8L101G3STM8L101K3 https://www.doczj.com/doc/be1815984.html,

相关主题
文本预览
相关文档 最新文档