//****************************************************************************** **** //本函数模块来自"51单片机世界",作者版主丁丁(聂小猛)。 //主页地址http://www.mcu51.com //本程序为本站推出的"MCU51-63K仿真器"及"DX-51多功能试验板"而设计的,详情请到本站 查看. //"51单片机世界"版权所有,未经允许,不得抄袭作为商业用途 //****************************************************************************** **** //串口中断服务程序,仅需做简单调用即可完成串口输入输出的处理 //串口输入设有缓冲区,大小可任意设置。 //可供使用的函数名: /* extern char getbyte(void);//从接收缓冲区取一个byte,如不想等待则在调用前检测 inbufsign是否为1。 extern putbyte(char c);//放入一个字节到发送缓冲区 extern putstring(uchar *puts);//发送一个字符串到串口 extern puthex(uchar c);//发送一个字节的hex码,分成两个字节发。 extern bit inbufsign; #define CR putstring("\r\n")//发送一个回车换行 extern void serial_init (void); extern putint(uint n); */
//************************************************************************* #include <reg52.h> #define uchar unsigned char #define uint unsigned int
#define ILEN 16 //32 //设置串口中断接收缓冲区大小 idata uchar inbuf[ILEN]; data uchar idata *inlast=inbuf; //最后由中断进入接收缓冲区的字节位置 data uchar idata *getlast=inbuf; //最后取走的字节位置 bit inbufsign; //接收缓冲区非空标志 有=1 bit inbufful; //输入缓冲区满标志 满=1 #define CR putstring("\r\n") //CR=回车换行
//***************************** //放入一个字节到发送缓冲区 putbyte(unsigned char c) { SBUF=c; while(!TI);TI=0; }
//*************************************** //发送一个定义在程序存储区的字符串到串口 putstring(uchar *puts) { for(;*puts!=0;puts++) //遇到停止符0结束 putbyte(*puts); } //************************************* //发送一个字节的hex码,分成两个字节发。 uchar code hex_[]={"0123456789ABCDEF"}; puthex(unsigned char c) { int ch; ch=(c>>4)&0x0f; putbyte(hex_[ch]); ch=c&0x0f; putbyte(hex_[ch]); } //************************************* //从接收缓冲区取一个byte,如不想等待则在调用前检测inbufsign是否为1。 uchar getbyte (void) { char idata c ; while (!inbufsign); //缓冲区空等待 ES=0; c= *getlast; //取数据 getlast++; //最后取走的数据位置加一 inbufful=0; //输入缓冲区的满标志清零 if (getlast==inbuf+ILEN) getlast=inbuf; //地址到顶部回到底部 if (getlast==inlast) inbufsign=0; //地址相等置接收缓冲区空空标 志,再取数前要检该标志 ES=1; return (c); //取回数据 } /* //************************* //以十进制的形式输出一个整型数到串口 putint(uint n) { uchar i[6]; i[0]=0x30+n/10000; i[1]=0x30+(n%10000)/1000; i[2]=0x30+(n%1000)/100; i[3]=0x30+(n%100)/10; i[4]=0x30+n%10; i[5]=0; putstring(i); }
//********************* //模拟接收到一个字符, putinbuf(uchar c) {ES=0; if(!inbufful) {*inlast= c; inlast++; if (inlast==inbuf+ILEN) inlast=inbuf; if (inlast==getlast) inbufful=1; inbufsign=1; } ES=1; } */ //***************************************** //串口中断处理
serial () interrupt 4 { if (RI) { RI = 0; if(!inbufful) { *inlast= SBUF; //放入数据 inlast++; //最后放入的位置加 一 inbufsign=1; if (inlast==inbuf+ILEN) inlast=inbuf;//地址到顶 部回到底部 if (inlast==getlast) inbufful=1; //接收缓冲区 满置满标志 } } }
//***************************** //串口初始化 0xfd=19200,0xfa=9600,0xf4=4800,0xe8=2400,0xd0=1200 110592 void serial_init (void) { //用t1作波特率 SCON = 0x50; // mode 1: 8-bit UART, enable receiver TMOD |= 0x21; // timer 1 mode 2: 8-Bit reload th0 1X16 PCON |= 0x80; TH1 = 0xfa;//fa, //baud*2 /* reload value 19200 baud TR1 = 1; // timer 1 run
//用t2作波特率 /* T2CON=0x30; RCAP2H=0xFF; RCAP2L=0xb8;//70=4800,b8=9600,dc=19200,ee=38400,f4=57600,fa=115200 TR2=1;ET2=1; SCON=0x50;//SCON=0xd0; */
ES = 1; REN=1; EA=1; SM2=1; //SM2=1时收到的第9位为1才置位RI标志
}
(文章推荐人:丁丁)
|