mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RF Transmitter des PIC12 geht nicht in Sleep Mode


Autor: Julius con Playa (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

für meine Abschlussarbeit verwende ich einen PIC12LFT39A mit 
integriertem RF Transmitter. Dieser liest Temp.- und Feuchtewerte via 
I²C aus, und sendet diese mittels FSK mit 869MHz.

Das System wacht alle 2 sec durch einen WDT reset aus dem Sleep Modus 
auf, liest die Werte aus und sendet diese. Danach geht er wieder 
schlafen.

Der RF-Transmitter sollte laut Datenblatt nach beeden der Übertragung in 
den Sleep Modus gehen, sofern sich dieser im Automatik Modus befindet. - 
Was er sich bei mir auch tut. Im genaueren: sobald die DATA & CTRL pins 
des RF- Transmitters Low sind. Ich habe die beiden Pins mit einem 
Oscilloscop abgegriffen um zu kontrollieren ob sie wirklich Low sind. 
(Bild)

Nur leider geht der RF-Transmitter nach übertragung nicht in den Sleep 
Modus, obwohl dieser auf Automatik Modus geschaltet ist.
Ein Network Analyser (Bild) zeigt an, dass das System ständig! ein 
Signal sendet. Somit ist der Energieverbrauch enorm hoch und der Sleep 
Mode des PICs nutzlos.

Wo liegt mein Fehler?

Vielen Dank für eure Hilfe!

Liebe Grüße

Hier mein C-Code:
(MPLAP X IDE; XC8 Compiler)
#include <htc.h>
#include "hardware.h"
#include "memorymap.h"
#include "typedefs.h"
#include "T39A.h"
#include "i2c.h"
#include "shtc1.h"


// PIC12LF1840T39A Configuration Bit Settings

#include <xc.h>

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = SWDTEN       // WDT controlled by the SWDTEN bit in the WDTCON register
#pragma config PWRTE = OFF       // Power-up Timer Enable (PWRT enabled)
#pragma config MCLRE = ON      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)

// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)

/** enumeration for state maschine*/
enum XMIT_STATE
{
    OFF,
    PREAMBLE,
    DATA,
    CHECKSUM,
    SHDN,
    CMPL
};

/** Current state of transmitter state machine. */
enum XMIT_STATE p_state = OFF;

/**
 * Transmit buffer. 
 */
#define dataPacketSize 6
volatile UINT8 dataPacket[6];// = {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF};


/**
 * Debug Counter //replace DEV ID // Caution: I useses PR2 to get data over the SW reset.
 */
#define DEBUG_COUNTER 0
#if DEBUG_COUNTER
volatile UINT8 ctr = 0;
#endif



/** Initialize microcontroller ports. */
void initPorts()
{  
    // Transmitter control
    DATA_OUT = 0;
    DATA_DIR = output_pin;
    CTRL_OUT = 0;
    CTRL_DIR = output_pin;

    //All ports are digital
    ANSELA = 0;
    
    //Transmit Disable
    TXSTAbits.TXEN = 1;
}
void Init_WDT(void);

/**Initialize Watchdog Timer */
void Init_WDT ()
{
      if (SEND_FREQUENCY == 1){
    WDTCONbits.WDTPS = 0b01010;         //0b01010 = 1:32768; 1sec     
    }
      else if (SEND_FREQUENCY == 2) {
    WDTCONbits.WDTPS = 0b01011;         //0b01011 = 1:65536; 2sec 
    }   
    WDTCONbits.SWDTEN = 0b01;          // WDT is turned on   
}


#define I2C_WRITE 0
#define I2C_READ 1

/** Initialise MSSP port. (12F1822 - other devices may differ) */
void i2c_Init(void){

  // Initialise I2C MSSP
  // Master 
  TRISA1=1;             // set SCL and SDA pins as inputs
  TRISA2=1;

  SSP1CON1 = 0b00101000;   // I2C enabled, Master mode
  SSP1CON2 = 0x00;
        // I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))

        #if (_XTAL_FREQ == 8000000)
            SSP1ADD = 4;        // 400Khz @ 8Mhz Fosc
        #elif (_XTAL_FREQ == 16000000)
            SSP1ADD = 9;        // 400Khz @ 16Mhz Fosc
        #elif (_XTAL_FREQ == 2000000)
            SSP1ADD = 12;        // 400Khz @ 20Mhz Fosc
        #endif


  SSP1STATbits.SMP = 0;   //Slew rate enabled for high speed mode
        SSP1STATbits.CKE = 1;   //Enable SMBus compilant Input logic
}

/**
 * Reads the I2C SHTC T/H sensor
 */
void sensor_read (volatile UINT8 dataPacket[]){
    //Start Measurement
    i2c_Start();                // send Start
    i2c_Address(I2C_SLAVE, I2C_WRITE);                  // Send  slave address with write operation
    // Start Low Power H/T Measurement with Clock Stetching
    i2c_Write(0x44);
    i2c_Write(0xDE);

    //Start Read
    i2c_Restart();                // send Start
    i2c_Address(I2C_SLAVE, I2C_READ);                  // Send  slave address with read operation
    for(char i=0; i<6;i++){
            dataPacket[i] = i2c_Read(1);
    }
    i2c_Stop();  // send Stop
}

/**
 * Initialize the EUSART interface for Clock out the plain bit stream for the transceiver
 */
void init_eusart (void){
    //TRISA4 = 0;
    //TRISA5 = 0;
    //connect to Pin 4/5
    TXCKSEL = 1;
    RXDTSEL = 1;

    //Configuriere für Sync Serial
    #if (_XTAL_FREQ == 8000000)
    SPBRGL = 19;//100k baud @8mhz
    //SPBRGL = 128;//50k baud @8mhz
    #elif (_XTAL_FREQ == 16000000)
    SPBRGL = 39;//100k baud @8mhz
    #elif (_XTAL_FREQ == 2000000)
    SPBRGL = 4;//100k baud @8mhz
    #endif

    SYNC = 1;         //Synchronous Mode
    SPEN = 1;       //Serial Port Enable
    CSRC = 1;         //Master Mode
    TXREG = 1;         //EUSART Transmit Data Register
    SCKP = 1;           //Transmit invertet data to the TC/CK pin

    //Transceiver aktivieren
    SREN = 0;           //Disable Single Receive
    CREN = 0;           //Disable Receiver
    //TXEN=1;

    //Enable Interrupt
    INTCONbits.GIE = 1;
    PIE1bits.TXIE = 1;
    PEIE = 1;
    ei();
}

void sendPacket()
{
    #if (TRANSMITTMODE)
    __delay_ms(1);
    #else
    //Start-up time, 2mS
    DATA_OUT = 1;
    __delay_ms(2);
    DATA_OUT = 0;
    #endif

    PIE1bits.TXIE = 1;
    TXSTAbits.TXEN = 1;
}


/** Interrupt vector */
static void interrupt int0()
{
    GIE = 0;
    static UINT8 pc = 0;
    //RF PART
    if (PIR1bits.TXIF){
         switch (p_state) {
            case PREAMBLE:
                pc++;
                //Preamble Statemaschine
                switch (pc){
                    //**Sync Word */
                    case (PREAMBLE_BYTES+1):
                    case (PREAMBLE_BYTES+3):
                        TXREG = 0xCC;
                        break;
                    case (PREAMBLE_BYTES+2):
                    case (PREAMBLE_BYTES+4):
                        TXREG = 0xAA;
                        break;
                    //** Change to send data and send uniqe device ID
                    case (PREAMBLE_BYTES+5):
                        #if DEBUG_COUNTER
                        TXREG = ctr;
                        ctr = ctr + 1;
                        #else
                        TXREG = DEV_ID;
                        #endif
                        pc = 0;
                        p_state = DATA;
                        break;
                    /**Send syncword*/
                    default:
                        TXREG = 0x55;
                        break;
                }                
                break;
        
            case DATA:
                TXREG = dataPacket[pc];
                pc++;
                //Check Packetcounter
                if (pc >= dataPacketSize){
                    pc = 0;
                    p_state = SHDN;                 
                    PIE1bits.TXIE = 0;   //Deactivate Interrupt because than it triggers always
                }
                break;
            default:
                break;
         }
         
      }

    GIE = 1;
    return;
}




void main ()
{
    
  while (1)        
    {
         
    __delay_ms(10);         
          
    PCON = 0x03;
    OSCCONbits.SCS = 0b10;
    #if (_XTAL_FREQ == 8000000)
    OSCCONbits.IRCF = 0b1110;
    #elif (_XTAL_FREQ == 16000000)
    OSCCONbits.IRCF = 0b1111;
    #elif (_XTAL_FREQ == 2000000)
    OSCCONbits.IRCF = 0b1100;
    #else
    #error unsupported clock frequency
    #endif
    OSCCONbits.SPLLEN = 0;
    
     
    
    //Initialize MC
    initPorts();

    //Start H/T measurement
    i2c_Init();
    sensor_read(dataPacket);


    //Initialize RF
    TX_Init();
    init_eusart();
    
    //Send Datapacket
    p_state = PREAMBLE;
    sendPacket();
    
    //Enter Sleep Mode
   if (VOLTAGE_MODE == 1){
     Init_WDT();                //Low Power for 1 or 2 sec
    SLEEP();
   }
        
   else {
       while (1){
           
        //Shutdown transmitter if the transmission is complete
      if (p_state == SHDN)
      {
               TXSTAbits.TXEN=0;                //Transmit Status and Control Register
              #if (TRANSMITTMODE)               //Transmit Disable
                    TX_MT_DIS();
                #endif
                p_state = CMPL;}                
                }
      
         }
  
  }
} // end of main
    
Und die Konfigurationsdatei:


#ifndef _HARDWARE_H_
#define _HARDWARE_H_

// Determine the transmitter
#if defined(_12LF1840T48A)
#define USE_T48A
#elif defined(_12LF1840T39A)
#define USE_T39A
#elif defined(_12LF1840)
// Pick definition manually
//#define USE_T48A
#define USE_T39A
#endif

/** MCU oscillator frequency. Used in PICC __delay macro. */
#define _XTAL_FREQ  16000000

#define CTRL        CTRL_OUT
#define CTRL_OUT    LATAbits.LATA0
#define CTRL_DIR    TRISAbits.TRISA0

#define DATA_OUT    LATAbits.LATA5
#define DATA_DIR    TRISAbits.TRISA5


#define output_pin  0
#define input_pin  1


#define DEV_ID 0x01             //Device ID 0x[ID]

//Havester Voltage Mode 0 == Puls Mode (Havester) // 1 == Constant Voltage (Battery))
#define VOLTAGE_MODE 1

// If in Constant VOLTAGE_MODE: Freqency to send Data
#define SEND_FREQUENCY 2        // 1 == Every 1 sec // 2 == Every 2 sec

#define RF_XTAL 24000000

//18 für Tag
//-17 für evalkit
#define FREQ_CORRECTION 18 //-20 = -27khz

#define PREAMBLE_BYTES 4

//Transmitmode 0 == Automatik // 1 == Manual
#define TRANSMITTMODE 0

#define T39A_APP_CONFIG (T39_MOD_FSK | T39_BAND1 | T39_FDEV_27kHz | T39_TX_0dB | T39_TX_20ms | T39_RESERVED_BITS)
#define T39A_FREQ_CONFIG (FREQUENCY_86985+FREQ_CORRECTION)

/* Macros to access bytes within words and words within longs */
#define LOW_BYTE(x)     ((unsigned char)((x)&0xFF))
#define HIGH_BYTE(x)    ((unsigned char)(((x)>>8)&0xFF))
#define LOW_WORD(x)     ((unsigned short)((x)&0xFFFF))
#define HIGH_WORD(x)    ((unsigned short)(((x)>>16)&0xFFFF))

#endif  // _HARDWARE_H_

Autor: picfan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
in der Watchdog Routine sehe ich WDTCONbits.WDTPS = 0b01010;
sollte dort nicht "WDTCON = 0b01010" stehen?
MFG Picfan

Autor: Julius con Playa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Picfan,

danke für deine Antwort.

Jedoch scheint es, als würde das schon funktionieren. Da der MC selber 
in Sleep Mode wechselt.
Nur der RF Transmitter bleibt weiterhin aktiv...

LG

Autor: Peter F. (loetbrutzel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Julius con Playa,


Im Kapitel 28.2 (Configuring the RF-Transmitter) wird der RF Transmitter 
behandelt. Diesen kann man separat in den sleep-mode versetzen.

Auf Seite 287 im Datasheet ist hierzu einiges Hilfreiches erwähnt.


Good Luck vom

Lötbrutzel

Autor: Peter F. (loetbrutzel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Julius,


Schau Dir vielleicht mal das T-OFFT-Timing (transmitter off timing) an.
Nach Table 28-3 kann man in Bit DA-3 den Wert auf 2ms oder 20ms 
festlegen.

Es könnte sein, dass hier etwas den Sleep-Mode des RF-Transmitters davon 
abhält aktiv zu werden.

Good Luck

LB

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.