Witam Wszystkich. Mam problem z obsługą zewnętrznego przetwornika ADC. W swojej pracy chcę zastosować 12bit przetwornik MAX1270 (link do dokumentacji Link), którego wynik przetwarzania miałby się wyświetlać poprzez RS232 na komputerze (na razie stosuje do tego celu terminal - "Terminal by Bra@y++").
Schemat układu wygląda jak ten zamieszczony w dokumentacji MAX1270, zmodyfikowany jedynie o połączenie wyprowadzenia SSTRB z INT0, co zaznaczyłem na rysunku poniżej).
Udało mi się zrobić komunikację poprzez RS232 jak i transmisję przez SPI. Problem polega na tym, że wyskakują błędne wartości, np. jeśli ustawię przetwornik do pracy w zakresie od 0V do 10V, to zwiększając napięcie od zera, zwiększa się wskazywana przez przetwornik wartość. Dochodząc do napięcia około 4,2V przetwornik pokazuje wartość dziesiętną około 2040, po czym jak mu się zwiększy napięcie to zaczyna wyświetlać wartości od zera ale od teraz zwiększając napięcie zwiększa poprawnie wskazania do maksymalnej wartości czyli 4094 dla 10V (co dla 12bitowego przetwornika zdaje się byś prawidłowe). Nie wiem dlaczego on mi się prawie w połowie zakresu napięcia zeruje, wg. rysunku zamieszczonego poniżej powinien zaczynać od zera i dochodzić do wartości 4094, a nie od zera gdzieś do 2040 i potem od 0 do 4094. Z tego co zauważyłem to zawsze pierwszy pomiar jest prawidłowy - zaraz po włączeniu układu czy po resecie, a potem zaczyna pokazywać takie głupoty (np. jeśli na jego wejście jest podane około 4,3V to wartość jaką pokazuje oscyluje w granicach 200, ale po wykonaniu resetu czy też wyłączeniu i ponownym włączeniu układu pierwszy przeprowadzony pomiar jest poprawny i wynosi około 1700, a potem znowu pokazuje mi wartości w okolicy 200).
Na wejście przetwornika podaję stałe napięcie +10V, które reguluje potencjometrem. w przypadku przetwornika korzystam z wewnętrznego napięcia odniesienia oraz z wewnętrznego zegara.
Dodam że od niedawna zajmuje się samymi uC jak i programowaniem w C (konkretnie w WinaAVR 2071221).
Format danych wychodzących z przetwornika:
Przebieg konwersji:
Poniżej zamieszczam kod programu:
-UART
-SPI
MAIN
Za pomoc z góry dziękuje.
Poprawiłem tytuł:
https://www.elektroda.pl/rtvforum/topic1015361.html
[c_p]
Schemat układu wygląda jak ten zamieszczony w dokumentacji MAX1270, zmodyfikowany jedynie o połączenie wyprowadzenia SSTRB z INT0, co zaznaczyłem na rysunku poniżej).
Udało mi się zrobić komunikację poprzez RS232 jak i transmisję przez SPI. Problem polega na tym, że wyskakują błędne wartości, np. jeśli ustawię przetwornik do pracy w zakresie od 0V do 10V, to zwiększając napięcie od zera, zwiększa się wskazywana przez przetwornik wartość. Dochodząc do napięcia około 4,2V przetwornik pokazuje wartość dziesiętną około 2040, po czym jak mu się zwiększy napięcie to zaczyna wyświetlać wartości od zera ale od teraz zwiększając napięcie zwiększa poprawnie wskazania do maksymalnej wartości czyli 4094 dla 10V (co dla 12bitowego przetwornika zdaje się byś prawidłowe). Nie wiem dlaczego on mi się prawie w połowie zakresu napięcia zeruje, wg. rysunku zamieszczonego poniżej powinien zaczynać od zera i dochodzić do wartości 4094, a nie od zera gdzieś do 2040 i potem od 0 do 4094. Z tego co zauważyłem to zawsze pierwszy pomiar jest prawidłowy - zaraz po włączeniu układu czy po resecie, a potem zaczyna pokazywać takie głupoty (np. jeśli na jego wejście jest podane około 4,3V to wartość jaką pokazuje oscyluje w granicach 200, ale po wykonaniu resetu czy też wyłączeniu i ponownym włączeniu układu pierwszy przeprowadzony pomiar jest poprawny i wynosi około 1700, a potem znowu pokazuje mi wartości w okolicy 200).
Na wejście przetwornika podaję stałe napięcie +10V, które reguluje potencjometrem. w przypadku przetwornika korzystam z wewnętrznego napięcia odniesienia oraz z wewnętrznego zegara.
Dodam że od niedawna zajmuje się samymi uC jak i programowaniem w C (konkretnie w WinaAVR 2071221).
Format danych wychodzących z przetwornika:
Przebieg konwersji:
Poniżej zamieszczam kod programu:
-UART
#define CPU_Hz 12000000 // częstotliwość zegara (kwarcu) w Hz
#define BAUD 14400 // prędkość transmisji dla RS232
#define MYUBRR CPU_Hz/16/BAUD-1
void USART_init(unsigned int ubrr) // INICJALIZACJA
{
UBRRH = (unsigned char) (ubrr>>8); // ustawienie prędkości
UBRRL = (unsigned char) ubrr;
UCSRB = (1<<RXEN)|(1<<TXEN); // transmisja dwukierunkowa, odbieranie/nadawanie
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // ustawienie 8 bitów danych i 1 bit stopu
//UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<UPM1); // ustawienie 8 bitów danych ,1 bit stopu i bit parzystości
}
void USART_out(char data) // WYSYŁANIE ZNAKU
{
while (!(UCSRA & (1<<UDRE))); //*Wait for empty transmit buffer*/
UDR = data; //*Put data into buffer, sends the data*/
}
unsigned char USART_in(void) // ODBIÓR ZNAKU
{
while (!(UCSRA & (1<<RXC))); //Wait for data to be received
return UDR; //Get and return received data from buffer
}
void usart_tablica(char *tablica) //WYSYŁANIE TABLICY
{
unsigned char i=0;
while(tablica[i])
{
USART_out(tablica[i]);
i++;
}
}
-SPI
#define SPI_DDR DDRB
#define SPI_PORT PORTB
#define SPI_PIN PINB
#define SCK 7
#define MISO 6
#define MOSI 5
#define AC_SSTRB 2
#define AC 3
#define AC_OFF SPI_PORT |= _BV(AC)
#define AC_ON SPI_PORT &=~_BV(AC)
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//FUNKCJE BITÓW REJESTRU SPCR//
//
//SPIE (1<<7)-włączenie obsługi przerwania dla SPI, na zakończonie transmisj, albo utraty panowania nad magistralą
//SPE (1<<6)-właczenie modułu SPI
//DORD (1<<5)-bitowa kolejność transmisji; jesli 1 to pierwszym przesyłanym bitem jest LSB z rejestru SPDR, jeśli 0 to wysylany jest najpierw MSB
//MSTR (1<<4)-wybór trybu pracy; 0 - urzadzenie pracuje jako slave, 1 jako master
//CPOL (1<<3)-polaryzacja sygnału zegarowego
//CPHA (1<<2)-faza sygnału zegarowego
//SPR1 (1<<1)-wybór częstotliwości taktowania transmisji
//SPR0 (1<<0)-jak wyżej
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//
// MAX 1270 CONTROL BYTE FORMAT
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define START_AC 7
#define SEL2_AC 6
#define SEL1_AC 5
#define SEL0_AC 4
#define RNG_AC 3
#define BIP_AC 2
#define PD1_AC 1
#define PD0_AC 0
void spi_master_init(void)
{
SPI_DDR |= (_BV(MOSI)|_BV(SCK)|_BV(AC)); //ustawienie wyprowadzeń jako wyjścia; MISO jest ustawiane automatycznie jako wejscie i jej znacznik byłby i tak ignorowany
AC_OFF; //ustawienie stanu wysokieg na wyprowadzeniach
SPCR = (1<<SPE)|(1<<MSTR); //konfiguracja rejestru SPCR
}
void spi_send (char data)
{
SPDR=data;
while(!(SPSR & (1<<SPIF)));
}
char spi_read (void)
{
while(!(SPSR & (1<<SPIF)));
return SPDR;
}
void spi_ac_run (void)
{
unsigned char control_byte;
control_byte= (1<<START_AC)|(1<<RNG_AC)|(1<<PD1_AC);
cli();
AC_ON;
//spi_send(0X8C);
spi_send(control_byte);
AC_OFF;
sei();
}
MAIN
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdlib.h>
#include "uart.h"
#include "spi.h"
#include <util/delay.h>
volatile int wynik=0;
volatile char wynik_msb=0;
volatile char wynik_lsb=0;
char bufor0[7];
char marker2;
void ex_interrupt(void)
{
MCUCR |= _BV(ISC01)|_BV(ISC00);
GICR |= _BV(INT0);
}
void transmisja (void)
{
AC_ON;
spi_send(0x00);
wynik_msb=spi_read(); //MSB
spi_send(0X00);
wynik_lsb=spi_read(); //LSB
AC_OFF;
marker2=1;
}
SIGNAL (SIG_INTERRUPT0)
{
transmisja();
}
//////////////////////// **** program główny **** //////////////////////////////////
int main(void)
{
//DDRx= 0 -wejscie ; 1 -wyjscie
DDRD=0Xff; //ustawienie portu D jako wyjście DIODY PD2-PD6
DDRD &=~_BV(AC_SSTRB);
PORTD=0xff;
DDRB=0Xff;
PORTB=0xff;
USART_init(MYUBRR); //inicjalizacja USARTa
ex_interrupt();
spi_master_init();
spi_ac_run();
while(1)
{
if(marker2)
{
marker2=0;
//wynik=wynik_msb<<4|wynik_lsb>>4;
wynik=wynik_msb;
wynik<<=4;
wynik|=(wynik_lsb>>4)&0x0f;
itoa(wynik,bufor0,10);
usart_tablica(bufor0);
USART_out(13);
USART_out(13);
_delay_ms(900);
dioda3;
spi_ac_run();
}
}
}Za pomoc z góry dziękuje.
Poprawiłem tytuł:
https://www.elektroda.pl/rtvforum/topic1015361.html
[c_p]
