mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 F2013 Special SPI: P1.7 vs. SDI


Autor: Nicco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo leute,

Ich weiss nicht ob dies ein Standard ist oder das ein spezial Fall ist:

Ich hab ein F2013, damit soll ich mit ein zweites Bauteil kommunizieren, 
der eine EEPROM beinhaltet. Der SPI Protokoll ist so gesetzt worden:

Write EEPROM:
ich sende (aus MSP430 Sicht) 6 bytes (command, address, 4 data). Falls 
dieses Bauteil die Kommunikation korrekt interpretiert und die EEPROM 
modifiziert wurde, setzt er nach max 12ms sein D_OUT auf 1.

Read EEPROM:
ich sende (aus MSP430 Sicht) 6 bytes (command, address, 
data(irrelevant)). Falls dieses Bauteil die Kommunikation korrekt 
interpretiert, setzt er nach etwa 50u (während 1 Clock) D_OUT auf 1. 
Danach soll der MSP430 noch 33 Clock pulses (1+ 4*8) raus lassen und den 
Daten einlesen (d_OUT von Bauteil, SDI auf MSP430).

Nun mein Problem...
Sobald ich die 6 Bytes gesendet habe, muss ich den P1.7 wieder auf Input 
setzen und warten bis es auf 1 ist (evtl. min einen interrupt). Falls 
ein ReadEEPROM gefagt ist, muss ich P1.7 wieder als SDI setzen.

Ich weiss dass USI überschreibt die Input/Output Port settings  (ich 
nehme mal an mit USICTL0 = USIPE7).
Falls ich dieses wider als Input benützen will, ist es genügend den 
USIPE7 wider auf Null setzen? Muss ich wieder P1DIR und/oder P1SEL 
ändern?

Oder sogar gibt es einen Weg, diesen D_OUT über SPI zu kontrollieren? 
(scheint mir kompliziert, speziell für die 12 ms Wartezeit...)

Danke für alle Tips!

Nicco

Autor: N. Z. (nicco)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich sehe niemand hat eine Antwort gegeben :(
Naja, mittlerweile hab ich den ganzen Code geschrieben:
//--------------------------------------------------------------------------------------------------------
//      Software
//
//      Ver 2.0   test writeEEPROM / rearEEPROM functions
//
//      Working on a MSP430 F2013 (eZ430 Development Tool
//      IAR Kickstart version 4.11
//--------------------------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------------------------
// Include Headers
//--------------------------------------------------------------------------------------------------------
#include <io430x20x3.h>                                 // Header file for this device
#include <intrinsics.h>                                 // Intrinsic functions
#include <stdint.h>                                     // Integers of defined sizes

//--------------------------------------------------------------------------------------------------------
// Define Fixed variables
//--------------------------------------------------------------------------------------------------------

#define DI1    P1IN_bit.P1IN_2                 // Digital Input 1 = P1.2 IN                      ***not fixed yet
#define D_OUT    P1IN_bit.P1IN_7                 // D_OUT from SL13A (when needed as input)

#define DI1IE    P1IE_bit.P1IE_2                 // Digital Input 1 = P1.2 IN                      ***not fixed yet
#define D_OUTIE          P1IE_bit.P1IE_7                 // D_OUT from SL13A (when needed as input)

#define DI1IFG    P1IFG_bit.P1IFG_2               // Digital Input 1 = P1.2 IN                      ***not fixed yet
#define D_OUTIFG  P1IFG_bit.P1IFG_7               // D_OUT from SL13A (when needed as input)

#define DI1IES    P1IES_bit.P1IES_2               // Digital Input 1 = P1.2 IN                      ***not fixed yet
#define D_OUTIES  P1IES_bit.P1IES_7               // D_OUT from SL13A (when needed as input)


//--------------------------------------------------------------------------------------------------------
// Initialize Functions
//--------------------------------------------------------------------------------------------------------

void HW_init(void);
void readEEPROM(void);
void writeEEPROM(void);

//--------------------------------------------------------------------------------------------------------
// Initialize variables
//--------------------------------------------------------------------------------------------------------

unsigned short ob[6];                                   // Define place for data of Online Block
int ICF = 0;                                            // Input Changed Flag
int ECF = 0;                                            // EEPROM Changed Flag

                                  

//--------------------------------------------------------------------------------------------------------
// Main 
//--------------------------------------------------------------------------------------------------------

void main (void)
{

  HW_init();                                            // Initalize Hardware
  
  readEEPROM();                                        // test write EEPROM
  
}


//--------------------------------------------------------------------------------------------------------
// Define Functions
//--------------------------------------------------------------------------------------------------------

//-------------------------------------------------------------------------------------------Initalisation
//Initializes all the ports and setting
void HW_init(void){
// Setup clocks
  WDTCTL = WDTPW | WDTHOLD;                       // stop Watchdog
        BCSCTL1 = CALBC1_8MHZ;              // Calibrated range for DCO
  DCOCTL = CALDCO_8MHZ;              // Calibrated tap and modulation
  BCSCTL3 = LFXT1S_2;                             // ACLK from VLO (12Khz)
        BCSCTL2 = DIVS_3;                               // SMCLK = DCO/8 = 1MHz
// Configure ports
        
  P1OUT = 0;                      // pre clear Buffer
  P1DIR = BIT5 | BIT6;              // all inputs (initally, then overwrited by SPI)
  P1REN = BIT0|BIT1|BIT2|BIT3|BIT4|BIT7;          // Pull resistors on unused pins
        
  P2SEL = 0;                // Digital i/o rather than crystal
        P2OUT = 0;                                      // preclear output buffer
  P2DIR = BIT6;                // set P2.6 Output
  P2REN = BIT7;                      // Pull resistors on P2.7
}

//---------------------------------------------------------------------------------------------Read EEPROM
//reads the online Block on the EEPROM and returns the value
void readEEPROM(void){
  int i;
  ob[0] = 0x41;                                         // read Command code for SPI communication
  ob[1] = 0x01;                                         // Address for SPI communication                  **to define!
  D_OUTIE = 0;
//Init USI  
  // Enable SDI, SDO, SCLK, msb first, master, enable output, latch data
  USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE | USISWRST;
  // Write then read (CPHA = 1 -> CKPH = 0), SPI not I2C, enable interrupt
  USICTL1 = USIIE | USIIFG;                             // Can't clear USIIE in reset mode
  USICKCTL = USIDIV_0 | USISSEL_3;                      // SCLK = SMCLK, clock idles low (CPOL = CKPL = 0)
  USICTL0 &= ~USISWRST;                                 // Release USI from reset
  USICTL1 &= ~USIIFG;                      // Avoid unwanted interrupt (clear pending IE)
//send request  
  for (i=0; i<6; i++){                                  // for 6 times (1 command, 1 address, 4 data)
     
     USISRL = ob[i];                                    // Write variable value to Shift Register
     USICNT = 8;                // Start SPI to transfer 8 bits
     __low_power_mode_0();
     
  }
//send 'Execute'  
  USICNT = 1;                                           // Start SPI to transfer 1 bit (execute)
   __low_power_mode_0();
//stop USI  
  USICTL1 &= ~USIIE;                                    // disable SPI Interrupts
  USICTL0 &= ~USIPE7;                                   // disable SDI -> P1.7 Input
//wait Ready
  P1IFG = 0;                                            // clear pending interrupts
  D_OUTIE = 1;                                          // enable interrupt
  D_OUTIES = 0;                                         // Sensitive on rising edge
  __low_power_mode_0();                                 // power down until interrupt released
  ECF = 0;                                              // clear ECF (changed EEPROM on purpose)
//send ACK
  D_OUTIE = 0;                                          // disable Port interrupt
  USICTL0 |= USIPE7;                                    // enable SDI
  USICTL1 |= USIIE;                                     // enable SPI Interrupts
  USICNT = 1;                                           // send one clock (USICNT = 1) 
  __low_power_mode_0();                                 
  
  for (i=2; i<6; i++){                                  // for 4 times
    USICNT = 8;                                         // send 8 clocks
    __low_power_mode_0();                               // wait until done...
    ob[i] = USISRL;                                     // ...and save the value
  }
//stop USI  
  //USICTL0 |= USISWRST;              // reset USI (??? needed?)
  USICTL1 &= ~USIIE;                                    // disable SPI Interrupts
  USICTL0 &= ~USIPE7;                                   // disable SDI -> P1.7 Input
//wait for ACK  
  P1IFG = 0;                                            // clear pending interrupts
  D_OUTIE = 1;                                          // enable interrupt
  D_OUTIES = 0;                                         // Sensitive on rising edge
  __low_power_mode_0();                                 // power down until interrupt released
  ECF = 0;                                              // clear ECF (changed EEPROM on purpose)
}
//--------------------------------------------------------------------------------------------Write EEPROM
//writes the given value on the Online Block of the EEPROM
void writeEEPROM(void){
  int i;
  ob[0] = 0x81;                                         // write Command code for SPI communication
  ob[1] = 0x01;                                         // Address for SPI communication                  **to define!
  ob[2] = 0x74;                                         // Preload random numbers
  ob[3] = 0x36;
  ob[4] = 0xF8;
  ob[5] = 0xA5;
  D_OUTIE = 0;                                          // disable interrupt
//Init USI  
  // Enable SDI, SDO, SCLK, msb first, master, enable output, latch data
  USICTL0 = USIPE7 | USIPE6 | USIPE5 | USIMST | USIOE | USISWRST;
  // Write then read (CPHA = 1 -> CKPH = 0), SPI not I2C, enable interrupt
  USICTL1 = USIIE | USIIFG;                    // Can't clear USIIE in reset mode
  USICKCTL = USIDIV_0 | USISSEL_3;                      // SCLK = SMCLK, clock idles low (CPOL = CKPL = 0)
  USICTL0 &= ~USISWRST;                      // Release USI from reset
  USICTL1 &= ~USIIFG;                      // Avoid unwanted interrupt (clear pending IE)
//send request  
  for (i=0; i<6; i++){                                  // for 6 times (1 command, 1 address, 4 data)
     
     USISRL = ob[i];                                    // Write variable value to Shift Register
     USICNT = 8;                // Start SPI to transfer 8 bits
     __low_power_mode_0();
    
     
  }
//send 'Execute'  
  USICNT = 1;                        // Start SPI to transfer 1 bit (execute)
   __low_power_mode_0();
  
//stop USI  
  //USICTL0 |= USISWRST;              // reset USI (??? needed?)
  USICTL1 &= ~USIIE;                                    // disable SPI Interrupts
  USICTL0 &= ~USIPE7;                                   // disable SDI -> P1.7 Input
//wait for ACK  
  P1IFG = 0;                                            // clear pending interrupts
  D_OUTIE = 1;                                          // enable interrupt
  D_OUTIES = 0;                                         // Sensitive on rising edge
  __low_power_mode_0();                                 // power down until interrupt released
  ECF = 0;                                              // clear ECF (changed EEPROM on purpose)
  return;      
}


//--------------------------------------------------------------------------------------------------------
// ISR for USI: clear flag and exit
//--------------------------------------------------------------------------------------------------------
#pragma vector = USI_VECTOR
__interrupt void USI_ISR (void)                    
{
  USICTL1 &= ~USIIFG;              // Clear flag
        __low_power_mode_off_on_exit();                 // leave LPM0 on exit 
       
}

//--------------------------------------------------------------------------------------------------------
// ISR for Inputs on P1
//--------------------------------------------------------------------------------------------------------
#pragma vector = PORT1_VECTOR
__interrupt void PORT1_ISR (void)            // NOT acknowledged automatically
{
  if(D_OUTIFG){                                         // P1.7 relased
        ECF = 1;                                        // set EEPROM Changed Flag
  }
  else if(DI1IFG){                                      // P1.0 relased  
        ob[3] ^= BIT6 ;                                 // toggle bit in ob[]                             ***modify numbers!
        DI1IES ^= 1;                                    // Toggle sensitive edge (rising <-> falling)
        ICF = 1;                                        // set 'Input Changed Flag'    
  }  
                                             
 

  do{
    P1IFG = 0;                                          // Clear any pending interrupt...
  } while(P1IFG != 0);                                  // ...until none remain
  
  __low_power_mode_off_on_exit();                       // leave LPM0 on exit
       
}


Solange dies in der Luft ist (ohne zweites Bauteil und mit SDI auf GND 
ausser um ein interrupt auszulösen), funktioniert alles bestens (schöne 
Pegel in Ausgang, und auf Clock).
ABER:

sobald ich den zweiten Bauteil verbinde, geht der Clock auf halbes 
Pegel, anstatt 8 bits, sind es 9, und und und...
Auf den zweiten Bauteil kann man nichts ändern (SPI enable oder 
ähnliches), und soll eigentlich funktionsfähig sein.

Bevor ich weiter gehe, hat jemand vielleicht eine kritik bezüglich mein 
Code? Verbesserungsmöglichkeiten? Fehler mit irgend ein PxREN (sobald 
ein Last gibt, krascht das ganze)...
ICh habe einiges ausprobiert, darum kann es gut sein dass unnötige 
Befehle drin sind...

Danke! Regards...

Nicco

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.