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


von Julius con Playa (Gast)


Angehängte Dateien:

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)
1
#include <htc.h>
2
#include "hardware.h"
3
#include "memorymap.h"
4
#include "typedefs.h"
5
#include "T39A.h"
6
#include "i2c.h"
7
#include "shtc1.h"
8
9
10
// PIC12LF1840T39A Configuration Bit Settings
11
12
#include <xc.h>
13
14
// CONFIG1
15
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
16
#pragma config WDTE = SWDTEN       // WDT controlled by the SWDTEN bit in the WDTCON register
17
#pragma config PWRTE = OFF       // Power-up Timer Enable (PWRT enabled)
18
#pragma config MCLRE = ON      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
19
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
20
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
21
#pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset disabled)
22
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
23
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
24
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
25
26
// CONFIG2
27
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
28
#pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
29
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
30
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
31
#pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
32
33
/** enumeration for state maschine*/
34
enum XMIT_STATE
35
{
36
    OFF,
37
    PREAMBLE,
38
    DATA,
39
    CHECKSUM,
40
    SHDN,
41
    CMPL
42
};
43
44
/** Current state of transmitter state machine. */
45
enum XMIT_STATE p_state = OFF;
46
47
/**
48
 * Transmit buffer. 
49
 */
50
#define dataPacketSize 6
51
volatile UINT8 dataPacket[6];// = {0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0xFF};
52
53
54
/**
55
 * Debug Counter //replace DEV ID // Caution: I useses PR2 to get data over the SW reset.
56
 */
57
#define DEBUG_COUNTER 0
58
#if DEBUG_COUNTER
59
volatile UINT8 ctr = 0;
60
#endif
61
62
63
64
/** Initialize microcontroller ports. */
65
void initPorts()
66
{  
67
    // Transmitter control
68
    DATA_OUT = 0;
69
    DATA_DIR = output_pin;
70
    CTRL_OUT = 0;
71
    CTRL_DIR = output_pin;
72
73
    //All ports are digital
74
    ANSELA = 0;
75
    
76
    //Transmit Disable
77
    TXSTAbits.TXEN = 1;
78
}
79
void Init_WDT(void);
80
81
/**Initialize Watchdog Timer */
82
void Init_WDT ()
83
{
84
      if (SEND_FREQUENCY == 1){
85
    WDTCONbits.WDTPS = 0b01010;         //0b01010 = 1:32768; 1sec     
86
    }
87
      else if (SEND_FREQUENCY == 2) {
88
    WDTCONbits.WDTPS = 0b01011;         //0b01011 = 1:65536; 2sec 
89
    }   
90
    WDTCONbits.SWDTEN = 0b01;          // WDT is turned on   
91
}
92
93
94
#define I2C_WRITE 0
95
#define I2C_READ 1
96
97
/** Initialise MSSP port. (12F1822 - other devices may differ) */
98
void i2c_Init(void){
99
100
  // Initialise I2C MSSP
101
  // Master 
102
  TRISA1=1;             // set SCL and SDA pins as inputs
103
  TRISA2=1;
104
105
  SSP1CON1 = 0b00101000;   // I2C enabled, Master mode
106
  SSP1CON2 = 0x00;
107
        // I2C Master mode, clock = FOSC/(4 * (SSPADD + 1))
108
109
        #if (_XTAL_FREQ == 8000000)
110
            SSP1ADD = 4;        // 400Khz @ 8Mhz Fosc
111
        #elif (_XTAL_FREQ == 16000000)
112
            SSP1ADD = 9;        // 400Khz @ 16Mhz Fosc
113
        #elif (_XTAL_FREQ == 2000000)
114
            SSP1ADD = 12;        // 400Khz @ 20Mhz Fosc
115
        #endif
116
117
118
  SSP1STATbits.SMP = 0;   //Slew rate enabled for high speed mode
119
        SSP1STATbits.CKE = 1;   //Enable SMBus compilant Input logic
120
}
121
122
/**
123
 * Reads the I2C SHTC T/H sensor
124
 */
125
void sensor_read (volatile UINT8 dataPacket[]){
126
    //Start Measurement
127
    i2c_Start();                // send Start
128
    i2c_Address(I2C_SLAVE, I2C_WRITE);                  // Send  slave address with write operation
129
    // Start Low Power H/T Measurement with Clock Stetching
130
    i2c_Write(0x44);
131
    i2c_Write(0xDE);
132
133
    //Start Read
134
    i2c_Restart();                // send Start
135
    i2c_Address(I2C_SLAVE, I2C_READ);                  // Send  slave address with read operation
136
    for(char i=0; i<6;i++){
137
            dataPacket[i] = i2c_Read(1);
138
    }
139
    i2c_Stop();  // send Stop
140
}
141
142
/**
143
 * Initialize the EUSART interface for Clock out the plain bit stream for the transceiver
144
 */
145
void init_eusart (void){
146
    //TRISA4 = 0;
147
    //TRISA5 = 0;
148
    //connect to Pin 4/5
149
    TXCKSEL = 1;
150
    RXDTSEL = 1;
151
152
    //Configuriere für Sync Serial
153
    #if (_XTAL_FREQ == 8000000)
154
    SPBRGL = 19;//100k baud @8mhz
155
    //SPBRGL = 128;//50k baud @8mhz
156
    #elif (_XTAL_FREQ == 16000000)
157
    SPBRGL = 39;//100k baud @8mhz
158
    #elif (_XTAL_FREQ == 2000000)
159
    SPBRGL = 4;//100k baud @8mhz
160
    #endif
161
162
    SYNC = 1;         //Synchronous Mode
163
    SPEN = 1;       //Serial Port Enable
164
    CSRC = 1;         //Master Mode
165
    TXREG = 1;         //EUSART Transmit Data Register
166
    SCKP = 1;           //Transmit invertet data to the TC/CK pin
167
168
    //Transceiver aktivieren
169
    SREN = 0;           //Disable Single Receive
170
    CREN = 0;           //Disable Receiver
171
    //TXEN=1;
172
173
    //Enable Interrupt
174
    INTCONbits.GIE = 1;
175
    PIE1bits.TXIE = 1;
176
    PEIE = 1;
177
    ei();
178
}
179
180
void sendPacket()
181
{
182
    #if (TRANSMITTMODE)
183
    __delay_ms(1);
184
    #else
185
    //Start-up time, 2mS
186
    DATA_OUT = 1;
187
    __delay_ms(2);
188
    DATA_OUT = 0;
189
    #endif
190
191
    PIE1bits.TXIE = 1;
192
    TXSTAbits.TXEN = 1;
193
}
194
195
196
/** Interrupt vector */
197
static void interrupt int0()
198
{
199
    GIE = 0;
200
    static UINT8 pc = 0;
201
    //RF PART
202
    if (PIR1bits.TXIF){
203
         switch (p_state) {
204
            case PREAMBLE:
205
                pc++;
206
                //Preamble Statemaschine
207
                switch (pc){
208
                    //**Sync Word */
209
                    case (PREAMBLE_BYTES+1):
210
                    case (PREAMBLE_BYTES+3):
211
                        TXREG = 0xCC;
212
                        break;
213
                    case (PREAMBLE_BYTES+2):
214
                    case (PREAMBLE_BYTES+4):
215
                        TXREG = 0xAA;
216
                        break;
217
                    //** Change to send data and send uniqe device ID
218
                    case (PREAMBLE_BYTES+5):
219
                        #if DEBUG_COUNTER
220
                        TXREG = ctr;
221
                        ctr = ctr + 1;
222
                        #else
223
                        TXREG = DEV_ID;
224
                        #endif
225
                        pc = 0;
226
                        p_state = DATA;
227
                        break;
228
                    /**Send syncword*/
229
                    default:
230
                        TXREG = 0x55;
231
                        break;
232
                }                
233
                break;
234
        
235
            case DATA:
236
                TXREG = dataPacket[pc];
237
                pc++;
238
                //Check Packetcounter
239
                if (pc >= dataPacketSize){
240
                    pc = 0;
241
                    p_state = SHDN;                 
242
                    PIE1bits.TXIE = 0;   //Deactivate Interrupt because than it triggers always
243
                }
244
                break;
245
            default:
246
                break;
247
         }
248
         
249
      }
250
251
    GIE = 1;
252
    return;
253
}
254
255
256
257
258
void main ()
259
{
260
    
261
  while (1)        
262
    {
263
         
264
    __delay_ms(10);         
265
          
266
    PCON = 0x03;
267
    OSCCONbits.SCS = 0b10;
268
    #if (_XTAL_FREQ == 8000000)
269
    OSCCONbits.IRCF = 0b1110;
270
    #elif (_XTAL_FREQ == 16000000)
271
    OSCCONbits.IRCF = 0b1111;
272
    #elif (_XTAL_FREQ == 2000000)
273
    OSCCONbits.IRCF = 0b1100;
274
    #else
275
    #error unsupported clock frequency
276
    #endif
277
    OSCCONbits.SPLLEN = 0;
278
    
279
     
280
    
281
    //Initialize MC
282
    initPorts();
283
284
    //Start H/T measurement
285
    i2c_Init();
286
    sensor_read(dataPacket);
287
288
289
    //Initialize RF
290
    TX_Init();
291
    init_eusart();
292
    
293
    //Send Datapacket
294
    p_state = PREAMBLE;
295
    sendPacket();
296
    
297
    //Enter Sleep Mode
298
   if (VOLTAGE_MODE == 1){
299
     Init_WDT();                //Low Power for 1 or 2 sec
300
    SLEEP();
301
   }
302
        
303
   else {
304
       while (1){
305
           
306
        //Shutdown transmitter if the transmission is complete
307
      if (p_state == SHDN)
308
      {
309
               TXSTAbits.TXEN=0;                //Transmit Status and Control Register
310
              #if (TRANSMITTMODE)               //Transmit Disable
311
                    TX_MT_DIS();
312
                #endif
313
                p_state = CMPL;}                
314
                }
315
      
316
         }
317
  
318
  }
319
} // end of main
1
Und die Konfigurationsdatei:
2
3
4
#ifndef _HARDWARE_H_
5
#define _HARDWARE_H_
6
7
// Determine the transmitter
8
#if defined(_12LF1840T48A)
9
#define USE_T48A
10
#elif defined(_12LF1840T39A)
11
#define USE_T39A
12
#elif defined(_12LF1840)
13
// Pick definition manually
14
//#define USE_T48A
15
#define USE_T39A
16
#endif
17
18
/** MCU oscillator frequency. Used in PICC __delay macro. */
19
#define _XTAL_FREQ  16000000
20
21
#define CTRL        CTRL_OUT
22
#define CTRL_OUT    LATAbits.LATA0
23
#define CTRL_DIR    TRISAbits.TRISA0
24
25
#define DATA_OUT    LATAbits.LATA5
26
#define DATA_DIR    TRISAbits.TRISA5
27
28
29
#define output_pin  0
30
#define input_pin  1
31
32
33
#define DEV_ID 0x01             //Device ID 0x[ID]
34
35
//Havester Voltage Mode 0 == Puls Mode (Havester) // 1 == Constant Voltage (Battery))
36
#define VOLTAGE_MODE 1
37
38
// If in Constant VOLTAGE_MODE: Freqency to send Data
39
#define SEND_FREQUENCY 2        // 1 == Every 1 sec // 2 == Every 2 sec
40
41
#define RF_XTAL 24000000
42
43
//18 für Tag
44
//-17 für evalkit
45
#define FREQ_CORRECTION 18 //-20 = -27khz
46
47
#define PREAMBLE_BYTES 4
48
49
//Transmitmode 0 == Automatik // 1 == Manual
50
#define TRANSMITTMODE 0
51
52
#define T39A_APP_CONFIG (T39_MOD_FSK | T39_BAND1 | T39_FDEV_27kHz | T39_TX_0dB | T39_TX_20ms | T39_RESERVED_BITS)
53
#define T39A_FREQ_CONFIG (FREQUENCY_86985+FREQ_CORRECTION)
54
55
/* Macros to access bytes within words and words within longs */
56
#define LOW_BYTE(x)     ((unsigned char)((x)&0xFF))
57
#define HIGH_BYTE(x)    ((unsigned char)(((x)>>8)&0xFF))
58
#define LOW_WORD(x)     ((unsigned short)((x)&0xFFFF))
59
#define HIGH_WORD(x)    ((unsigned short)(((x)>>16)&0xFFFF))
60
61
#endif  // _HARDWARE_H_

von picfan (Gast)


Lesenswert?

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

von Julius con Playa (Gast)


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

von Peter F. (loetbrutzel)


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

von Peter F. (loetbrutzel)


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

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.