一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 1166|回复: 6
收起左侧

[51单片机] 1602串口通信问题

[复制链接]
发表于 2019-3-7 17:15 | 显示全部楼层 |阅读模式
自己改的代码,编译成功,但是就是不显示,不知道什么问题,大神帮看看



#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LCD_RS = P0^7;
sbit LCD_RW = P0^6;
sbit LCD_EN = P0^5;
#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,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20};
uchar temp,buf,m,count;
uint k;
bit playflag=0;


/**********************************************************
延时子程序
**********************************************************/
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;
P2 = 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; //从串口缓冲区取得数据
playflag=1;
senddata(buf); //接受数据,将其发送给计算机

if(buf!=0x0D)
{
if(buf!=0x0A)
{
temp =buf;
if(count<16)
{
RXDdata[count]=temp;
count++;
}
}
}
ES = 1; //允许串口中断
}
/*********************************************************
数据显示函数
*********************************************************/
void dsplay()
{
if(playflag)
{
lcd_pos(0x00); //设置位置为第一行

for(m=0;m<16;m++)
{
lcd_pos(0x00+m); //设置显示位置为第一行
lcd_wdat(RXDdata[m]); //显示字符
}
lcd_pos(0x40); //设置位置为第二行
for(m=0;m<16;m++)
{
lcd_pos(0x40+m); //设置显示位置为第二行
lcd_wdat(RXDdata[m]); //显示字符
}
playflag=0;            
count=0x00;
RXDdata[m]=0x20;
}
}


/*********************************************************
主函数
*********************************************************/
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();

while(1)
{
dsplay();
}
}


发表于 2019-3-7 17:46 | 显示全部楼层
请问你在哪里买的串口1602呢?
另外你写命令和写数据里明明用了两个不同的输出端,P0和P2.你这是怎么通讯的
听说把本站有此功能,为了支持站长,求打赏,哈哈
发表于 2019-3-7 18:21 | 显示全部楼层
讲个笑话,1602对比没调,怎么都不出字符,弄了半天才发现
发表于 2019-3-8 07:12 | 显示全部楼层
这最好是慢慢调试,最多情况出现在初始化的过程,比如检测忙信号、延时等

建议先不要管串口,直接给些字符显示。然后再调试串口。。。。。


代码还不让拿来尝试编译,不像是个人写的
发表于 2019-3-8 09:41 | 显示全部楼层
2楼说的对,写命令用的是P0,写数据是P2,明显是错误的代码,数据的输出应该是P2,因为P0.5-P0.7已经被用了
还有,程序里为啥要用串口?
就算你的电路接法正确,应该也不会显示,因为你显示的全部是空格,就是空字符
 楼主| 发表于 2019-3-8 18:29 | 显示全部楼层
本帖最后由 xixi2006 于 2019-3-8 18:33 编辑

谢谢2楼和5楼的,改了P2端口已经可以显示了。这个是串口助手发送字符,1602显示的。我也是小白一个,纯粹业余爱好。

还有问题想请教各位大神,
void dsplay()
{
if(playflag)
{
lcd_pos(0x00); //设置位置为第一行

for(m=0;m<16;m++)
{
lcd_pos(0x00+m); //设置显示位置为第一行
lcd_wdat(RXDdata[m]); //显示字符
}
lcd_pos(0x40); //设置位置为第二行
for(m=0;m<16;m++)
{
lcd_pos(0x40+m); //设置显示位置为第二行
lcd_wdat(RXDdata[m]); //显示字符
}
playflag=0;            
count=0x00;
RXDdata[m]=0x20;
这个显示函数也不对,显示的时候第一行还显示正常点,第二行就不对了,不知道函数应该怎么改写才是正确的。

点评

我也不太懂,最多是抄别人的改改自用,自娱自乐呗。你试试把循环里设两个变量试试,会不会一个m不行, 再一个我怎么记得第一行地址是0x80来的  详情 回复 发表于 2019-3-10 17:16
发表于 2019-3-10 17:16 | 显示全部楼层
xixi2006 发表于 2019-3-8 18:29
谢谢2楼和5楼的,改了P2端口已经可以显示了。这个是串口助手发送字符,1602显示的。我也是小白一个,纯粹业 ...

我也不太懂,最多是抄别人的改改自用,自娱自乐呗。你试试把循环里设两个变量试试,会不会一个m不行,

再一个我怎么记得第一行地址是0x80来的
听说把本站有此功能,为了支持站长,求打赏,哈哈

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-4-20 17:30 , Processed in 0.064381 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表