微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > PIC16F877A单片机 I2C模块 24CXXX存储器实现路径记忆

PIC16F877A单片机 I2C模块 24CXXX存储器实现路径记忆

时间:11-24 来源:互联网 点击:
利用24CXXX系列E2PRAM存储器实现机器人的路径记忆。

首先,利用PIC16F877A单片机将机器人的路径采集转换成数据,单片机进行处理。但是,由于单片机RAM太小不能够存储大量的数据。因此,这里用24CXXX系列的存储器存储大量的数据,单片机实现的是对数据的采集和处理。

此过程用的是PIC16F877A单片机的I2C协议。

具体I2C使用如下:

1.写过程

(1)上电后等待一个延时(1ms)。

(2)器件寻址,给一个起始信号(SCL为高电平时SDA给一个下降沿)。发送从器件地址,高5位为10110,然后根据A1/A0(如果和器件的地址相同则那个器件会应答)进行读/写控制(O为读)。

(3)应答,器件在SCL的第9个周期时SDA给出一个低电平,作为应答信号。

(4)开始写有两种模式:字节写模式和页写模式。

·字节模式:给出A15~A8应答,给出A7~A0应答;然后给出DATA和停止信号 (SCL为高电平时,SDA给出一个上升沿),接着要等待一个擦写时间。

·页写模式:给出地址以后连续给出64个数据。如果多于64个数据,则地址计数器自动翻转。(如果少于64昵,估计是没有问题的,但是需要实验验证。)

(5)判断擦写操作是否完毕的一个方法(应答查询),如果器件还处于擦写状态,则不会应答器件寻址;如果有应答,则说明擦写完毕。

2.读过程

(1)上电以后等待一个延时(lms)。

(2)器件寻址。

(3)应答。

(4)开始读有三种模式:立即当前地址读、选择/随机读、连续读。

·立即当前地址读:如果上次读/写的操作地址为N,则现在是N+1。不需要ACK,但是需要Stop信号。

·选择/随机读:先伪写(用于给出一个地址),然后再次启动,读取数据。

·连续读:读取一个以后给一个应答,这样器件会再给出下一个地址的数据内容。

(5)开始数据传输Start后、停止数据传输Stop前,SCL高电平期间,SDA上为有效数据。

最终实现的效果





I2C模式7位寻址数据接收过程时序图

该过程的部分程序:

void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
void init() //端口初始化
{
TRISB=0X00;
PORTB=0X00;
TRISD=0x00;
PORTD=0x00;
TRISC=0XFF; //TRISC<4:3>=11即可
// PORTC=0X00;
SSPSTAT=0X80;
SSPCON=0X38;
SSPCON2=0X00;
SSPADD=0x09;

}
void didi(uchar num) //蜂鸣器,检测读写是否完成
{
uchar di_num;
for(di_num=num;di_num>0;di_num--)
{
RD0=1;
delay(500);
RD0=0;
delay(500);
}
}
void write() //写函数
{
uchar i;
SSPIF=0;
SEN=1; //启动信号
while(!SSPIF); //1的时候是真 0的时候是假 !SSPIF为非真,为假退出语句
SSPIF=0; //软件清零 不会自动清零
SSPBUF=0XA0; //发送设备片选地址 即1010 A0 A1 A2 R/W
while(!SSPIF); //判断是否发送完毕
SSPIF=0;
SSPBUF=add; //发送E2PROM内存储地址00~FF
while(!SSPIF); //监测数据是否发完
SSPIF=0;
//此处似乎缺ACK应答
for(i=0;i<6;i++) //写入数据
{
SSPBUF=ee_data[i];//每发送一个数据都要检测是否成功
while(!SSPIF); //判断
SSPIF=0;
}
PEN=1; //发送停止信号
while(!SSPIF);//如果收到停止信号同样会置位
SSPIF=0;
didi(1); //如果写成功发出两声嘀嘀 此处可有可无

}
void read() //读函数
{
uchar i;
SSPIF=0;
SEN=1; // 启动信号
while(!SSPIF);//如果启动成功 置位
SSPIF=0; //同样清零
SSPBUF=0XA0; //发送片选地址 即1010 A0 A1 A2 R/W
while(!SSPIF); //判断是否发送完毕
SSPIF=0;
//此处似乎也需要应答ACK
SSPBUF=add; //E2PROM片内写数据地址从00到FF中的任意一个
while(!SSPIF); //监测数据是否发完
SSPIF=0;
SSPIF=0;
//又一个ACK应答
RSEN=1; //重启信号
while(!SSPIF); //监测数据是否发完
SSPIF=0;
SSPBUF=0XA1; //传输方向即开始读取数据
while(!SSPIF); //监测数据是否发完
SSPIF=0;
for(i=0;i<6;i++) //接受的数据
{
RCEN=1;
while(!SSPIF);
read_data[i]=SSPBUF;//read_data[i]为SSPBUF中读回来的数 每读一次IIC地址自动加1
while(!SSPIF);
SSPIF=0; //等待read_data[i]将数据读走标志位清零

if(i>=5)
{ ACKDT=1;} //应答标志
else { ACKDT=0;}

ACKEN=1;
while(!SSPIF);
SSPIF=0;
}
//此处好像有一个ACK应答
PEN=1; //读操作完毕
while(!SSPIF); //监测
SSPIF=0;
didi(3);
}

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

网站地图

Top