//************************************************************ // Easy SD Logger // // Used Microchip Memory Disk Drive File System:FAT16 // // LCD unlook busy : not switch direction (write fixed) // // AD Sample Interval: 0.5Sec(2Hz) // The Number of AD Sample: 100Data(1100Byte Asccii) // AD Input: CH1(DC 0 - 5V) // // CPU dsPIC30F4013(Program Memory:48kBytes) // 7.37MHz Internal RC oscillator, 16x PLL enabled // Fcy=7.37MHzx16/4=29.48MHz, Tcy=33.92ns // // 2010/8/24: N.Ishii //************************************************************* /* Addition to MPLAB Project File (Be connected File System) */ // Source Files Folder FSIO.c // SD-SPI.c // sd_r_w_check.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[] = {"Wait Write SW ON\0"}; char msg3[] = {"Write NG !!\0"}; char msg4[] = {"SD Not Mount\0"}; char msg5[] = {"Initial OK !!\0"}; char msg6[] = {"Write OK !!\0"}; char msg7[] = {"Ix:\0"}; char msg8[] = {"Writing!\0"}; char msg9[] = {"000\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 //--------------------------------------------------------------------------------------------- #define CR 0x0d #define LF 0x0a //---------------------------------------------------- FSFILE *pfile; // Structure Pointer for FAT File unsigned int Buf_Input[1]; // Write Vol for SD Card int N_Write; // The Number of Write Times unsigned int Ix; unsigned char write_error_flag; // adc data unsigned int ResultData; float Volt; unsigned int Volt_int; unsigned char sw1_m0; unsigned char sw1_m1; unsigned char sw1_m2; //------------------------------------------------------------------------- // For SD Data Format unsigned char SD_write_data[] = { 0x00, // [0]:Number of Write Times(Ix) 0x00, // [1]: 0x00, // [2]: 0x2c, // [3]:',' 0x00, // [4]:Volt 0x2e, // [5]:'.' 0x00, // [6]: 0x00, // [7]: 0x00, // [8]: CR, // [9]: LF // [10]: }; //------------------------------------------------------------------------------------------------------------- // 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 lcd_volt_disp(void) { // digit[3] disp lcd_inst_wr(0x88); 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_Ix_disp(void) { // Number of Write Times(Ix) Data lcd_inst_wr(0x83); one_chr_wr((Ix/100)%10 | 0x30); one_chr_wr((Ix/10)%10 | 0x30); one_chr_wr(Ix%10 | 0x30); } //------------------------------------------------------------------------ void SD_Data_Ascii_Conv(void) { // Number of Write Times(Ix) Data SD_write_data[0] = (Ix/100)%10 | 0x30; SD_write_data[1] = (Ix/10)%10 | 0x30; SD_write_data[2] = Ix%10 | 0x30; // Volt_Data SD_write_data[4] = (Volt_int/100)/10 | 0x30; SD_write_data[6] = (Volt_int/100)%10 | 0x30; SD_write_data[7] = (Volt_int/10)%10 | 0x30; SD_write_data[8] = Volt_int%10 | 0x30; } //------------------------------------------------------------------------------------ // SW Read 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 } //--------------------------------------------------------------------------------- // Interrupt routine (T1 = 0.5Sec) void __attribute__((__interrupt__, no_auto_psv)) _T3Interrupt(void) { unsigned char i; // 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(); // SD Write SD_Data_Ascii_Conv(); for (i = 0; i < 11; i++) { // 1Data@11Byte // 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 write_error_flag = 1; i = 11; // Escape For Loop } } if (write_error_flag != 1) { Ix++; lcd_Ix_disp(); } IFS0bits.ADIF = 0; // Clear Intterrupt ADC_Flag IFS0bits.T3IF = 0; // Clear Intterrupt Timer3_Flag } //------------------------------------------------------------------------------------------ // Main routine int main(void) { // Set ADPCFG: RB1 Port is All Digital Pin ADPCFG = 0xFFFF; TRISDbits.TRISD0=0; // RD0 is LED output used debug TRISBbits.TRISB0=1; // RB0 is SW1 input 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 write_error_flag = 0; sw1_m0=sw1_m1=sw1_m2= 0; ResultData = 0; // Inittalize Timer3(2Hz = Fcy /256 * 57578) // OpenTimer3(T3_ON & T3_GATE_OFF & T3_PS_1_256 & T3_SOURCE_INT, 57579-1); OpenTimer3(T3_ON & T3_GATE_OFF & T3_PS_1_256 & T3_SOURCE_INT, 57578-1); // Mod 110103 // Initialize LCD lcd_init(); lcd_inst_wr(DISP_ON_CURSOR_OFF_BLINK_OFF); // 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); // ConfigIntADC12(ADC_INT_DISABLE); _ADCON1=ADC_MODULE_ON & ADC_IDLE_CONTINUE & ADC_FORMAT_INTG & // ADC_CLK_AUTO & ADC_CLK_TMR & // ADC Clock Syncronas Timer 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); while(1) { lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg2); // "Wait Write SW ON" Disp while(sw1_m2 != 1) { // SW1 Edge Sence sw_read(); Waitx1ms(1); } sw1_m2 = 0; // 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"); Ix = 0; PORTDbits.RD0 = 0; // LED ON lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg7); // 'Ix:' Disp lcd_chr_wr(msg9); // '000' Disp lcd_inst_wr(0xc0); lcd_chr_wr(msg8); // 'Writing!' Disp // Set Timer3 intterrupt ConfigIntTimer3(T3_INT_PRIOR_5 & T3_INT_ON); // enable interrupt EnableIntT3; // Wait till Write 100 Data do { if (write_error_flag == 1) { lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg3); // 'Write NG !!' Disp DisableIntT3; FSfclose(pfile); // File Close write_error_flag = 0; Waitx1ms(1000); return 0; } } while(Ix < 100); // SD Write End DisableIntT3; PORTDbits.RD0 = 1; // LED OFF lcd_inst_wr(DISP_CLEAR_CURSOR_HOME); lcd_chr_wr(msg6); // 'Write OK !!' Disp Waitx1ms(1000); FSfclose(pfile); // File Close SD_CS_DISABLE; // CS = 1 } }