i2c.c

来自「上学时做的一个51单片机按键显示程序」· C语言 代码 · 共 283 行

C
283
字号
/*
* Copyright(c)2005 - 2009 danise .China
* All rights reserved.
* Redistribution and use in source and bianry forms
* with or without modification ,are permitted provided
* that following conditions are met:
* 
* 1.Redistrubution of source code must retain the 
* above copyright notice,this list of conditions and
* following disclaimer.
* 
* 2.Redistributions in binary form must reproduce the 
* above copyright notice,this list of conditions and 
* following disclaimer in the documentation and /or other
* materials provided with the distribution.
* 
* Alternately, this acknowledgment may appear in the software
* itself,if and wherever such third-party acknowledgements
* normally appear.
*
* This software is designed for key board and led display.
* 
	
*/
#include "./include/i2c.h"
#include "./include/global.h"
#include "./include/display.h"
#include "./include/system.h"

UINT8 idata I2CRC = 0;
UINT8 idata i2cbuf[13];
UINT8 idata i2recvbuf[13] ;//= {4,0x22,0x41,0x05};
UINT8 i2cSendOk=0;
UINT8 i2cRecvOk=0;

UINT8 sendindex = 0;
UINT8 recvindex = 0;
UINT16 i2cChkCount=0;

bit RcvByte(UINT8 *c)
{ I2CON = RELEASE_BUS_ACK;     		/* 清除标志位				*/
  while( SI==0 );   				/* 放开总线,等待接收		*/
  if( I2STAT==0xA0 )				/* 接收到停止位或重新启动位 */
  { I2CON = RELEASE_BUS_ACK;		/* 先放开总线,再返回0		*/
    return(0);
  }
  *c = I2DAT;       				/* 取数据					*/
  return(1);
}
/*

*/


bit SendByte(UINT8 c)
{ if( I2STAT==0xC0 )                /* 上次发送数据后,接收到非应答位 */
  { I2CON = RELEASE_BUS_ACK;
    return(0);
  }
  I2DAT = c;       					/* 发送数据					*/
  I2CON = RELEASE_BUS_ACK;  		/* 释放总线					*/
  while( SI==0 ); 					/* 等待字节数据发送完成		*/
  return(1);
}
/*
	
*/
void SetBus(UINT8 addr)
{ I2ADR = addr&0xfe;    	/* 设置从地址不接收广播地址			*/
  I2CON =  RELEASE_BUS_ACK; /* 启动硬件I2C						*/
}

/*
*/
void I2CISR(void) interrupt 6 
{
	bit i2csendresult = 0;
	bit i2crecvresult = 0;
	
	UINT8 temp = 0;
	sendindex = 0;
	recvindex = 0;
	
	CPL932_ET0=0;
	EI2C=0;
	elapsetime = 0;
	I2CRC= 0;
	sreensaveclk = 0; /* clr screen save */
	scrflag = 0;      /* stop screen save */
	switch(I2STAT)
	{
	 	case RDSLA:	while(1)/* Sending */
		 			{ 
						EA =0;
						i2csendresult=SendByte(i2cbuf[sendindex++]);
						EA =1;
						if(!i2csendresult){
							i2cSendOk = 0x1;
							break;
						}
						if( sendindex>i2cbuf[0] ){
							i2cSendOk = 0x1;
							break;							
						}
						if(elapsetime>=40){
							/*1 s*/	
							i2cSendOk=0x0;/* fail testing by time elapse */
							break;
						}
					}
					
			 break;
		case WRSLA: if(0x0 == i2cRecvOk){ //if_1
			        	while(1)/* receiving */
						{// while
							EA =0;
							i2crecvresult= RcvByte(&temp);
							EA =1;
							if(!i2crecvresult){
							//	I2CRC=I2CRC+temp;  /* ? */
								if( 0xff == I2CRC )
									i2cRecvOk = 1;
								else
							 	   i2cRecvOk = 0;
								break;														
							}
							i2recvbuf[recvindex++]=temp;
							I2CRC=I2CRC+temp;
							if(recvindex > i2recvbuf[0]){
								if( I2CRC == 0xff ){
									i2cRecvOk = 1;
								}
								else 
								i2cRecvOk =0;
								break;
								
							}

							if(elapsetime>=50){
								/*1 s*/	
								i2cRecvOk = 0;/* reception testing by time elapse */
								break;
							}	
						
						}//while
					}//if_1
			 break;
		default :break;
	}
 	I2CON = 0x44;
	EI2C=1;
	CPL932_ET0=1;
}
/*
*/
void I2cSendFrame(UINT8 err )
{
	UINT8 idata count = 0;
	LWORD data i;
	i2cSendOk = 0;
	while(count <4 && i2cSendOk == 0 )
	{
		count++;
		INT1 = 1;
		INT1 = 0;  /*pull down the INT1 to make main CPU recognise and start IIC */
		for(i=0;i<20;i++); /*hold 0 for a moment */
		INT1=1;
		for(i=0;i<25000;i++)
		{
			/*kick dog*/
			if(0x1 == i2cSendOk){
				break;
			}
		}
		if(0x0 == i2cSendOk){
			i2cSendOk = 0;
			SparkLights( LIGHT_PROBLEM );
			error( err );			
		}
	}	
}
void RegisterMachine(void)
{
	memset(i2cbuf,0,13);
	i2cbuf[0] = 0x2;
	i2cbuf[1] = 0xaa;
	i2cbuf[2] = 0x53;
	I2cSendFrame(0x0c);
}

void ProcessI2cRecvFrame(void)
{
	UINT8 cmd = 0;
	bit	 isdot;
	bit  updown;
	if(0x1 == i2cRecvOk){	
		Enter_Critical_OS();
		i2cRecvOk=0x0; /* clear the singal for next packet */
		Exit_Critical_OS();	
		cmd = i2recvbuf[1];		
		switch( cmd )
		{
			case 0x01:	ClearUpLeds();RESETLEDSHOWSTR();
				break;
			case 0x02:	ClearDownLeds();RESETLEDSHOWSTR();
				break;
			case 0x22:  FillStruLed( i2recvbuf+2 ,2,0 );
						memcpy(&scrsavebuf[8],&LedsShowStr.ledbuf[4],4);
						UpateLeds( POSITION_DOWN );
						RESETLEDSHOWSTR();
				 break;
			case 0x66:  FillStruLed( i2recvbuf+2 ,1,0 );
						LedsShowStr.ledbuf[5]=14; /*show H0 X*/
						UpateLeds( POSITION_UP );
						RESETLEDSHOWSTR();					
			     break;
			case 0xbb:
						if( TestBit(i2recvbuf[2],7 )) isdot= 1;							
						else isdot= 0;
						if(TestBit(i2recvbuf[2],6 ))  updown=0;
						else updown = 1;
						SparkLights(i2recvbuf[2]);
						FillStruLed(i2recvbuf+3,i2recvbuf[0]-3,isdot );								
						UpateLeds(updown);	
						RESETLEDSHOWSTR();
						
				 break;	
	        default : break;	

		}	
		
	}
}
/*

*/
void FillStruLed(UINT8 *buf,UINT8 len, bit isdot )
{
	INT8 idata i;
	UINT8 idata j = LED_MAX_NUM -1;
	if(len ==0){
		LedsShowStr.isdot = 0;
		LedsShowStr.dotposition = LED_MAX_NUM-1;
		memset(&LedsShowStr.ledbuf[0],17, LED_MAX_NUM );
		return;
	}
	if( isdot ){
		LedsShowStr.isdot = 1;
		LedsShowStr.dotposition = 0x5;
	}
	else{
			LedsShowStr.isdot = 0;
			LedsShowStr.dotposition = LED_MAX_NUM-1;
	}
	LedsShowStr.length = len*2 ;
	memset(&LedsShowStr.ledbuf[0],0, LED_MAX_NUM );
	for(i= len-1;i>=0;i--)
	{
		LedsShowStr.ledbuf[j--] = buf[i] & 0x0f; 
		LedsShowStr.ledbuf[j--] = buf[i] >> 4;
	}
	/* add E ->EEE */
	/*when error code */
	if(0x1 == len){
	   LedsShowStr.ledbuf[5] = 12;	
	}

	

}
bit TestBit(UINT8 dat,UINT8 n)
{
	UINT8 temp;
	temp = dat;
	temp = temp >> n;
	temp = temp & 0x01;
	if(temp)
		return 1;
	else
		return 0;
	
}

⌨️ 快捷键说明

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