或許是我的構(gòu)思一開始就是錯誤的,串口的接受速度遠(yuǎn)大于數(shù)據(jù)的存取和液晶的驅(qū)動的時間總和。從電腦傳過去的字符總是會漏掉好多,如今只能寫入一個字節(jié)的數(shù)據(jù)。真是豬腦子,浪費(fèi)了半天時間。
這是我自己寫的單片機(jī)實現(xiàn)電話本,可以從電腦錄入姓名與電話,并可以手動查詢。但是存儲和液顯的時間太長,沒法及時從電腦錄入數(shù)據(jù)。但是串口,I2C總線,EEPROM,液晶的驅(qū)動程序是對的。串口的傳輸能否像I2C一樣能被我自己控制呢。
#include <reg52.h>
#define unchar unsigned char
unchar ac;
sbit E=P2^7 ;
sbit RS=P2^6 ;
sbit RW=P2^5 ;
sbit SDA=P2^1;
sbit SCL=P2^0;
/****數(shù)據(jù)延時****/
void NOP(void)
{;;}
/******操作延時*****/
void delay(unsigned int i)
{
i=124*i;
while(--i);
}
/****液晶指令寫入****/
void LCD_cmd(unchar cmd)
{
E=0;
RW=0;
RS=0;
P0=cmd;
delay(2);
E=1;
delay(2);
E=0;
}
/****液晶數(shù)據(jù)的寫入*****/
void LCD_date(unchar date)
{
RW=0;
RS=1;
P0=date;
delay(1);
E=1;
delay(1);
E=0;
}
void init(void)
{
/********* 串口初始化 ******/
TMOD=0X20;
SCON=0X50;
PCON=0X80;
ET1=1;
TR1=1;
TH1=0XF3;
TL1=0XF3;
RI=0;
TI=0;
/********* 液晶初始化 *******/
LCD_cmd(0x6);//設(shè)置讀寫方式,指針自動增一(第二位 1),畫面不移動(第一位 0)
LCD_cmd(0xc);//顯示開(第三位 1)光標(biāo)開(第二位 1)光標(biāo)閃爍開(第一位 1);
LCD_cmd(0x38);//設(shè)置顯示模式
LCD_cmd(0x1);//清屏,清除指針和RAM數(shù)據(jù)
/*****按鍵中斷初始化*******/
EA=1;
EX0=1;
EX1=1;
}
/*****數(shù)據(jù)起始端*********/
void start(void)
{
SDA=1;
NOP();
SCL=1;
NOP();
SDA=0;
NOP();
}
/***** 數(shù)據(jù)結(jié)束端 ********/
void stop(void)
{
SDA=0;
NOP();
SCL=1;
NOP();
SDA=1;
NOP();
}
/******發(fā)送數(shù)據(jù)*********/
void send_message(unchar date)
{
unchar temp,i;
temp=date;
SCL=0;
NOP();
for (i=0;i<8;++i)
{
temp=temp<<1;
SDA=CY;
NOP();
SCL=1;
NOP();
SCL=0;
NOP();
}
SDA=1;
NOP();
}
/***** 接收數(shù)據(jù) *****/
unchar rece_message(void)
{
unchar date,temp,i;
SCL=0;
CY=0;
NOP();
for(i=0;i<8;++i)
{
SCL=1;
NOP();
temp=SDA;
date=date<<1;
date=date|temp;
SCL=0;
NOP();
}
SDA=1;
NOP();
return date;
}
/***** 應(yīng)答接收 ********/
unchar ack_back(void)
{
unchar ack;
SCL=0;
NOP();
SCL=1;
NOP();
ack=SDA;
NOP();
SCL=0;
return ack;
}
/****完整接收數(shù)據(jù)*******/
unchar get(unchar add)
{
unchar date;
delay(50);
start();
send_message(0xa0);
ack_back();
send_message(add);
ack_back();
start();
send_message(0xa1);
ack_back();
date=rece_message();
stop();
delay(50);
return date ;
}
/******完整寫入數(shù)據(jù)*******/
void write(unchar date,unchar add)
{
init();
start();
send_message(0xa0); //發(fā)送地址碼
ack_back();
send_message(add); //存儲的內(nèi)容首地址
ack_back();
send_message(date);
ack_back();
stop();
}
/*****寫入數(shù)據(jù)串 并分配指針地址*******/
void write_s (unchar date)
{
if(date!='#')
write(date,ac);
if (date=='#')
{ac=ac+0x10;write(ac,0xff);}
}
void main()
{
init();
//ac=get(0xff);
while(1)
{
while(!RI);
RI=0;
// write_s(SBUF);
LCD_date(SBUF);
}
}
不以程序長短論英雄,成敗完全取決于細(xì)節(jié)的把握。一步登天難,十天學(xué)會單片機(jī)更難。扎實的基礎(chǔ),刻苦的精神是成功的必備。謹(jǐn)以此句,哀悼我三個失敗的項目。EPROM莫名的錯誤已讓我發(fā)瘋。高強(qiáng)度的腦力,低質(zhì)量的四小時睡眠,我已經(jīng)精疲力竭了。我真以為我能一步登天,我太急躁了。
