Forum: Mikrocontroller und Digitale Elektronik SPI Bus: Digitales Poti MCP4261 mit PIC18F45K50 (xc8)


von turbokiller (Gast)


Lesenswert?

Servus,

Bekomme mein digitales Potentiometer Microchip MCP4261 einfach nicht zum 
laufen über den SPI Bus und meinem PIC18F45K50. Werke nun schon seit 
Tagen daran und bringe es einfach nicht hin. Möchte es über den Hardware 
SPI Bus meines PIC18F45K50 programmieren. (xc8 compiler) Mein Programm 
sieht derzeit so aus. Habe nur die wichtigen Schnipsel rauskopiert.Sorry 
ist dennoch etwas viel Code. Kann es sein, dass ich beim Pot was falsch 
anschließe ? Wiper Pin und Shutdown Pin sind beide auf Vdd. 
Potentiometeranschluss A auf Vdd und der Schleifer geht zu einer LED mit 
noch einem Vorwiderstand. Lt. Datenblatt sollte das möglich sein. 
"Floating either Terminal A or B = Rheostat Mode).

void main (void)
{
    initPIC();                  // Configure Microchip, I/O, etc
    initSPI();                  // Configure SPI BUS
    unsigned int a;

    while(1)
    {
            writePOT(244,2);            // Send resistance to both Pots

            for (a=0;a<20;a++)
            {
                __delay_ms(30);
            }

            writePOT(0,2);            // Send resistance to both Pots

            for (a=0;a<20;a++)
            {
                __delay_ms(30);
           }
     }
}

Hier die Funktionen zum Übertragen der 2 Bytes an das Poti und für die 
Konfiguration.

void initSPI()
{

    // I/O Settings
    TRISBbits.TRISB0 = 1;    // set SDI as input
    TRISBbits.TRISB3 = 0;    // set SDO as output
    TRISBbits.TRISB1 = 0;    // set SCK as output
    TRISBbits.TRISB2 = 0;    // set CS as output
    TRISAbits.TRISA5 = 1;    // set SS as input
    ANSELAbits.ANSA5 = 0;    // RA5 digital input buffer enabled


    PCLATH = 0x00;             //
    INTCON = 0x00;             // Interrupts Disabled


    // SSPSTAT Register
    SSP1STATbits.CKE = 1;       // Transmit occurs on transition from 
active to idle clock state
    SSP1STATbits.SMP = 1;       // Input data sampled at end of data 
output time




    // SSP1CON1 Register
    SSP1CON1bits.SSPM0 = 0;     // SPI Master Mode - 0000 Clock = Fosc/4 
<- selected
    SSP1CON1bits.SSPM1 = 0;     // SPI Master Mode - 0001 Clock = 
Fosc/16
    SSP1CON1bits.SSPM2 = 0;     // SPI Master Mode - 0010 Clock = 
Fosc/64
    SSP1CON1bits.SSPM3 = 0;     // SPI Master Mode - 0011 Clock = TMR2/2
    SSP1CON1bits.CKP   = 1;     // Idle clock state is high
    SSP1CON1bits.SSPEN = 1;     // Enable S-Port & Config PINS

}


/* Send 2 bytes via SPI bus                                        */

#define SPI_CS  LATBbits.LATB2

unsigned char writeSPI(unsigned char tbyte0, unsigned char tbyte1)
{
    unsigned char temp;            // received bytes

    SPI_CS = 1;                     // Pull the chip select line high

    temp = SSP1BUF;                  // clear BF

    SPI_CS = 0;                         // Pull the chip select line low


    SSP1BUF = tbyte0;                // transmit byte 1

    while(!SSP1STATbits.BF)         // wait for Transmission to complete
    {}

    temp = SSP1BUF;                 // clear BF and read byte 1

    SSP1BUF = tbyte1;                // transmit byte 2

    while(!SSP1STATbits.BF)         // wait for Transmission to complete
    {}

    temp = SSP1BUF;                 // clear BF and read byte 2

    SPI_CS = 1;                     // Pull the chip select line high

}


/* Send  a Resistance from 0 to 255 to the potentiometers 
*/



void writePOT(unsigned char resistance, unsigned char channel)
{


    // Choose Potentiometer 0
    if (channel == 0)
    {
         writeSPI(0b00010001,resistance);   // Write to POT 0
    }

    // Choose Potentionmeter 1
    if (channel == 1)
    {
        writeSPI(0b00010010,resistance);   // Write to POT 1
    }

    // Choose both Potentionmeters
    if (channel == 2)
    {
        writeSPI(0b00010011,resistance);   // Write to both POTS
    }

}


void initPIC(void)
{

    // digital I/O configuration
    TRISA = 0b00100000;      // Register A
    TRISB = 0b11100001;      // Register B
    TRISC = 0b11000100;      // Register C
    TRISD = 0b00000000;      // Register D

    // ADC configuration
    ADCON0 = 0b01001101;     // ADC Channel Select 19 = RC7, ADC is 
Enabled, GO = 0

    // ADC Reference & Conversion Settings
    ADCON1 = 0b00000000;     // Vref+ = VDD // Vref- = VSS
    ADCON2bits.ADFM = 1;     // Results formant 1 = Right justified
    ADCON2bits.ACQT = 1;     // Acquition Time 7 = 20TAD / 2 = 4TAD / 1 
= 2TAD
    ADCON2bits.ADCS = 2;     //Clock conversion bits 6 = FODSC/64 / 2 = 
FOSC/32

    // ADC I/O configuration
    ANSELA = 0b00000000;     // Register A - analog OFF
    ANSELB = 0b00000000;     // Register B - analog OFF
    ANSELC = 0b10000000;     // Register C - analog OFF - RC7/AN19 ON


    // INTCONbits.GIEL = 0; // Enables all unmasked peripheral 
interrupts
    IOCCbits.IOCC2 = 0; // Interrupt on change PIN RC2 disabled


    // System Clock Select bits Oscillator
    OSCCONbits.SCS0 = 0;        // Pimary Clock determined by FOS 
0,1,2,3
    OSCCONbits.SCS1 = 0;


    // Internal Oscillator Frequency Select bits
                                    // 111: 16 MHz <-- active
    OSCCONbits.IRCF2 = 1;           // 110:  8 MHz
    OSCCONbits.IRCF1 = 1;           // 101:  4 MHz
    OSCCONbits.IRCF0 = 1;           // 100:  2 MHz
}

von turbokiller (Gast)


Lesenswert?

Habe mich genau an diese Anleitung gehalten.

Ist halt in Assembler Mnemonics geschrieben. Was überseh ich?


http://nnp.ucsd.edu/phy120b/application_notes/an746_digital_potentiometer_interface.pdf

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.