日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Basic脚本解释器移植到STM32

發布時間:2025/6/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Basic脚本解释器移植到STM32 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

上次講了LUA移植到STM32,這次講講Basic腳本解釋器移植到STM32。在STM32上跑Basic腳本,同樣可以跟穿戴設備結合,也可以作為初學者學習MCU的入門工具,當然前提是有人做好Basic的STM32交互實現。這里使用的是uBasic開源腳本解釋器(http://dunkels.com/adam/ubasic/),不過uBasic不支持完整的Basic算法,所以用起來略費心,如果有好的Basic開源腳本解釋器,ANSI-C實現的,歡迎推薦。。。

本文實現的功能是輸入以下basic腳本:

[vb]?view plaincopyprint?
  • 10?v=1??
  • 20?for?p?=?4?to?7??
  • 40?write?"gpioa",p,v??
  • 50?next?p??
  • 60?if?v=0?then?goto?10??
  • 70?if?v=1?then?v=0??
  • 80?goto?20??
  • run??
  • 實現的功能是同時把4個LED燈同時開后再同時關,通過自定義的命令 write來實現,p是IO腳,v是IO的數值。 [vb]?view plaincopyprint?
  • write?"gpioa",p,v??
  • 如下圖:

    本文代碼可以到這里下載http://download.csdn.net/detail/hellogv/7391265。

    main.c的源碼如下,通過USART1來發送Basic腳本到STM32,另外還要通過readline()來做些預處理,例如收到“run”這個字符串就表示腳本結束開始運行:

    [cpp]?view plaincopyprint?
  • #include?"stm32f10x_lib.h"??
  • #include?<assert.h>??
  • #include?"stdio.h"??
  • #include?<stdlib.h>??
  • #include?<string.h>??
  • #include?"ubasic.h"??
  • ??
  • /*******************************************************************************?
  • ?*?函數名??:?RCC_Configuration?
  • ?*?函數描述??:?設置系統各部分時鐘?
  • ?*******************************************************************************/??
  • ??
  • void?RCC_Configuration(void)?{??
  • ??/*?定義枚舉類型變量?HSEStartUpStatus?*/??
  • ??ErrorStatus?HSEStartUpStatus;??
  • ??
  • ??/*?復位系統時鐘設置*/??
  • ??RCC_DeInit();??
  • ??/*?開啟HSE*/??
  • ??RCC_HSEConfig(RCC_HSE_ON?);??
  • ??/*?等待HSE起振并穩定*/??
  • ??HSEStartUpStatus?=?RCC_WaitForHSEStartUp();??
  • ??/*?判斷HSE起是否振成功,是則進入if()內部?*/??
  • ??if?(HSEStartUpStatus?==?SUCCESS)?{??
  • ????/*?選擇HCLK(AHB)時鐘源為SYSCLK?1分頻?*/??
  • ????RCC_HCLKConfig(RCC_SYSCLK_Div1?);??
  • ????/*?選擇PCLK2時鐘源為?HCLK(AHB)?1分頻?*/??
  • ????RCC_PCLK2Config(RCC_HCLK_Div1?);??
  • ????/*?選擇PCLK1時鐘源為?HCLK(AHB)?2分頻?*/??
  • ????RCC_PCLK1Config(RCC_HCLK_Div2?);??
  • ????/*?設置FLASH延時周期數為2?*/??
  • ????FLASH_SetLatency(FLASH_Latency_2?);??
  • ????/*?使能FLASH預取緩存?*/??
  • ????FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable?);??
  • ????/*?選擇鎖相環(PLL)時鐘源為HSE?1分頻,倍頻數為9,則PLL輸出頻率為?8MHz?*?9?=?72MHz?*/??
  • ????RCC_PLLConfig(RCC_PLLSource_HSE_Div1,?RCC_PLLMul_9?);??
  • ????/*?使能PLL?*/??
  • ????RCC_PLLCmd(ENABLE);??
  • ????/*?等待PLL輸出穩定?*/??
  • ????while?(RCC_GetFlagStatus(RCC_FLAG_PLLRDY?)?==?RESET)??
  • ??????;??
  • ????/*?選擇SYSCLK時鐘源為PLL?*/??
  • ????RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK?);??
  • ????/*?等待PLL成為SYSCLK時鐘源?*/??
  • ????while?(RCC_GetSYSCLKSource()?!=?0x08)??
  • ??????;??
  • ??}??
  • ??
  • ??/*?開啟USART1和GPIOA時鐘?*/??
  • ??RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1?|?RCC_APB2Periph_GPIOA,??
  • ??????ENABLE);??
  • }??
  • ??
  • /*******************************************************************************?
  • ?*?函數名??????:?GPIO_Configuration?
  • ?*?函數描述??????:?設置各GPIO端口功能?
  • ?*******************************************************************************/??
  • ??
  • void?GPIO_Configuration(void)?{??
  • ??/*?定義GPIO初始化結構體?GPIO_InitStructure?*/??
  • ??GPIO_InitTypeDef?GPIO_InitStructure;??
  • ??
  • ??/*?設置USART1的Tx腳(PA.9)為第二功能推挽輸出功能?*/??
  • ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_9;??
  • ??GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;??
  • ??GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;??
  • ??GPIO_Init(GPIOA,?&GPIO_InitStructure);??
  • ??
  • ??/*?設置USART1的Rx腳(PA.10)為浮空輸入腳?*/??
  • ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_10;??
  • ??GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_IN_FLOATING;??
  • ??GPIO_Init(GPIOA,?&GPIO_InitStructure);??
  • }??
  • ??
  • /*******************************************************************************?
  • ?*?函數名??????:?USART_Configuration?
  • ?*?函數描述??????:?設置USART1?
  • ?*******************************************************************************/??
  • ??
  • void?USART_Configuration(void)?{??
  • ??/*?定義USART初始化結構體?USART_InitStructure?*/??
  • ??USART_InitTypeDef?USART_InitStructure;??
  • ??/*?定義USART初始化結構體?USART_ClockInitStructure?*/??
  • ??USART_ClockInitTypeDef?USART_ClockInitStructure;??
  • ??
  • ??/*??波特率為115200bps;?
  • ???*??8位數據長度;?
  • ???*??1個停止位,無校驗;?
  • ???*??禁用硬件流控制;?
  • ???*??禁止USART時鐘;?
  • ???*??時鐘極性低;?
  • ???*??在第2個邊沿捕獲數據?
  • ???*??最后一位數據的時鐘脈沖不從?SCLK?輸出;?
  • ???*/??
  • ??
  • ??USART_ClockInitStructure.USART_Clock?=?USART_Clock_Disable;??
  • ??USART_ClockInitStructure.USART_CPOL?=?USART_CPOL_Low;??
  • ??USART_ClockInitStructure.USART_CPHA?=?USART_CPHA_2Edge;??
  • ??USART_ClockInitStructure.USART_LastBit?=?USART_LastBit_Disable;??
  • ??USART_ClockInit(USART1,?&USART_ClockInitStructure);??
  • ??
  • ??USART_InitStructure.USART_BaudRate?=?9600;??
  • ??USART_InitStructure.USART_WordLength?=?USART_WordLength_8b;??
  • ??USART_InitStructure.USART_StopBits?=?USART_StopBits_1;??
  • ??USART_InitStructure.USART_Parity?=?USART_Parity_No?;??
  • ??USART_InitStructure.USART_HardwareFlowControl?=USART_HardwareFlowControl_None;??
  • ??USART_InitStructure.USART_Mode?=?USART_Mode_Rx?|?USART_Mode_Tx;??
  • ??USART_Init(USART1,?&USART_InitStructure);??
  • ??
  • ??/*?使能USART1?*/??
  • ??USART_Cmd(USART1,?ENABLE);??
  • }??
  • ??
  • int?fputc(int?ch,?FILE?*f)?{??
  • ??USART_SendData(USART1,?(u8)?ch);??
  • ??while?(USART_GetFlagStatus(USART1,?USART_FLAG_TC?)?==?RESET);??
  • ??return?ch;??
  • }??
  • ??
  • int?getKey(void)?{??
  • ??while?(!(USART1?->SR?&?USART_FLAG_RXNE?));??
  • ??return?((int)?(USART1?->DR?&?0x1FF));??
  • }??
  • ??
  • /*******************************************************************************?
  • ?*?函數名??????:?readLine?
  • ?*?函數描述??????:?從串口讀取Basic代碼?
  • ?*******************************************************************************/??
  • bool?readLines(char?*s)?{??
  • ??bool?isString?=?FALSE;?//判斷是否字符串??
  • ??char?ch;??
  • ??char?*p?=?s;??
  • ????
  • ??if(*p!='\0')??
  • ????return?FALSE;??
  • ????
  • ??while?(1)?{??
  • ????ch?=?getKey();??
  • ????if?(ch?==?'\"')?{?//檢測到字符串??
  • ??????isString?=?!isString;??
  • ????}??
  • ??
  • ????if?(ch?==?'\r')?//屏蔽'\r'這個字符??
  • ??????continue;??
  • ????else?{??
  • ??????if?(isString)?//不改變代碼中字符串的大小寫??
  • ????????*p++?=?ch;??
  • ??????else?//關鍵字都轉為小寫??
  • ????????*p++?=?tolower(ch);??
  • ????}??
  • ??????
  • ????if?(*(p-3)?==?'r'??
  • ??????????&&*(p-2)=='u'??
  • ??????????&&*(p-1)=='n'){?//run表示程序結束??
  • ??????*(p-3)?=?'\0';??
  • ??????break;??
  • ????}??
  • ??}??
  • ??return?TRUE;??
  • }??
  • ??
  • #define?_MAX_LINE_LENGTH?256??
  • int?main(void)?{??
  • ??/*?設置系統時鐘?*/??
  • ??RCC_Configuration();??
  • ??/*?設置GPIO端口?*/??
  • ??GPIO_Configuration();??
  • ??/*?設置USART?*/??
  • ??USART_Configuration();??
  • ??
  • ??char?line[_MAX_LINE_LENGTH];??
  • ??while(1){??
  • ????memset(line,?0,?_MAX_LINE_LENGTH);??
  • ????if(readLines(line)){??
  • ??????ubasic_init(line);??
  • ??????do?{??
  • ????????ubasic_run();??
  • ??????}?while(!ubasic_finished());??
  • ????}??
  • ??};??
  • ??
  • ??return?0;??
  • ??
  • }??
  • 實現write命令的源碼如下:

    [cpp]?view plaincopyprint?
  • #include?"tokenizer.h"??
  • #include?"stm32f10x_lib.h"??
  • #include?<string.h>??
  • #include?<ctype.h>??
  • #include?<stdlib.h>??
  • GPIO_TypeDef?*gpio_x;??
  • u16?gpio_pin_x;??
  • u16?gpio_value;??
  • struct?GPIO_KEYWORD?gpio_kt;??
  • struct?PIN_KEYWORD?pin_kt;??
  • ??
  • #define?GET_ARRAY_LEN(array,len){len?=?(sizeof(array)?/?sizeof(array[0]));}??
  • ??
  • struct?GPIO_KEYWORD?{??
  • ??char?*keyword;??
  • ??GPIO_TypeDef?*token;??
  • };??
  • ??
  • static?const?struct?GPIO_KEYWORD?gpio_keywords[]?=???
  • {?{?"GPIOA",?GPIOA?},??
  • ????{?"GPIOB",?GPIOB??},??
  • ????{?"GPIOC",?GPIOC??},??
  • ????{?"GPIOD",?GPIOD??}};??
  • ??
  • struct?PIN_KEYWORD?{??
  • ??u16?keyword;??
  • ??u16?token;;??
  • };??
  • ??
  • static?const?struct?PIN_KEYWORD?pin_keywords[17]?=???
  • {??{?0,?GPIO_Pin_0?},??
  • ????{?1,?GPIO_Pin_1?},??
  • ????{?2,?GPIO_Pin_2?},??
  • ????{?3,?GPIO_Pin_3?},??
  • ????{?4,?GPIO_Pin_4?},??
  • ????{?5,?GPIO_Pin_5?},??
  • ????{?6,?GPIO_Pin_6?},??
  • ????{?7,?GPIO_Pin_7?},??
  • ????{?8,?GPIO_Pin_8?},??
  • ????{?9,?GPIO_Pin_9?},??
  • ????{?10,?GPIO_Pin_10?},??
  • ????{?11,?GPIO_Pin_11?},??
  • ????{?12,?GPIO_Pin_12?},??
  • ????{?13,?GPIO_Pin_13?},??
  • ????{?14,?GPIO_Pin_14?},??
  • ????{?15,?GPIO_Pin_15?}};??
  • ??
  • void?init_my_statement(){??
  • ??gpio_x=NULL;??
  • ??gpio_pin_x=NULL;??
  • ??gpio_value=NULL;??
  • }??
  • ??
  • void?put_value(u16?value){??
  • ??gpio_value=value;??
  • }??
  • ??
  • u16?get_value(){??
  • ??return?gpio_value;??
  • }??
  • ??
  • /**?
  • **獲取GPIO_PIN_X?
  • **/??
  • bool?put_pin(u16?pin){??
  • ????int?size=0;??
  • ????
  • ????if(gpio_pin_x==NULL){??
  • ??????GET_ARRAY_LEN(pin_keywords,size);??
  • ??????if(pin<size){??
  • ????????gpio_pin_x?=?pin_keywords[pin].token;??
  • ????????printf?("------P");printf?("%d\r\n",pin);??
  • ????????return?TRUE;??
  • ??????}??
  • ????}??
  • ????return?FALSE;??
  • }??
  • ??
  • u16?get_pin(){??
  • ??return?gpio_pin_x;??
  • }??
  • ??
  • /**?
  • **獲取獲取GPIO_X?
  • **/??
  • bool?put_gpio(char*?p){??
  • ????int?i=0;??
  • ????int?size=0;??
  • ??
  • ????if(gpio_x==NULL){??
  • ??????GET_ARRAY_LEN(gpio_keywords,size);??
  • ??????for?(i=0;?i<size;?i++)?{??
  • ????????gpio_kt?=?gpio_keywords[i];??
  • ????????if?(strncasecmp(p,?gpio_kt.keyword,?strlen(p))?==?0)?{??
  • ??????????printf?("------");printf?("%s\r\n",gpio_kt.keyword);??
  • ??????????gpio_x?=?gpio_kt.token;??
  • ??????????return?TRUE;??
  • ????????}??
  • ??????}??
  • ????}??
  • ????return?FALSE;??
  • }??
  • ??
  • GPIO_TypeDef?*?get_gpio(){??
  • ??return?gpio_x;??
  • }??
  • ??
  • bool?write_gpio(){??
  • ????
  • ??//USART1不能被寫??
  • ??if(gpio_x==?GPIOA???
  • ?????&&?(gpio_pin_x==GPIO_Pin_9???
  • ?????????||?gpio_pin_x==GPIO_Pin_10)){??
  • ????return?FALSE;??
  • ??}??
  • ????
  • ??GPIO_InitTypeDef?GPIO_InitStructure;??
  • ??
  • ??GPIO_InitStructure.GPIO_Pin?=?gpio_pin_x;??
  • ??GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;??
  • ??GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_Out_PP;??
  • ??GPIO_Init(gpio_x?,?&GPIO_InitStructure);???
  • ??????????
  • ??GPIO_WriteBit(gpio_x?,?gpio_pin_x,(BitAction)gpio_value);????????????????????????????????
  • ??return?TRUE;??
  • }??


  • 總結

    以上是生活随笔為你收集整理的Basic脚本解释器移植到STM32的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。