一.熟悉AVR單片機(jī)UART資源,首先從波特率和幀說起 波特率:與51不同有單獨(dú)的波特率發(fā)生器,不需要定時(shí)器來產(chǎn)生,節(jié)省了資源
波特率計(jì)算公式,這里我采用IccAVR的配置功能,直接計(jì)算生成
單片機(jī)支持的模式:異步正常模式,異步倍數(shù)模式,和同步模式,一般選第一種模式
幀格式:起始位+數(shù)據(jù)位(5-9位可選)+校驗(yàn)位(可選)+停止位(1、2位) 空閑
o ********* P 1 1
通訊電路空閑時(shí)為高電平
本文引用地址:http://m.butianyuan.cn/article/201611/320644.htm二、大概了解了下硬件資源后,就要了解軟硬件的橋梁—寄存器了
1.數(shù)據(jù)寄存器:數(shù)據(jù)來了要有個(gè)接受的地方吧,數(shù)據(jù)發(fā)送要有個(gè)數(shù)據(jù)發(fā)送的信封吧。
這就是數(shù)據(jù)寄存器 UDR (RXB和TXB) 物理上為分開的,地址上是一樣的。就像寫信和接信時(shí),你家的地址只
有同一個(gè)地址一樣,但是寫信和別人發(fā)給你的信封卻有2個(gè)一樣。使用時(shí)自動(dòng)控制的。
數(shù)據(jù)寄存器為空時(shí)才能發(fā)送數(shù)據(jù),否則會(huì)無效。數(shù)據(jù)進(jìn)入后,進(jìn)入移位寄存器,由引腳TXD一位位發(fā)出。
2.控制和狀態(tài)寄存器 UCSRA
RXC TXC UDRE FE DOR PE U2X MPCM
接受完成置1 發(fā)送完成置1 數(shù)據(jù)為空標(biāo)志 幀錯(cuò)誤1 接受數(shù)據(jù) 校驗(yàn)位錯(cuò)誤 倍速模式 多機(jī)通信
讀取數(shù)據(jù)清0 中斷時(shí)自動(dòng)清0 數(shù)據(jù)完全到移 溢出1 1 1 地址位
位寄存器中1
UCSRB 設(shè)置相關(guān)中斷的允許
RXCIE TXCIE UDRIE RXEN TXEN UXSZ2 RXB8 TXB8
接受中斷允許 發(fā)送中斷允許 空中斷允許 數(shù)據(jù)接受允許 數(shù)據(jù)發(fā)送允許 位數(shù)設(shè)置 接受第9位
RXEN,TXEN設(shè)置時(shí)會(huì)改變時(shí)普通IO口,或者是當(dāng)做復(fù)用口用,在發(fā)送數(shù)據(jù)時(shí)設(shè)置下,數(shù)據(jù)全部發(fā)送后才生效
RXB8,TXB8需要先讀寫出
UCSRC
URSEL UMSEL UPM1 UPM0 USBS UCSZ1 UCSZ0 UCPOL
寄存器選擇 工作模式 校驗(yàn)方式 停止位 和上面的UXSZ2設(shè)置
寫時(shí)需要設(shè)為1 1異步 數(shù)據(jù)個(gè)數(shù)
存在共用寄存器 00禁止11奇10偶 0為1個(gè)1為2個(gè)
波特率寄存器:UBRRL UBRRH
UBRRH和UCSRC共用 了底4位 加上UBRRL共12位 設(shè)置后正在傳的數(shù)據(jù)會(huì)被打斷
需要注意URSEL的設(shè)置 :0 寫入的比特率高4位
1 寫入的是寄存器的內(nèi)容
讀UBRRH,第一次是比特率的內(nèi)容 在連續(xù)的2個(gè)時(shí)鐘周期內(nèi)再讀一次就是UCRSC的內(nèi)容
使用時(shí)可以查速查表,直接用ICCAVR生成工具即可。
三,相關(guān)操作 等練習(xí)個(gè)程序后補(bǔ)上
1 初始化 關(guān)全局中斷
TXC RXC看數(shù)據(jù)是否完成 發(fā)送數(shù)據(jù)前TXC必須請零
把數(shù)據(jù)放入到發(fā)送緩沖器即可 UDR中 5-8位
2 注意下空中斷 允許后需要不斷寫數(shù)據(jù) 否則一直不斷的中斷產(chǎn)生 一般禁止就可以了
TXEN 設(shè)置0后 所有數(shù)據(jù)發(fā)送后生效 然后就當(dāng)普通IO口用了
禁止接受 會(huì)立即 丟失數(shù)據(jù)
四一些總線標(biāo)準(zhǔn)
RS232 9針D型接口
1 -3 ~-25 0 3-25V
需要使用電平轉(zhuǎn)換電路 MAX232
五.工業(yè)設(shè)計(jì)中的串口
這里如果大家看到了還是注意下比較好 ,網(wǎng)上寫的不多的,我也是從工程實(shí)踐和查找大量的參考書中總結(jié)的
設(shè)計(jì)思路是基于狀態(tài)機(jī),并自定義了協(xié)議,同時(shí)協(xié)議中使用了CRC校驗(yàn),和簡易的加密技術(shù)
思路是:主從方式,上位機(jī)發(fā)送數(shù)據(jù)包,下位機(jī)在中斷中接受,接受數(shù)據(jù)時(shí)要一位位的確認(rèn),并不斷進(jìn)行切換,發(fā)送的位置狀態(tài),把初步確認(rèn)的數(shù)據(jù)放到接受緩沖器里,等所有的數(shù)據(jù)接收好了,程序進(jìn)入大循環(huán)了,就執(zhí)行主程序中加入uart操作函數(shù),這個(gè)函數(shù)首先判斷主機(jī)發(fā)送的命令和設(shè)置是否接受完成,在完成的狀態(tài)下進(jìn)行校驗(yàn)正確性,校驗(yàn)后,根據(jù)主機(jī)命令,組裝數(shù)據(jù)包和存貯主機(jī)的設(shè)置數(shù)據(jù),并把需要發(fā)送的數(shù)據(jù)包或設(shè)置完成數(shù)據(jù)包放在需要發(fā)送的數(shù)據(jù)緩沖區(qū),接著改變下此時(shí)的狀態(tài):為我組好了,準(zhǔn)備發(fā)送數(shù)據(jù)了,接著觸發(fā)中斷,可以直接往串口發(fā)個(gè)數(shù)據(jù)即可,正常發(fā)送后,單片機(jī)會(huì)執(zhí)行其他程序,等上位機(jī)接受到這個(gè)觸發(fā)數(shù)據(jù)后,下位機(jī)會(huì)中斷,中斷程序會(huì)根據(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; //開始時(shí)狀態(tài)為接受起始位狀態(tài),其實(shí)這里是因?yàn)槲以诔绦蛑杏昧送ㄐ艆f(xié)議
//本篇為基礎(chǔ),就把協(xié)議的內(nèi)容刪去了,僅僅提供了能運(yùn)行的最簡單的框架
SEI(); //re-enable interrupts
}
//函數(shù)說明:波特率設(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)機(jī)就可以了
//把接收到得內(nèi)容放在緩沖區(qū),然后再創(chuàng)建個(gè)處理緩沖區(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進(jìn)程函數(shù),放在大循環(huán)中
void Uart_Process(void)
{
//接收到得數(shù)據(jù),再具體的在系統(tǒng)中實(shí)現(xiàn),比如上位機(jī)的監(jiān)控,或者傳輸數(shù)據(jù)等
}
//函數(shù)說明:uart測試程序
void Uart_Test(uchar data)
{
UDR0 = 0x01;//發(fā)送數(shù)據(jù)
}
//- 功能描述:串口發(fā)送字節(jié)的函數(shù)
//- 函數(shù)屬性:外部,使用戶使用
//- 參數(shù)說明:mydata:要發(fā)送的一個(gè)字節(jié)
//- 返回說明:無
//- 注:發(fā)送一個(gè)字節(jié),是串口發(fā)送的基礎(chǔ)操作
void UART_Send_Byte(unsigned char mydata)
{
// UCSR0B = (1< UCSR0B &= ~((1< while(!(UCSR0A &(1< //等待發(fā)送緩沖區(qū)為空
UDR0 = mydata;
// delay_nms(5);
UCSR0B |= (1< //改的時(shí)候不要影響其它寄存器位,開串口中斷
}
評論