常用程序模塊備份(二):STC12C5A60S2,串口Uart
uart作為程序調(diào)試很有幫助,所以一個(gè)好的uart模塊個(gè)人認(rèn)為非常重要的
這里的用stc12單片機(jī),因?yàn)椴挥?2分頻,所以可以進(jìn)行115200波特率快速傳輸(注意晶振必須11.0592MHz,12MHz的會(huì)亂碼,本人親測(cè)),而如果改用其他的51單片機(jī),只需要把UartInit()函數(shù)改成自己的初始化設(shè)置就行,比如89c52,當(dāng)然要記得改52頭文件。
此uart本人比較欣賞的是可以直接調(diào)用UartPrintf()函數(shù),跟c中prinf()用法幾乎相同,支持%d%0.2f等省去了字符轉(zhuǎn)換。而對(duì)于接收到的字符命令進(jìn)行處理只需要在UartReceiveHandler函數(shù)中修改即可,例子中是對(duì)“End”字符命令進(jìn)行處理,測(cè)試程序main.c是博文手寫,未經(jīng)測(cè)試,只是提示主框架用法
main.c-------------------------------------------------------------------------------------------------------
#include"uart.h"
void main(void)
{
UartInit();
while(1)
{
UartReceiveHandler();
}
}
uart.h--------------------------------------------------------------------------------------------------------
#ifndef __UART_H__
#define __UART_H__
void UartInit(void);
void UartPrintf(const char *fmt,...);
void UartReceiveHandler(void);
#endif
uart.c--------------------------------------------------------------------------------------------------------
#include"STC12C5A60S2.h"
#include
#include //stdio.h,stdarg.h用于vsprintf函數(shù)原型
#include
#define UART0_BUF_LEN 32
int UART1_Recv_count; //接收計(jì)數(shù)
bit UART1_Overflow_Flag;//緩沖區(qū)滿標(biāo)志
bit MarkFlag = 1;
idata unsigned char UART1_Recv_BUF[UART0_BUF_LEN];
//串口接收緩沖區(qū)
void UartInit(void) //115200bps@11.0592MHz
{
PCON &= 0x7F; //波特率不倍速
SCON = 0x50; //8位數(shù)據(jù),可變波特率
AUXR |= 0x04; //獨(dú)立波特率發(fā)生器時(shí)鐘為Fosc,即1T
BRT = 0xFD; //設(shè)定獨(dú)立波特率發(fā)生器重裝值
AUXR |= 0x01; //串口1選擇獨(dú)立波特率發(fā)生器為波特率發(fā)生器
AUXR |= 0x10; //啟動(dòng)獨(dú)立波特率發(fā)生器
ES = 1; //充許串口1中斷
EA=1; //開總中斷
}
void sendbyte(unsigned char c)
{
if(c=='\n') //如果遇到\n就換行
{
//發(fā)送CR(carriage return)
SBUF=0x0D;
while(!TI); //等待發(fā)送完成
TI=0;
//發(fā)送 LF(NL line feed,new line)
SBUF=0x0A;
while(!TI); //等待發(fā)送完成
TI=0;
}
else
{
SBUF=c;
while(!TI); //等待發(fā)送完成
TI=0;
}
}
void sendstring(unsigned char *string)
//此處*string相當(dāng)于數(shù)組
{
while(*string!='\0')//判斷是否到字符串末尾
{
sendbyte(*string);
string++;
}
}
void UartPrintf(const char *fmt,...)
{
va_list ap;
char xdata string[1024]; //訪問內(nèi)部拓展RAM,非訪問外部RAM,不能超過內(nèi)部拓展RAM大小(此處為1024)
va_start(ap,fmt);
vsprintf(string,fmt,ap); //此處也可以使用sprintf函數(shù),用法差不多,稍加修改即可,此處略去
sendstring(string);
va_end(ap);
}
void UART1_Int(void) interrupt 4
{
if (RI == 1)
{
RI = 0;
if(UART1_Overflow_Flag==0)
{
if(UART1_Recv_count
{
UART1_Recv_BUF[UART1_Recv_count++] = SBUF;
if(SBUF=='\r' || SBUF=='\n')
{
UART1_Overflow_Flag=1;
}
}
else
{
UART1_Overflow_Flag=1; // 關(guān)閉串口中斷,停止接收
}
}
}
}
//void Delay_10ms()
//{
// unsigned int i,j;
// for(i=0; i<5; i++)
// for(j=0; j<2000; j++);
//}
void UartReceiveHandler(void)
{
// unsigned char i;
// unsigned int Led;
unsigned long Count;
if (UART1_Overflow_Flag==1) //串口中斷數(shù)據(jù)接收完畢,開始處理
{
if(0 == strncmp("End",UART1_Recv_BUF,strlen("End")))
{
UartPrintf("Start\n");
Count = ReadCount();
UartPrintf("End:%ld\n",Count);
}
// UartPrintf("\r\n");
UART1_Recv_count = 0; //緩存清零
UART1_Overflow_Flag=0;//允許串口繼續(xù)接收數(shù)據(jù)
}
}