. 首先放置LUA资源

2. 整体思路

创建Keil工程 -> 移植Lua -> 补充相应功能

3. 移植Lua

步骤1:

正常解压即可,只有这个文件有用。

步骤2:

在这个文件夹里搜索,删掉这两个文件(这两个文件在STM32中不使用)。剩余的文件按照添加BSP的流程添加即可。

步骤3:

打开工程,添加完毕后应该是这个样子的,如果不一样,可以跟着改一下。

步骤4:

修改Stack_Size,找到这个文件。Stack_Size必须修改,Heap_Size根据情况进行修改。

步骤5:

创建LUA所需函数。//随便找个文件丢进去就行(建议创建一个特定存放lua函数的c文件)

```c

time_t time(time_t * time){ return 0; }

void exit(int status){ }

int system(const char * string){ return 0; }

```

步骤6:

编译一下,没报错,就OK了!

4. Lua的基本使用

步骤1:基本LUA函数的创建

```c

int Lua_LED(lua_State *L) {

uint8_t flag = lua_tointeger(L,1); // 读取传入函数的参数,数字是传入的所有数据的第几个

if(flag){

switch (flag) {

case 1:{LED0_TOGGLE();}break; //LED0_TOGGLE()是写好的c语言函数

case 2:{LED1_TOGGLE();};break;

case 3:{LED0_TOGGLE();};break;

};

}

return 1; //返回的是个数 不是参数

}

```

步骤2:关于Lua函数的注册

只有注册过的Lua函数才能被Lua解释器识别。

重构后的内容如下:

1. 定义一个Lua库结构体数组;

2. 编写LuaLED函数;

3. 编写Lua_delay_ms函数;

4. 编写Lua_ADC函数;

5. 创建一个符合Lua语法规则的字符串;

6. 创建Lua解释器;

7. 在主循环中启动Lua。

```c

#include

#include "lua.h"

#include "lauxlib.h"

#include "lualib.h"

const struct luaL_Reg mylib[] = {

{"Lua_LED", Lua_LED},

{"Lua_delay_ms", Lua_delay_ms},

{"Lua_ADC", Lua_ADC},

{NULL, NULL}

};

// LuaLED函数实现(此处省略)

// ...

// Lua_delay_ms函数实现(此处省略)

// ...

// Lua_ADC函数实现(此处省略)

// ...

char lua_test[] = {

"print(\"LUA 启动\")

"

#if (defined(__SAMD51__)) && (!defined(ARDUINO)) && (!defined(COMPILATION)) && (!defined(__SWO__)) && (!defined(ARDUINO_ARCH_ESP32)) && (!defined(ARDUINO_ARCH_ESP8)) && (!defined(ARDUINO_ARCH_STM32)) && (!defined(ARDUINO_ARCH_AVR)) && (!defined(INVERTER_GENERIC)) && (!defined(INVERTER_MAX31865)) && (!defined(INVERTER_TM1638)) && (!defined(INVERTER_MAX645X)) && (!defined(INVERTER_TM1637)) && (!defined(INVERTER_MAX32600)) && (!defined(INVERTER_PCA9685)) && (!defined(INVERTER_BME280)) && (!defined(INVERTER_SHT3X)) && (!defined(INVERTER_BH1750FVI)) && (!defined(__AVR__)) && (!defined(__ARM__)) && (!defined(__PIC32MX__)) && (!defined(__PIC32MX795__)) && (!defined(__PIC32MX495__)) && (!defined(__PIC32MX7K__)) && (!defined(__PIC32E__)) && (!defined(__RZ__)),

#ifdef __SAMD51__ || defined(ARDUINO) || defined(COMPILATION) || defined(__SWO__) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8) || defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_AVR) || defined(INVERTER_GENERIC) || defined(INVERTER_MAX31865) || defined(INVERTER_TM1638) || defined(INVERTER_MAX645X) || defined(INVERTER_TM1637) || defined(INVERTER_MAX32600) || defined(INVERTER_PCA9685) || defined(INVERTER_BME280) || defined(INVERTER_SHT3X) || defined(INVERTER_BH1750FVI),

"main() {

"

LUA_START();

luaL_dostring(LUA, "print(\"Hello, world!\\")");

LUA_STOP();

}",

0, NULL};

};

int LUA_Start() {

LUA_ENV = luaL_newstate(); // 创建Lua编译器

luaopen_base(LUA_ENV); // 注册基本函数

luaL_setfuncs(LUA_ENV, mylib, 0); // 将自定义函数添加到Lua环境中

return 0;

}

```

以下是根据您提供的内容重构的代码:

```c

while (1) {

usart_code_Get(); //接收串口指令

if (receive_code_complete == 1) {

int a = luaL_dostring(LUA_ENV, lua_test); //执行脚本语句

if (a == 1) {

printf("Lua-Code Running Error!

");

printf("Error: %s

", lua_tostring(LUA_ENV, -1)); //如果出错了,Lua解释器会把报错压入栈中,直接读取就行

receive_code_complete = 0;

}

} else {

LED0_TOGGLE();

delay_ms(3000);

}

}

```

关于串口传输语句的规则:

1. 串口传输语句按照lua语法直接传输即可。

2. 注意串口协议和串口助手的不同。很多例程里以`

`作为串口接收的结束。如果你在串口传输的时候,在串口助手中依靠回车换行,请务必转换成16进制,查看是否为`0D 0A`或是单独的`0A`。有条件的最好可以自己写一个上位机。

3. 针对程序更新后,如果重新上电丢失的问题,可以使用flash(毕竟字符串才多大啊)。