. 首先放置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(毕竟字符串才多大啊)。