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

📄 slave2.c

📁 pic16 i2c slave (picc)
💻 C
字号:
#include	<pic.H>
#include    "delay.h"

#define		IDLE			0
#define		WAIT_START 		1
#define		START_RECIEV	2
#define		RECIVE			3
#define		NEXT_BYTE		4
#define     ACK             5
#define     WAIT_STOP       6

#define     SCL		RA3
#define     SDA     RA2
#define     SCL_DIR		TRISA0
#define     SDA_DIR     TRISA1

#define     INPUT		1
#define     OUTPUT      0
unsigned char I2C_STAT,Bptr,BitCount,adress,t0cnt;
unsigned char B[4];
bit t0flag;

unsigned char cont_mode,flash_mode,flash_time,pwr_mode;
//eeprom adress
#define 	CONT_ADR	0
#define     FLASH_ADR   1
#define     TIME_ADR    2
//controls
#define     SET_CONT	0x10
#define     SET_FLASH   0x20
#define     SET_TIME    0x30
#define     OFF         0x40
#define     ON          0x50	
//*********************************
#define     READ_CONT   0x10
#define     READ_FLASH  0x20
#define     READ_TIME   0x30

 	

bit I2C_CMD,NEW_TASK;
void I2CLOOP(void);
#define			READ	1
#define         WRITE   0

//__CONFIG  ( MCLREN & UNPROTECT & WDTDIS & PWRTEN & INTIO & LVPDIS  & BORDIS); 
__CONFIG  ( UNPROTECT & WDTDIS & PWRTEN  & LVPDIS  & BOREN & XT); 

#define     FCPU     4000000
#define     FPWM	 20000
#define 	PERIOD	 1/FPWM
#define     PR2VAL   50//PERIOD*FCPU/4
#define     DUTY    10



void interrupt isr(void)
{
	if(INTE && INTF)
	{
		INTF=0;
			CCPR1L = flash_mode >> 2;
			if (flash_mode & 0x02) CCP1X = 1;
			else
			CCP1X = 0;
			if (flash_mode & 0x01) CCP1Y = 1;
			else
			CCP1Y = 0;  
		while (!RB0)
		{}
			CCPR1L = cont_mode >> 2;
			if (cont_mode & 0x02) CCP1X = 1;
			else
			CCP1X = 0;
			if (cont_mode & 0x01) CCP1Y = 1;
			else
			CCP1Y = 0;  
		
	}
	if (TMR0IE && TMR0IF)
	{
	TMR0IF = 0;
	TMR0 = 100;//200us interrupt
	t0flag = 1;
	t0cnt++;
	if (t0cnt > 100) 
	{

		t0cnt = 0;
	}
	}

	
}

void EESAVE(unsigned char adrr,unsigned char data)
{
	EEADR = adrr;
	EEDATA = data;
//	EEPGD = 0;
	WREN = 1;
	GIE = 0;
	EECON2 = 0x55;
	EECON2 = 0xaa;
	WR = 1;
	GIE = 1;
	WREN = 0;
	while (WR)
	{
	}
}

unsigned char EEREAD(unsigned char adrr)
{
	EEADR = adrr;
//	EEPGD = 0;
	RD = 1;
	return EEDATA;
}
void I2CLOOP(void)
{
	switch (I2C_STAT)
	{
		case IDLE:
			if ((SCL) && (SDA)) 
			{
			I2C_STAT = WAIT_START;
			Bptr = 0;
			BitCount = 0;
			}
			break;
		case WAIT_START:
			if ((SCL) && (!SDA)) 
			{
			I2C_STAT = START_RECIEV;
			}
			break;
		case START_RECIEV:
			if (!SCL) 
			{
			I2C_STAT = RECIVE;
			}
			if ((SDA) && (SCL))
			{
			I2C_STAT = IDLE;
			}
			break;
		case RECIVE:
			if (SCL) 
			{
				if (BitCount++ == 8) 
				{
					I2C_STAT = ACK;
				}
				else
				{ 
					I2C_STAT = NEXT_BYTE;
         			B[Bptr] <<= 1;
					if	(SDA) B[Bptr]+=0x01; 
					if (BitCount == 8)
					{
						if ((B[0] & 0x0e) == adress)
						{
							if (B[0] & 0x80) I2C_CMD = READ;
							else
							{
								I2C_CMD = WRITE;
							}
							SDA = 0;
	//						SDA_DIR = OUTPUT;  temporary down
							RA3 = 0;
						}
						else
						{
							I2C_STAT = IDLE;
						}	
					}
				}
			}
			break;
		case NEXT_BYTE:
			if (!SCL) 
			{
				I2C_STAT = RECIVE;
			}	
			break;
		case ACK:				

			if (!SCL)
			{
				I2C_STAT = RECIVE;
				BitCount = 0;
				Bptr ++;
				SDA_DIR = INPUT;
				if (Bptr == 3) 	
				I2C_STAT = WAIT_STOP;
			}

			break;
		case WAIT_STOP:				
			if (SCL)
			{
				I2C_STAT = IDLE;
				NEW_TASK = 1;
			}

			break;
	 }
}


void main(void)
{
	unsigned char t,t1,q;
//CMCON = 0xff;
T0CS = 0;
PSA = 0;//prescale for timer0
PS0 = 0;
PS1 = 0;
PS2 = 0;
ADCON1 = 0x07;
adress = 0x00;
Bptr = 0;
TRISA=0xff;
TRISB3 = 0;
TRISC2 = 0;
RA3 = 1;
NEW_TASK = 0;
T2CON = 0;
TMR2ON = 1;
CCP1M3 = 1;
CCP1M2 = 1;
PR2 = PR2VAL;
RBPU = 0; //set pull ups
INTEDG = 0; //interrup on falling EDGE
INTE = 1; //enable interrupt on RB0
TMR0IF = 0;
TMR0IE = 1; //enable tmr0 int
GIE = 1;
cont_mode = EEREAD(CONT_ADR);
flash_mode = EEREAD(FLASH_ADR);
/*
	CCPR1L = cont_mode >> 2;
	if (cont_mode & 0x02) CCP1X = 1;
	else
	CCP1X = 0;
	if (cont_mode & 0x01) CCP1Y = 1;
	else
	CCP1Y = 0;
*/
			CCPR1L = 0;
			CCP1X = 0;
			CCP1Y = 0;   
RC3 = 0;
TRISC3 = 0;



while(1)
{
if 	(t0flag) 
{
	I2CLOOP();
	t0flag = 0;
}
if (NEW_TASK)
{
	NEW_TASK = 0;
	switch (B[0] & 0xf0)
	{
		case     SET_CONT:
			EESAVE(CONT_ADR,B[2]);		//saves the value recived
			cont_mode = B[2];
			CCPR1L = B[2] >> 2;
			if (B[2] & 0x02) CCP1X = 1;
			else
			CCP1X = 0;
			if (B[2] & 0x01) CCP1Y = 1;
			else
			CCP1Y = 0;  
			break;
		case     SET_FLASH: 
			if (B[2] != 0) 
			{
				EESAVE(FLASH_ADR,B[2]);
				flash_mode = B[2]; 
			}
			else
			{ 
				EESAVE(FLASH_ADR,cont_mode);//store the value of the light if 0 else store value
				flash_mode = cont_mode;
			}   
			break;
		case     SET_TIME:   
			EESAVE(TIME_ADR,B[2]);		// save time
			flash_time = B[2];
			break; 
		case     OFF:
			CCPR1L = 0;
			CCP1X = 0;
			CCP1Y = 0;   
			break;       
		case     ON:   
			CCPR1L = cont_mode >> 2;
			if (cont_mode & 0x02) CCP1X = 1;
			else
			CCP1X = 0;
			if (cont_mode & 0x01) CCP1Y = 1;
			else
			CCP1Y = 0;  		    
			break;
		default:
			break;
	}    

}
}


while(1)
{
for (q = 0; q<200;q++)
{
	CCPR1L = q >> 2;
	if (q & 0x02) CCP1X = 1;
	else
	CCP1X = 0;
	if (q & 0x01) CCP1Y = 1;
	else
	CCP1Y = 0;
	DelayMs(100);
	RC3 = 1;
	DelayMs(8);
	RC3 = 0;
}
}  		    
}

⌨️ 快捷键说明

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