#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit RS = P3^5 ;
sbit RW = P3^6 ;
sbit EN = P3^7 ;
sbit BUSY = P2^7;
sbit LED = P0^0;
sbit zhendong = P0^1;
sbit spk = P0^2;
sbit k1 = P0^3;
sbit k2 = P0^3;
sbit k3 = P0^5;
sbit k4 = P0^6;
uchar HMS_string[]=" 00:00:00 ";
uchar buf,millisecond,hour = 0,minute = 0,second = 0;
uint m,n;
bit settime = 0;
bit change_H_or_M=1; // 1表示修改时,0表示修改分
uchar RX_BUF[20]; //串口接受到的数据缓冲区域
uchar flag_head=0; //数据标志
uchar RX_data_ln=0; //串口接收到的数据长度
uchar flag_rev=0; //一次数据接受完成标志
/****************************************************************************
延迟程序
****************************************************************************/
void delay(uint h)
{
for(m=0;m<h;m++)
for(n=0;n<110;n++) ;
}
/*********************************************************************
LCD1602
***********************************************************************/
/**
* 等待繁忙标志
*/
void wait(void)
{
P2 = 0xFF;
do
{
RS = 0;
RW = 1;
EN = 0;
EN = 1;
}while (BUSY == 1);
EN = 0;
}
//写数据
void w_dat(uchar dat)
{
wait();
EN = 0;
P2 = dat;
RS = 1;
RW = 0;
EN = 1;
EN = 0;
}
//写命令
void w_cmd(uchar cmd)
{
wait();
EN = 0;
P2 = cmd;
RS = 0;
RW = 0;
EN = 1;
EN = 0;
}
/**
* 初始化1602
*/
void Init_LCD1602(void)
{
w_cmd(0x38); // 16*2显示,5*7点阵,8位数据接口
w_cmd(0x0C); // 显示器开、光标开、光标允许闪烁
w_cmd(0x06); // 文字不动,光标自动右移
w_cmd(0x01); // 清屏
}
/****************蜂鸣函数**************************************************/
void beep()
{
uchar i,j=70;
for(i=0;i<200;i++)
{
while(--j);
spk = ~spk;
}
delay(300);
spk = 0;
}
/*******显示函数,在LCD指定的行上显示字符串********************************/
void display_string(uchar *str,uchar lineNo)
{
uchar k;
for(k=0;k<16;k++)
{
w_cmd(lineNo+k);
w_dat(str[k]);
}
}
/***************时分秒显示**************************************/
void display_HMS(uchar h,m,s)
{
if(settime)
HMS_string[3] = '>';
else
HMS_string[3] = ' ';
HMS_string[4] = h/10 +'0';
HMS_string[5] = h%10 +'0';
HMS_string[7] = m/10 +'0';
HMS_string[8] = m%10 +'0';
HMS_string[10] = s/10 +'0';
HMS_string[11] = s%10 +'0';
display_string(HMS_string,0xC0);
}
/******************设置时间*******************************/
void change_time()
{
settime = 0;
// if(k1==0||k2==0||k3==0)
// {
// TR0 = 0;
// settime = 1;
// }
while(settime)
{
if(k1==0)
{
beep();
while(k1==0)
change_H_or_M = !change_H_or_M;
}
else if(k2==0)
{
beep();
while(k2==0);
if(change_H_or_M==1)
{if(++hour==24) hour = 0;}
else
{if(++minute==60) minute = 0;}
}
else if(k3==0)
{
beep();
while(k3==0);
if(change_H_or_M==1)
{if(--hour==0xff) hour=23;}
else
{if(--minute==0xff) minute=59;}
}
else if(k4==0)
{
beep();
while(k4==0);
settime = 0;
TR0 = 1;
}
display_HMS(hour,minute,second);
}
}
/********************************************************************
主函数
*******************************************************************/
void main(void)
{
uint i;
TMOD=0x21; //定时器1工作于8位自动重载模式, 用于产生波特率
SCON=0x50; //设定串口工作方式
PCON=0x00; //波特率不倍增
TH1 = 256-(22118400/12/16/115200);
TL1 = TH1;
TH0 = 0x4c;
TL0 = 0x00;
IP = 0x10;
TR0 = 1;
ET0 = 1;
TR1 = 1;
ET1 = 1;
spk = 0;
ES = 1; //允许串口中断
EA=1;
Init_LCD1602();
while(1)
{
if(flag_rev==1) //判断数据接受完成
{
flag_rev=0;
if(RX_BUF[2]>='1'&&RX_BUF[3]!='.')
{
LED = 0;
delay(100);
LED = ~LED;
delay(100);
zhendong = 0;
}
else
{zhendong = 1;}
}
for(i=1;i<RX_data_ln;i++)
{
w_cmd(0x80+i-1);
w_dat(RX_BUF[1+i]);
delay(100);
}
display_HMS(hour,minute,second);
delay(100);
change_time();
}
}
/*************************************************************
串行中断服务函数
*************************************************************/
void serial() interrupt 4
{
if(RI ==1)
{
//ES = 0; //关闭串行中断
RI = 0; //清除串行接受标志位
buf = SBUF; //从串口缓冲区取得数据
if(buf=='R'&&flag_head==0) //表明接收到了数据头
{
RX_data_ln=0;
flag_head=1;
return;
}
if(buf=='
'&&flag_head==1)//接受到了数据尾
{
flag_rev=1; //接受完成标志
flag_head=0;
return;
}
if(flag_head==1)
{
RX_BUF[++RX_data_ln]=buf;
}
//ES = 1; //允许串口中断
}
else
{
TI=0;
}
}
/************************************************************/
void timer0() interrupt 1
{
TH0 = 0x4c;
TL0 = 0x00;
if(++millisecond == 39)
{
millisecond = 0;
if(++second==59)
{
second = 0;
if(++minute ==59)
{
minute = 0;
if(++hour==23)
{
hour = 0;
minute = 0;
second = 0;
}
}
}
}
}
程序结果显示如图
LCD上面一行本来应该显示串口接受的数据,下面一行显示时间。但是现在串口接受的数据显示不出来了,怎么才能使上面的接受数据显示出来?(备注:在加时间程序前,串口程序时刻以接受数据并且是能够显示的。)
此帖出自
小平头技术问答
for(i=1;i<RX_data_ln;i++)
{
w_cmd(0x80+i-1);
w_dat(RX_BUF[1+i]);
delay(100);
}
直接用void display_string(uchar *str,uchar lineNo)函数试试。
我把RX_data_ln改成16的话 ,上面的一行就显示,但是是乱码.
你在for循环中没有正确调用显示的程序,你仔细看看就明白。
你是怎样调用display_string的?
显示单个字符子程序:
void display_lcd_byte(uchar y,uchar x,uchar z) //Y=0,1(起始行)X=0~15(起始列)Z=想写字符的ASCII码
{
if(y) //是否显示在第二行(若在第一行Y=0,不进入IF语句,若在第二行,进入IF语句
{
x+=0x40; //第二行起始地址加上列数为字符显示地址
}
x+=0x80; //设置数据指针位置
}
然后就可以显示了
一周热门 更多>