ใครใจดีช่วยแก้โค๊ด et-base dspic30f2010 การรับค่า ADC แสดงผล LCD ของ จาก W ให้แสดงออกมาเปน V หน่อยครับ

ใครใจดีช่วยแก้โค๊ด et-base dspic30f2010 การรับค่า ADC แสดงผล LCD ของ จาก W ให้แสดงออกมาเปน V หน่อยครับ
หรือใจดีเขียนให้ใหม่เลยจะขอบคุณมากครับ

ข้อมูล  โปรแกรมควบคุม

#include <p30f2010.h>    
#define RS         LATEbits.LATE4  
#define E             LATEbits.LATE5    

#define RESETSW        PORTCbits.RC13  
#define RESETSW_PRESSED        0

#define CELL(x) (0x7FFC00+2*(unsigned long)x) // Macro for access to EEPROM cell x(x = 0...511)

//-------------------------- Device Configuration ------------------------      

_FOSC(CSW_FSCM_OFF & XT_PLL16);
_FWDT(WDT_OFF);
_FBORPOR(PBOR_ON & BORV_20 & PWRT_64 & MCLR_EN);

//-------------------------- Global Variables ------------------------      

unsigned int Samples,Energy,iEEPROM;
long AccPwr,Power;
long long AddE;
//-------------------------- Interrupt Routine ------------------------      

void __attribute__((__interrupt__)) _ADCInterrupt(void) // Fs = 50,000 Hz ( 1,000 Samples/Cycle of 50Hz )
{
    long DCV,ACA;
    unsigned int nEnergy;

    IFS0bits.ADIF = 0;    // Clear interrupt flag

    DCV = (long)ADCBUF1;         

    ACA = (long)ADCBUF0-512;    // AC Amp.

    AccPwr += (DCV*ACA);

    Samples++;        // LSB = Least Significant Value per Bit
    if(Samples==1000) {     // Pwr(xx.xxx) = AccPwr * 1000 * (LSB of AccPwr) / 1000
        Samples=0;     // LSB of AccPwr = (LSB of V) * (LSB of A)
        if(AccPwr<0) AccPwr=0;
        Power=AccPwr/210;    // LSB of V = Vpp / (2^n of ADC) = (50) / 1024
        AccPwr=0;     // LSB of A = App / (2^n of ADC) = (50+50) / 1024
                // 210 ~ 209.7152 = 1 / ((50+/1024)*((50+50)/1024))
        AddE +=    (long long)Power;    // Energy(xx.xxx) = 1kW in a Hour
        nEnergy=(unsigned int)(AddE/180000000);
        if(nEnergy!=Energy){
            Energy=nEnergy;
            ADCON1bits.ADON = 0;
            IEC0bits.ADIE = 0;        
            WriteEEPROM();
            IEC0bits.ADIE = 1;        
            ADCON1bits.ADON = 1;
        }
    }
    
    return;
}

//-------------------------- ADC10 ------------------------      

void InitADC10(void)
{

    ADPCFG = 0x003C;            // RB0 and RB1 are Analog input
    ADCON1 = 0x00EE;            // Auto ends TSAMP and starts conversion, Unsigned integer conversions
    ADCON2 = 0x0100;            // S/H All CH0, CH1
    ADCON3 = 0x0416;            // ADCS = 010110 of 384.615nS = 1*TAD of 30MIP fs=50kHz
                    // TSAMC = 00100 = 4*TAD
                    // Sample = TSAMP(4*TAD)+TCONV(4*12*TAD)
    ADCHS  = 0x0001;            // A0+ > CH1,A1+ > CH2,A2+ > CH3, A1+ > CH0, AN- > VREF-
                    // A1 - ADCBUF0 - I, A0 - ADCBUF1 - V
    IFS0bits.ADIF = 0;            // Clear ISR flag
    IEC0bits.ADIE = 1;            // Enable interrupts
    
    ADCON1bits.ADON = 1;        // turn ADC ON
    return;
}

//-------------------------- LCD ------------------------      

void lcd_init()
{
    TRISE = 0;
    lcd_command(0x33);          // Command set format 4 bit
    lcd_command(0x32);        // Command set format 4 bit
    lcd_command(0x28);        // 2 line ,5*7 dot
    lcd_command(0x0C);          // Display ON , none curser
    lcd_command(0x01);        // Clear screen
}

void lcd_command(unsigned char com)    
{
    unsigned char buff;                    // For Keep command send to LCD

    buff = (com & 0xF0)>>4;                // Keep 4 bit high byte befor send to LCD
    RS = 0;                    // Select send command to LCD                        
    E = 1;                     // Start generate pluse clock LCD
    LATE = (LATE & 0xFFF0)|buff;          // Send data to LCD port
    delay_ms(1);                           
    E = 0;                                     // Stop generate pluse clock LCD
    delay_ms(1);                           
    
    buff = (com & 0x0F);                   // Keep 4 bit low byte befor send to LCD
    RS = 0;                    // Select send command to LCD                        
    E = 1;                    // start generate pluse clock LCD
    LATE = (LATE & 0xFFF0)|buff;         // Send data to LCD port
    delay_ms(1);                           
    E = 0;                    // Stop generate pluse clock LCD
    delay_ms(1);                           
}

void lcd_text(char text)        
{
    unsigned char buff;                           // For Keep data send to LCD
    buff = (text & 0xF0)>>4;            // Keep 4 bit high byte befor send to LCD
    RS = 1;                    // Select send data to LCD                        
    E = 1;                    //  start generate pluse clock LCD
    LATE = (LATE & 0xFFF0)|buff;            // Send data to LCD port
    delay_ms(1);                        
    E = 0;                                    // Stop generate pluse clock LCD
    delay_ms(1);                         
    
    buff = (text & 0x0F);             // Keep 4 bit low byte befor send to LCD
    RS = 1;                    // Write Command to LCD                        
    E = 1;                    //  start generate pluse clock LCD
    LATE = (LATE & 0xFFF0)|buff;            // Send data to LCD port
    delay_ms(1);                        
    E = 0;                                    // Stop generate pluse clock LCD
    delay_ms(1);                         
}

void lcd_puts(unsigned char addr,char *p)
{
    lcd_command(0x02);                     // Set origin address of LCD
    lcd_command(addr);        
    while(*p)                                  // Check data pointer = 0?
    {
        lcd_text(*p);            
        p++;                    
    }
}

void PrintLCD(unsigned char addr,long value)
{
    int i;
    char ibuff[7];

    if(addr==0x83) {
        value/=100;
        ibuff[0] = (value/10000) | '0';    
        ibuff[1] = ((value000)/1000) | '0';    
        ibuff[2] = (((value000)00)/100) | '0';  
        ibuff[3] = ((((value000)00)0)/10) | '0';
        ibuff[4] = '.';
        ibuff[5] = ((((value000)00)0)) | '0';
        ibuff[6] = 0;
        if(ibuff[0]=='0') ibuff[0]=' ';
        if((ibuff[1]=='0')&&ร้องไห้ibuff[0]==' ')) ibuff[1]=' ';
        if((ibuff[2]=='0')&&ร้องไห้ibuff[1]==' ')) ibuff[2]=' ';
    }else{
        ibuff[0] = (value/10000) | '0';    
        ibuff[1] = ((value000)/1000) | '0';    
        ibuff[2] = '.';
        ibuff[3] = (((value000)00)/100) | '0';  
        ibuff[4] = ((((value000)00)0)/10) | '0';
        ibuff[5] = ((((value000)00)0)) | '0';
        ibuff[6] = 0;
        if(ibuff[0]=='0') ibuff[0]=' ';
    }

    lcd_puts(addr,&ibuff[0]);      
}

//-------------------------- MISC ------------------------      

void delay_ms(unsigned int ms) // Delay millisecond
{
    unsigned int i,k;    
    for(i=0;i<ms;i++)
    {
        for(k=0;k<5120;k++); // Delay 1 ms each, at 7.3738 MHz at PLL 16x
    }
}

//-------------------------- EEPROM Routine ------------------------      

void eeprom_erase_word(unsigned long address_erase)
{
    __asm__ volatile("MOV W1,NVMADRU");    // Keep  High byte address
    __asm__ volatile("MOV W0,NVMADR");    // Keep  low byte address
    __asm__ volatile("MOV #0x4044,W0");        // Load command
    __asm__ volatile("MOV W0,NVMCON");
    __asm__ volatile("DISI #5");
    __asm__ volatile("MOV #0x55,W0");        // Lanch command step 1
    __asm__ volatile("MOV W0,NVMKEY");
    __asm__ volatile("MOV #0xAA,W1");        // Lanch command step 2    
    __asm__ volatile("MOV W1,NVMKEY");
    NVMCONbits.WR = 1;            // Start to write data to EEPROM    
    while(NVMCONbits.WR);            // Wait until success
    NVMCONbits.WREN = 0;             // Clear WREN for ensure
}

void eeprom_write_word(unsigned long address,unsigned int val)
{
    __asm__ volatile("MOV W1,TBLPAG");        // Keep  High byte address
    __asm__ volatile("TBLWTL W2,[W0]");        // Write data to table
    __asm__ volatile("MOV #0x4104,W0");        // Load command
    __asm__ volatile("MOV W0,NVMCON");
    __asm__ volatile("DISI #5");
    __asm__ volatile("MOV #0x55,W0");        // Lanch command step 1
    __asm__ volatile("MOV W0,NVMKEY");
    __asm__ volatile("MOV #0xAA,W1");        // Lanch command step 2    
    __asm__ volatile("MOV W1,NVMKEY");
    NVMCONbits.WR = 1;            // Start to write data to EEPROM    
    while(NVMCONbits.WR);            // Wait until success
    NVMCONbits.WREN = 0;            // Clear WREN for ensure
}

unsigned int eeprom_read_word(unsigned long address)
{
    __asm__ volatile("MOV W1,TBLPAG");        // Keep  High byte address
    __asm__ volatile("TBLRDL [W0],W4");        // Load data into W4
    return(WREG4);                // Return data for EEPROM        
}

void WriteEEPROM(void)
{
unsigned int i,data;

    eeprom_erase_word(CELL(iEEPROM));
    eeprom_write_word(CELL(iEEPROM),0x0000);
    delay_ms(1);
    if(iEEPROM==511) iEEPROM=0;
    else iEEPROM++;
    eeprom_erase_word(CELL(iEEPROM));
    eeprom_write_word(CELL(iEEPROM),Energy);
    delay_ms(1);
}

void ResetEnergy(void)
{
unsigned int data,i,Pressed;

    Pressed=0;
    i=599;
    lcd_puts(0x80,"Pressing at zero");    
    lcd_puts(0xC0,"to confirm:   s.");    
    while(i<600){
        lcd_command(0xCC);        
        lcd_text( (i/100) | '0' );    
        if(RESETSW==RESETSW_PRESSED) {
            Pressed=1;
            break;
        }
        delay_ms(6);
        i--;
        if(i==0) break;
    }
    if((Pressed)&&ร้องไห้(i/100)==0)) {
        i=0;
        while(i<512){
            data=eeprom_read_word(CELL(i));
            if(data!=0x0000) {
                eeprom_erase_word(CELL(i));
                eeprom_write_word(CELL(i),0x0000);
                delay_ms(1);
            }
            else i++;
        }
        iEEPROM=511;
        Energy=0;    
        AddE=0;        
        lcd_puts(0x80,"RESET Confirmed!");    
        lcd_puts(0xC0,"                ");    
        delay_ms(3000);
    }else{
        lcd_puts(0x80,"RESET Failed!   ");    
        lcd_puts(0xC0,"                ");    
        delay_ms(3000);
    }        
    lcd_puts(0x80,"P:        Watts ");    
    lcd_puts(0xC0,"E:        Units ");    
}

void LoadEEPROM(void)
{
unsigned int i,data;

    if(eeprom_read_word(CELL(511))==0xFFFF) {
        for(i=0;i<512;i++) {
            eeprom_erase_word(CELL(i));
            eeprom_write_word(CELL(i),0x0000);
            delay_ms(1);
        }
        iEEPROM=511;
        Energy=0;
    }else{
        data=i=0;
        while(i<512){
            data=eeprom_read_word(CELL(i));
            if(data!=0x0000) break;
            else i++;
        }
        if(i>=512) iEEPROM=511;
        else iEEPROM=i;
        Energy=data;    // in xx.xxx Resolution, maximum 65.535 Units
    }        
    AddE=(long long)Energy*180000000;    // 60*60*50*1000
}

//-------------------------- MAIN Routine ------------------------      

int main(void)
{
int i;

    TRISC |= 0x6000;        

    Samples = 0;

    AccPwr=0;
    Power=0;

    LoadEEPROM();

    lcd_init();                                
    lcd_puts(0x80,"P:        Watts ");    
    lcd_puts(0xC0,"E:        Units ");    

    InitADC10();    // Start Sampling                    

    for(;;)
    {
        PrintLCD(0x83,Power);
        PrintLCD(0xC3,Energy);

        if(RESETSW==RESETSW_PRESSED) {
            ADCON1bits.ADON=0;
            IEC0bits.ADIE=0;        
            ResetEnergy();
            Samples=0;
            AccPwr=0;
            IEC0bits.ADIE=1;        
            ADCON1bits.ADON=1;
        }

        delay_ms(5);
    }
    return 0;
}







แสดงความคิดเห็น
โปรดศึกษาและยอมรับนโยบายข้อมูลส่วนบุคคลก่อนเริ่มใช้งาน อ่านเพิ่มเติมได้ที่นี่