微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PIC IIC & 24c02

PIC IIC & 24c02

时间:11-21 来源:互联网 点击:

#include //调用头文件,可以去PICC18软件下去查找PIC18FXX2.H

__CONFIG(1,XT) ; //晶振为外部4M

__CONFIG(2,WDTDIS) ; //看门狗关闭

__CONFIG(4,LVPDIS) ; //禁止低电压编程

#define uint unsigned int

#define uchar unsigned char

#define nop NOP()

#define scl RC3 //时钟线

#define sda RC4 //数据线

char shuma[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

uint count=0;

uchar sec;

void usdelay()

{

nop; //其实在用IIC对EEPROM操作时,它反应很快,延时可以很短,但必须延时,只要一个NOP()就可以了

}

void init_24c() //初始化24C,就是把两根线拉高

{

TRISC4=0;

scl=1;

sda=1;

usdelay();

}


void start() //开始信号,根据时序图(sx)

{

TRISC4=0;

scl=1;

usdelay();

sda=1;

usdelay();

sda=0;

}

void stop() //结束信号 sx

{

TRISC4=0;

scl=1;

usdelay();

sda=0;

usdelay();

sda=1;

}

void ack() //不知道为什么,在PIC中不能用ack,好像一用就会出错= =?

{

uchar i;

TRISC4=0;

sda=1;

nop;

TRISC4=1;

scl=1;

nop;

while(sda==1&&i<10)i++;

scl=0;

}


void write_byte(uchar dat) //写字节 sx 由于不仅要写数据,还要写地址,所以只能先写字节的最高位R7,最后写最低位R0

{

uchar i;

TRISC4=0;

sda=0;

scl=0;

nop;

for(i=0;i<=8;i++)

{

sda=(dat&0x80)>>7;

nop;

scl=1;

nop;

scl=0;

dat<=1;

nop;

}

}

uchar read_byte() //读字节 sx 先读高位R7,最后读地位R0

{

uchar i,dat=0;

TRISC4=1;

sda=0;

usdelay();

scl=1;

usdelay();

for(i=0;i<8;i++)

{

dat<=1;

usdelay();

scl=1;

nop;

dat=dat|sda;

nop;

scl=0;

usdelay();

}

return dat;

}



void write_add(uchar add,uchar dat) //写数据到地址 sx 注意不要用ack

{

start();

write_byte(0xa0);

write_byte(add);

write_byte(dat);

stop();

}



uchar read_add(uchar add) //从地址读数据 sx 注意不要用ack

{

uchar dat;

start();

write_byte(0xa0);

write_byte(add);

start();

write_byte(0xa1);

dat=read_byte();

stop();

return dat;

}

void interrupt kaito() //定时器中断0

{

if(TMR0IF==1)

{

TMR0IF=0;

TMR0=0xff13;

count++;

if(count==4000)

{

count=0;

sec++;

if(sec>9)

sec=0;

write_add(0x10,sec); //每次要显示的数据发生变化,就写入到24c02中存起来,方便断电后保留

}

}

}

void main(void)

{

sec=0;

ADCON1=0X06;

TRISD=0x00;

TRISC3=0;

TRISC4=0;

init_24c();

GIE=1;

IPEN=0;

TMR0IE=1;

TMR0IF=0;

T0CON=0x88;

TMR0=0xff13;

GIE=1;

sec=read_add(0x10);

while(1)

{

PORTD=shuma[sec];

}

}

就是感觉很奇怪,为什么不能用attack,时序图上明明有,可是一写上就是错的= =?

达到效果,定时器计数,数码管显示,如果关机或者复位,数码管从关机前的数开始继续计数。

如果对一个地址以前没有用过,它里面存的是出厂时设置在里面的数据,很多是ff,如果不对它做正确的写入,读出的数据就会是ff,如果用1602来显示,要取十位和个位,都是f,在加上显示时的0x30,就变成0x59,和0x35,显示出来的就是I5

还有在定时器中断中要写入多个数据,必须按照条件分开写入,同时写入的话会有几条语句可能写入失败。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top