Forum: Mikrocontroller und Digitale Elektronik Proleme beim Auslesen MAX31865 und Programmablauf in C


von Daniel B. (dannyboy1994)


Lesenswert?

Hallo zusammen.

Ich bin derzeit wieder dabei etwas ehr Zeit für die "Bastelei" zu 
investieren. Aktuell möchte ich einen Fillament-Extruder bauen (Die 
Mechanische Seite ist so gut wie fertig.

Als Temperatusensor für die Nozzle habe ich mir einen PT100 in 
Kombination mit einem MAX 31865 geschnappt.

Nach dem ich erst einmal eine Möglichkeit gebaut habe über Timer die 
Motoren durchlaufen zu lassen mit vorgegebener RPM um die CPU nicht zu 
blocken, teste ich nun die Möglichkeiten mit dem MAX aus.

Das Problem ist folgendes. Ich habe hier einen Arduino Mega liegen 
welchen ich gerne verwenden möchte. Dar die Arduino IDE allerdings die 
Timer und sämtliche Resourcen nach belieben selbst konfiguriert, mlchte 
ich das ganze in C umsetzen mit AVR Studio. Meine C Kenntnisse sind 
fasst als katastrophal zu bezeichnen, worum es hier aber nicht gehen 
soll.

Nun habe ich folgendes Problem. Der Serielle Port (USB vom Arduino 
Board) spuckt mir leider nur "Müll" aus.

Und ich stecke in einer gewissen Sackgasse was den MAX angeht. 
anscheinend bleibt der AVR in irgendeiner schleife hängen, was mangels 
RS232 schnittstelle aktuell schwer zu diagnostizieren ist..

Ich wäre ber Hilfe in jeglicher hinsicht mehr als Dankbar.
1
/*
2
 * MAX31Soft_SPI.c
3
 *
4
 * Created: 15.04.2019 16:46:55
5
 * Author : dbern
6
 */ 
7
8
#include <avr/io.h>
9
10
#define F_CPU 16000000UL
11
#define BAUD 9600UL
12
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
13
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
14
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
15
16
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
17
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
18
#endif
19
20
21
uint16_t RTD;
22
uint16_t RTD_value;
23
uint16_t resistance;
24
uint8_t referenz=4300;
25
26
int main(void)
27
{setup_SPI_MAX31865();
28
  USART_Init();
29
  USART_Transmit("X");
30
  while(1)
31
  {
32
    RTD=messure_resistance();
33
    USART_Transmit(RTD);
34
  }
35
}
36
void USART_Init( unsigned int ubrr)
37
{
38
  /* Set baud rate */
39
  DDRE |= (1<<PE1);
40
  UBRR0H = (unsigned char)(ubrr>>8);
41
  UBRR0L = (unsigned char)ubrr;
42
43
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
44
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
45
}
46
47
void USART_Transmit(unsigned char data)
48
{
49
50
  while ( !( UCSR0A & (1<<UDRE0)) );
51
  UDR0 = data;
52
}
53
int setup_SPI_MAX31865(void){
54
  DDRB = (1<<PB2)|(1<<PB1);
55
  SPCR = (1<<SPE)|(1<<MSTR)>(1<<SPR0);
56
  SPI_trans_8(0x80);
57
  SPI_trans_8(0b01000000);        //4WIRE MODE no Fault detection Auto cycle
58
  
59
}
60
61
int SPI_trans_8(uint8_t cData){
62
  SPDR = cData;
63
  while(!(SPSR & (1<<SPIF)))
64
  return SPDR;
65
}
66
67
68
69
70
int messure_resistance(void){
71
  //Temperature (NC) ? (ADC code/32) – 256
72
  SPI_trans_8(0x01);
73
  uint8_t MSB=SPI_trans_8(0);
74
  SPI_trans_8(0x02);
75
  uint8_t LSB=SPI_trans_8(0);
76
  
77
  RTD_value = MSB;
78
  RTD_value<<=8;
79
  RTD_value+=LSB;
80
  RTD_value>>=1;
81
  RTD_value=(RTD_value>>1);
82
  
83
  resistance=RTD_value*referenz*10;
84
  resistance/=32768;
85
  resistance+=0.5;
86
  
87
  
88
  return(resistance);
89
}

von Bärenmarke (Gast)


Lesenswert?

Daniel B. schrieb:
> SPCR = (1<<SPE)|(1<<MSTR)>(1<<SPR0);

Die Zeile macht sicher Probleme, das "größer als" sollte wohl eine Pipe 
sein.
Mit Wurst im SPCR wird auch Wurst im SPDR landen.
1
int messure_resistance(void){
2
  //Temperature (NC) ? (ADC code/32) – 256
3
  SPI_trans_8(0x01);
4
  uint8_t MSB=SPI_trans_8(0);
5
  SPI_trans_8(0x02);
6
  uint8_t LSB=SPI_trans_8(0);
7
  ....

Ich kenne das IC nicht, aber hier wird das Ergebnis der ersten SPI 
Transaktion nicht gesichert. Bist Du sicher, dass das 2. SPI_trans_8 den 
Wert liefert, den Du möchtest?

Compiliert das Programm ohne Meldungen? main() sieht die anderen 
Funktionen ja nicht, da die Prototypen nicht vorhanden sind.

von Bärenmarke (Gast)


Lesenswert?

Den Typ von resistance solltest Du nochmal überdenken. Kann es sein, 
dass die Variable überläuft?

von Daniel B. (dannyboy1994)


Lesenswert?

Bärenmarke schrieb:
> Daniel B. schrieb:
>> SPCR = (1<<SPE)|(1<<MSTR)>(1<<SPR0);
>
> Die Zeile macht sicher Probleme, das "größer als" sollte wohl eine Pipe
> sein.
> Mit Wurst im SPCR wird auch Wurst im SPDR landen.
>
>
1
> int messure_resistance(void){
2
>   //Temperature (NC) ? (ADC code/32) – 256
3
>   SPI_trans_8(0x01);
4
>   uint8_t MSB=SPI_trans_8(0);
5
>   SPI_trans_8(0x02);
6
>   uint8_t LSB=SPI_trans_8(0);
7
>   ....
8
>
>
> Ich kenne das IC nicht, aber hier wird das Ergebnis der ersten SPI
> Transaktion nicht gesichert. Bist Du sicher, dass das 2. SPI_trans_8 den
> Wert liefert, den Du möchtest?
>
> Compiliert das Programm ohne Meldungen? main() sieht die anderen
> Funktionen ja nicht, da die Prototypen nicht vorhanden sind.

Ich komm leider ursprünglich aus der Assembler Fraktion, was man mir 
wohl an der Sauberkeit und Ordnung hier auch anmerkt. C wurde gewählt da 
es schlussendlich doch etwas mehr 16bit Berechnungen werden und C hier 
einfach komfortabler ist.

Es sollte in messure_resistance folgendermaßen ablaufen:
Sende 0x01 (empfangen wird nichts dar es eine Registeradresse ist)
Sende ein DummyByte um das Höherwertige Byte zu empfangen
Sende 0x02 (Adresse LSB)
Sende ein DummyByte um das Niederwertige Byte zu Empfangen

von Bärenmarke (Gast)


Lesenswert?

1
uint16_t RTD;
2
3
void USART_Transmit(unsigned char data)
4
5
// und dann:
6
7
USART_Transmit(RTD);

unsigned char ist 8-Bit, die oberen 8 Bit aus RTD gehen hier verloren.

von Bärenmarke (Gast)


Lesenswert?

Daniel B. schrieb:
> C wurde gewählt da
> es schlussendlich doch etwas mehr 16bit Berechnungen werden und C hier
> einfach komfortabler ist.

Absolut. Dann lies Dir vielleicht nochmal was zur Arithmetik in C durch.
1
resistance=RTD_value*referenz*10;

Hier z.B.: Schon der konstante Teil (referenz*10=43000) "füllt" die 
16-bit
Variable. Bei der Multiplikation mit 2 bist Du über den Wertebereich 
raus. Nimm hier einen 32-bit Typen!

von Daniel B. (dannyboy1994)


Lesenswert?

Bärenmarke schrieb:
>
1
> 
2
> uint16_t RTD;
3
> 
4
> void USART_Transmit(unsigned char data)
5
> 
6
> // und dann:
7
> 
8
> USART_Transmit(RTD);
9
> 
10
>
>
> unsigned char ist 8-Bit, die oberen 8 Bit aus RTD gehen hier verloren.


Das Entstand wohl dadurch das ich ursprünglich direkt die Temperatur 
berechnen und Ausgeben wollte und mich dann doch vorerst mit weniger 
zufrieden geben wollte um erst einmal eien Wert der sich in Abhängigkeit 
der Temperatur ändert beobachten zu können.
Wie könnte man dies vorerst quick&dirty korrigieren?
Der USART soll derweil als Diagnosemöglichkeit herhalten und später die 
Steuerung des ganzen Per LCD und Drehencoder geschehen.


Ich erhalte leider vom USART immer nur ein "?" als Zeichen aus obigen 
Zeile

int main(void)
{setup_SPI_MAX31865();
  USART_Init(UBRR_VAL);
  USART_Transmit("H");

Anscheinend ist bei der USART Konfiguration schon etwas im Busch.

von Karl M. (Gast)


Lesenswert?

Daniel B. schrieb:
> USART_Transmit("H");

Lustig !

Siehst Du diesen Prototype?
>>void USART_Transmit(unsigned char data);

Gibt es denn keine Fehlermeldung(en)?

von Daniel B. (dannyboy1994)


Lesenswert?

Karl M. schrieb:
> Daniel B. schrieb:
>> USART_Transmit("H");
>
> Lustig !
>
> Siehst Du diesen Prototype?
>>>void USART_Transmit(unsigned char data);
>
> Gibt es denn keine Fehlermeldung(en)?

AVR Studio gibt 0 Errors 0 Warnings 0 Messages beim Compilieren aus.

von Bärenmarke (Gast)


Lesenswert?

Daniel B. schrieb:
>> Gibt es denn keine Fehlermeldung(en)?
>
> AVR Studio gibt 0 Errors 0 Warnings 0 Messages beim Compilieren aus.

Dann compiliere das mal mit -Wall -Wextra!

von leo (Gast)


Lesenswert?

Daniel B. schrieb:
> AVR Studio gibt 0 Errors 0 Warnings 0 Messages beim Compilieren aus.

Dann wuerde ich mal ganz schnell danach suchen oder gcc aktualisieren:
e.g.
1
a.c:4:20: warning: large integer implicitly truncated to unsigned type [-Woverflow]
2
   uint8_t referenz=4300;
3
                    ^~~~

leo

von Bärenmarke (Gast)


Lesenswert?

Das hier...

Daniel B. schrieb:
1
 RTD_value>>=1;
2
 RTD_value=(RTD_value>>1);

sieht auch irgendwie "unbeabsichtigt" aus. Du machst zweimal das selbe?

von Daniel B. (dannyboy1994)


Lesenswert?

Bärenmarke schrieb:
> Das hier...
>
> Daniel B. schrieb:
>
1
>  RTD_value>>=1;
2
>  RTD_value=(RTD_value>>1);
3
>
>
> sieht auch irgendwie "unbeabsichtigt" aus. Du machst zweimal das selbe?

Besten Dank, das hatte ich übersehen. Natürlich nur einmal nach rechts 
schieben. Die Frage ist wo er hängen bleibt. Hab AVR Studio nochmal 
compilieren lassen. Habe 9 Wernings und etliche Meldungen. Meine 
C-Kenntinisse lassen in der Richtung doch dann zu wünschen übrig.



Was meint ihr betreff dieses Prototypens?

von Daniel B. (dannyboy1994)


Lesenswert?

Guten morgen zusammen. Ich hab das ganze noch einmal von null auf 
gerollt.
Die Berechnung mit Ablauf stimmen soweit im Simulator. Die Kommunikation 
mit dem MAX31 ADC ist noch nicht geprüft. Auch die Serielle 
Schnittstelle ist noch nicht implementiert.


Hier einmal der COde
1
#include <avr/io.h>
2
#include <math.h>
3
    #define RTD_A 3.9083e-3
4
    #define RTD_B -5.775e-7
5
uint16_t refResistor=430;
6
7
//Rechnung passt. Die Kommunikation mit dem Sensor muss noch geprüft werden. hier könnte der kurze HighPulse von SS ein Problem werden
8
9
int main(void)
10
{
11
  SPI_init();
12
  
13
    while (1) 
14
    {
15
    int8_t temperatur= calculate_temperatur(MAX_read());
16
    PORTA = (temperatur);
17
    };
18
  return(0);
19
}
20
21
22
int SPI_init(void){
23
  //MISO PB3  SCK PB1  SS PB0  MOSI PB2
24
  DDRB |= (1<<PB2)|(1<<PB1);
25
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
26
  //SPI Master Init mit prescaler 128
27
  return(0);
28
}
29
30
int SPI_cycle(int8_t data){
31
  SPDR = data;
32
  while(!(SPSR & (1<<SPIF)));
33
  return (SPDR);
34
}
35
36
int MAX_setup(void){
37
  int8_t ctrl_write = 0x80;
38
  int8_t configbyte = 0b01000000;
39
  
40
  SPI_cycle(ctrl_write);
41
  SPI_cycle(configbyte);
42
  //SS könnte ein Probem werden, dar es zwischenzeitlich high wird
43
  return(0);
44
}
45
46
int MAX_read(void){
47
  SPI_cycle(0x01);
48
  uint8_t rMSB = SPI_cycle(0x00);
49
  SPI_cycle(0x02);
50
  uint8_t rLSB = SPI_cycle(0x00);
51
  
52
  uint16_t  RTD_value = rMSB;
53
       RTD_value<<=8;
54
       RTD_value+=rLSB;
55
       RTD_value>>=1;
56
  return(RTD_value);
57
}
58
59
int calculate_resistance(uint16_t Rt){      //ergebniss von Max Read übergeben
60
  Rt /=32768;
61
  Rt*= refResistor;
62
  
63
  return(Rt, 8);
64
}
65
66
67
int calculate_temperatur(uint16_t Rt){      //ergebniss von resistance
68
    
69
//Temperature (NC) ≈ (ADC code/32) – 256 
70
71
int8_t temp = (Rt/32)-256;
72
return (temp);
73
  }

von Peter D. (peda)


Lesenswert?

Daniel B. schrieb:
> C wurde gewählt da
> es schlussendlich doch etwas mehr 16bit Berechnungen werden und C hier
> einfach komfortabler ist.

Ich würde sogar die ganzen Meßwertumrechnungen in float machen, dann 
hast Du keine Überlaufprobleme mehr. Und die Übertragung zum PC dann als 
Text mit sprintf().

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Daniel B. schrieb:
> int calculate_resistance(uint16_t Rt){
>   Rt /=32768;
Nach dieser Rechnung wird Rt entweder 0 oder 1 sein. Andere Werte gibt 
es hier nicht mehr.
>   Rt*= refResistor;
Ergo wird Rt hiernach entweder 0 oder 430 sein.
>   return(Rt, 8);
Ein Kommaoperator an einer ganz interessanten Stelle.
Ich würde da den Wert 8 als Rückgabewert erwarten. Was erwartest du?
Der Compiler meint zu dieser Zeile:
"warning: left-hand operand of comma expression has no effect"
Sieh auch:
https://en.wikipedia.org/wiki/Comma_operator

: Bearbeitet durch Moderator
von Daniel B. (dannyboy1994)


Lesenswert?

So hier nun einmal ein Code der Zumindest durchläuft. Es sind einige 
Serielle Ausgaben eingebaut um den Ablauf etwas nachvollziehen zu 
könenn.

Der Prinzipielle Abllauf scheint nun zu funktionieren. Auch aus der SPI 
Schleife springt er heraus. Leider spuckt der MAX keinerlei Messwerte 
aus. Ich erhalte nur 000 als LSB und 000 als MSB...
Es ist alles etwas quick and dirty.

1
#include <avr/io.h>
2
#include <math.h>
3
#define F_CPU 16000000UL
4
#define BAUD 19200UL
5
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
8
9
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
10
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
11
#endif
12
#include <stdlib.h>
13
uint16_t refResistor=430;
14
  char puffer[10];
15
16
int main(void)
17
{
18
  USART0_init(UBRR_VAL);
19
  SPI_init();
20
  uart_putc('6');
21
   uart_putc('\n'); 
22
   
23
 MAX_setup();
24
 
25
  uint8_t data=231;
26
27
    while (1) 
28
    {
29
      data=calculate_temperatur(MAX_read());
30
  uart_puts( itoa( data, puffer, 10 ) );    //Variablenwert als Asci senden
31
  uart_putc('\n');
32
  _delay_ms(1000);
33
  
34
    };
35
  return(0);
36
}
37
38
39
int SPI_init(void){
40
  //MISO PB3  SCK PB1  SS PB0  MOSI PB2
41
  DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB4);
42
  PORTB |=(1<<PB4);
43
  SPCR = 0;
44
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0) | (1<<SPR1);
45
  //SPI Master Init mit prescaler 128
46
  return(0);
47
}
48
49
50
int SPI_cycle(uint8_t data){
51
  SPDR = data;
52
  while(!(SPSR & (1<<SPIF))){};
53
  return (SPDR);
54
}
55
56
int MAX_setup(void){
57
  uint8_t ctrl_write = 0x80;
58
  uint8_t configbyte = 0b01000000;
59
    PORTB &= ~(1<<PB4);
60
    
61
  SPI_cycle(ctrl_write);
62
    uart_putc('7');
63
  SPI_cycle(configbyte);
64
  uart_putc('9');
65
    PORTB |=(1<<PB4);
66
  //SS könnte ein Probem werden, dar es zwischenzeitlich high wird......gelöst mit PB4
67
  return(0);
68
}
69
70
int MAX_read(void){
71
  PORTB &= ~(1<<PB4);
72
  SPI_cycle(0x01);
73
  uint8_t rMSB = SPI_cycle(0x00);
74
  PORTB |=(1<<PB4);
75
 uart_puts( itoa( rMSB, puffer, 10 ) );
76
  
77
  PORTB &= ~(1<<PB4);
78
  SPI_cycle(0x02);
79
  uint8_t rLSB = SPI_cycle(0x00);
80
  PORTB |=(1<<PB4);
81
 uart_puts( itoa( rLSB, puffer, 10 ) );
82
  
83
  uint16_t  RTD_value = rMSB;
84
       RTD_value<<=8;
85
       RTD_value+=rLSB;
86
       RTD_value>>=1;
87
  return(RTD_value);
88
}
89
90
int calculate_resistance(uint16_t Rt){      //ergebniss von Max Read übergeben
91
  Rt /=32768;
92
  Rt*= refResistor;
93
  
94
  return(Rt, 8);
95
}
96
97
98
int calculate_temperatur(uint16_t Rt){      //Max Read
99
    
100
//Temperature (NC) ? (ADC code/32) – 256 
101
102
int8_t temp = (Rt/32)-256;
103
return (temp);
104
  }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
int USART0_init(unsigned int ubrr){
129
  
130
  UBRR0 = (unsigned char)ubrr; // Set baud rate
131
132
  UCSR0B = 0b00011000; // USART ein
133
  UCSR0C = 0b10001110; // URSEL 8N1
134
  
135
  return(1);
136
}
137
138
139
140
141
142
143
144
145
146
int uart_putc(unsigned char c)
147
{
148
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
149
    {
150
    }                             
151
152
    UDR0 = c;                      /* sende Zeichen */
153
    return 0;
154
}
155
156
157
/* puts ist unabhaengig vom Controllertyp */
158
void uart_puts (char *s)
159
{
160
    while (*s)
161
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
162
        uart_putc(*s);
163
        s++;
164
    }
165
}

von Daniel B. (dannyboy1994)


Lesenswert?

Ich möchte euch gerne immer am laufenden halten. Leider bekomme ich hier 
4 Fehlermeldungen beim Compilieren. Die Arduino IDE flashed es 
allerdings ohne nachzudenken.

Severity  Code  Description  Project  File  Line
Error    conflicting types for 'write_MAX_reg'  MAX31Soft_SPI 
C:\Users\dbern\Documents\Atmel 
Studio\7.0\MAX31Soft_SPI\MAX31Soft_SPI\main.c  71

Diese Meldung bekomme ich für jede Funktion... leider bekomme ich den 
Fehler nicht behoben und stehe etwas auf dem schlauch.

Messwerte bekomme ich vom MAX31 ebenfalls noch keine. nur 0 als MSB 0 
als LSB und folglich 0 als Temperatur.
ich wäre sehr froh wenn ihr mir dabei helfen könntet. Dann steht 
demnächst die Hochzeit mit dem Teil der stepperansteuerung an.

Gruß Daniel

1
#include <avr/io.h>
2
#include <math.h>
3
#define F_CPU 16000000UL
4
#define BAUD 19200UL
5
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
8
9
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
10
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
11
#endif
12
#include <stdlib.h>
13
uint16_t refResistor=430;
14
char puffer[20];
15
16
int main(void)
17
{
18
  USART0_init(UBRR_VAL);
19
  SPI_init();
20
  uart_putc('6');
21
  uart_putc('\n');
22
  MAX_setup();
23
24
  while (1)
25
  {
26
    uint8_t data=calculate_temperatur(MAX_read_ADC());
27
    uart_puts( itoa( data, puffer, 10 ) );    //Variablenwert als Asci senden
28
    uart_putc('\n');
29
    _delay_ms(1000);
30
    MAX_clear_fault();
31
    
32
  };
33
  return(0);
34
}
35
36
37
int SPI_init(void){
38
  //MISO PB3  SCK PB1  SS PB0  MOSI PB2
39
  DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB4);
40
  PORTB |=(1<<PB4);
41
  SPCR = 0;
42
  SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0) | (1<<SPR1);
43
  //SPI Master Init mit prescaler 128
44
  return(0);
45
}
46
47
int SPI_cycle(uint8_t data){
48
  SPDR = data;
49
  while(!(SPSR & (1<<SPIF))){};
50
  return (SPDR);
51
}
52
53
int MAX_setup(void){
54
  uint8_t ctrl_write = 0x80;
55
  uint8_t configbyte = 0b11000011;
56
  write_MAX_reg(ctrl_write, configbyte);
57
  return(0);
58
}
59
60
61
int MAX_read_fault(void){
62
  return(read_MAX_reg (0x07));
63
}
64
int MAX_clear_fault(void){
65
  uint8_t data=read_MAX_reg(0x00);
66
  data &=~ 0x2C;
67
  write_MAX_reg(0x80,data);
68
  return(1);
69
}
70
71
int write_MAX_reg(uint8_t addrs, uint8_t data){
72
  PORTB &= ~(1<<PB4);
73
  SPI_cycle(addrs);
74
  SPI_cycle(data);
75
  PORTB |=(1<<PB4);
76
  return(1);
77
}
78
79
int read_MAX_reg(uint8_t addrs){
80
81
  PORTB &= ~(1<<PB4);
82
  
83
  SPI_cycle(addrs);
84
  uint8_t  data= SPI_cycle(0x00);
85
  PORTB |=(1<<PB4);
86
  return(data);
87
  
88
}
89
90
91
int MAX_read_ADC(void){
92
  uint8_t MSB=read_MAX_reg(0x01);
93
  uart_puts( itoa( MSB, puffer, 10 ) );
94
  uint8_t LSB=read_MAX_reg(0x02);
95
  uart_puts( itoa( LSB, puffer, 10 ) );
96
  
97
  uint16_t  RTD_value = MSB;
98
  RTD_value<<=8;
99
  RTD_value+=LSB;
100
  RTD_value>>=1;
101
  return(RTD_value);
102
}
103
104
int calculate_resistance(uint16_t Rt){      //ergebniss von Max Read übergeben
105
  Rt /=32768;
106
  Rt*= refResistor;
107
  
108
  return(Rt, 8);
109
}
110
111
112
int calculate_temperatur(uint16_t Rt){      //Max Read
113
  
114
  //Temperature (NC) ? (ADC code/32) – 256
115
116
  int8_t temp = (Rt/32)-256;
117
  return (temp);
118
}
119
int USART0_init(unsigned int ubrr){
120
  
121
  UBRR0 = (unsigned char)ubrr; // Set baud rate
122
123
  UCSR0B = 0b00011000; // USART ein
124
  UCSR0C = 0b10001110; // URSEL 8N1
125
  
126
  return(1);
127
}
128
int uart_putc(unsigned char c)
129
{
130
  while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
131
  {
132
  }
133
134
  UDR0 = c;                      /* sende Zeichen */
135
  return 0;
136
}
137
/* puts ist unabhaengig vom Controllertyp */
138
void uart_puts (char *s)
139
{
140
  while (*s)
141
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
142
    uart_putc(*s);
143
    s++;
144
  }
145
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Daniel B. schrieb:
> Messwerte bekomme ich vom MAX31 ebenfalls noch keine.
Nimm einen Logikanalyzer oder ein Speicheroszi und miss die 
Kommunikation. Dann kannst du wenigstens sehen, was du am MOSI sendest 
und kontrollieren, ob das zu dem passt, was der MAX laut Datenblatt 
erwartet. Und du kannst sehen, ob der am MISO überhaupt irgendwie auf 
dein Kommando reagiert. Ohne LA/Oszi kann man solche seriellen 
Schnittstellen meist nur unglaublich holprig per Try&Error in Betrieb 
nehmen.

von Bernd N (Gast)


Lesenswert?


von Falk B. (falk)


Lesenswert?

Daniel B. schrieb:
> Ich möchte euch gerne immer am laufenden halten. Leider bekomme ich hier
> 4 Fehlermeldungen beim Compilieren. Die Arduino IDE flashed es
> allerdings ohne nachzudenken.
>
> Severity  Code  Description  Project  File  Line
> Error    conflicting types for 'write_MAX_reg'  MAX31Soft_SPI
> C:\Users\dbern\Documents\Atmel
> Studio\7.0\MAX31Soft_SPI\MAX31Soft_SPI\main.c  71

Da stimmen die Datentypen zwischen Funktionsdeklaration und Aufruf nicht 
überein.

1.) Lange Texte gehören in den Anhang, siehe Netiquette.

> Messwerte bekomme ich vom MAX31 ebenfalls noch keine. nur 0 als MSB 0
> als LSB und folglich 0 als Temperatur.

> ich wäre sehr froh wenn ihr mir dabei helfen könntet.

Du musst erstmal einen GAAANZ einfachen SPI-Zugriff machen und testen. 
Also ein möglichst einfaches Register lesen und schreiben, z.B.  High 
Fault Threshold MSB. Wenn das funktioniert geht es weiter, siehe 
Fehlersuche.

Ein Oszi oder Logicanalyzer ist hier SEHR hilfreich.

"Nun habe ich folgendes Problem. Der Serielle Port (USB vom Arduino
Board) spuckt mir leider nur "Müll" aus.

Und ich stecke in einer gewissen Sackgasse was den MAX angeht.
anscheinend bleibt der AVR in irgendeiner schleife hängen, was mangels
RS232 schnittstelle aktuell schwer zu diagnostizieren ist.."

So geht das nicht! Zuerst muss dein UART laufen, damit du ein Chance 
hast, den Fehler zu finden!

von daniel bernhard (Gast)


Lesenswert?

Falk B. schrieb:
> Daniel B. schrieb:
> Ich möchte euch gerne immer am laufenden halten. Leider bekomme ich hier
> 4 Fehlermeldungen beim Compilieren. Die Arduino IDE flashed es
> allerdings ohne nachzudenken.
> Severity  Code  Description  Project  File  Line
> Error    conflicting types for 'write_MAX_reg'  MAX31Soft_SPI
> C:\Users\dbern\Documents\Atmel
> Studio\7.0\MAX31Soft_SPI\MAX31Soft_SPI\main.c  71
>
> Da stimmen die Datentypen zwischen Funktionsdeklaration und Aufruf nicht
> überein.
>
> 1.) Lange Texte gehören in den Anhang, siehe Netiquette.
>
> Messwerte bekomme ich vom MAX31 ebenfalls noch keine. nur 0 als MSB 0
> als LSB und folglich 0 als Temperatur.
>
> ich wäre sehr froh wenn ihr mir dabei helfen könntet.
>
> Du musst erstmal einen GAAANZ einfachen SPI-Zugriff machen und testen.
> Also ein möglichst einfaches Register lesen und schreiben, z.B.  High
> Fault Threshold MSB. Wenn das funktioniert geht es weiter, siehe
> Fehlersuche.
>
> Ein Oszi oder Logicanalyzer ist hier SEHR hilfreich.
>
> "Nun habe ich folgendes Problem. Der Serielle Port (USB vom Arduino
> Board) spuckt mir leider nur "Müll" aus.
>
> Und ich stecke in einer gewissen Sackgasse was den MAX angeht.
> anscheinend bleibt der AVR in irgendeiner schleife hängen, was mangels
> RS232 schnittstelle aktuell schwer zu diagnostizieren ist.."
>
> So geht das nicht! Zuerst muss dein UART laufen, damit du ein Chance
> hast, den Fehler zu finden!


Also in Aktueller Version läuft der USART. Das Problem waren " " statt ' 
'.
weitere Tests folgen heute Nacht. Die Schleifen durchläuft er jetzt 
ebenfalls vernünftig. Nur das Problem einer toten Kommunikation bleibt 
bestehen.

Eine weitere kleine Fehlerquelle ist aktuell denke ich auch der weg wie 
ich den AVR flash.  Ich schreibe in Atmel Studio 7 und flashe und 
recompiliere dabei den Code mit der Arduino IDE, um den Bottloader und 
die serielle Schnittstelle weiterhin nutzen zu können.

Gruß Daniel
PS: Ich werde absofort den Quellcode als .c Anhängen.

von Bernd N (Gast)


Lesenswert?

Hast du dir den verlinkten Artikel angesehen ?

von Daniel B. (dannyboy1994)


Lesenswert?

Bernd N schrieb:
> Hast du dir den verlinkten Artikel angesehen ?

In dem Artikel geht es um die Problematik das CS nach jedem Byte High 
Level annimmt. Ich habe allerdings schon einen seperaten CS eingebaut 
welcher bei mir an Portb4 angeschlossen ist. An den LA hab ich das ganze 
noch nicht anschließen können zwecks Zeitmangel.

Gruß Daniel

von Daniel B. (dannyboy1994)


Lesenswert?

Guten Abend zusammen. Nun mit aktuellem oberen Code erhalte ich nach 
Identifizierung eines Verdrahtungsfehlers durchgehend 0xFF als Wert 
zurück gegeben. Die Arduino IDE compiliert ihn Probemlos, AVR STUDIo hat 
allerdings ein Problem mit :

Severity  Code  Description  Project  File  Line
Error    conflicting types for 'write_MAX_reg'  MAX31Soft_SPI 
C:\Users\dbern\Documents\Atmel 
Studio\7.0\MAX31Soft_SPI\MAX31Soft_SPI\main.c  70
Error    conflicting types for 'read_MAX_reg'  MAX31Soft_SPI 
C:\Users\dbern\Documents\Atmel 
Studio\7.0\MAX31Soft_SPI\MAX31Soft_SPI\main.c  77
Error    conflicting types for 'uart_putc'  MAX31Soft_SPI 
C:\Users\dbern\Documents\Atmel 
Studio\7.0\MAX31Soft_SPI\MAX31Soft_SPI\main.c  126



Ich komm hier allerdings nicht auf die Lösung. ich übergebe eine uint8_t 
an die Funktion welche einen uint8_t erwartet und erhalte einen 
Fehler???

Gruß Daniel

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.