//********************************************
//本程序用51和24c08实现P0口上的流水灯
////管脚地址都接地(A0,A1,A2)
//
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda="P3"^7; //定义数据线
sbit scl="P3"^6; //定义时钟线
uchar code table[]={0xfe,0xfd,
0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//灯的显示代码
void delay()
{;;}
void delay1(uint z) //延时
{
int x,y;
for(x=0;x<110;x++)
for(y=z;y>0;y--);
}
void init () //初始化 要比较好
{
sda=1;
scl=1;
delay();
}
void start()//开始 /当时钟线为高时,数据线从高到低的跳变,表示开始。当然当中的延时有3us 已经足够。
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop()//结束 /当时钟线为高时,数据线从低到高的跳变表示结束。
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons()//应答器件会将sda线拉低,表示收完了8位数据,所以一开始将数据拉高,是位了观察sda线是否被拉低;然而若从件没有给应答信号
{ //若从件没有给应答信号,过了一段时间后 ,就默认它以接受完了。
uchar i="0";
scl=1;
delay();
while((sda==1)&&(i<255))i++;
scl=0;
delay();
}
void wr_date(uchar date)//写入芯片
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
scl=0; //当scl 线为低时,才允许sda变化,所以将其拉低
delay();
temp=(temp<<1); //将要发的东西左移到CY位,
sda=CY; // 将要发的数据给sda线
delay();
scl=1; //
delay();
}
scl=0; //当scl线从高到低跳变时,发送一位数据
delay();
}
uchar re_date()//读出芯片的内容 原理和上面写数据差不多。
{
uchar i,num;
for(i=0;i<8;i++)
{
scl=1;
delay();
num=(num<<1)|sda;
delay();
scl=0;
delay();
}
return num;
}
void wr_rea(uchar address,uchar date)//总的写入芯片
{
start(); //开始
wr_date(0xa0); //写要找的器件的地址(现三个地址选择端都是零电位)。
respons(); //应答
wr_date(address); //写器件内部的地址(要写入数据 的地方)
respons(); //
wr_date(date); //写要写 的数据
respons(); //
stop(); //终止信号
}
uchar re_rea(uchar address)//总的读出芯片的内容(和上面差不多)
{
uchar date;
start();
wr_date(0xa0);
respons();
wr_date(address);
respons();
start();
wr_date(0xa1);
respons();
date=re_date();
respons();
stop();
return date;
}
void main()
{
uchar i;
init(); //有没有问题不是很大,但最好有
while(4)
{
for(i=0;i<8;i++) //让流水灯闪烁
{
wr_rea(23,table); //写数据
delay1(100); //写与读之间要相隔一段时间
P0=re_rea(23); // 读数据,赋给P0口
delay1(400);
}
}
}
文章评论(0条评论)
登录后参与讨论