#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++); }}
|