UART自適應波特率的設置方法

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/LinLingPeng_/article/details/8944993
在單片機中,UART是常用的通信方式。最近在做Profibus DP的產品,由於Profibus DP有波特率自適應的特性,故研究了一下UART的波特率自適應方法。現在介紹一種自適應波特率的設置方法。

條件

空閒的內部定時器1個

方法

通過定時器,連續檢測UART輸入引腳RXD上的電平變化,以達到波特率自適應。 

STM32來舉例

假設要自適應的UART爲STM32的USART1,其RXD引腳爲GPIOA.10。同時也假定定時器3空閒。

代碼 

u32 USART1_Baud(void)                                                                        
{
        u16 t1=0,t2,t=0;               // 定時器寄存器爲16位
        u32 b1,b2;
        u32 i;
         
        GPIO_Init(GPIOA, 10, GPIO_IN_FLOAT);         // GPIOA.10浮空輸入
        TIM_Open(Tim3);                // 開TIM3的時鐘
        TIM_Enable(TIM3);              // 開啓TIM3
        b1 = GPIO_Pin_Get(GPIOA,10);            // 讀GPIOA.10的電平
        for(i=0;i<32;)                                    // 連續檢測GPIO.10引腳32次電平變化
        {
                b2 = GPIO_Pin_Get(GPIOA,10);    // 讀GPIOA.10的新值
                if(b2 != b1)                               // 如果有電平變化
                {
                        t2 = TIM3->COUNT;         // 讀定時器中的值
                        b1 = b2;                          // 更新爲新的引腳值
                        if((t1 == 0)&&(t==0))        // 第一個電平變化
                        {
                                t1 = t2;                     // 記錄第一個時刻點
                        }
                        else                                  // 不是第一個電平變化
                        {
                                if(t == 0)                   // 第一段電平
                                {
                                        t = t2-t1;           // 記錄第一段電平所用時間
                                }
                                else                          // 不是第一段電平
                                {
                                        if((t2-t1)< t)       // 保留電平段的最小值 
                                        {
                                                t = t2-t1;
                                        }
                                }
                                t1 = t2;                      // 更新爲新的時刻點
                        }
                        i++;                                  // 電平變化數+1
                }
        }
         
        TIM_Close(Tim3);                               // 關閉TIM3的時鐘
        return ((u32)t*403/400);  
 // 修正波特率值(加上電平變化的斜率,大概爲0.75%,經驗值)
}

上述函數的返回值,直接填入USART1的波特率寄存即可(如果APB2的時鐘與定時器時鐘相同的話)。
上述計算檢測出來的波特率值,與實際波特有一點點差異,但不影響正常通信。
參與測試的波特率有1200、2400、4800、9600、14400、19200、28800、38400、56000、57600、115200、128000、250000、500000bps.


還有一點要說明的是:我沒有使用ST的庫,上面的函數,是我自己用的。但註釋已經很好的說明了如何進行自適應波特率的設置,不依賴於發送方的發送數據。當然,數據幀的前面部分,肯定有多個字節是收不到的(被檢測用掉了)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章