1. Basic development environment
The development environment is based on the Wildfire STM32 development board.
The Lua interpreter version tested before is 5.4.2.
Download the lua resource package from the official website. The download address is as follows:
https://www.lua.org/
https://github.com/rjpcomputing/luaforwindows/releases
lua: Lua domestic mirror (gitee.com)
Two, transplant Lua interpreter
1. Unzip the downloaded Lua, delete the lua.c and luac.c (if any) files in the source file.
2. Create a new stm32 project
3. Add Lua source code to the project
Copy the Lua source file to the project
add header file
Change part of the loslib.c file
-
Comment the if(L) exit(status) in the os_exit(lua_State * L) function, and add the status=status statement.
2. Add time(time_t *time) and system(const char *string)
The above was changed because of the Use MicroLIB mode.
static int os_exit (lua_State *L) {
int status;
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
status = (int)luaL_optinteger(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
//if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
status=status;
return 0;
}
time_t time(time_t *time)
{
return 0;
}
int system(const char * string)
{
return 0;
}
Three, Lua use test
-
write test code
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static int lua_led_on(lua_State *L)
{
LED1( ON );
return 1;
}
static const struct luaL_Reg mylib[]=
{
{"led_on",lua_led_on},
{NULL,NULL}
};
const char LUA_SCRIPT_GLOBAL_ON[] =" \
while 1 do\
led_on() \
end";
int main(void)
{
SystemClock_Config();
LED_GPIO_Config();
LED1( ON ); // 亮
HAL_Delay(1000);
LED1( OFF ); // 灭
HAL_Delay(1000);
lua_State *L;
L = luaL_newstate(); //建立Lua运行环境
luaopen_base(L);//注册基础函数(此函数要屏蔽luaL_setfuncs(L, base_funcs, 0);)
luaL_setfuncs(L, mylib, 0);//注册自定义函数
luaL_dostring(L, LUA_SCRIPT_GLOBAL_ON);
while(1)
{
}
}
/**
******************************************************************************
* @file main.c
* @author fire
* @version V1.0
* @date 2017-xx-xx
* @brief GPIOÊä³ö--ʹÓù̼þ¿âµãÁÁLEDµÆ
******************************************************************************
* @attention
*
* ʵÑéƽ̨:Ò°»ð STM32 F407 ¿ª·¢°å
* ÂÛ̳ :http://www.firebbs.cn
* ÌÔ±¦ :http://firestm32.taobao.com
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx.h"
#include "./led/bsp_led.h"
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static void SystemClock_Config(void);
#if 1
static int lua_led_delay_ms(lua_State *L)
{
// int i=0xFFFFF;
// while(i--)
// {
// ;;
// }
// //HAL_Delay(1000);
HAL_Delay(1000);
return 1;
}
static int lua_led_on(lua_State *L)
{
LED1( ON ); // ÁÁ
lua_led_delay_ms(L);
LED1( OFF );
lua_led_delay_ms(L);
//HAL_GPIO_TogglePin(GPIOG,GPIO_PIN_7);
return 1;
}
static int lua_led_off(lua_State *L)
{
LED1( OFF ); // Ãð
return 1;
}
static const struct luaL_Reg mylib[]=
{
{"led_on",lua_led_on},
{NULL,NULL}
};
const char LUA_SCRIPT_GLOBAL_ON[] =" \
while 1 do\
led_on() \
end";
const char LUA_SCRIPT_GLOBAL_OFF[] =" \
led_off() \
end";
const char LUA_SCRIPT_GLOBAL_TEST[] =" \
while 1 do\
led_on() \
led_delay()\
led_off() \
led_delay()\
end";
void BEEP_GPIO_Config(void)
{
/*¶¨ÒåÒ»¸öGPIO_InitTypeDefÀàÐ͵ĽṹÌå*/
GPIO_InitTypeDef GPIO_InitStruct;
/*¿ªÆôBEEPÏà¹ØµÄGPIOÍâÉèʱÖÓ*/
__GPIOG_CLK_ENABLE();
/*Ñ¡ÔñÒª¿ØÖƵÄGPIOÒý½Å*/
GPIO_InitStruct.Pin = GPIO_PIN_7;
/*ÉèÖÃÒý½ÅµÄÊä³öÀàÐÍΪÍÆÍìÊä³ö*/
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
/*ÉèÖÃÒý½ÅΪÉÏÀģʽ*/
GPIO_InitStruct.Pull = GPIO_PULLUP;
/*ÉèÖÃÒý½ÅËÙÂÊΪ¸ßËÙ */
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
/*µ÷Óÿ⺯Êý£¬Ê¹ÓÃÉÏÃæÅäÖõÄGPIO_InitStructure³õʼ»¯GPIO*/
HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOG,GPIO_PIN_7,0);
}
/**
* @brief Ö÷º¯Êý
* @param ÎÞ
* @retval ÎÞ
*/
int main(void)
{
/* ϵͳʱÖÓ³õʼ»¯³É168MHz */
SystemClock_Config();
/* LED ¶Ë¿Ú³õʼ»¯ */
LED_GPIO_Config();
//BEEP_GPIO_Config();
LED1( ON ); // ÁÁ
HAL_Delay(1000);
LED1( OFF ); // Ãð
HAL_Delay(1000);
#if 0
lua_State *L;
L = luaL_newstate(); //
luaopen_base(L);
lua_register(L, "led_on", lua_led_on);
lua_register(L, "led_off", lua_led_off);
lua_register(L, "led_delay", lua_led_delay_ms);
while(1)
{
luaL_dostring(L, LUA_SCRIPT_GLOBAL_TEST);
}
#else
/* ¿ØÖÆLEDµÆ */
while(1)
{
lua_State *L;
L = luaL_newstate(); //
luaopen_base(L);
luaL_setfuncs(L, mylib, 0);
luaL_dostring(L, LUA_SCRIPT_GLOBAL_ON);
while(1);
}
#endif
}
#else
static int lua_led_on(lua_State *L)
{
LED1( ON );
return 1;
}
static int lua_led_off(lua_State *L)
{
LED1( OFF );
return 1;
}
static int lua_delay(lua_State *L)
{
int num;
// num= lua_tointeger(L, 1);
HAL_Delay(500);
return 1;
}
static const struct luaL_Reg mylib[]=
{
{"led_on",lua_led_on},
{"led_off",lua_led_off},
{"delay",lua_delay},
{NULL,NULL}
};
const char LUA_SCRIPT_GLOBAL[] =" \
off = 500 \
on = 500 \
while 1 do \
led_on() \
delay(on) \
led_off() \
delay(off) \
end";
/**
* @brief Ö÷º¯Êý
* @param ÎÞ
* @retval ÎÞ
*/
int main(void)
{
/* ϵͳʱÖÓ³õʼ»¯³É168MHz */
SystemClock_Config();
/* LED ¶Ë¿Ú³õʼ»¯ */
LED_GPIO_Config();
LED1( ON ); // ÁÁ
HAL_Delay(1000);
LED1( OFF ); // Ãð
HAL_Delay(1000);
/* ¿ØÖÆLEDµÆ */
while(1)
{
lua_State *L;
L = luaL_newstate(); //
luaopen_base(L);
luaL_setfuncs(L, mylib, 0);
luaL_dostring(L, LUA_SCRIPT_GLOBAL);
while(1);
}
}
#endif
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 168000000
* HCLK(Hz) = 168000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 8000000
* PLL_M = 25
* PLL_N = 336
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 25;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
while(1) {};
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
while(1) {};
}
/* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
if (HAL_GetREVID() == 0x1001)
{
/* Enable the Flash prefetch */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
}
}
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
2. Download and view the test results
According to the experimental phenomenon, the indicator light turns on first, then turns off and then stays on, which is in line with expectations.
Welcome to pay attention to the personal public number: embedded learning and practice
reference:
https://www.gd32mcu.com/data/documents/userManual/AN019_CN_Rev1.0.pdf
https://blog.csdn.net/weixin_38728721/article/details/104068015
https://blog.csdn.net/weixin_41558887/article/details/101385077
https://www.armbbs.cn/forum.php?mod=viewthread&tid=94757