|
//包含文件定義
//#include "reg51.h"
//#include <stc.h>
#include "intrins.h"
#include "string.h"
//串口相關常量定義
#define FOSC 22118400L //系統頻率11059200L 22118400L
#define Uart1_MaxString 32 //串口1最大接收緩沖區字符數量(0-31)共32個字符
#define Uart2_MaxString 32 //串口2最大接收緩沖區字符數量(0-31)共32個字符
//串口相關變量定義
char Uart1_Data[Uart1_MaxString]; //串口1接收字串
unsigned char Uart1_String_P; //串口1接收字串位置指針
bit Uart1_busy; //串口1正在發送標記,1,正在發送,0,發送完成
unsigned char Uart1_ParitySet; //串口1奇偶校驗方式 0不校驗 1奇校驗 2偶校驗 3始終1 4始終0
bit Uart1_Parity; //串口1接收到的奇偶校驗狀態 1,0
bit Uart1_Parity_out; //串口1驗證接收到的奇偶校驗狀態 1,驗證,0驗證錯誤
char Uart2_Data[Uart1_MaxString]; //串口2接收字串
unsigned char Uart2_String_P; //串口2接收字串位置指針
bit Uart2_busy; //串口2正在發送標記,1,正在發送,0,發送完成
unsigned char Uart2_ParitySet; //串口2奇偶校驗方式 0不校驗 1奇校驗 2偶校驗 3始終1 4始終0
bit Uart2_Parity; //串口2接收到的奇偶校驗狀態 1,0
bit Uart2_Parity_out; //串口2驗證接收到的奇偶校驗狀態 1,驗證,0驗證錯誤
//Uart1包含函數申明
void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx); //串口1波特率和時基源設置函數
void Uart1_SendData(unsigned char Uart1_dat); //串口1單字符發送函數
void Uart1_SendString(char *s); //串口1字符串發送函數
//void Uart1_Isr() interrupt 4 using 1; //串口1中斷服務函數
void Uart2_Setup(unsigned long Uart2_Baud); //串口2波特率
void Uart2_SendData(unsigned char Uart2_dat); //串口2單字符發送函數
void Uart2_SendString(char *s); //串口2字符串發送函數
//void Uart1_Isr() interrupt 4 using 1; //串口2中斷服務函數
/*串口編程示范============================================================================
Uart1_String_P=0; //串口1接收字串下標歸0
Uart1_ParitySet=1; //串口1使用9位可變波特率方式,校驗方式為奇校驗
Uart1_Setup(9600,0); //串口1波特率為9600bps,時基源選擇定時器1
Uart1_SendString("hello word"); //串口1發送數據,英文字母 hello word
Uart2_String_P=0; //串口2接收字串下標歸0
Uart2_ParitySet=1; //串口2使用9位可變波特率方式,校驗方式為奇校驗
Uart2_Setup(9600); //串口2波特率為9600bps
Uart2_SendString("hello word"); //串口2發送數據,英文字母 hello word
=======================================================================================*/
/*********************************************************
** 函數名稱: void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx)
** 功能描述: 初始化串口函數
** 輸 入: unsigned long Uart1_Baud,bit Uart1_Tx
** 輸 出: 無
** 全局變量: PCON,SCON,TMOD,AUXR,TCON,TH1,
** 調用模塊:
** 備 注:時鐘為22118400Hz
參數1:波特率設置,300;600;1200;2400;4800;9600;19200
參數2:計數器選擇,0,定時器1;1,獨立波特率
**********************************************************/
void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx)
{
unsigned int Uart1_Brt;
//時基源設置-------------------------------------------------
if(Uart1_Tx)
{
AUXR |= 0x01; //串口1選擇獨立波特率發生器
}
else
{
AUXR &= 0xFE; //串口1選擇定時器1做波特率發生器
}
//校驗方式設置-------------------------------------------------
switch (Uart1_ParitySet)
{//判斷校驗方式
case 1:
{//9位串口, 奇校驗 Uart1_ParitySet=1; //校驗位初值狀態標記置1
SCON=0xD8; //9位波特率可變,允許接收,TB8待發第9位初始置1
break;
}
case 2:
{//9位串口, 偶校驗 Uart1_ParitySet=2; //校驗位初值狀態標記置2
SCON=0xD4; //9位波特率可變,允許接收,RB8待收第9位初始置1
break;
}
case 3:
{//9位串口, 掩碼校驗 校驗值始終為 1 Uart1_ParitySet=3; //校驗位初值狀態標記置3
SCON|=0xD8; //9位波特率可變,允許接收,TB8待發第9位初始置1
break;
}
case 4:
{//9位串口, 空校驗 校驗值始終為 0 Uart1_ParitySet=4; //校驗位初值狀態標記置4
SCON=0xD4; //9位波特率可變,允許接收,RB8待收第9位初始置1
break;
}
default:
{//8位串口, 無校驗 Uart1_ParitySet=0; //校驗位初值狀態標記置0
SCON&=0x5F; //清除第5位,第7位
SCON|=0x50; //8位波特率可變,允許接收
break;
}
}
//波特率設置并開始運行串口-------------------------------------------------
//時鐘為22118400Hz
Uart1_Brt=FOSC/32/Uart1_Baud;
if(Uart1_Brt>255)
{//如果重裝值>255,使用12T模式12分頻
if(Uart1_Tx)
{//如果使用獨立波特率發生器
//PCON |= 0x80; //串口1波特率加倍
//PCON &= 0x7f; //串口1波特率不加倍
AUXR &= 0xFB; //獨立波特率使用12T模式
//AUXR |= 0x04; //獨立波特率使用1T模式
BRT = 256-Uart1_Brt/12; //獨立波特率發生器初值設置
AUXR|= 0x10; //獨立波特率發生器開始計數
}
else
{//如果使用定時器1做波特率發生器
TMOD&=0xCF; //清除定時器1設置狀態,定時器0不修改
TMOD|=0x20; //定時器1使用8位自動重裝模式
//PCON |= 0x80; //串口1波特率加倍
//PCON &= 0x7f; //串口1波特率不加倍
AUXR &= 0xBF; //定時器1使用12T模式
//AUXR|=0x40; //定時器1使用1T模式
TH1 = TL1 = 256-Uart1_Brt/12; //設置自動裝入的值
ET1 = 0; //關閉定時器1中斷
TR1 = 1; //TCON|=0x40;定時器1開始計數,TCON&=0xBF;關閉計數
}
}
else
{//如果重裝值<255,使用1T模式1分頻
if(Uart1_Tx)
{//如果使用獨立波特率發生器
//PCON |= 0x80; //串口1波特率加倍
//PCON &= 0x7f; //串口1波特率不加倍
//AUXR &= 0xFB; //獨立波特率使用12T模式
AUXR |= 0x04; //獨立波特率使用1T模式
BRT = 256-Uart1_Brt; //獨立波特率發生器初值設置
AUXR|= 0x10; //獨立波特率發生器開始計數
}
else
{//如果使用定時器1做波特率發生器
TMOD&=0xCF; //清除定時器1設置狀態,定時器0不修改
TMOD|=0x20; //定時器1使用8位自動重裝模式
//PCON |= 0x80; //串口1波特率加倍
//PCON &= 0x7f; //串口1波特率不加倍
//AUXR &= 0xBF; //定時器1使用12T模式
AUXR|=0x40; //定時器1使用1T模式
TH1 = TL1 = 256-Uart1_Brt; //設置自動裝入的值
ET1 = 0; //關閉定時器1中斷
TR1 = 1; //TCON|=0x40;定時器1開始計數,TCON&=0xBF;關閉計數
}
}
ES = 1; //打開串口中斷
EA = 1; //打開總中斷
}
/*********************************************************
** 函數名稱: void Uart2_Setup(unsigned long Uart2_Baud)
** 功能描述: 初始化串口函數
** 輸 入: unsigned long Uart1_Baud
** 輸 出: 無
** 全局變量:
** 調用模塊:
** 備 注:時鐘為22118400Hz
參數1:波特率設置,300;600;1200;2400;4800;9600;19200
**********************************************************/
void Uart2_Setup(unsigned long Uart2_Baud)
{
unsigned int Uart2_Brt;
//校驗方式設置-------------------------------------------------
switch (Uart2_ParitySet)
{//判斷校驗方式
case 1:
{//9位串口, 奇校驗 Uart1_ParitySet=1; //校驗位初值狀態標記置1
S2CON=0xD8; //9位波特率可變,允許接收,TB8待發第9位初始置1
break;
}
case 2:
{//9位串口, 偶校驗 Uart1_ParitySet=2; //校驗位初值狀態標記置2
S2CON=0xD4; //9位波特率可變,允許接收,RB8待收第9位初始置1
break;
}
case 3:
{//9位串口, 掩碼校驗 校驗值始終為 1 Uart1_ParitySet=3; //校驗位初值狀態標記置3
S2CON|=0xD8; //9位波特率可變,允許接收,TB8待發第9位初始置1
break;
}
case 4:
{//9位串口, 空校驗 校驗值始終為 0 Uart1_ParitySet=4; //校驗位初值狀態標記置4
S2CON=0xD4; //9位波特率可變,允許接收,RB8待收第9位初始置1
break;
}
default:
{//8位串口, 無校驗 Uart1_ParitySet=0; //校驗位初值狀態標記置0
S2CON&=0x5F; //清除第5位,第7位
S2CON|=0x50; //8位波特率可變,允許接收
break;
}
}
//波特率設置并開始運行串口-------------------------------------------------
//時鐘為22118400Hz
Uart2_Brt=FOSC/32/Uart2_Baud;
if(Uart2_Brt>255)
{//如果重裝值>255,使用12T模式12分頻
//PCON |= 0x80; //串口1波特率加倍
//PCON &= 0x7f; //串口1波特率不加倍
AUXR &= 0xFB; //獨立波特率使用12T模式
//AUXR |= 0x04; //獨立波特率使用1T模式
BRT = 256-Uart2_Brt/12; //獨立波特率發生器初值設置
}
else
{//如果重裝值<255,使用1T模式1分頻
//PCON |= 0x80; //串口1波特率加倍
//PCON &= 0x7f; //串口1波特率不加倍
//AUXR &= 0xFB; //獨立波特率使用12T模式
AUXR |= 0x04; //獨立波特率使用1T模式
BRT = 256-Uart2_Brt; //獨立波特率發生器初值設置
}
AUXR|= 0x10; //獨立波特率發生器開始計數
IE2|=0x01; ////打開串口2中斷
EA = 1; //打開總中斷
}
//=======================================================================================
/**********************************************************
串口1中斷服務函數
**********************************************************/
void Uart1_Isr() interrupt 4 using 1
{// UART 中斷服務函數
EA=0; //關總中斷
if (RI)
{//如果 UART 接收產生中斷
RI = 0; //清除 UART 接收中斷標記
ACC= SBUF; //接收緩沖區數據寫入累加器A
Uart1_Parity = P; //保存校驗值到Uart1_Parity
Uart1_Parity_out=0; //清除允許寫入標記,為下面判斷準備
switch(Uart1_ParitySet)
{//根據校驗要求判斷
case 1:
{//要求奇校驗
Uart1_Parity_out=Uart1_Parity^RB8; //如果檢驗結果和接收結果不符合則成立,允許寫入
break;
}
case 2:
{//要求偶校驗
Uart1_Parity_out=~(Uart1_Parity^RB8); //如果檢驗結果和接收結果符合則成立,允許寫入
break;
}
case 3:
{//要求常1校驗
Uart1_Parity_out=RB8; //如果接收結果為1則成立,允許寫入
break;
}
case 4:
{//要求常0校驗
Uart1_Parity_out=~RB8; //如果接收結果為0則成立,允許寫入
break;
}
default:
{//要求無校驗
Uart1_Parity_out=1; //如果無校驗,允許寫入
break;
}
}
if(Uart1_Parity_out)
{//如果允許寫入
Uart1_Data[Uart1_String_P]= SBUF; //接收緩沖區數據順序寫入串口接收字串
Uart1_String_P++; //串口接收字串指針累加
//↓如果串口接收字串指針在大于最大接收緩沖區字符數量,串口接收字串指針歸零
if(Uart1_String_P >= Uart1_MaxString)
{//如果接受字串指針越界
Uart1_String_P=0; //接受字串指針歸零
}
}
}
if (TI)
{//如果 UART 發送產生中斷
TI = 0; //清除 UART 發送中斷標記
Uart1_busy = 0; //發送完成,清除正在發送標記
}
EA=1; //開總中斷
}
//=======================================================================================
/**********************************************************
串口2中斷服務函數
**********************************************************/
void Uart2_Isr() interrupt 8 using 1
{// UART 中斷服務函數
EA=0; //關總中斷
if (S2CON&0x01)
{//如果 UART 接收產生中斷
S2CON &= 0xFE; //清除 UART 接收中斷標記
ACC= S2BUF; //接收緩沖區數據寫入累加器A
Uart2_Parity = P; //保存校驗值到Uart1_Parity
Uart2_Parity_out=0; //清除允許寫入標記,為下面判斷準備
switch(Uart2_ParitySet)
{//根據校驗要求判斷
case 1:
{//要求奇校驗
Uart2_Parity_out=Uart2_Parity^(S2CON&0x04); //如果檢驗結果和接收結果不符合則成立,允許寫入 (S2CON&0x04)==S2RB8
break;
}
case 2:
{//要求偶校驗
Uart2_Parity_out=~(Uart2_Parity^(S2CON&0x04)); //如果檢驗結果和接收結果符合則成立,允許寫入
break;
}
case 3:
{//要求常1校驗
Uart2_Parity_out=(S2CON&0x04); //如果接收結果為1則成立,允許寫入
break;
}
case 4:
{//要求常0校驗
Uart2_Parity_out=~(S2CON&0x04); //如果接收結果為0則成立,允許寫入
break;
}
default:
{//要求無校驗
Uart2_Parity_out=1; //如果無校驗,允許寫入
break;
}
}
if(Uart2_Parity_out)
{//如果允許寫入
Uart2_Data[Uart2_String_P]= S2BUF; //接收緩沖區數據順序寫入串口接收字串
Uart2_String_P++; //串口接收字串指針累加
//↓如果串口接收字串指針在大于最大接收緩沖區字符數量,串口接收字串指針歸零
if(Uart2_String_P >= Uart2_MaxString)
{//如果接受字串指針越界
Uart2_String_P=0; //接受字串指針歸零
}
}
}
if (S2CON&0x02)
{//如果 UART 發送產生中斷
S2CON &= 0xFD; //清除 UART 發送中斷標記
Uart2_busy = 0; //發送完成,清除正在發送標記
}
EA=1; //開總中斷
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart1_SendData(unsigned char Uart1_dat)
** 功能描述: UART1 單個字符發送函數
** 輸 入: unsigned char Uart1_dat
** 輸 出: 無
** 全局變量:
** 調用模塊:
** 備 注:參數1:待發送的單個字符
**********************************************************/
void Uart1_SendData(unsigned char Uart1_dat)
{//UART 發送字節函數
while (Uart1_busy); //循環等待正在發送標記被清空
ACC = Uart1_dat; //被發送數據送累加器A,準備求奇偶校驗位 P
TB8 = P; //寫奇偶校驗標記
switch(Uart1_ParitySet)
{//根據校驗要求判斷
case 1:
{//要求奇校驗
TB8=~TB8; //翻轉TB8的值
break;
}
/*偶校驗,TB8不變
case 2:
{//要求偶校驗
TB8=TB8; //TB8不變
break;
}
*/
case 3:
{//要求常1校驗
TB8=1; //TB8恒等于1
break;
}
case 4:
{//要求常0校驗
TB8=0; //TB8恒等于0
break;
}
default:
{//要求無校驗
break;
}
}
Uart1_busy = 1; //正在發送標記置 1
SBUF = ACC; //累加器 A 中的數據送發送緩沖區發送
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart2_SendData(unsigned char Uart2_dat)
** 功能描述: UART2 單個字符發送函數
** 輸 入: unsigned char Uart2_dat
** 輸 出: 無
** 全局變量:
** 調用模塊:
** 備 注:參數1:待發送的單個字符
**********************************************************/
void Uart2_SendData(unsigned char Uart2_dat)
{//UART 發送字節函數
while (Uart2_busy); //循環等待正在發送標記被清空
ACC = Uart2_dat; //被發送數據送累加器A,準備求奇偶校驗位 P
TB8 = P; //寫奇偶校驗標記
switch(Uart2_ParitySet)
{//根據校驗要求判斷
case 1:
{//要求奇校驗
S2CON^=0x08; //翻轉S2TB8的值
break;
}
/*偶校驗,S2TB8不變
case 2:
{//要求偶校驗
S2TB8=1; //S2TB8不變
break;
}
*/
case 3:
{//要求常1校驗
S2CON|=0x08; //S2TB8恒等于1
break;
}
case 4:
{//要求常0校驗
S2CON&=0xF7; //TB8恒等于0
break;
}
default:
{//要求無校驗
break;
}
}
Uart2_busy = 1; //正在發送標記置 1
S2BUF = ACC; //累加器 A 中的數據送發送緩沖區發送
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart1_SendString(char *s)
** 功能描述: UART1 按字符串發送函數
** 輸 入: char *s
** 輸 出: 無
** 全局變量:
** 調用模塊:
** 備 注:參數1:待發送的字符串
**********************************************************/
void Uart1_SendString(char *s)
{//UART 按字符串發送
while (*s)
{
Uart1_SendData(*s++); //將待發字符串依次使用SendData函數按字節發送
}
}
//=======================================================================================
/**********************************************************
** 函數名稱: void Uart2_SendString(char *s)
** 功能描述: UART2 按字符串發送函數
** 輸 入: char *s
** 輸 出: 無
** 全局變量:
** 調用模塊:
** 備 注:參數1:待發送的字符串
**********************************************************/
void Uart2_SendString(char *s)
{//UART 按字符串發送
while (*s)
{
Uart2_SendData(*s++); //將待發字符串依次使用SendData函數按字節發送
}
}
//=======================================================================================
/*常用串口設置開關===============================副錄===================================
AUXR |= 0x01; //串口1選擇獨立波特率發生器
AUXR &= 0xFE; //串口1選擇定時器1做波特率發生器
AUXR |= 0x40; //定時器1使用1T模式
AUXR &= 0xBF; //定時器1使用12T模式
AUXR |= 0x04; //獨立波特率使用1T模式
AUXR &= 0xFB; //獨立波特率使用12T模式
AUXR |= 0x10; //打開獨立波特率發生器
AUXR &= 0xEF; //關閉獨立波特率發生器
PCON |= 0x80; //串口1波特率加倍
PCON &= 0x7f; //串口1波特率不加倍
AUXR |= 0x08; //串口2波特率加倍
AUXR &= 0xf7; //串口2波特率不加倍
=======================================================================================*/
|
|