#include<reg51.h>
#include<intrins.h>
#include<absacc.h>
#define lcddisp P0
#define unint unsigned int
#define unchar unsigned char
#define _5us_delay {_nop_();_nop_();_nop_();_nop_();_nop_()}
sbit EN=P2^0;
sbit RW=P2^1;
sbit RS=P2^2;
sbit SCL=P2^3;
sbit SDA=P2^4;
bit ack;
unchar rxtable[56];
unchar m=0;//for 1602 顯示計數
unchar txtable[56]=" FM 89.6 please turn the key to the channel you wish to!";//
void main()
{ void lcd_init(void);
void lcd_wcom(unchar com);
void lcd_wdata(unchar lcddata);
void iic_init(void);
void iic_star(void);
void iic_stop(void);
void iic_sendbyte(unchar c);//需發送c
unchar iic_rcvbyte();//需返回c
void iic_ack(void);
void iic_nack(void);
void ms_delay(unchar);
void iic_sendstr(unchar sla,unchar suba,unchar *s,unchar n);
void iic_rcvstr(unchar sla,unchar suba,unchar *s,unchar n);
unchar i;
TMOD=0x20;//定時器0工作方式2
SCON=0xd0;//串口工作方式3,sm2=0允許接收
PCON&=0x7F;//SMOD=0
TH1=0xfd;
TL1=0xfd;//9600 @11.0592MHZ
TR1=1;//定時器1開
ES=1;//開串口中斷
EA=1;//開中斷
lcd_init();//1602&iic初始化
iic_init();
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void iic_sendstr(0xa8,0x10,txtable,0x38);//報錯IIC_24C02.C(45): error C141: syntax error near 'void'
ms_delay(110);
void iic_rcvstr(0xa8,0x10,rxtable,0x38);//報錯IIC_24C02.C(47): error C141: syntax error near 'void'
ms_delay(110);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
lcd_wcom(0x80);
for(m=0;m<16;m++)
{lcd_wdata(rxtable[m]);
ms_delay(5);}
lcd_wcom(0x80+0x44);
{for(m=16;m<32;m++)
lcd_wdata(rxtable[m]);}
while(1);
}
/*--------向地址為sla,子地址為suba,寫入以*s為地址的數據------*/
void iic_sendstr(unchar sla,unchar suba,unchar *s,unchar n)
{unchar i;
iic_star();//啟動總線
iic_sendbyte(sla);//發送器件地址 sla
iic_sendbyte(suba);//發送器件子地址 suba
for(i=0;i<n;i++)//發送數據
{iic_sendbyte(*s);
s++;
}
iic_stop();//發送結束
}
/*--------接收數據------*/
void iic_rcvstr(unchar sla,unchar suba,unchar *s,unchar n)
{unchar i;
iic_star();//啟動總線
iic_sendbyte(sla);//送器件地址
iic_sendbyte(suba);//送器件子地址
iic_star();//再次發起啟動信號,啟動讀程序
sendbyte(sla+1);//SLA+1 進入讀程序
for(i=0;i<n;i++)//對前n-1個字節發應答信號
{*s=iic_rcvbyte();//接收iic_rcvbyte信號
iic_ack();
s++;
}
*s=rcvbyte();//接收最后一個信號
iic_nack();//發非應答信號
iic_stop();//結束
}
/*------------------從iic BUS接收(讀)一個字節--------------------*/
unchar rcvbyte()
{unchar c,n;
for(n=0;n<8;n++)
{SDA=1;
SCL=1;
if(SDA==0)c=c&0x7f;
else c=c|0x80;
c=_crol_(c,1);
SCL=0;
}
return(c);//傳回c
}
/*------------------向iic BUS 發送一個字節+應答判斷------------------*/
void sendbyte(unchar c)
{unchar n;
delay : _5us_delay;
for(n=0;n<8;n++)//循環8次,先送高位,后送低位
{if(c&0x08)SDA=1;//根據發送位將SDA置為1/清零
else SDA=0;
SCL=1; //置時鐘線SCL為高,通知被控從機開始接收數據位
_5us_delay;
SCL=0;//SCL LOW 防誤,及準備下次通信。
c=c<<1; //移到到最高位
}
_5us_delay;
SDA=1; //8位發送完后釋放數據線,準備接收應答位
_NOP_();
scl=1; // SCL由低變高,產生一個時鐘,讀取SDA狀態
_5us_delay;
if(SDA==1){ack=0;goto delay;}//如果SDA=1,則發送失敗,將ack_mk清零
else ack=1; // 否則發送成功,將ack_mk置1
SCL=0;
}
void iic_init(void)
{sda=1;
_5us_delay;
scl=1;
_5us_delay;
}
void ii_star()//啟動iic函數
{SDA=1;
SCL=1;
_5us_delay;
SDA=0;
_5us_delay;
SCL=0;
}
void iic_stop()//結束iic函數
{SDA=0;
SCL=1;
_5us_delay;
SDA=1;
_5us_delay;
SCL=0;
}
void ack(void)
{SDA=0;//SDA先清零,發送應答信號
SCL=1;
_5us_delay;
SCL=0;
}
void nack(void)
{SDA=1;//SDA先置1,發非應答信號
SCL=1;// 由低變高,產生一個時鐘
_5us_delay;// 延時5us
SCL=0; //時鐘線SCL清恢復到低電平,以便繼續接收
}
/*----------LCD 初始化---------------------------*/
void lcd_init() /*LCD intiation*/
{lcd_wcom(0x38); //八位數據,雙列
lcd_wcom(0x0c);
lcd_wcom(0x06);
lcd_wcom(0x01);
}
/*-------------1602指令-------------------------*/
void lcd_wcom(unchar com)/*com regester*/
{RW=0; //寫1602
RS=0; //選寄存器
lcddisp=com; //指令傳送
ms_delay(1); //等待1602發送數據
EN=1;
_nop_();
_nop_();
EN=0;
}
/*--------------1602數據顯示---------------------------*/
void lcd_wdata(unchar lcddata)/*data regester*/
{
RW=0;
RS=1;
lcddisp=lcddata;//lcd data 是否還需申明呢?
ms_delay(1);
EN=1;
_nop_();
_nop_();
EN=0;
}
/*---------------delay-----------------------*/
void ms_delay(unint delaytime)//delay
{unint i=0;
for(;delaytime>0;delaytime--)
{for(i=0;i<124;i++); }}
|