2013-04-05 64 views
1

我試圖做ATMEGA32串行通信和我有一個問題:ATMEGA32 UART通信

在異步串行通信都UBRRHUCSRC寄存器具有相同的位置。我不知道哪個位置將作爲UBRRH的條件,並且在哪些條件下,它將作爲UCSRC。根據分配給這些寄存器的工作,我需要爲每個寄存器設置不同的值

在數據表中,他們提到使用URSEL位在兩個寄存器之間進行選擇,但不知何故,我沒有那樣做。

回答

5

答案是:是的,URSEL位。根據數據表:

做這件事時的I/O位置的寫入權限,則 價值的書面高位,USART寄存器選擇(URSEL)位,控制這兩個寄存器的 一個將被寫入。如果在寫操作 期間URSEL爲零,則UBRRH值將被更新。如果URSEL爲1,則 將更新UCSRC設置。

這意味着,當你寫UCSRC,無論你想放有什麼價值,還設置了URSEL位(確保URSEL1):

UCSRC = (1<<URSEL)| ... whatever else ... 

當你寫UBRRH,確保URSEL位必須爲零。以下是一些不同的方法:

UBRRH = (0<<URSEL)| ... whatever else ... // just showing that URSEL isn't set 
UBRRH = ...some value...     // simple not setting URSEL 
UBRRH = (someValue)&(~(1<<URSEL)   // Ensuring that URSEL isn't set 

URSEL位只是一個高位。因此,無論您寫入UCSRC的值是什麼,請設置(打開,使1)高位(位7)。當寫入UBRRH時,確保第7位被清除。另一種考慮它的方式是,你寫入UBRRH的每個值必須小於128.並且你想要寫入的每個值都寫入UCSRC,然後給它加128:這會打開第7位。這只是一種解釋方式,上面的代碼更清晰。


這是如何完成的?我不知道,我不是一個uC設計師。看起來有可能是相同的IO位置位置映射到處理器中的兩個不同的寄存器。假設你有一個名爲foo的寄存器,當你給它寫一個值時,uC檢查是否設置了高位。如果是,則將值寫入內部存儲器位置1,如果不是,則將值寫入內部存儲器位置2


如果您正確使用URSEL位,那麼這些值將被正確寫入。你的測試沒有顯示正確的值,因爲你沒有閱讀它們的屬性。數據表的第162頁:

對UBRRH或UCSRC寄存器進行讀訪問是一個更復雜的操作 。但是,在大多數應用中,讀取這些寄存器中的任何一個都很少需要 。

讀訪問由定時序列控制。讀取I/O 位置後,會返回UBRRH寄存器的內容。如果在前一個系統時鐘週期中讀取了寄存器 的位置,則在當前時鐘週期讀取寄存器 將返回UCSRC內容。請注意, 讀取UCSRC的時間順序是一個原子操作。因此,在讀取操作期間,必須控制中斷(例如,通過在全局中禁用中斷 )。

所以,當你第一次讀UBRRH/UCSRC時,你會得到UBRRH。如果你立即再次閱讀你讀UCSRC。但正如文檔所述,讀取這些寄存器沒有真正的理由。看起來你不信任數據表,但這是一個錯誤:數據表是有關這些問題的最佳信息來源:沒有數據表我們就無處可去。

+0

但如何發生這種情況,因爲兩個寄存器具有相同的位置,那麼他們如何可以有不同的值...........我已經嘗試過URSEL = 1和0並調試代碼,但是當它是0,那麼兩個寄存器都寫入相同的值,但是當它爲1時,沒有任何寄存器被寫入UCSRC = UCSRC =(1 << URSEL)| (1 << UCSZ1)| (1 << UCSZ0)只是在我的AtmelStudio 6.0調試器中不做任何事情,雖然URSEL已經設置好了,但是如果它是0,那麼兩者都是用相同的值寫成......... – 2013-04-06 11:26:47

+0

我沒有犯任何冒犯,但如果你誤解了我,我很抱歉:).........我正在調試我的代碼,只是爲了檢查所有初始化是否已經正確完成,在這種情況下,我正面臨着上述問題錯誤,所以我很困惑,不管我的代碼是否會工作..........:(........但是,正如你曾經說過,我會問這個新的問題:) – 2013-04-06 17:46:54