2012-11-07 151 views
1

我正在使用嵌入式C並嘗試爲GPRS終端進行應用。我的主要問題是使用AT命令。我使用串口線發送AT命令,但如果它是一些面向網絡的命令,它的響應可能需要一些時間,因此我有很多等待,而處理器不做任何事情。想法是讓這個等待以同樣的方式完成,就像在不同的線程中一樣。有沒有人有想法如何做到這一點,因爲我的系統不支持線程? 我有想法使用一些定時器,因爲我們有每5ms調用一次的中斷,但是我不知道有多少秒鐘我必須等待響應,並且如果我比較中斷中的字符串以檢查是否收到所有消息可能效率很低,對吧?嵌入式系統中的AT命令

回答

2

您可以使用中斷,將數據可用時將串行接口配置爲中斷,或使用RTOS的某些東西(如FreeRTOS)運行兩個線程,一個用於主代碼,另一個用於阻塞並等待串行數據。

更新:基於您的意見,你說你不知道數據的大小,沒關係,在中斷處理程序中檢查終止數據的字節,這是一個簡單而通用的示例應檢查實例爲您的MCU:

void on_serial_char() 
{  
    //disable interrupts 
    disable_interrupts(); 

    //read byte 
    byte = serial.read(); 

    //check if it's the terminating byte 
    if (byte == END) { 
     //set the flag here 
     MESSAGE_COMPLETE = 1; 
    } 

    //add byte to buffer 
    buf[length++] = byte; 

    //enable interrupts 
    enable_interrupts();  
} 

而在你的主循環檢查該標誌:

... 
if (MESSAGE_COMPLETE) { 
    //process data 
    ... 

    //you may want to clear the flag here 
    MESSAGE_COMPLETE = 0; 

    //send next command 
    ... 
}  
+0

我有串行接口的中斷,但它沒有檢測到消息的結束,它只是從輸出中取出一個字符,並將它放入緩衝區 –

+0

@ viktor.radovic,如果你現在消息大小,保持運行計數,當你達到這個數字,設置一個標誌並在主代碼中處理。 – iabdalkader

+0

不幸的是,我沒有那個信息,我只知道什麼字符串可能是消息的結束,但它太慢檢查緩衝區是否存在結束字符串? –

2

你可以簡單地調用每個mainLoopCycle一個packetHandler。
該處理程序檢查串口是否有新字符可用。

如果消息已完成(發現CR LF),則packetHandler將爲位構建響應消息位,然後調用messageReceive函數,否則它將簡單地返回到mainLoop。

int main() 
{ 
    init(); 
    for (;;) 
    { 
    packetHandler(); 
    } 
} 

char msgBuffer[80]; 
int pos=0; 
void packetHandler() 
{ 
    char ch; 
    while (isCharAvailable()) 
    { 
    ch=getChar(); 
    msgBuffer[pos++] = ch; 
    if (ch == '\n') 
    { 
     messageReceived(msgBuffer); 
     pos=0; 
    } 
    } 
} 
+0

該解決方案對應用程序和硬件的性質做了很多假設。問題在於,您已經在主循環的執行時間和串行總線波特率之間創建了嚴格的耦合依賴關係。如果主程序比串行總線快得多,那麼這是沒有問題的。如果速度較慢,那麼您遇到問題,因爲您可能會遇到緩衝區溢出問題。 – Lundin

+0

一個正常的GSM模塊可以工作在9600或115200波特率,對於今天的任何_normnal_ cpu來說這都不成問題。另一方面,接收數據是有限的,因爲gsm模塊只回答問題(大部分時間)。因此,如果串行ISR接收緩衝區足夠大,則不會發生緩衝區溢出。最大的正常消息大約是180字節。 – jeb

+1

對於低端MCU來說,115200波特率可能是一個問題。此外,OP可能會運行一個慢時鐘來降低功耗和/或噪聲,但我們不知道。現代MCU上也有許多片上UART模塊具有有限的硬件緩衝區。如果在後臺的某個地方有一個接收緩衝區,那麼你的解決方案是有意義的,從ISR獲得補足,但是你不會在你的答案的任何地方提到ISR。 – Lundin

0

這聽起來像你比較接近硬件驅動程序。如果是這樣,最好的方法是使用DMA,如果MCU支持,則使用DMA硬件中的標誌來確定何時開始解析接收到的數據。

第二個最佳選擇是使用rx中斷,將每個接收到的字節存儲在一個簡單的FIFO中,例如循環緩衝區,然後在收到它們後設置一些標誌。一個輸入數據緩衝區和一個最近收到的有效數據緩衝區可能是必要的。