<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      玩轉單片機之智能車小露——通過UART為單片機增加TTY終端

      單片機只能使用按鍵與程序進行交互嗎?有時候限于單片機有限的引腳,沒有多余的IO口設計按鍵以實現不同的功能,這時候怎么辦?
      最簡單的是使用UART與PC進行通信,這樣PC上的鍵盤就可以變成控制單片機最靈活的工具。本文實現稍復雜但是炫酷的UART通信交互功能,類似于電腦Shell程序,通過字符串傳遞命令和參數,比如可以這樣(默認實現測試命令):
      串口發送:echo hello,world!
      串口接收:hello,world!

      串口初始化及命令字符串接收

      直接使用單片機ISP串口,波特率設置稍高一些避免通信時間過長。
      SystickCallbackUART1函數負責檢測通信數據流是否結束,并打上結束標記。

      void TTYInit(void){
      	GPIO_InitTypeDef gpio;
      	COMx_InitDefine com1;
      	
      	gpio.Pin = GPIO_Pin_0|GPIO_Pin_1;
      	gpio.Mode = GPIO_PullUp;
      	
      	GPIO_Inilize(GPIO_P3,&gpio);
      	
      	com1.UART_Mode = UART_8bit_BRTx;
      	com1.UART_BRT_Use = BRT_Timer1;
      	com1.UART_BaudRate = 115200ul;
      	com1.UART_RxEnable = ENABLE;
      	com1.BaudRateDouble = DISABLE;
      	UART_Configuration(UART1,&com1);
      	
      	NVIC_UART1_Init(ENABLE,Priority_1);
      	
      	UART1_SW(UART1_SW_P30_P31);
      }
      
      //UART1 systick callback(10ms)
      void SystickCallbackUART1(void){
      	if(--COM1.RX_TimeOut < 1){
      		RX1_Buffer[COM1.RX_Cnt] = '\0';
      		COM1.RX_Cnt = 0;			//UART1 timeout reset RX_Cnt
      		TTYsig = TRUE;
      	}
      }
      

      串口命令行參數分割與解析

      串口命令行默認格式為:cmd arg0 arg1 arg2 arg3 arg4各參數以空格區分,支持1個命令加最多5個參數,TTYArgPhase函數負責分割這些字符串命令和參數。

      unsigned char *pTTYCmd;
      unsigned char *pTTYArg[5];
      
      //tty 命令行解析與參數分割
      unsigned char TTYArgPhase(void){
      	unsigned char i = 0;
      	char *str = RX1_Buffer;
      	
      	if(*str == ' ' || *str == '\0')
      		return FALSE;
      	
      	pTTYCmd = str;
      	
      	while(*str != '\0' || i > 4){
      		str++;
      		if(*str == ' '){
      			*str = '\0';
      			pTTYArg[i++] = ++str;
      		}
      	}
      	return TRUE;
      }
      

      命令解析并轉換為函數調用

      在定時器(500ms)中判斷是否有新的命令,并解析命令轉調真正的功能函數,根據具體函數傳遞正確的參數類型。

      unsigned char TTYsig,TTYInfork;
      
      void TTYFork(void){
      	TTYsig = FALSE;
      	
      	if(TTYArgPhase() == FALSE)
      		return;
      	if(strcmp(pTTYCmd,"echos") == 0 && pTTYArg[0] != NULL)
      		TTYEchoString(pTTYArg[0]);
      	if(strcmp(pTTYCmd,"echon") == 0 && pTTYArg[0] != NULL)
      		TTYEchoNumber(atoi(pTTYArg[0]));
      	if(strcmp(pTTYCmd,"echot") == 0)
      		TTYEchoTime();
      	
      	// TODO: 在此處添加用戶代碼
      	if(strcmp(pTTYCmd,"exit") == 0){
      		TTYechot = FALSE;
      	}
      	
      	*pTTYCmd = NULL;		//目前由輸入者確保參數正確性
      	*pTTYArg[0] = NULL;
      	*pTTYArg[1] = NULL;
      	*pTTYArg[2] = NULL;
      	*pTTYArg[3] = NULL;
      	*pTTYArg[4] = NULL;
      }
      
      //Systick callback 500s
      void SystickCallbackTTY(void){
      	if(TTYsig == TRUE)
      		TTYFork();
      }
      

      可命令行執行函數的設計

      命令行可執行函數可以設計為兩類,一類是單次執行的,執行完成后即可退出,如echosechon
      另一類需要持續運行,直到命令行收到退出命令exit后退出,如echot,真正的動作仍然需要在特定的定時函數里執行。

      unsigned char TTYechot;
      
      //tty 字符回顯函數
      void TTYEchoString(char *str){
      	printf(str);
      }
      
      //tty 數字回顯函數
      void TTYEchoNumber(int num){
      	printf("%hd",num);
      }
      
      //tty 循環顯示開機運行時間
      void TTYEchoTime(void){
      	TTYechot = TRUE;		//接收"exit"后復位
      }
      
      //Systick callback 1s
      void SystickCallbackTTYEchot(void){
      	if(TTYechot == TRUE)
      		printf("Running time(s):%ld",systick);
      }
      

      實戰例程:七彩呼吸燈控制

      玩轉單片機之智能車小露——七彩LED呼吸燈 為例,編寫命令行控制函數還不是手到擒來?

      //顏色字符串轉換為整形
      unsigned char ctoi(char *str){
      	if(strcmp(str,"red") == 0)
      		return BLED_COLOR_RED;
      	if(strcmp(str,"orange") == 0)
      		return BLED_COLOR_ORANGE;
      	if(strcmp(str,"yellow") == 0)
      		return BLED_COLOR_YELLOW;
      	if(strcmp(str,"green") == 0)
      		return BLED_COLOR_GREEN;
      	if(strcmp(str,"cyan") == 0)
      		return BLED_COLOR_CYAN;
      	if(strcmp(str,"blue") == 0)
      		return BLED_COLOR_BLUE;
      	if(strcmp(str,"purple") == 0)
      		return BLED_COLOR_PURPLE;
      	if(strcmp(str,"white") == 0)
      		return BLED_COLOR_WHITE;
      	return BLED_COLOR_OFF;
      }
      
      //模式字符串轉換為整形
      unsigned char mtoi(char *str){
      	if(strcmp(str,"single") == 0)
      		return BLED_MODE_SINGLE;
      	if(strcmp(str,"color") == 0)
      		return BLED_MODE_COLOR;
      	return BLED_MODE_OFF;
      }
      
      void TTYFork(void){
      	。。。
      	if(strcmp(pTTYCmd,"bledon") == 0 && pTTYArg[0] != NULL)
      		BLEDTurnOn(ctoi(pTTYArg[0]));
      	if(strcmp(pTTYCmd,"bleddisplaycolor") == 0 && pTTYArg[0] != NULL && pTTYArg[1] != NULL && pTTYArg[2] != NULL)
      		BLEDDisplayColor((unsigned char)atoi(pTTYArg[0]),(unsigned char)atoi(pTTYArg[1]),(unsigned char)atoi(pTTYArg[2]));
      	if(strcmp(pTTYCmd,"bledbreath") == 0 && pTTYArg[0] != NULL && pTTYArg[1] != NULL)
      		BLEDBreath(mtoi(pTTYArg[0]),ctoi(pTTYArg[1]));
      	if(strcmp(pTTYCmd,"bledoff") == 0)
      		BLEDTurnOff();
      	。。。
      }
      
      posted @ 2025-10-25 18:08  芥子的世界  閱讀(6)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲大尺度无码专区尤物| 欧美成人精品三级网站| 吉安市| 高清偷拍一区二区三区| 欧美性猛交xxxx乱大交丰满 | 国产福利精品一区二区| 天堂网亚洲综合在线| 日韩精品一区二区av在线| 五月综合激情婷婷六月| 国产熟睡乱子伦午夜视频| 老司机精品影院一区二区三区| 无码一区二区三区视频| 中文字幕亚洲精品人妻| 吉安县| 亚洲成人av高清在线| 国产偷窥熟女高潮精品视频| 成人亚洲欧美成αⅴ人在线观看 | 日韩精品中文字幕有码| 亚洲美免无码中文字幕在线| 欧美xxxxhd高清| 亚洲高清国产拍精品熟女| 国产精品一区二区AV| 激情国产一区二区三区四区| 国产精品自在拍在线播放| 艳妇乳肉豪妇荡乳xxx| 中文字幕亚洲综合久久| 精品国产中文字幕在线看| 国产精品美女久久久| 无码加勒比一区二区三区四区| 亚洲中文字幕精品无人区| 中文字幕乱妇无码AV在线| 黄色网站免费在线观看| av无码精品一区二区乱子| 日韩午夜一区二区福利视频| 蜜臀午夜一区二区在线播放| 国产精品成人一区二区三区| 成人爽A毛片在线视频淮北| 自偷自拍亚洲综合精品| 激情在线网| 婷婷五月综合丁香在线| 99福利一区二区视频|