//************************************************************ // Easy SD Logger 3 // // Used Microchip Memory Disk Drive File System:FAT16 // // LCD unlook busy : not switch direction (write fixed) // RTC: RTC8564 // // ADサンプル間隔: 1秒(rtcの外部同期用1秒パルスによりint0割込み) // SDカードへの収録間隔:1分 // SDカードへの収録データ数:1441データascii(16byte/1dataなので、23056Byte) // SDカードへの収録時間:24時間((1441-1)/60分= 24時間) // AD Input: CH1(DC 0 - 3V) // // CPU dsPIC30F4013(Program Memory:48kBytes) // 7.37MHz Internal RC oscillator, 16x PLL enabled // Fcy=7.37MHzx16/4=29.48MHz, Tcy=33.92ns // // 作成年月日 // 2022/9/27: N.Ishii //************************************************************* /* Addition to MPLAB Project File (Be connected File System) */ // Source Files Folder FSIO.c // SD-SPI.c // easy_sd_logger_2.c // Header Files Folder FScohfig.h // FSDefs.h // FSIO.h // GenericTypeDefs.h // SD-SPI.h // Linker Script Folder p30f4013.gld* #include #include "stdio.h" #include "timer.h" #include "adc12.h" #include "FSIO.h" //-------------------------------------------------------------- // Divice configuration _FWDT(WDT_OFF); _FGS(CODE_PROT_OFF); _FOSC(CSW_FSCM_OFF & FRC_PLL16); //OSC, PLL Setting _FBORPOR(PBOR_OFF & PWRT_64 & MCLR_EN); //---------------------------------------------------------------- // A/D control register unsigned int _ADCON1; unsigned int _ADCON2; unsigned int _ADCON3; unsigned int _ADCHS; unsigned int _ADPCFG; unsigned int _ADCSSL ; //-------------------------------------------------------------- // message table char msg1[] = {" V\0"}; char msg2[] = {"/ 1441\0"}; char msg3[] = {"Write NG !!\0"}; char msg4[] = {"SD Not Mount\0"}; char msg5[] = {"Initial OK !!\0"}; char msg6[] = {"Write OK !!\0"}; char msg7[] = {"REC:\0"}; char msg8[] = {"Writing!\0"}; char msg9[] = {"0000\0"}; /// message table for RTC char msg10[] = {"20\0"}; // Years 20** char msg11[] = {"SUN\0"}; // Weekdays char msg12[] = {"MON\0"}; char msg13[] = {"TUE\0"}; char msg14[] = {"WED\0"}; char msg15[] = {"THU\0"}; char msg16[] = {"FRI\0"}; char msg17[] = {"SAT\0"}; //------------------------------------------------------------------------------ // LCD Define: R/W_pin= GND (Fixed Write) #define LCD_DATA_WR_MODE LATFbits.LATF1 = 1 // RS_pin = 1 #define LCD_INST_WR_MODE LATFbits.LATF1 = 0 // RS_pin = 0 #define LCD_ENABLE_ON LATFbits.LATF0 = 1 #define LCD_ENABLE_OFF LATFbits.LATF0 = 0 #define LCD_DATA_BIT4 LATBbits.LATB9 #define LCD_DATA_BIT5 LATBbits.LATB10 #define LCD_DATA_BIT6 LATBbits.LATB11 #define LCD_DATA_BIT7 LATBbits.LATB12 //--------------------------------------------------------------------------------------------- // LCD Instraction Code #define FOUR_BIT_FONT5x7dot 0x28 // + TWO_LINE(1/16Duty), SEG1_50_SEG51_100, COM1_COM16 #define DISP_ON_CURSOR_ON_BLINK_OFF 0x0e #define DISP_CLEAR_CURSOR_HOME 0x01 #define RAM_WR_AFTER_PLUS_1 0x06 // Entory mode set #define DDRAM_START_ADDRESS_SET 0x80 #define DISP_ON_CURSOR_OFF_BLINK_OFF 0x0c //--------------------------------------------------------------------------------------------- // SD Define #define SD_CS_ENABLE PORTBbits.RB2 = 0 // CS_pin = 0 #define SD_CS_DISABLE PORTBbits.RB2 = 1 // CS_pin = 1 //--------------------------------------------------------------------------------------------- // RTC-I2C define #define RTC8564_SLVADRS_WR 0xa2 #define RTC8564_SLVADRS_RD 0xa3 #define SDA_OUT LATFbits.LATF5 #define SCL_OUT LATFbits.LATF4 #define SDA_IN PORTFbits.RF5 //--------------------------------------------------------------------------------------------- #define CR 0x0d #define LF 0x0a //---------------------------------------------------- FSFILE *pfile; // Structure Pointer for FAT File // RTC関連 unsigned char digit[3]; unsigned int Sec; /// SD, ADC関連 unsigned int Buf_Input[1]; // Write Vol for SD Card unsigned int sample_set= 1441; // 24時間収録 int N_Write; // The Number of Write Times unsigned int Ix; // adc data unsigned int ResultData; float Volt; unsigned int Volt_int; /// その他 unsigned char sw1_m0; unsigned char sw1_m1; unsigned char sw1_m2; unsigned char sw2_m0; unsigned char sw2_m1; unsigned char sw2_m2; unsigned char sw3_m0; // sw3は、時計合わせの時のみ、entreyキーとして使用、収録stopは長押しにした。 unsigned char sw3_m1; unsigned char sw3_m2; unsigned char sw1_on_flag; unsigned char minute_flag; unsigned char Logging_mode_flag; // '1'=ロギング画面表示 '0'=通常画面表示 //------------------------------------------------------------------------- /// initialize RTC8564 Side Reg Write Data unsigned char rtc_write_data_tbl[] = { 0x20, // [0]:Control1REG: Time Stop 0x00, // [1]:Control2REG: ALM INT.TIMMER INT Desable 0x00, // [2]:SecondsREG: Set 0 Set 0x00, // [3]:MinutesREG: Set 0 Min 0x00, // [4]:HourREG: Set 0 Hour 0x15, // [5]:DayREG 0x02, // [6]:WeekdaysREG: TUE 0x06, // [7]:MonthsREG 0x10, // [8]:YearsREG 0x80, // [9]:Minute_AlamREG: Not Used ALM Interrupt 0x80, // [10]:Hour_AlamREG 0x80, // [11]:Day_AlamREG 0x80, // [12]:Weekday_AlamREG 0x83, // [13]:CLKOUT_frequencyREG: Set 1Hz Output ON 0x00, // [14]:Timer_contorolREG: Not Used Timer Interrupt 0x01 // [15]:Timer_downcount Set Vule }; unsigned char rec_data[16]; // RTCからの受信(読込み)データバッファ ///------------------------------------------------------------------------------------------------------ /// 1サンプル毎の収録バイト数:16バイト // For SD Data Format unsigned char SD_write_data[] = { 0x00, // [0]:Hour 0x00, // [1]: 0x3a, // [2]:':' 0x00, // [3]:Minute 0x00, // [4]: 0x3a, // [5]:':' 0x00, // [6]:Seconds 0x00, // [7]: 0x2c, // [8]:',' 0x00, // [9]:Volt 0x2e, // [10]:'.' 0x00, // [11]: 0x00, // [12]: 0x00, // [13]: CR, // [14]: LF // [15]: }; //------------------------------------------------------------------------------------------------------------- // Delay Subrutin void Waitx1ms(int x) // Td = 1mS * x { int i,j; for(i = 0 ; i < x ; ++i) { for(j = 0 ; j < 5000 ; ++j) asm("clrwdt"); //Td=1mS } } void Waitx1us(int x) // Td = 1uS * x { int i,j; for(i = 0 ; i < x ; ++i) { for(j = 0 ; j < 5 ; ++j) asm("clrwdt"); //Td=1uS } } //-------------------------------------------------------------------- void one_chr_wr(char chr_code) { LCD_DATA_WR_MODE; //RS_pin = 1: select data Reg // A Higher 4bit data out LCD_DATA_BIT7 = (unsigned int)((chr_code & 0x80)>>7); LCD_DATA_BIT6 = (unsigned int)((chr_code & 0x40)>>6); LCD_DATA_BIT5 = (unsigned int)((chr_code & 0x20)>>5); LCD_DATA_BIT4 = (unsigned int)((chr_code & 0x10)>>4); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; // A Lower 4bit data out LCD_DATA_BIT7 = (unsigned int)((chr_code & 0x08)>>3); LCD_DATA_BIT6 = (unsigned int)((chr_code & 0x04)>>2); LCD_DATA_BIT5 = (unsigned int)((chr_code & 0x02)>>1); LCD_DATA_BIT4 = (unsigned int)(chr_code & 0x01); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1us(50); } void lcd_chr_wr(char *buffer) { while(*buffer != '\0') { one_chr_wr(*buffer); /* calling another function */ /* to write each char to the lcd module */ buffer++; } } void lcd_inst_wr(char inst_code) { LCD_INST_WR_MODE; //RS_pin = 0: select Instruction Reg // A Higher 4bit data out LCD_DATA_BIT7 = (unsigned int)((inst_code & 0x80)>>7); LCD_DATA_BIT6 = (unsigned int)((inst_code & 0x40)>>6); LCD_DATA_BIT5 = (unsigned int)((inst_code & 0x20)>>5); LCD_DATA_BIT4 = (unsigned int)((inst_code & 0x10)>>4); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; // A Lower 4bit data out LCD_DATA_BIT7 = (unsigned int)((inst_code & 0x08)>>3); LCD_DATA_BIT6 = (unsigned int)((inst_code & 0x04)>>2); LCD_DATA_BIT5 = (unsigned int)((inst_code & 0x02)>>1); LCD_DATA_BIT4 = (unsigned int)(inst_code & 0x01); Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; if ((inst_code & 0x03) != 0) Waitx1ms(20); // inst_code is Clear(0x01) or Cursor Home(0x02) Then Wait 20mS else Waitx1us(50); // other code Then Wait 50uS } void lcd_init(void) { // Allow a delay(minimum of 15ms) Waitx1ms(20); //------ 1st step: port_output regster set -------------- // Initialize the data port/control pins to zero LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 0; LCD_DATA_BIT4 = 0; LCD_INST_WR_MODE; //RS_pin = 0 LCD_ENABLE_OFF; //E_pin = 0 //-------------------------------------------------------- // dsPIC30F4013 //------- 2nd step: port_mode regster set --------------- // Configure the data pins as output TRISBbits.TRISB9 =0; // RB9 is LCD DB4 OUTPUT TRISBbits.TRISB10 =0; // RB10 is LCD DB5 OUTPUT TRISBbits.TRISB11 =0; // RB11 is LCD DB6 OUTPUT TRISBbits.TRISB12 =0; // RB12 is LCD DB7 OUTPUT // Make all control pins as outputs TRISFbits.TRISF0 =0; // RF0 is LCD Enable OUTPUT TRISFbits.TRISF1 =0; // RF1 is LCD RS OUTPUT //------------------------------------------------------- // Initialize stage 1: Set stage 1 only 8-bit Interface // Set Upper 4 Bit Data on RB9 - RB12 LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 1; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(5); // Initialize stage 2: Set stage 2 only 8-bit Interface LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 1; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(1); // Initialize stage 3: Set stage 3 only 8-bit Interface LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 1; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(1); // Initialize stage 4: 4-bit Interface LCD_DATA_BIT7 = 0; LCD_DATA_BIT6 = 0; LCD_DATA_BIT5 = 1; LCD_DATA_BIT4 = 0; Waitx1us(1); LCD_ENABLE_ON; Waitx1us(1); LCD_ENABLE_OFF; Waitx1ms(1); //----- Fixed LCD Setting------------ lcd_inst_wr(FOUR_BIT_FONT5x7dot); // Function Set lcd_inst_wr(DISP_ON_CURSOR_ON_BLINK_OFF); lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); // Set DDRAM Address = 0 lcd_inst_wr(RAM_WR_AFTER_PLUS_1); // Entry mode Set } //------------------------------------------------------------------------- void const_lcd_disp(void) { // Initialize RTC Screen LCD Disp lcd_inst_wr(0x80); lcd_chr_wr(msg10); // '20' const disp1 220921 lcd_inst_wr(0x84); one_chr_wr(0x2f); // '/' const disp2 lcd_inst_wr(0x87); one_chr_wr(0x2f); // '/' const disp3 lcd_inst_wr(0x87); one_chr_wr(0x2f); // '/' const disp3 lcd_inst_wr(0x8a); one_chr_wr(0x28); // '(' const disp4 lcd_inst_wr(0x8e); one_chr_wr(0x29); // ')' const disp5 lcd_inst_wr(0xc2); one_chr_wr(0x3a); // ':' const disp6 lcd_inst_wr(0xc5); one_chr_wr(0x3a); // ':' const disp6 } void lcd_volt_disp(void) { // digit[3] disp lcd_inst_wr(0xC9); one_chr_wr((Volt_int/100)/10 | 0x30); // '.' decimal point disp one_chr_wr(0x2e); // '.' decimal point disp // digit[2]-[0] disp one_chr_wr((Volt_int/100)%10 | 0x30); one_chr_wr((Volt_int/10)%10 | 0x30); one_chr_wr(Volt_int%10 | 0x30); // unit disp:' V' lcd_chr_wr(msg1); } void lcd_REC_disp(void) { // Number of REC Data lcd_inst_wr(0x84); one_chr_wr(((Ix+1)/100)/10 | 0x30); one_chr_wr(((Ix+1)/100)%10 | 0x30); one_chr_wr(((Ix+1)/10)%10 | 0x30); one_chr_wr((Ix+1)%10 | 0x30); } void line_clear(char clear_position , char clear_vol) { unsigned char i; lcd_inst_wr(clear_position); for (i = 0 ; i != clear_vol ; i++) {one_chr_wr(0x20);} // ' ' disp } //------------------------------------------------------------------------ void RTC_variable_disp(unsigned char Vol, unsigned char loc) { // Vol(BCD): 0x00-0x59( 00-59 Disp) unsigned char ascii[2]; // BCD_to_Ascii ascii[0] = (Vol & 0x0f) | 0x30; ascii[1] = ((Vol >> 4) & 0x0f) | 0x30; // LCD Disp lcd_inst_wr(loc); one_chr_wr(ascii[1]); one_chr_wr(ascii[0]); } /************************************************** * カレンダ時計関係変数部lcd表示関数 * 通常画面表示モードの時は、カレンダ時計表示 * ロギング画面表示モードの時は2行目の時刻のみ表示 ***************************************************/ void variable_lcd_disp(void) { if (Logging_mode_flag != 1) { RTC_variable_disp(rec_data[8], 0x82); // Years: 10 RTC_variable_disp(rec_data[7] & 0x1f, 0x85); // Months: 1-12 (Noise mask: AND 1Fh Add 0613) RTC_variable_disp(rec_data[5] & 0x3f, 0x88); // Day: 1-31 lcd_inst_wr(0x8b); if ((rec_data[6] & 0x07) == 0) {lcd_chr_wr(msg11);} // 'SUN' if ((rec_data[6] & 0x07) == 1) {lcd_chr_wr(msg12);} // 'MON' if ((rec_data[6] & 0x07) == 2) {lcd_chr_wr(msg13);} // 'TUE' if ((rec_data[6] & 0x07) == 3) {lcd_chr_wr(msg14);} // 'WED' if ((rec_data[6] & 0x07) == 4) {lcd_chr_wr(msg15);} // 'THU' if ((rec_data[6] & 0x07) == 5) {lcd_chr_wr(msg16);} // 'FRI' if ((rec_data[6] & 0x07) == 6) {lcd_chr_wr(msg17);} // 'SAT' } RTC_variable_disp(rec_data[4] & 0x3f, 0xc0); // Hour: 0-24 RTC_variable_disp(rec_data[3] & 0x7f, 0xc3); // Minutes: 0-59 RTC_variable_disp(rec_data[2] & 0x7f, 0xc6); // Seconds: 0-59 } void time_set_disp(unsigned char Vol, unsigned char loc) { // Vol: 0x00-0xff( 000-255 Disp) unsigned char i; unsigned char digit[3]; unsigned char ascii[3]; // Bin_to_pacdec digit[0] = Vol%10; digit[1] = (Vol/10)%10; // Decimal_to_ascii for (i = 0; i <= 1; ++i) {ascii[i] = digit[i] | 0x30;} // LCD Disp lcd_inst_wr(loc); one_chr_wr(ascii[1]); one_chr_wr(ascii[0]); } unsigned char bin_to_bcd(unsigned char Vol) { return(Vol + 6 * (Vol/10)); } //------------------------------------------------------------------------------ // I2C Sub routine void i2c_write(unsigned char send_data) { unsigned char i; for (i = 0; i <= 7; ++i) { if (( send_data & 0x80) == 0) SDA_OUT = 0; else SDA_OUT = 1; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SCL_OUT = 0; send_data <<= 1; } } unsigned char i2c_read(void) { unsigned char i; unsigned char read_data; TRISFbits.TRISF5=1; // RF5 is SDA Input for (i = 0; i <= 7; ++i) { read_data <<= 1; Waitx1us(5); // Add 1002 read_data |= SDA_IN; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SCL_OUT = 0; } return(read_data); } void receive_ack(void) { TRISFbits.TRISF5=1; // RF5 is SDA Hi-Z(input) Waitx1us(5); SCL_OUT = 1; while(SDA_IN != 0); // Wait ACK Waitx1us(5); SCL_OUT = 0; TRISFbits.TRISF5=0; // RF5 is SDA output } //------------------------------------------------------------------------------------ void i2c_write_sr(unsigned char start_adrs, unsigned char end_adrs) { unsigned char i; // START Bus Event TRISFbits.TRISF4=0; // RF4 is SCL output TRISFbits.TRISF5=0; // RF5 is SDA output SCL_OUT = 1; SDA_OUT = 1; Waitx1us(5); SDA_OUT = 0; Waitx1us(5); SCL_OUT = 0; // Send Slave Address + Writebit i2c_write(RTC8564_SLVADRS_WR); // Receive ACK From RTC8564 receive_ack(); // Send Write Top Address i2c_write(start_adrs); // Receive ACK From RTC8564 receive_ack(); // Send RTC_REG Write Data (Write Address Auto Incriment) for (i = start_adrs; i != end_adrs + 1; ++i) { i2c_write(rtc_write_data_tbl[i]); // Receive ACK From RTC8564 receive_ack(); } // Stop Bus Event SDA_OUT = 0; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SDA_OUT = 1; TRISFbits.TRISF4=1; // RF4 is SCL Hi-Z TRISFbits.TRISF5=1; // RF5 is SDA Hi-Z Waitx1us(200); // Delay for 200uS (needs > 1.3uS next start) } void i2c_read_sr(unsigned char start_adrs, unsigned char end_adrs) { unsigned char i; // START Bus Event TRISFbits.TRISF4=0; // RF4 is SCL output TRISFbits.TRISF5=0; // RF5 is SDA output SCL_OUT = 1; SDA_OUT = 1; Waitx1us(5); SDA_OUT = 0; Waitx1us(5); SCL_OUT = 0; // Send Slave Address + Writebit i2c_write(RTC8564_SLVADRS_WR); // Receive ACK From RTC8564 receive_ack(); // Send Read Start Address i2c_write(start_adrs); // Receive ACK From RTC8564 receive_ack(); // RESTART Bus Event SDA_OUT = 1; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SDA_OUT = 0; Waitx1us(5); SCL_OUT = 0; // Send Slave Address + Readbit i2c_write(RTC8564_SLVADRS_RD); // Receive ACK From RTC8564 receive_ack(); // Receive RTC_REG Read Data (Read Address Auto Incriment) for (i = start_adrs; i != end_adrs + 1; ++i) { rec_data[i] = i2c_read(); // Send ACK From PIC if (i != end_adrs) { TRISFbits.TRISF5=0; // RF5 is SDA output SDA_OUT = 0; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SCL_OUT = 0; } } // Send NACK From PIC: End of Rx TRISFbits.TRISF5=0; // RF5 is SDA output SDA_OUT = 1; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SCL_OUT = 0; // Stop Bus Event SDA_OUT = 0; Waitx1us(5); SCL_OUT = 1; Waitx1us(5); SDA_OUT = 1; TRISFbits.TRISF4=1; // RF4 is SCL Hi-Z TRISFbits.TRISF5=1; // RF5 is SDA Hi-Z Waitx1us(200); // Delay for 200uS (needs > 1.3uS next start) } //------------------------------------------------------------------------ /************************************************************* * I2C受信データをascii変換し、SD書込みバッファに転送 * <I2C受信データ> * @ RTC * A 電池電圧 **************************************************************/ void forward_rec_data(void) { // RTC Data SD_write_data[0] = (((rec_data[4] & 0x3f) >> 4) & 0x0f) | 0x30; // Hour SD_write_data[1] = ((rec_data[4] & 0x3f) & 0x0f) | 0x30; // SD_write_data[3] = (((rec_data[3] & 0x7f) >> 4) & 0x0f) | 0x30; // Minute SD_write_data[4] = ((rec_data[3] & 0x7f) & 0x0f) | 0x30; // SD_write_data[6] = (((rec_data[2] & 0x7f) >> 4) & 0x0f) | 0x30; // Seconds SD_write_data[7] = ((rec_data[2] & 0x7f) & 0x0f) | 0x30; // // Volt_Data SD_write_data[9] = (Volt_int/100)/10 | 0x30; SD_write_data[11] = (Volt_int/100)%10 | 0x30; SD_write_data[12] = (Volt_int/10)%10 | 0x30; SD_write_data[13] = Volt_int%10 | 0x30; } /******************************************************** * SDへの書込み関数 *********************************************************/ void logging_rec_sr(void) { unsigned char i; forward_rec_data(); // I2C受信データをascii変換し、SD書込みバッファに転送 lcd_REC_disp(); // ロギング中のデータ数を表示:xxxx if (Ix < sample_set) { // Example: When sample_set is 16-> True is Ix = 0 - 15(Packet) for (i = 0; i < 16; i++) { // 1Data@16Byte // File in Write Data Buf_Input[0] = SD_write_data[i]; N_Write = FSfwrite((const void*)Buf_Input , sizeof(unsigned int) , 1 , pfile); if (N_Write != 1) { // Write NG lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg3); // 'Write NG !!' Disp IEC0bits.INT0IE = 0; // Desable INT0 Interrupt Service Routine DISICNT = 0x0001; // Dsable Interrupt FSfclose(pfile); // File Close SD_CS_DISABLE; // CS = 1 LATDbits.LATD2 = 1; // EXT_Red LED OFF while(1); } } ++Ix; } if ((Ix == sample_set) || (PORTDbits.RD3 == 0)) { // Ixが指定データ数に達するか、SW3が押されたらファイルをクローズして収録を終了する // SD Write End LATDbits.LATD2 = 1; // EXT_Red LED OFF Ix = 0; sw1_on_flag = 0; FSfclose(pfile); // File Close SD_CS_DISABLE; // CS = 1 } } //------------------------------------------------------------------------------------ // SW Read:220918 void sw_read(void) { sw1_m0 = PORTBbits.RB0; //New SW1 Data sw1_m2 = sw1_m1^(sw1_m0 & sw1_m1); //Neg_Edge Sence SW1 sw1_m1 = sw1_m0; //Chenge New Data to Old Data m1 sw2_m0 = PORTBbits.RB8; //New SW2 Data sw2_m2 = sw2_m1^(sw2_m0 & sw2_m1); //Neg_Edge Sence SW2 sw2_m1 = sw2_m0; //Chenge New Data to Old Data m1 sw3_m0 = PORTDbits.RD3; //New SW3 Data sw3_m2 = sw3_m1^(sw3_m0 & sw3_m1); //Neg_Edge Sence SW3 sw3_m1 = sw3_m0; //Chenge New Data to Old Data m1 } void time_adjust_mode(void) { unsigned char blink_location_tbl[] = { 0x83, // Year 0x86, // Months 0x89, // Days 0x8d, // Weekdays 0xc1, // Hour 0xc4, // Minute 0xc7 // Seconds }; unsigned char time_set_end; unsigned char sw1_count; unsigned char year_set,months_set,days_set,weekdays_set; unsigned char hour_set,minute_set,seconds_set; sw1_count = 0; year_set=months_set=days_set=weekdays_set=0; hour_set=minute_set=seconds_set=0; const_lcd_disp(); // '20xx/ / ...etc // initial time_set_mode all zero LCD Disp time_set_disp(year_set,0x82); time_set_disp(months_set,0x85); time_set_disp(days_set,0x88); time_set_disp(weekdays_set,0x8c); time_set_disp(hour_set,0xc0); time_set_disp(minute_set,0xc3); time_set_disp(seconds_set,0xc6); // Read SW Loop while(time_set_end != 1) { //Read SW sw_read(); if (sw1_m2 == 1){ // an Item Select SW ON ? // sw1_m2 = 0; ++sw1_count; if (sw1_count == 8) {sw1_count = 1;} if (sw1_count <= 7) { lcd_inst_wr(blink_location_tbl[sw1_count-1]); // Set CURSOR Location lcd_inst_wr(DISP_ON_CURSOR_ON_BLINK_OFF); // LCD CURSOR ON } } if (sw2_m2 == 1 && sw1_count >= 1){ // Time Set SW ON ? lcd_inst_wr(DISP_ON_CURSOR_OFF_BLINK_OFF); // LCD CURSOR OFF if (sw1_count == 1) { ++year_set; if (year_set >= 100) {year_set = 0;} time_set_disp(year_set,0x82); } if (sw1_count == 2) { ++months_set; if (months_set >= 13) {months_set = 1;} time_set_disp(months_set,0x85); } if (sw1_count == 3) { ++days_set; if (days_set >= 32) {days_set = 1;} time_set_disp(days_set,0x88); } if (sw1_count == 4) { ++weekdays_set; if (weekdays_set >= 7) {weekdays_set = 0;} time_set_disp(weekdays_set,0x8c); } if (sw1_count == 5) { ++hour_set; if (hour_set >= 25) {hour_set = 0;} time_set_disp(hour_set,0xc0); } if (sw1_count == 6) { ++minute_set; if (minute_set >= 60) {minute_set = 0;} time_set_disp(minute_set,0xc3); } if (sw1_count == 7) { ++seconds_set; if (seconds_set >= 60) {seconds_set = 0;} time_set_disp(seconds_set,0xc6); } } if (sw3_m2 == 1){ // Set Enter SW ON ? lcd_inst_wr(DISP_ON_CURSOR_OFF_BLINK_OFF); // 100831 Add LCD CURSOR OFF rtc_write_data_tbl[8] = bin_to_bcd(year_set); rtc_write_data_tbl[7] = bin_to_bcd(months_set); rtc_write_data_tbl[6] = bin_to_bcd(weekdays_set); rtc_write_data_tbl[5] = bin_to_bcd(days_set); rtc_write_data_tbl[4] = bin_to_bcd(hour_set); rtc_write_data_tbl[3] = bin_to_bcd(minute_set); rtc_write_data_tbl[2] = bin_to_bcd(seconds_set); // Initialize Slave RTC8564 i2c_write_sr(0,15); // Write RTC_Reg 16bytes: adrs = 0 to 15 -> Time Stop // CLKOUT = 1Hz time_set_end = 1; lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); const_lcd_disp(); // '20xx/ / ...etc } Waitx1ms(1); // wait 1mS } } ///--------------------------------------------------------------------------------- /// INT0 External Interrupt T=1Sec void __attribute__((__interrupt__, no_auto_psv)) _INT0Interrupt(void) { i2c_read_sr(2,8); // Read SecondsREG - YearsREG variable_lcd_disp(); // '2010/xx/xx/xx(xxx) xx:xx:xx /// ADC Read while(!IFS0bits.ADIF); // End of convertion ? ResultData = ReadADC12(0); // Read 12bit ADC Datatyu Volt = (5.06 / 4096) * ResultData; Volt_int = Volt * 1000; lcd_volt_disp(); /// Loging Interval Count 1分 ++Sec; if (Sec >= 60) { Sec = 0; minute_flag = 1; } //Reset INT0 interrupt flag IFS0bits.INT0IF = 0; } //------------------------------------------------------------------------------------------ // Main routine int main(void) { // Set ADPCFG: RB1 Port is All Digital Pin ADPCFG = 0xFFFF; TRISDbits.TRISD0=0; // RD0 is LED output used debug TRISDbits.TRISD2 = 0; // RD2 is RED_LED output TRISDbits.TRISD8 = 0; // RD3 is GREEN_LED output TRISBbits.TRISB0=1; // RB0 is SW1 input TRISBbits.TRISB8 =1; // RB8 is SW2 input TRISDbits.TRISD3 =1; // RD3 is SW3 input LATDbits.LATD2 = 1; // Red LED OFF LATDbits.LATD8 = 1; // Green LED OFF PORTDbits.RD0 = 1; // LED OFF // SD Port Mode Set TRISBbits.TRISB2 = 0; // RB2 is CS/ output TRISFbits.TRISF3 = 0; // RF3 is SDO output TRISFbits.TRISF6 = 0; // RF6 is SCK output TRISFbits.TRISF2 = 1; // RF2 is SDI input TRISBbits.TRISB4 = 1; // RB4 is CD input TRISBbits.TRISB5 = 1; // RB5 is WE input SD_CS_DISABLE; // CS = 1 sw1_m0=sw1_m1=sw1_m2=sw2_m0=sw2_m1=sw2_m2=sw3_m0=sw3_m1=sw3_m2 = 0; Sec = 0; minute_flag = 0; Logging_mode_flag = 0; sw1_on_flag= 0; ResultData = 0; // Initialize LCD lcd_init(); lcd_inst_wr(DISP_ON_CURSOR_OFF_BLINK_OFF); // Initialize Master PIC I2C Port 220918 TRISFbits.TRISF4=1; // RF4 is SCL Hi-Z TRISFbits.TRISF5=1; // RF5 is SDA Hi-Z // Confirm to ADC Off ADCON1bits.ADON=0; // Initialize ADC _ADCHS= ADC_CH0_POS_SAMPLEA_AN1 & ADC_CH0_NEG_SAMPLEA_NVREF; // A-D channel-1 select SetChanADC12(_ADCHS); _ADCON1=ADC_MODULE_ON & ADC_IDLE_CONTINUE & ADC_FORMAT_INTG & ADC_CLK_INT0 & // ADC Clock Syncronas INT0: 220918 ADC_AUTO_SAMPLING_ON & // Auto sampling on ADC_SAMP_OFF; _ADCON2=ADC_VREF_AVDD_AVSS & ADC_SCAN_OFF & ADC_SAMPLES_PER_INT_1 & ADC_ALT_BUF_OFF & ADC_ALT_INPUT_OFF; // Tad={Tcy(ADCS+1)}/2>334ns, Then ADCS>18.7, Tad=10*Tcy _ADCON3=ADC_SAMPLE_TIME_1 & ADC_CONV_CLK_SYSTEM & ADC_CONV_CLK_10Tcy; _ADPCFG=ENABLE_AN1_ANA; // A-D channel-1 analog input _ADCSSL=SCAN_NONE; OpenADC12(_ADCON1, _ADCON2, _ADCON3, _ADPCFG, _ADCSSL); // INT0 pin to interupt on Rise Edge Trig INTCON2bits.INT0EP=0; Waitx1ms(1000); // Wait 1Sec /// SW1+SW2 OFF and Power ON Then Normal Mode Batt Backup 220918 if (_RB0 == 1 && _RB8 == 1) { i2c_write_sr(0,1); // Cont1,2Reg write i2c_write_sr(9,15); // ALM,TIMInt,CLKOUTReg write const_lcd_disp(); // '20xx/ / ...etc } // SW2 ON and Power ON Then Time Adjust Mode if (_RB8 == 0) {time_adjust_mode();} // RTC Time Start-> RTC_CLOCKOUT ON rtc_write_data_tbl[0] = 0x00; i2c_write_sr(0,0); // Enable Interrupt IEC0bits.INT0IE = 1; // Enable INT0 Interrupt Service Routine DISICNT = 0x0000; // Enable Interrupt while(1) { //Read SW sw_read(); if (sw1_m2 == 1) { // REC Mode IEC0bits.INT0IE = 0; // Desable INT0 Interrupt Service Routine DISICNT = 0x0001; // Dsable Interrupt // Check Mount SD Card and Format SD_CS_ENABLE; // CS = 0 while(FSInit() != 1) // Check Mount SD Card and Format { lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg4); // 'SD Not Mount' Disp Waitx1ms(1000); lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); Waitx1ms(1000); } // SD Mount lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg5); // 'Initial OK !!' Disp Waitx1ms(1000); // File Open (Write Mode) Non File Then Make New File pfile = FSfopen("DATA.CSV" , "w"); LATDbits.LATD2 = 0; // Red LED ON Ix = 0; Logging_mode_flag = 1; line_clear(0x80,16); // 1行目をクリア lcd_inst_wr(0x80); lcd_chr_wr(msg7); // 'REC:' Disp lcd_chr_wr(msg9); // '0000' Disp lcd_chr_wr(msg2); // '/ 1440' Disp lcd_inst_wr(0xc2); one_chr_wr(0x3a); // ':' const disp lcd_inst_wr(0xc5); one_chr_wr(0x3a); // ':' const disp Sec = 60; sw1_on_flag = 1; } if (sw1_on_flag == 1) { IEC0bits.INT0IE = 1; // Enable INT0 Interrupt Service Routine DISICNT = 0x0000; // Enable Interrupt if (minute_flag == 1) { minute_flag = 0; logging_rec_sr(); } } Waitx1ms(1); } }