新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > AVR串口通訊的詳解

AVR串口通訊的詳解

作者: 時間:2016-11-24 來源:網(wǎng)絡 收藏
一.熟悉AVR單片機UART資源,首先從波特率和幀說起

波特率:與51不同有單獨的波特率發(fā)生器,不需要定時器來產(chǎn)生,節(jié)省了資源
波特率計算公式,這里我采用IccAVR的配置功能,直接計算生成
單片機支持的模式:異步正常模式,異步倍數(shù)模式,和同步模式,一般選第一種模式
幀格式:起始位+數(shù)據(jù)位(5-9位可選)+校驗位(可選)+停止位(1、2位) 空閑
o ********* P 1 1
通訊電路空閑時為高電平

本文引用地址:http://m.butianyuan.cn/article/201611/320644.htm

二、大概了解了下硬件資源后,就要了解軟硬件的橋梁—寄存器了
1.數(shù)據(jù)寄存器:數(shù)據(jù)來了要有個接受的地方吧,數(shù)據(jù)發(fā)送要有個數(shù)據(jù)發(fā)送的信封吧。
這就是數(shù)據(jù)寄存器 UDR (RXB和TXB) 物理上為分開的,地址上是一樣的。就像寫信和接信時,你家的地址只

有同一個地址一樣,但是寫信和別人發(fā)給你的信封卻有2個一樣。使用時自動控制的。
數(shù)據(jù)寄存器為空時才能發(fā)送數(shù)據(jù),否則會無效。數(shù)據(jù)進入后,進入移位寄存器,由引腳TXD一位位發(fā)出。
2.控制和狀態(tài)寄存器 UCSRA
RXC TXC UDRE FE DOR PE U2X MPCM
接受完成置1 發(fā)送完成置1 數(shù)據(jù)為空標志 幀錯誤1 接受數(shù)據(jù) 校驗位錯誤 倍速模式 多機通信
讀取數(shù)據(jù)清0 中斷時自動清0 數(shù)據(jù)完全到移 溢出1 1 1 地址位
位寄存器中1
UCSRB 設置相關(guān)中斷的允許
RXCIE TXCIE UDRIE RXEN TXEN UXSZ2 RXB8 TXB8
接受中斷允許 發(fā)送中斷允許 空中斷允許 數(shù)據(jù)接受允許 數(shù)據(jù)發(fā)送允許 位數(shù)設置 接受第9位

RXEN,TXEN設置時會改變時普通IO口,或者是當做復用口用,在發(fā)送數(shù)據(jù)時設置下,數(shù)據(jù)全部發(fā)送后才生效
RXB8,TXB8需要先讀寫出

UCSRC

URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL
寄存器選擇 工作模式 校驗方式 停止位 和上面的UXSZ2設置
寫時需要設為1 1異步 數(shù)據(jù)個數(shù)
存在共用寄存器 00禁止11奇10偶 0為1個1為2個

波特率寄存器:UBRRL UBRRH
UBRRH和UCSRC共用 了底4位 加上UBRRL共12位 設置后正在傳的數(shù)據(jù)會被打斷
需要注意URSEL的設置 :0 寫入的比特率高4位
1 寫入的是寄存器的內(nèi)容
讀UBRRH,第一次是比特率的內(nèi)容 在連續(xù)的2個時鐘周期內(nèi)再讀一次就是UCRSC的內(nèi)容

使用時可以查速查表,直接用ICCAVR生成工具即可。

三,相關(guān)操作 等練習個程序后補上
1 初始化 關(guān)全局中斷
TXC RXC看數(shù)據(jù)是否完成 發(fā)送數(shù)據(jù)前TXC必須請零
把數(shù)據(jù)放入到發(fā)送緩沖器即可 UDR中 5-8位
2 注意下空中斷 允許后需要不斷寫數(shù)據(jù) 否則一直不斷的中斷產(chǎn)生 一般禁止就可以了
TXEN 設置0后 所有數(shù)據(jù)發(fā)送后生效 然后就當普通IO口用了
禁止接受 會立即 丟失數(shù)據(jù)

四一些總線標準
RS232 9針D型接口
1 -3 ~-25 0 3-25V
需要使用電平轉(zhuǎn)換電路 MAX232

五.工業(yè)設計中的串口

這里如果大家看到了還是注意下比較好 ,網(wǎng)上寫的不多的,我也是從工程實踐和查找大量的參考書中總結(jié)的

設計思路是基于狀態(tài)機,并自定義了協(xié)議,同時協(xié)議中使用了CRC校驗,和簡易的加密技術(shù)

思路是:主從方式,上位機發(fā)送數(shù)據(jù)包,下位機在中斷中接受,接受數(shù)據(jù)時要一位位的確認,并不斷進行切換,發(fā)送的位置狀態(tài),把初步確認的數(shù)據(jù)放到接受緩沖器里,等所有的數(shù)據(jù)接收好了,程序進入大循環(huán)了,就執(zhí)行主程序中加入uart操作函數(shù),這個函數(shù)首先判斷主機發(fā)送的命令和設置是否接受完成,在完成的狀態(tài)下進行校驗正確性,校驗后,根據(jù)主機命令,組裝數(shù)據(jù)包和存貯主機的設置數(shù)據(jù),并把需要發(fā)送的數(shù)據(jù)包或設置完成數(shù)據(jù)包放在需要發(fā)送的數(shù)據(jù)緩沖區(qū),接著改變下此時的狀態(tài):為我組好了,準備發(fā)送數(shù)據(jù)了,接著觸發(fā)中斷,可以直接往串口發(fā)個數(shù)據(jù)即可,正常發(fā)送后,單片機會執(zhí)行其他程序,等上位機接受到這個觸發(fā)數(shù)據(jù)后,下位機會中斷,中斷程序會根據(jù)狀態(tài),一位位的發(fā)生緩沖區(qū)的數(shù)據(jù),直到所有的數(shù)據(jù)發(fā)送完成,發(fā)送完成后還要置位到接受數(shù)據(jù)狀態(tài)0。

我的環(huán)境是atmega128

初始化


uchar LED_Temp=0xFF;
uchar OUT_temp=0x04;
static uchar Uart_Status;
static uchar R_Data_Lenth;


uchar Tx_Buf[TxBufSize];
uchar Rx_Buf[RxBufSize];
uchar *P_Uart_Rx;
uchar *P_Uart_Tx;
uchar Rx_Count;
uchar Tx_Count;

void Uart_Init(void)
{
//UCSR0B = 0x00; //先關(guān)閉
UCSR0A=0x00;
UCSR0C=0x06; //8 DATA ,1 STOP, NO PARITY
UCSR0B = (1< // RXCIE=1;TXCIE=1;UDREIE=0;RXEN=1;TXEN=1
Com_baudrate (9600);
P_Uart_Tx=Tx_Buf; //緩沖區(qū)指針定義
P_Uart_Rx=Rx_Buf;
Uart_Status=0; //開始時狀態(tài)為接受起始位狀態(tài),其實這里是因為我在程序中用了通信協(xié)議

//本篇為基礎,就把協(xié)議的內(nèi)容刪去了,僅僅提供了能運行的最簡單的框架
SEI(); //re-enable interrupts
}


//函數(shù)說明:波特率設置

void Com_baudrate (unsigned int baudrate)
{
unsigned int tmp;
tmp= 8000000/baudrate/16-1;
UBRR0H=(unsigned char)(tmp>>8);
UBRR0L=(unsigned char)tmp;
}

//函數(shù)說明:串口接收中斷函數(shù)

#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)

{

//這里填寫串口中斷處理的內(nèi)容,可以添加協(xié)議,使用狀態(tài)機就可以了

//把接收到得內(nèi)容放在緩沖區(qū),然后再創(chuàng)建個處理緩沖區(qū)數(shù)據(jù)的函數(shù),直接放在主循環(huán)中即可
}

//函數(shù)說明:串口發(fā)送完成中斷函數(shù)
#pragma interrupt_handler uart0_tx_isr:iv_USART0_TXC
void uart0_tx_isr(void)
{
//發(fā)送數(shù)據(jù)的處理函數(shù)

}


//函數(shù)說明:uart進程函數(shù),放在大循環(huán)中
void Uart_Process(void)
{
//接收到得數(shù)據(jù),再具體的在系統(tǒng)中實現(xiàn),比如上位機的監(jiān)控,或者傳輸數(shù)據(jù)等

}


//函數(shù)說明:uart測試程序

void Uart_Test(uchar data)
{
UDR0 = 0x01;//發(fā)送數(shù)據(jù)
}


//- 功能描述:串口發(fā)送字節(jié)的函數(shù)
//- 函數(shù)屬性:外部,使用戶使用
//- 參數(shù)說明:mydata:要發(fā)送的一個字節(jié)
//- 返回說明:無
//- 注:發(fā)送一個字節(jié),是串口發(fā)送的基礎操作
void UART_Send_Byte(unsigned char mydata)
{
// UCSR0B = (1< UCSR0B &= ~((1< while(!(UCSR0A &(1< //等待發(fā)送緩沖區(qū)為空
UDR0 = mydata;
// delay_nms(5);
UCSR0B |= (1< //改的時候不要影響其它寄存器位,開串口中斷
}



關(guān)鍵詞: AVR串口通

評論


技術(shù)專區(qū)

關(guān)閉