// PIC I2C SLAVE COMPONENT // counter & adc & port-I/O // // ver 1.0 2025-10-4 for PIC16F1938 // #include "16F1938.H" #fuses INTRC_IO,NOWDT,NOMCLR,NOBROWNOUT,NOLVP,PUT #device ADC=10 #use I2C(slave,fast,sda=PIN_C4,scl=PIN_C3,address=0xa0,force_hw) #use delay(internal=32MHz) #use fast_io(A) #use fast_io(B) #use fast_io(C) unsigned int16 old_time; unsigned int16 upper_time; unsigned int16 lower_time; unsigned int16 trans_word16; int count_flag = 1; int16 get_ad() { int1 done; int16 value; read_adc(ADC_START_ONLY); done = adc_done(); while(!done) done=adc_done(); value=read_adc(ADC_READ_ONLY); return(value); } #INT_SSP void ssp_interupt (){ int code,adrs,state; state=i2c_isr_state(); if(state>=0x80) //addrs match with master read { if(state==0x80) i2c_write((trans_word16 >> 8)&0xff); else i2c_write(trans_word16 & 0xff); } else if(state >0){ //adrs match with master write code=i2c_read(1); switch(code){ case 0x00: // counter reset & count run set_timer1(1); count_flag = 1; old_time = 0; upper_time = 0; lower_time = 0; break; case 0x01: // stop counter if(count_flag){ lower_time=(unsigned int16)get_timer1(); if(old_time > lower_time) upper_time++; } count_flag = 0; break; case 0x02: // upper time set trans_word16 = upper_time; break; case 0x03: // lower time set trans_word16 = lower_time; break; case 0x10: // ADC CH0 case 0x11: // ADC CH1 case 0x12: // ADC CH2 case 0x13: // ADC CH3 set_adc_channel(code-0x10); trans_word16 = get_ad(); trans_word16 = trans_word16 << 2; break; case 0x20:trans_word16 = input_b(); break; case 0x30:output_low(PIN_B0); break; case 0x31:output_high(PIN_B0); break; case 0x32:output_low(PIN_B1); break; case 0x33:output_high(PIN_B1); break; default:break; } } else adrs = i2c_read(1); } void io_select() { set_tris_a(0xff); set_tris_b(0xff); set_tris_c(0xff); setup_timer_1(T1_EXTERNAL); set_timer1(0); setup_adc(ADC_CLOCK_INTERNAL); setup_adc_ports(sAN0 | sAN1 | sAN2 | sAN3); set_adc_channel(0); port_b_pullups(0xfc); output_drive(PIN_B0);output_high(PIN_B0); output_drive(PIN_B1);output_high(PIN_B1); output_float(PIN_C4); //I2C SDA pin float output_float(PIN_C3); //I2C SCL pin float } void main() { unsigned int16 f; setup_oscillator(OSC_8MHZ | OSC_PLL_ON); io_select(); count_flag = 1; // count available old_time = upper_time = lower_time = 0; set_timer1(0); enable_interrupts(INT_SSP); enable_interrupts(GLOBAL); while(1){ if(count_flag){ f = get_timer1(); if(old_time>f) upper_time++; old_time = lower_time = f; delay_ms(1); } } }