⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 24c01.c

📁 PC端发送3个数据 n0,n1,n2 n0=0,写
💻 C
字号:
/**************************************************

;24C01.C
 
;功能描述:
;PC端发送3个数据 n0,n1,n2
;n0=0,写,将n1写入n2地址中
;n0=1,读,读出n1地址中的数据,n2不起作用,但必须有
;收到一个字节后,将其地址值显示在数码管第1、2位上,数值显示在第5、6位上
;读出一个字节后,将其地址值显示在数码管第1、2位上,读出的值显示在第5、6位上
;**************************************************/
#define uchar unsigned char
#define uint  unsigned int
#define Slaw	0x0a;	//写命令字
#define Slar	0xa1;	//读命令字
#include "reg52.h"
#include "intrins.h"

	sbit	Scl=P3^6;	//串行时钟
	sbit	Sda=P3^7;	//串行数据


	bit	Rec;		//接收到数据的标志
	uchar	RecBuf[3];	//接收缓冲区

#define Hidden 0x10;	//消隐字符在字形码表中的位置
uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};
uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xFF};
uchar DispBuf[6];	//6字节的显示缓冲区

uchar code TH0Val=63266/256;
uchar code TL0Val=63266%256;//当晶振为11.0592时,定时2.5ms的定时器初值

//以下是中断程序,用于显示
void Timer0() interrupt 1
{	uchar tmp;
	static uchar 	dCount;	//计数器,显示程序通过它得知现正显示哪个数码管
	TH0=TH0Val;
	TL0=TL0Val;	
	tmp=BitTab[dCount];		//根据当前的计数值取位值
	P2=P2|0xfc;				//P2与11111100B相或,将高6位置1
	P2=P2&tmp;				//P2与取出的位值相与,将某一位清零
	tmp=DispBuf[dCount];	//根据当前的计数值取显示缓冲待显示值	
	tmp=DispTab[tmp];		//取字形码
	P0=tmp;					//送出字形码
	dCount++;				//计数值加1
	if(dCount==6)			//如果计数值等于6,则让其回0
		dCount=0;	
}

/*发送起始条件*/
void Start(void)        /*起始条件*/
{
        Sda=1;
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Sda=0;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
}
void Stop(void) /*停止条件*/
{
        Sda=0;
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Sda=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
}
void Ack(void)  /*应答位*/
{
        Sda=0;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=0;
}
void  NoAck(void)       /*反向应答位*/
{
        Sda=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=1;
        _nop_ ();
        _nop_ ();
        _nop_ ();
        _nop_ ();
        Scl=0;
}
void Send(uchar Data)   /*发送数据子程序,Data为要求发送的数据*/
{
        uchar BitCounter=8;       /*位数控制*/
        uchar temp;     /*中间变量控制*/
        do
        {
           temp=Data;
           Scl=0;
           _nop_ ();
           _nop_ ();
           _nop_ ();
           _nop_ ();
           if((temp&0x80)==0x80)/* 如果最高位是1*/
                Sda=1;
           else
                Sda=0;
           Scl=1;
           temp=Data<<1;        /*RLC*/
           Data=temp;
           BitCounter--;
         }while(BitCounter);
         Scl=0;
}
uchar Read(void) /*读一个字节的数据,并返回该字节值*/
{
        uchar temp=0;
        uchar temp1=0;
        uchar BitCounter=8;
        Sda=1;
        do{
          Scl=0;
          _nop_ ();
          _nop_ ();
          _nop_ ();
          _nop_ ();
          Scl=1;
          _nop_ ();
          _nop_ ();
          _nop_ ();
          _nop_ ();
          if(Sda)       /*如果Sda=1;*/
                temp=temp|0x01;  /*temp的最低位置1*/
          else
                temp=temp&0xfe;  /*否则temp的最低位清0*/
          if(BitCounter-1)
          {   temp1=temp<<1;
              temp=temp1;
          }
          BitCounter--;
        }while(BitCounter);
        return(temp);
}
void WrToROM(uchar Data[],uchar Address,uchar Num)
{
     uchar i=0;
     uchar *PData;
     PData=Data;
     Start();        
     Send(0xa0);    
     Ack();
     Send(Address);  
     Ack();
     for(i=0;i<Num;i++)
     {
        Send(*(PData+i));
        Ack();
     }
     Stop();
}
void  RdFromROM(uchar Data[],uchar Address,uchar Num)
{
     uchar i=0;
     uchar *PData;
     PData=Data;
     for(i=0;i<Num;i++)
     {
        Start();
        Send(0xa0);
        Ack();
        Send(Address+i);
        Ack();
        Start();
        Send(0xa1);
        Ack();
        *(PData+i)=Read();
        Scl=0;
        NoAck();
        Stop();
   }
}

void Recive() interrupt 4	//串行中断程序
{	static uchar Count=0;
	if(TI)
	{	TI=0;
		return;	//如果是发送中断,直接退出
	}
	RI=0;		//清RI标志
	RecBuf[Count]=SBUF;
	Count++;
	Rec=0;
	if(Count>=3)
	{	Count=0;
		Rec=1;		//置位标志
	}
}

void Init()
{	TMOD=0x21;
	RI=0;
	TH1=0xfd;
	TL1=0xfd;
	PCON|=0x80;
	TR1=1;
	SCON=0x50;

	TH0=TH0Val;
	TL0=TL0Val;	
	ET0=1;				//开T0中断
	EA=1;				//开总中断
	ES=1;
	TR0=1;				//T0开始运行
	TR1=1;
}

void Calc(uchar Dat1,uchar Dat2)	//第一个参数放在第1、2位,第二个参数放入第5、6位
{	DispBuf[0]=Dat1/16;
	DispBuf[1]=Dat1%16;

	DispBuf[4]=Dat2/16;
	DispBuf[5]=Dat2%16;
}
	
void main()
{	uchar	RomDat[4];
	Init();							//初始化
	DispBuf[2]=Hidden;
	DispBuf[3]=Hidden;
	for(;;)
	{			
		Calc(RecBuf[1],RomDat[0]);	//分别显示地址和数据
		if(Rec)						//接收到数据
		{	Rec=0;					//清除标志
			if(RecBuf[0]==0)		//第一种功能,写入
			{	RomDat[0]=RecBuf[2];
				WrToROM(RomDat,RecBuf[1],1);
				SBUF=RomDat[0];	
			}
			else
			{	RdFromROM(RomDat,RecBuf[1],1);
				SBUF=RomDat[0];
			}
		}
	}
}	


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -