/************************************************************************ * * * TX-51STAR单片机开发系统演示程序 - 串行通迅 * * * * LCD1602显示 * * * * 工作芯片:STC89C516 晶振频率:11.0592MHz * * * * 版本: V1.0 (2009/1/2) * * 作者: 郭天祥 (Email: txmcu@163.com) * * 网站: www.txmcu.com(天祥电子) * * 邮箱: txmcu@163.com * * * *【版权】Copyright(C)天祥电子 www.txmcu.com All Rights Reserved * *【声明】此程序仅用于学习与参考,引用请注明版权和作者信息! * * * ************************************************************************* * * * 描述: * * * * 主机发送123456给单片机,单片机接收到数据后发送TX-MCU给主机。 * * * * 主机发送其它数据给单片机,单片机接收到数据后,再发送给主机。 * * * * LCD1602显示接收数据的ASCII码。 波特率9600 * * * * 注:当单片机收到数据只有凑够16个时才会一次在液晶上显示出来 * * * ************************************************************************/ #include #include #define uchar unsigned char #define uint unsigned int sbit LCD_RS = P3^5; sbit LCD_EN = P3^4; #define delayNOP(); {_nop_();_nop_();_nop_();_nop_();}; uchar data RXDdata[ ] = {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20 }; uchar temp,buf,m,count; bit playflag=0; uchar code cdis1[ ] = {" SERILA TRANFER "}; uchar code cdis2[ ] = {" "}; /********************************************************** 延时子程序 **********************************************************/ void delay1(uint ms) { uchar k; while(ms--) { for(k = 0; k < 120; k++); } } /******************************************************************/ /* */ /*检查LCD忙状态 */ /*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */ /* */ /******************************************************************/ bit lcd_busy() { bit result; LCD_RS = 0; // LCD_RW = 1; LCD_EN = 1; delayNOP(); result = (bit)(P0&0x80); LCD_EN = 0; return(result); } /*******************************************************************/ /* */ /*写指令数据到LCD */ /*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */ /* */ /*******************************************************************/ void lcd_wcmd(uchar cmd) { // while(lcd_busy()); LCD_RS = 0; // LCD_RW = 0; LCD_EN = 0; _nop_(); _nop_(); P0 = cmd; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } /*******************************************************************/ /* */ /*写显示数据到LCD */ /*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */ /* */ /*******************************************************************/ void lcd_wdat(uchar dat) { // while(lcd_busy()); LCD_RS = 1; // LCD_RW = 0; LCD_EN = 0; P0 = dat; delayNOP(); LCD_EN = 1; delayNOP(); LCD_EN = 0; } /*******************************************************************/ /* */ /* LCD初始化设定 */ /* */ /*******************************************************************/ void lcd_init() { delay1(15); lcd_wcmd(0x01); //清除LCD的显示内容 lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据 delay1(5); lcd_wcmd(0x38); delay1(5); lcd_wcmd(0x38); delay1(5); lcd_wcmd(0x0c); //开显示,显示光标,光标闪烁 delay1(5); lcd_wcmd(0x01); //清除LCD的显示内容 delay1(5); } /*******************************************************************/ /* */ /* 设定显示位置 */ /* */ /*******************************************************************/ void lcd_pos(uchar pos) { lcd_wcmd(pos | 0x80); //数据指针=80+地址变量 } /********************************************************* 发送数据函数 *********************************************************/ void senddata(uchar dat) { SBUF =dat; while(!TI); TI = 0; } /********************************************************* 串行中断服务函数 *********************************************************/ void serial() interrupt 4 { ES = 0; //关闭串行中断 RI = 0; //清除串行接受标志位 buf = SBUF; //从串口缓冲区取得数据 switch(buf) { case 0x31: senddata('T');break; //接受到1,发送字符'T'给计算机 case 0x32: senddata('X');break; //接受到2,发送字符'X'给计算机 case 0x33: senddata('-');break; //接受到3,发送字符'-'给计算机 case 0x34: senddata('M');break; //接受到4,发送字符'M'给计算机 case 0x35: senddata('C');break; //接受到5,发送字符'C'给计算机 case 0x36: senddata('U');break; //接受到5,发送字符'U'给计算机 default: senddata(buf);break; //接受到其它数据,将其发送给计算机 } if(buf!=0x0D) { if(buf!=0x0A) { temp =buf; if(count<16) { RXDdata[count]=temp; count++; if(count==16) playflag=1; } } } ES = 1; //允许串口中断 } /********************************************************* 数据显示函数 *********************************************************/ void play() { if(playflag) { lcd_pos(0x40); //设置位置为第二行 for(m=0;m<16;m++) { lcd_wdat(cdis2[m]); //清LCD1602第二行 delay1(5); } lcd_pos(0x40); //设置位置为第二行 for(m=0;m<16;m++) { // lcd_pos(0x40+m); //设置显示位置为第二行 lcd_wdat(RXDdata[m]); //显示字符 delay1(5); } playflag=0; count=0x00; for(m=0;m<16;m++) { RXDdata[m]=0x20; //清显存单元 delay1(5); } } } /********************************************************* 主函数 *********************************************************/ void main(void) { P0 = 0xff; P2 = 0xff; SCON=0x50; //设定串口工作方式 PCON=0x00; //波特率不倍增 TMOD=0x20; //定时器1工作于8位自动重载模式, 用于产生波特率 EA=1; ES = 1; //允许串口中断 TL1=0xfd; TH1=0xfd; //波特率9600 TR1=1; lcd_init(); lcd_pos(0x00); //设置显示位置为第一行 for(m=0;m<16;m++) { lcd_wdat(cdis1[m]); //显示字符 delay1(5); } lcd_pos(0x40); //设置显示位置为第二行 for(m=0;m<16;m++) { lcd_wdat(cdis2[m]); //显示字符 delay1(5); } while(1) { play(); } } /*********************************************************/