IIC_24c02

这次写代码执行出来后终于是科学的了
也算是对24c系列的芯片更加了解了

接下来给上代码,这次注释会详细一点

这次要实现的是矩阵键盘按键按下记录,并且在开机时显示上一次关机之前最护按的那个键的键值

#include  
__CONFIG(1,XT) ;         //晶振为外部4M
__CONFIG(2,WDTDIS) ;      //看门狗关闭
__CONFIG(4,LVPDIS) ;     //禁止低电压编程
#define uchar unsigned char
#define uint unsigned int
#define nop NOP()
#define rs RB5
#define rw RB4
#define en RB3
#define scl RB0
#define sda RB1
uchar q[]="I am iron man";

void delay(uint x) //延时没什么好讲的
{
int i,j;
for(i=0;i<=110;i++)
for(j=0;j<=x;j++);
}

void write_com(uchar com) //关于LCD1602的没什么好讲的了
{
rs=0;
rw=0;
delay(1);
en=1;
delay(1);
PORTD=com;
en=0;
delay(1);
}

void write_dat(uchar dat)
{
rs=1;
rw=0;
delay(1);
en=1;
delay(1);
PORTD=dat;
en=0;
delay(1);
}

void write_zfc(uchar *p) //关于在PIC18F452里我第一次成功写入字符串
{
while(*p)
write_dat(*p++);
}

void init_1602()
{
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
write_zfc(q);
write_com(0x80+0x40);
write_dat('A');
write_dat(':');
}

void start() //开始信号
{
TRISB1=0;
sda=1;
scl=1;
sda=0;
}

void stop() //结束信号
{
TRISB1=0;
sda=0;
scl=1;
sda=1;
}

void ack() //应答信号,之前有一张说这个没用,哪里说错了,其实是有用的
{
uchar i;
TRISB1=0;
sda=1;
TRISB1=1;
scl=1; //在数据线为高电平的情况下,给一个始终线的高电平
nop;
while(sda&&i<100)i++; //等待数据线的变化,若出现数据线为低(当然也不可能一直等下去),则表示之前的数据处理好了,可以处理下一个数据了
scl=0;
}

void write_byte(uchar dat) //写字节,先写高位,在写低位
{
uchar i;
TRISB1=0;
for(i=0;i<8;i++)
{
scl=0;
nop;
sda=(dat&0x80)>>7;
nop;
scl=1;
nop;
scl=0;
dat<<=1;
}
}

uchar read_byte() //读字节,先读高位,在读低位,这两个读写函数只要注意顺序,按时序图写就好,方法有很多种
{
uchar dat=0,i;
TRISB1=1;
for(i=0;i<8;i++)
{
dat<<=1;
scl=1;
nop;
dat=dat|sda;
nop;
scl=0;
}
return dat;
}

void write_add(uchar add,uchar dat) //这个函数里的ack必须有
{
start();
write_byte(0xa0); //a是固定的,0有4位,前三位表示A2A1A0的接法是什么电平,最后一位0表示写
ack();
write_byte(add);
ack();
write_byte(dat);
ack();
stop();
}

uchar read_add(uchar add) //ack同样必须有
{
uchar dat;
start();
write_byte(0xa0);
ack();
write_byte(add); //先写入要读的地址
ack();
start(); //重新开始
write_byte(0xa1); //最后一位1表示读数据
ack();
dat=read_byte();
ack();
stop();
return dat;
}

void main(void)
{
uchar temp;
ADCON1=0X06; 
TRISB=0B11000110;
TRISD=0x00;  
TRISC=0x0f;
init_1602();
temp=read_add(0x01);
if(temp<10) //这个if/else是为了不显示个位数时十位上的0
{
write_com(0x80+0x40+9);
write_dat(0x30+temp); //显示从0x01位置储存的数据
}
else
{
write_com(0x80+0x40+8); //同上
write_dat(0x30+temp/10);
write_dat(0x30+temp);
}
while(1)
{
PORTC=0B11101111;
if(RC0==0)
{
delay(10); //检测到按键按下,必须到按键松开才表示读入有效
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(' ');
write_add(0x01,1); //把数据存到0x01的位置
}
else if(RC1==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+5);
write_dat(' ');
write_add(0x01,5);
}
else if(RC2==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+9);
write_dat(' ');
write_add(0x01,9);
}
else if(RC3==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+3);
write_add(0x01,13);
}

PORTC=0B11011111;
if(RC0==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+2);
write_dat(' ');
write_add(0x01,2);
}
else if(RC1==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+6);
write_dat(' ');
write_add(0x01,6);
}
else if(RC2==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+0);
write_add(0x01,10);
}
else if(RC3==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+4);
write_add(0x01,14);
}

PORTC=0B10111111;
if(RC0==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+3);
write_dat(' ');
write_add(0x01,3);
}
else if(RC1==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+7);
write_dat(' ');
write_add(0x01,7);
}
else if(RC2==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+1);
write_add(0x01,11);
}
else if(RC3==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+5);
write_add(0x01,15);
}

PORTC=0B01111111;
if(RC0==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+4);
write_dat(' ');
write_add(0x01,4);
}
else if(RC1==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+8);
write_dat(' ');
write_add(0x01,8);
}
else if(RC2==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+2);
write_add(0x01,12);
}
else if(RC3==0)
{
delay(10);
write_com(0x80+0x40+4);
write_dat(0x30+1);
write_dat(0x30+6);
write_add(0x01,16);
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值