[C] Atmega16 a ADC MAX187

C,C++,C#

Moderátori: psichac, Moderátori

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1538
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

[C] Atmega16 a ADC MAX187

Príspevok od používateľa jirka.jirka. » 29 Jan 2013, 20:59

Hoj hoj.
Tak jsem si zase řekl, že se naučím něco nového. Dneska jsem dostal nápad s AD převodníkem MAX187.
Zapojil jsem ho podle datasheetu (schema zde)

podle datasheetu obsahuje referenci 4.096V. Napsal jsem si rutinu, kterou ten ADC obsluhuju a zobrazuju údaj na LCD, ale ukazují se mi tam čísla a znaky které podle mě nemají.

Třeba nastavil jsem si vstupní napětí 2.00V (podle multimetru) a na LCD se mi zobrazuje údaj: -167xx, kde xx se mi mění a to hodně rychle.

Komunikaci SPI jsem si nastavil na 1MHz.
Jako MCU používám ATmegu16 & 16MHz krystal.

Nenašel by se někdo kdo by pomohl?

Kód: Vybrať všetko

#include <avr/io.h>  
#include <stdio.h>
#include <util/delay.h>  
#include <avr/interrupt.h>  
#include "lcd.h"	//knihovna pro komunikaci s LCD 2004

// Mega16 rozložení pinu
#define MOSI	4
#define MISO	6
#define SCLK	7
#define SS		4

char buffer[50];

unsigned int get_adc(unsigned char adata)
{
	static unsigned int temp=0;
	
	PORTB &= ~(1<<SS);					// SET CS do 0 (aktivovani ADC) 
	_delay_us(10);						// zde by měla být krátká prodleva??
	SPDR = adata;						// vložit data do odesílací registru
	while(!(SPSR & (1<<SPIF)));			// Poslat 1 byte přes HW SPI a čeka na tx
	temp = SPDR;						// přijatá data nahraje do proměnné TEMP
	temp = temp << 8;					// posune proměnnou TEMP o 8 vlevo
	SPDR = adata;						// vloží data do odesílacího registru
	while(!(SPSR & (1<<SPIF)));			// Poslat 1 byte přes HW SPI a čeka na tx	
	temp |= SPDR;						// přijatá data nahraje do proměnné TEMP
	PORTB |= (1<<SS);					// nastavi CS do 1 a tim zakaze ADC 
	return temp;						// navratí hodnotu ADcka
}

void spim_init(void)
{
	// SET PORT B jako výstup 
	DDRB |= (1<<MOSI) | (1<<SCLK) | (1<<SS);
	// SET MISO jako vstup
	DDRB &= ~(1<<MISO); 
	// Povoleni SPI, SPI Master, LSB First, SPI CLK XTAL/16)
	SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0);	
	// nastaveni funkcniho registra SPI (SPCR), CPHA a CPOL v log 0
	SPCR &= ~ (1<<CPOL); 
	SPCR &= ~ (1<<CPHA);	
	// CS HIGH protože SPI ADS je aktivní v 0
	PORTB |= (1<<SS);		 
}

int main (void)
{
	static unsigned int adc_value=0;	// promenna AD prevodniku
	
	lcd_init(LCD_DISP_ON);	    //inicializace LCD
	spim_init();			    // Inicializace SPI jako MASTER

   for(;;){
	adc_value = get_adc(0xFF);				// získání hodnoty z AD prevodniku

	lcd_gotoxy(0,1);
	sprintf(buffer,"%d",adc_value);
	lcd_puts(buffer);	
	}
}
0

delmadord
Okoloidúci
Okoloidúci
Príspevky: 27
Dátum registrácie: 11 Nov 2012, 13:18
Bydlisko: Kežmarok okolie

Re: [C] Atmega16 a ADC MAX187

Príspevok od používateľa delmadord » 30 Jan 2013, 00:15

OT: Ak sa mozem spytat: preco je pin 4 aj na MOSI aj na Slave Select?
// Mega16 rozložení pinu
#define MOSI 4
#define MISO 6
#define SCLK 7
#define SS 4
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1538
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: [C] Atmega16 a ADC MAX187

Príspevok od používateľa jirka.jirka. » 30 Jan 2013, 13:02

No správně má být

Kód: Vybrať všetko

// Mega16 Pinout
#define MOSI	5
#define MISO	6
#define SCLK	7
#define SS		4
Ale díky tomu, že MAX187 je sám na sběrnici a MOSI nepotřebuje tak to funguje.

Už jsem trošku postoupil

Kód: Vybrať všetko

PORTB &= ~(1<<SS);					// SET CS do 0 (aktivovani ADC) 
	_delay_us(10);						// zde by měla být krátká prodleva??
	SPDR = adata;						// vložit data do odesílací registru
	while(!(SPSR & (1<<SPIF)));			// Poslat 1 byte přes HW SPI a čeka na tx
	temp = SPDR;						// přijatá data nahraje do proměnné TEMP
	temp = temp << 8;					// posune proměnnou TEMP o 8 vlevo
	SPDR = adata;						// vloží data do odesílacího registru
	while(!(SPSR & (1<<SPIF)));			// Poslat 1 byte přes HW SPI a čeka na tx	
	temp += SPDR;						// combine data
	temp >>=4;							// posune proměnnou TEMP o 4 vpravo
	PORTB |= (1<<SS);					// nastavi CS do 1 a tim zakaze ADC 
	return temp;						// navratí 12-bit hodnotu ADcka
Ale problém je ten, že čísla na displeji se zobrazují od:
2048 = 0V
4095 = 4.11V
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1538
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: [C] Atmega16 a ADC MAX187

Príspevok od používateľa jirka.jirka. » 30 Jan 2013, 13:14

Ale z datasheetu jsem vyčetl toto:

Kód: Vybrať všetko

byte1   1 B11 B10 B9 B8 B7 B6 B5
byte2  B4  B3  B2 B1 B0 xx xx xx
Takže nejspíš bude problém v těch rotacích a součtu. Ale teď zjistit kde. :(
0

Používateľov profilový obrázok
jirka.jirka.
Ultimate člen
Ultimate člen
Príspevky: 1538
Dátum registrácie: 17 Okt 2008, 00:00
Bydlisko: Uherské Hradiště
Kontaktovať používateľa:

Re: [C] Atmega16 a ADC MAX187

Príspevok od používateľa jirka.jirka. » 30 Jan 2013, 15:48

Tak problém byl vyřešen.

Kód: Vybrať všetko

	static unsigned int temp=0;
	
	PORTB &= ~(1<<SS);				// SET CS do 0 (aktivovani ADC) 
	_delay_us(10);					// zde by měla být krátká prodleva??
	SPDR = adata;					// vložit data do odesílací registru
	while(!(SPSR & (1<<SPIF)));	// Poslat 1 byte přes HW SPI a čeka na tx (příjem MSB)
	temp = SPDR & 0x7F;				// přijatá data nahraje do proměnné TEMP
	temp <<= 8;					// posune proměnnou TEMP o 8 vlevo
	SPDR = adata;					// vloží data do odesílacího registru
	while(!(SPSR & (1<<SPIF)));	// Poslat 1 byte přes HW SPI a čeka na tx (příjem LSB)
	temp += SPDR;					// combine data
	temp >>=3;
	PORTB |= (1<<SS);				// nastavi CS do 1 a tim zakaze ADC 
	return temp;					// navratí 12-bit hodnotu ADcka

Kód: Vybrať všetko

byte1   1 B11 B10 B9 B8 B7 B6 B5
byte2  B4  B3  B2 B1 B0 xx xx xx 
Bylo dúležité vymaskovat v byte1 tu jedničku, to jsem provedl pomocí & 0x7F. No a nakonec stačilo výslednou hotnotu temp rotovat 3x doprava, jak je vidět byte2. No a výsledek se dostavil hned. ;-)
0

Napísať odpoveď
  • Podobné témy
    Odpovedí
    Zobrazení
    Posledný príspevok