亚洲 日韩 激情 无码 中出,无码人妻久久一区二区三区蜜桃,亚无码乱人伦一区二区,四虎影视永久免费观看,四虎成人精品一区二区免费网站

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

小編:芯水 更新時間:2022-08-25 08:41

第2節(jié)介紹了如何用單片機控制 LED 小燈閃爍起來,在此基礎(chǔ)上,又在上一節(jié)討論了如何制作“呼吸燈”。

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

缺乏交互的單片機

不過,這兩節(jié)制作的小燈時,我們把使用 C語言編寫的控制程序燒寫到單片機后,就無法再控制 LED 小燈了,也就是說,“只能看不能動”,交互性比較差。接下來兩節(jié),將介紹一種交互方法,目的是燒寫 C語言控制程序到單片機后,仍然能夠從外界控制 LED 小燈。

既然想實現(xiàn)交互,單片機就得能捕捉外界的變化,最簡單的方法就是通過按鍵。不過這里不打算使用按鍵,而是通過“輸入命令”的方式控制 LED 小燈。

將單片機內(nèi)部的信息,printf 傳遞給電腦

一般的軟件開發(fā)中,如果想查看某個變量的值,或者想輸出一句提示信息,直接使用 printf 將信息輸出到屏幕即可。遇到分支流程需要外界選擇時,我們也只需按一下鍵盤就可以。但是對于 51 單片機來說,怎么輸入命令給它呢?我的這款 51 單片機可既沒有配屏幕,也沒有配鍵盤:

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

其實 printf 只是將信息輸出到終端,終端不一定必須是屏幕,也可以是其他字符設(shè)備,比如一般單片機都會有的串口外設(shè)。所以,沒有屏幕的 51 單片機也能夠使用 printf 函數(shù),只需要將其輸出口重定向到串口即可。

重定向的工作 keil4 已經(jīng)做好了,剩下需要我們做的工作僅僅只是配置一下單片機的串口寄存器而已,這項工作非常簡單,C語言代碼可以如下寫,請看:

void init_uart(unsigned int baud) { SCON = 0x5a; TMOD = 0x20; TH1 = TL1 = -(FOSC/12/32/baud); TR1 = 1; ES = 1; EA = 1; }

其中 FOSC 是單片機的晶振頻率,我使用的單片機頻率是 11.0592MHz?,F(xiàn)在包含一下“stdio.h”頭文件就可以使用 printf 函數(shù)了:

#include "reg51.h" #include "stdio.h" void main() { init_uart(9600); printf("hello world, num: %d\n", 98); while(1); }

編譯程序并燒寫到單片機,打開電腦中的串口調(diào)試軟件,發(fā)現(xiàn)字符串都正確,但是C語言程序明明想傳遞的是 98,電腦端的串口工具顯示的數(shù)字卻是 25088!

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

這個問題估計是因為我使用的單片機是 8 位的原因。解決問題的方法,其實 keil 幫助文件里也提了:

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

使用格式符 “%bd”代替“%d”即可,或者將要輸出的數(shù)字強轉(zhuǎn)為 int 類型也可以:

... printf("hello world, num: %bd\n", 98); printf("hello world, num: %d\n", (int)98); ...

再編譯燒寫,發(fā)現(xiàn)輸出正常了。

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

將信息傳遞給單片機

以后可以使用 printf 函數(shù)將單片機內(nèi)部的信息傳遞給電腦了,但是既然是“交互”,就應(yīng)該還能把電腦端的信息傳遞給單片機才行。那么,怎樣把電腦端的信息傳給單片機呢?其實還可以借助串口。請看 init_uart() 函數(shù)的代碼,應(yīng)該能發(fā)現(xiàn)C語言程序已經(jīng)把串口中斷打開了,所以可以如下寫中斷處理程序,請看:

#define MAX_CMD_LEN 32 static bit is_cmd_ready = 0; static char cmd[MAX_CMD_LEN] = {0}; static unsigned char cmd_len = 0; void interrupt_uart() interrupt 4 { static unsigned char i = 0; if(RI){ RI = 0; cmd[i%MAX_CMD_LEN] = SBUF; if(cmd[i%MAX_CMD_LEN]=='\n'){ cmd_len = i; i = 0; is_cmd_ready = 1; }else i++; } } 實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

當電腦通過串口發(fā)送數(shù)據(jù)給單片機時,串口數(shù)據(jù)會被逐字節(jié)放入 SBUF,而 C語言程序則會立刻進入 interrupt_uart() 函數(shù),這時可以將串口數(shù)據(jù)用全局變量 cmd 接收。我們與電腦端約定,每次發(fā)送的命令都以換行符 ‘\n’ 結(jié)束,所以當接收到 ‘\n’ 時,就可以把 is_cmd_ready 標志位置 1 了。

我們常說的“通信協(xié)議”其實就是一系列約定,這么看來,這里說的“每次發(fā)送的命令都以換行符 ‘\n’ 結(jié)束”其實也屬于一種“通信協(xié)議”。

也就是說,電腦端通過串口發(fā)送的命令都會被自動放入 cmd 里,因此我們可以如下定義接收命令的 C語言函數(shù):

unsigned char get_uart_cmd(char* oCmd) { unsigned char i = 0; while(!is_cmd_ready); for(i=0;i實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

這個函數(shù)會阻塞等待 is_cmd_ready 標志位,收到電腦端發(fā)送來的命令后,將命令通過 oCmd 傳出,返回接收到的命令長度?,F(xiàn)在可以如下寫測試程序了:

void main() { char mycmd[32] = {0}; init_uart(9600); printf("enter a num...\n"); get_uart_cmd(mycmd); printf("cmd: %d\n", (int)(mycmd[0])); printf("enter a string...\n"); get_uart_cmd(mycmd); printf("cmd: %s\n", mycmd); while(1); } 實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

編譯C語言程序并燒寫,會在電腦端的串口調(diào)試工具中發(fā)現(xiàn)如下提示信息:

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

因為單片機先需要一個數(shù)字,且命令需要換行符結(jié)尾,所以勾選了下面的選項,點擊發(fā)送,發(fā)現(xiàn)終端輸出:

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

104正好等于十六進制的 68,接著再輸入一段字符串:

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

一切與預(yù)期一致。

將通信模塊封裝成庫

這一步是簡單的,只需要刪去 my_uart.c 文件里的 main 函數(shù),然后再新建一個頭文件,如下圖:

實現(xiàn)電腦和單片機通信(單片機如何與電腦相連)

以后在其他功能開發(fā)中,如果需要與電腦端交互,直接把這兩個文件加入工程就可以了。將使用本節(jié)介紹的交互模塊,目的是能夠通過電腦控制單片機,決定單片機的動作。例如:

在電腦端輸入 led twinkle 命令,LED 小燈會閃爍。

在電腦端輸入 led breath 命令,LED 小燈會變成“呼吸燈”,并且在變暗階段向電腦端輸出“呼氣”,在變亮階段向電腦端輸出“吸氣”。

限于篇幅,下一節(jié)再介紹了。