|
|
//此段包含串口1和定時(shí)器1的相關(guān)函數(shù)
/*串口編程示范說明==李斌20120802==========================================================
說明
串口接收ASCII字符,最大允許接收 Uart1_MaxString 個(gè)字符到Uart1_Data字符組,其中可包括回車
、換行符號(hào),當(dāng)接收到字0x00后,字符數(shù)組標(biāo)示為可讀,在字符串接收滿后如果未接收到字0x00,所有
后續(xù)接收全部被忽略,直到接收到0x00,字符數(shù)組標(biāo)示為可讀。
使用22118400晶振,最大波特率19200bit/s
串口編程示范
//文件包含
#include "STC.H"
#include <stdio.h>
#include "Uart1.c"
//函數(shù)申明
void Uart1_setup(); //初使化串口函數(shù)申明,在函數(shù)中設(shè)定串口工作方式
//主函數(shù)
void main()
{
printf("Helloo Word"); //使用庫函數(shù)向串口寫數(shù)據(jù),再使用printf前必須使用過Uart1_SendString函數(shù)
while(1) //主程序循環(huán)避免死機(jī)
{
if(Uart1.Read==1)
{ //如果串口1數(shù)據(jù)可讀
Uart1_SendString(Uart1_Data); //串口1回送接收的數(shù)據(jù)
Uart1.Read=0; //串口1不可讀(已讀,為下次讀出做準(zhǔn)備)
}
}
}
//初使化串口函數(shù) ,必須寫在主函數(shù)尾,在主函數(shù)頭部申明并引用
void Uart1_setup()
{
for(Uart1.Data_P=0;Uart1.Data_P<=Uart1_MaxString;Uart1.Data_P++)
{//清空串口1接收字串內(nèi)容,寫0x00
Uart1_Data[Uart1.Data_P]='\0';
}
Uart1.Data_P= 0; //串口1接收字串下標(biāo)歸0
Uart1.ParitySet= 0; //串口1使用9位可變波特率方式,校驗(yàn)方式為無校驗(yàn), 0無校驗(yàn),1:奇校驗(yàn),2:偶校驗(yàn),3:校驗(yàn)=1,4:校驗(yàn)=0
Uart1_Setup(19200,0); //串口1波特率為19200bps,時(shí)基源選擇定時(shí)器1 , 0為定時(shí)器1,1為獨(dú)立波特率發(fā)生器
}
=======================================================================================*/
//包含文件定義
//串口相關(guān)常量定義
#define FOSC 22118400L //系統(tǒng)頻率11059200L 22118400L
#define Uart1_MaxString 64 //串口1最大接收緩沖區(qū)字符數(shù)量
//串口相關(guān)變量定義
char xdata Uart1_Data[Uart1_MaxString+1]; //串口1接收字串
struct Uart1
{//串口1結(jié)構(gòu)數(shù)據(jù)類型
unsigned char Data_P; //串口1接收字串位置指針
unsigned char ParitySet; //串口1奇偶校驗(yàn)方式 0不校驗(yàn) 1奇校驗(yàn) 2偶校驗(yàn) 3始終1 4始終0
unsigned char Busy:1; //串口1正在發(fā)送標(biāo)記,1,正在發(fā)送,0,發(fā)送完成 ,保留未使用
unsigned char Read:1; //串口1接受字符組可讀標(biāo)記
unsigned char Parity:1; //串口1接收到的奇偶校驗(yàn)狀態(tài) 1,0
unsigned char Parity_out:1; //串口1驗(yàn)證接收到的奇偶校驗(yàn)狀態(tài) 1,驗(yàn)證,0驗(yàn)證錯(cuò)誤
}Uart1; //結(jié)構(gòu)變量名
//Uart1包含函數(shù)申明
void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx); //串口1波特率和時(shí)基源設(shè)置函數(shù)
void Uart1_chars_Int(); //串口1中斷服務(wù)函數(shù)采用字符數(shù)組接收以'\0'為停止符的實(shí)際內(nèi)容
void Uart1_SendData(unsigned char Uart1_dat); //串口1單字符發(fā)送函數(shù)
void Uart1_SendString(char *s); //串口1字符串發(fā)送函數(shù)
//非必要包含的函數(shù)申明
//void Time1_Isr() interrupt 3 using 1; //定時(shí)器1中斷服務(wù)函數(shù)入口
//void Uart1_Isr() interrupt 4 using 1; //串口1中斷服務(wù)函數(shù)入口
/*********************************************************
** 函數(shù)名稱: void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx)
** 功能描述: 初始化串口函數(shù)
** 輸 入: unsigned long Uart1_Baud,bit Uart1_Tx
** 輸 出: 無
** 全局變量: PCON,SCON,TMOD,AUXR,TCON,TH1,
** 調(diào)用模塊:
** 備 注:時(shí)鐘為22118400Hz
參數(shù)1:波特率設(shè)置,300;600;1200;2400;4800;9600;19200
參數(shù)2:計(jì)數(shù)器選擇,0,定時(shí)器1;1,獨(dú)立波特率
**********************************************************/
void Uart1_Setup(unsigned long Uart1_Baud,bit Uart1_Tx)
{
unsigned int Uart1_Brt; //串口定時(shí)器重裝值臨時(shí)存儲(chǔ)位
//時(shí)基源設(shè)置-------------------------------------------------
if(Uart1_Tx)
{
AUXR |= 0x01; //串口1選擇獨(dú)立波特率發(fā)生器
}
else
{
AUXR &= 0xFE; //串口1選擇定時(shí)器1做波特率發(fā)生器
}
//校驗(yàn)方式設(shè)置-------------------------------------------------
switch(Uart1.ParitySet)
{//判斷校驗(yàn)方式
case 1:SCON=0xD8;break; //9位串口, 奇校驗(yàn)
case 2:SCON=0xD4;break; //9位串口, 偶校驗(yàn)
case 3:SCON|=0xD8;break; //9位串口, 掩碼校驗(yàn),校驗(yàn)值始終為 1
case 4:SCON=0xD4;break; //9位串口, 空校驗(yàn)
default:
{//8位串口, 無校驗(yàn) Uart1.ParitySet=0; 校驗(yàn)位初值狀態(tài)標(biāo)記置0
SCON&=0x5F; //清除第5位,第7位
SCON|=0x50; //8位波特率可變,允許接收
break;
}
}
//波特率設(shè)置并開始運(yùn)行串口-------------------------------------------------
//時(shí)鐘為22118400Hz
Uart1_Brt=FOSC/32/Uart1_Baud;
if(Uart1_Brt>255)
{//如果重裝值>255,使用12T模式12分頻
if(Uart1_Tx)
{//如果使用獨(dú)立波特率發(fā)生器
AUXR &= 0xFB; //獨(dú)立波特率使用12T模式
BRT = 256-Uart1_Brt/12; //獨(dú)立波特率發(fā)生器初值設(shè)置
AUXR|= 0x10; //獨(dú)立波特率發(fā)生器開始計(jì)數(shù)
}
else
{//如果使用定時(shí)器1做波特率發(fā)生器
TMOD&=0xCF; //清除定時(shí)器1設(shè)置狀態(tài),定時(shí)器0不修改
TMOD|=0x20; //定時(shí)器1使用8位自動(dòng)重裝模式
AUXR &= 0xBF; //定時(shí)器1使用12T模式
TH1 = TL1 = 256-Uart1_Brt/12; //設(shè)置自動(dòng)裝入的值
//ET1 = 1; //允許定時(shí)器1中斷=========使用定時(shí)器1中斷做串口中斷時(shí)書寫
TR1 = 1; //TCON|=0x40;定時(shí)器1開始計(jì)數(shù),TCON&=0xBF;關(guān)閉計(jì)數(shù)
}
}
else
{//如果重裝值<255,使用1T模式1分頻
if(Uart1_Tx)
{//如果使用獨(dú)立波特率發(fā)生器
AUXR |= 0x04; //獨(dú)立波特率使用1T模式
BRT = 256-Uart1_Brt; //獨(dú)立波特率發(fā)生器初值設(shè)置
AUXR|= 0x10; //獨(dú)立波特率發(fā)生器開始計(jì)數(shù)
}
else
{//如果使用定時(shí)器1做波特率發(fā)生器
TMOD&=0xCF; //清除定時(shí)器1設(shè)置狀態(tài),定時(shí)器0不修改
TMOD|=0x20; //定時(shí)器1使用8位自動(dòng)重裝模式
AUXR|=0x40; //定時(shí)器1使用1T模式
TH1 = TL1 = 256-Uart1_Brt; //設(shè)置自動(dòng)裝入的值
//ET1 = 1; //允許定時(shí)器1中斷=========使用定時(shí)器1中斷做串口中斷時(shí)書寫
TR1 = 1; //TCON|=0x40;定時(shí)器1開始計(jì)數(shù),TCON&=0xBF;關(guān)閉計(jì)數(shù)
}
}
TI = 1; //兼容系統(tǒng)函數(shù)printf,需要先對(duì)TI置1
ES = 1; //打開串口中斷
EA = 1; //打開總中斷
}
//=======================================================================================
/**********************************************************
串口1中斷服務(wù)函數(shù)
**********************************************************/
void Uart1_Isr() interrupt 4 using 1
{
Uart1_chars_Int();
}
void Uart1_chars_Int()
{
//EA=0;
if (RI)
{//如果 UART 接收產(chǎn)生中斷
RI = 0; //清除 UART 接收中斷標(biāo)記
//TF1=0; //清除定時(shí)器1的中斷標(biāo)記,在使用串口中斷時(shí),這行不寫
ACC= SBUF; //接收緩沖區(qū)數(shù)據(jù)寫入累加器A
Uart1.Parity = P; //保存校驗(yàn)值到Uart1_Parity
Uart1.Parity_out=0; //清除允許寫入標(biāo)記,為下面判斷準(zhǔn)備
switch(Uart1.ParitySet)
{//根據(jù)校驗(yàn)要求判斷
case 0:Uart1.Parity_out=1; break; //要求無校驗(yàn),如果無校驗(yàn),允許寫入
case 1:Uart1.Parity_out=Uart1.Parity^RB8; break; //要求奇校驗(yàn),如果檢驗(yàn)結(jié)果和接收結(jié)果不符合則成立,允許寫入
case 2:Uart1.Parity_out=~(Uart1.Parity^RB8);break; //要求偶校驗(yàn),如果檢驗(yàn)結(jié)果和接收結(jié)果符合則成立,允許寫入
case 3:Uart1.Parity_out=RB8; break; //要求常1校驗(yàn),如果接收結(jié)果為1則成立,允許寫入
case 4:Uart1.Parity_out=~RB8; break; //要求常0校驗(yàn),如果接收結(jié)果為0則成立,允許寫入
default:Uart1.Parity_out=0;break; //非法的參數(shù),不接收
}
if(Uart1.Parity_out)
{//如果允許寫入
if(Uart1.Data_P<Uart1_MaxString)
{//如果接受字符組指針小于字符數(shù)組最大下標(biāo)減1(字符數(shù)組最后一位始終為0x00,方便指針做底判斷)
if(SBUF=='\0')
{//如果接受字符是0x00
Uart1_Data[Uart1.Data_P]=SBUF; //接受數(shù)據(jù)寫入字符數(shù)組
Uart1.Data_P=0; //字符數(shù)組下標(biāo)歸0
Uart1.Read=1; //串口數(shù)據(jù)可讀
}
else
{//如果接受字符不是0x00
Uart1_Data[Uart1.Data_P]=SBUF; //接受數(shù)據(jù)寫入字符數(shù)組
Uart1.Data_P++; //字符數(shù)組下標(biāo)自加1
}
}
else
{//如果接受字符組指針大于等于字符數(shù)組最大下標(biāo)減1
if(SBUF=='\0')
{//如果接受字符是0x00
Uart1.Data_P=0; //字符數(shù)組下標(biāo)歸0
Uart1.Read=1; //串口數(shù)據(jù)可讀
}
}
}
}
/*
if (TI)
{//如果 UART 發(fā)送產(chǎn)生中斷
}
*/
/*=============使用定時(shí)器1中斷時(shí)需要書寫,使用串口中斷時(shí)忽略
if(TF1)
{
TF1=0; //清定時(shí)器1中斷標(biāo)記
}
=============*/
//EA=1;
}
//=======================================================================================
/**********************************************************
** 函數(shù)名稱: void Uart1_SendData(unsigned char Uart1_dat)
** 功能描述: UART1 單個(gè)字符發(fā)送函數(shù)
** 輸 入: unsigned char Uart1_dat
** 輸 出: 無
** 全局變量:
** 調(diào)用模塊:
** 備 注:參數(shù)1:待發(fā)送的單個(gè)字符
**********************************************************/
void Uart1_SendData(unsigned char Uart1_dat)
{//UART 發(fā)送字節(jié)函數(shù)
bit TB8_Temp;
ACC = Uart1_dat; //被發(fā)送數(shù)據(jù)送累加器A,準(zhǔn)備求奇偶校驗(yàn)位 P
TB8_Temp = P; //寫奇偶校驗(yàn)標(biāo)記
while (~TI); //循環(huán)等待正在發(fā)送標(biāo)記被清空
TI=0;
switch(Uart1.ParitySet)
{//根據(jù)校驗(yàn)要求判斷
case 0:TB8=0;break; //要求無校驗(yàn)
case 1:TB8=~TB8_Temp;break; //要求奇校驗(yàn),翻轉(zhuǎn)TB8的值
case 2:TB8=TB8_Temp;break; //偶校驗(yàn),TB8不變
case 3:TB8=1;break; //要求常1校驗(yàn),TB8恒等于1
case 4:TB8=0;break; //要求常0校驗(yàn),TB8恒等于0
default: break; //要求無校驗(yàn)
}
SBUF = Uart1_dat; //累加器 A 中的數(shù)據(jù)送發(fā)送緩沖區(qū)發(fā)送
}
//=======================================================================================
/**********************************************************
** 函數(shù)名稱: void Uart1_SendString(char *s)
** 功能描述: UART1 按字符串發(fā)送函數(shù)
** 輸 入: char *s
** 輸 出: 無
** 全局變量:
** 調(diào)用模塊:
** 備 注:參數(shù)1:待發(fā)送的字符串
**********************************************************/
void Uart1_SendString(char *s)
{//UART 按字符串發(fā)送
while (*s)
{
Uart1_SendData(*s++); //將待發(fā)字符串依次使用SendData函數(shù)按字節(jié)發(fā)送
}
}
//=======================================================================================
/*常用串口設(shè)置開關(guān)===============================附錄====================================
AUXR |= 0x01; //串口1選擇獨(dú)立波特率發(fā)生器
AUXR &= 0xFE; //串口1選擇定時(shí)器1做波特率發(fā)生器
AUXR |= 0x40; //定時(shí)器1使用1T模式
AUXR &= 0xBF; //定時(shí)器1使用12T模式
AUXR |= 0x04; //獨(dú)立波特率使用1T模式
AUXR &= 0xFB; //獨(dú)立波特率使用12T模式
AUXR |= 0x10; //打開獨(dú)立波特率發(fā)生器
AUXR &= 0xEF; //關(guān)閉獨(dú)立波特率發(fā)生器
PCON |= 0x80; //串口1波特率加倍
PCON &= 0x7f; //串口1波特率不加倍
AUXR |= 0x08; //串口2波特率加倍
AUXR &= 0xf7; //串口2波特率不加倍
==========================================================================================*/
|
|