Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATmega8 SPI ADS1242
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
URANst
Пытаюсь наладить связь ATmega8 (7.3728 MHz) с ADS1242 (2.4576 MHz) по SPI (WinAVR).
Вопрос : как узнать что пришли данные от ADS1242.
Инициализирую SPI ATmega8 как мастер:
void SPI_MasterInit(void) {
// MOSI,SCK,SS на выход, MISO на вход
DDRB=0x2E;
// Включение SPI, мастер, частота /32
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
SPSR = (1<<SPI2X);
PORTB|=(1<<2);
void SPI_Transmit(unsigned char cData) {
/* Запуск передачи данных */
SPDR = cData;
/* Ожидание завершения передачи данных */
while(!(SPSR & (1<<SPIF)));

В документации на ADS1242 написано, что для чтения данных из регистра нужно послать команду
Encoding: 0001 rrrr xxxx nnnn (rrrr - номер первого регистра для чтения, nnnn читать колличество регистров после первого )

Читаю так:
PORTB&=(~(1<<2));//выбор чипа SS=0;
SPI_Transmit(0x10);//читать регистр с номером 0x00
SPI_Transmit(0x01);// читать 2 регистра начиная с первого
_delay_us (25);// задержка по даташиту мин. 50 Tosc(2.4576)
USART_Transmit(SPDR);//пытаюсь прочитать присланные данные
PORTB|=(1<<2);//SS выставляю в 1 для сброса
читаються то 0x00 то 0xFF
Как понять что данные о первом регистре уже пришли их нада прочитать, ну а затем соответственно и данные от второго регистра
Подскажите что не так
Master
Цитата(URANst @ Jan 21 2008, 16:04) *
...
PORTB&=(~(1<<2));//выбор чипа SS=0;
SPI_Transmit(0x10);//читать регистр с номером 0x00
SPI_Transmit(0x01);// читать 2 регистра начиная с первого
_delay_us (25);// задержка по даташиту мин. 50 Tosc(2.4576)
USART_Transmit(SPDR);//пытаюсь прочитать присланные данные
PORTB|=(1<<2);//SS выставляю в 1 для сброса
читаються то 0x00 то 0xFF
Как понять ...
SPI ведь у нас как работает? Для того, чтобы прочитать, нужно послать smile.gif Ну, в общем, наиболее частом случае.
Если хотите прочитать 2 регистра, то читаем доку, стр.19, и обращаем внимание на Data Transfer Sequence.
Попробуйте вместо выделенной строки вставить что-нибудь вроде:
Код
SPI_Transmit(0xAA); //На самом деле, неважно что посылать
USART_Transmit(SPDR); //Посылаем данные из первого регистра
SPI_Transmit(0xAA); //Тут тоже неважно что посылать
USART_Transmit(SPDR); //Посылаем данные из второго регистра

Удачи!
URANst
Цитата
SPI_Transmit(0xAA); //На самом деле, неважно что посылатьUSART_Transmit(SPDR); //Посылаем данные из первого регистраSPI_Transmit(0xAA); //Тут тоже неважно что посылатьUSART_Transmit(SPDR); //Посылаем данные из второго регистра


Что то я вас не пойму : что значит неважно что посылать ? Там помойему четко написано : для того что бы прочитать регистр нужно записать 0001 - номер регистра(4 бита) - количество регистров(8 бит): всего 2 байта.
Может вы не совсем поняли USART_Transmit(SPDR); читает принятые от АЦП данные и посылает по RS232.
Так вот я спрашивал как мне узнать что из 2-ух байт, которые должны прити, сейчас пришел первый из них, а потом второй . Я имею ввиду может SPIF какой устанавливается или еще что. И еще как поступать если програмирую ATmega8 по SPI. Это оказывает какое влияние на АЦП и если да то что делать. Пока при попытке прочитать шлю 00010000 00000000 (прочитать значение регистра с номером 0x00) принимаю строго 0xFF. Что за ерунда кто скажет.
Aesthete Animus
2URANst

Я полагаю, что должно быть так:

Код
#include <avr\io.h>

#define SPI_PORT PORTB
#define SPI_DDR DDRB

#define MOSI_P PB3
#define MISO_P PB4
#define SCK_P PB5
#define SS_P PB2

// При этом, SS_P подключен к чип-селектку ведеомого устройства


// Эта функция сдвигает по SPI один байт, и возвращает байт,
// прочитанный со слейва
uint8_t spi_shift_byte(uint8_t data)
{    
    SPI_PORT &= ~(1 << SS_P);

    SPDR = data;
    while(!(SPSR & (1 << SPIF)));
    
    SPI_PORT |= (1 << SS_P);
    
    return SPDR;
}


int main(void)
{

    uint8_t data[3]; // Данные прочитанные с АЦП
    
    //////////////////////////////////////////////////////////////////////////
    // Настройки SPI    
    SPI_DDR = (1 << MOSI_P)|(1 << SCK_P)|(1 << SS_P);
    SPI_PORT = (1 << SS_P); // Чипселект в еденице - приемник неактивен
    SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR1);
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    // Далее, судя по документации, делать нужно так:
    
    spi_shift_byte(0x01); // Код команды
    spi_shift_byte(0); // Байт параметров (как я понял). Оставляем пустым
    
    // Далее читаем три байта ригистра АЦП:
    data[2] = spi_shift_byte(0); // Старший байт
    data[1] = spi_shift_byte(0); // Средний байт
    data[2] = spi_shift_byte(0); // Младший байт    
    
}
URANst
До чтения данных оцифровки я еще не дошел (комманда 0x01 по моему она используется без байта параметров).
Я хотел пока прочитать настройки АЦП (регистры SETUP и т.д.) вот сдесь используются команды по 2 байта. Так вот с этим непонятки. В даташите в Data Transfer Sequence еще стоит задержка с которой тож не совсем ясно. С SPI работаю первый раз, так что кто чем может, кто работал уже подскажите как ?
Aesthete Animus
2URANst
Вот я попытался изобразить функции чтения/записи группы регистров. Плюс, некоторые изменения вне в функцию spi_shift_byte.

Код
#include <avr\io.h>
#include <util/delay.h>

#define SPI_PORT PORTB
#define SPI_DDR DDRB

#define MOSI_P PB3
#define MISO_P PB4
#define SCK_P PB5
#define SS_P PB2

#define SELECT() SPI_PORT &= ~(1 << SS_P)
#define DESELECT() SPI_PORT |= (1 << SS_P)

// При этом, SS_P подключен к чип-селектку ведеомого устройства


// Эта функция сдвигает по SPI один байт, и возвращает байт,
// прочитанный со слейва
uint8_t spi_shift_byte(uint8_t data)
{

    SPDR = data;
    while(!(SPSR & (1 << SPIF)));    
    
    return SPDR;
}

adc_read_registers(uint8_t start_address, uint8_t count, uint8_t* buffer)
{
    start_address &= 0x0F;
    count &= 0x0F;

    SELECT();
    
    spi_shift_byte(0x08 | (start_address)); // 0001 rrrr
    spi_shift_byte(count - 1); // xxxx nnnn, почему "минус 1" - написано в документации
  
    // Задержку, я думаю подберете сами...
    _delay_us(25);
    
    for (;count; count--, buffer++)
        *buffer = spi_shift_byte(0); // Читаем count регистров в массив buffer

    DESELECT();
}

adc_write_registers(uint8_t start_address, uint8_t count, uint8_t* buffer)
{
    start_address &= 0x0F;
    count &= 0x0F;
    
    SELECT();
    
    spi_shift_byte(0x50 | (start_address)); // 0101 rrrr
    spi_shift_byte(count - 1); // xxxx nnn, почему "минус 1" - написано в документации
    
    for (;count; count--, buffer++)
        spi_shift_byte(*buffer); // Передаем count значений из массива buffer
        
    DESELECT();
}


int main(void)
{
    //////////////////////////////////////////////////////////////////////////
    // Настройки SPI    
    SPI_DDR = (1 << MOSI_P)|(1 << SCK_P)|(1 << SS_P);
    SPI_PORT = (1 << SS_P); // Чипселект в еденице - приемник неактивен
    SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR1); // F_CPU/128
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    uint8_t buffer[2] = {0xAA, 0xBB}; // Значения от балды...
    
    // Пишем два регистра и buffer, начиная с решистра №1
    adc_write_registers(1, 2, buffer);
    
    // Читаем 2 регситра в buffer, начиная с регистра №5
    adc_read_registers(5,2,buffer);    
}
URANst
Люди подскажите что за ерунда !
#define SPI_PORT PORTB
#define SPI_DDR DDRB

#define MOSI_P PB3
#define MISO_P PB4
#define SCK_P PB5
#define SS_P PB2

#define SELECT() SPI_PORT &= ~(1 << SS_P)
#define DESELECT() SPI_PORT |= (1 << SS_P)

void SPI_init(void) {

SPI_DDR = (1 << MOSI_P)|(1 << SCK_P)|(1 << SS_P);
SPI_PORT = (1 << SS_P); // Чипселект в еденице
SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR1)|(1 << SPR0);// делим 7.3728/128
}

void RREG (void) {
if (SPDR) {};//на всякий случай сбрасываем SPIF
SELECT();// выбор чипа
SPDR = 0x1B;//команда для чтения регистра 0x0B
while(!(SPSR & (1 << SPIF)));
SPDR = 0x00;// читаем колличество регистров 1 + 0x00
while(!(SPSR & (1 << SPIF)));
_delay_us(50);// задержка по даташиту 50 Tosc (2.4576)
SPDR = 0xAA;//записываем что бы прочитать
while(!(SPSR & (1 << SPIF)));
SPI_buf = SPDR;// читаем содержимое регистра 0x0B
USART_Transmit(SPI_buf); посылаем значение по RS 232
DESELECT(); //выключаем чим ведомый
}

После этого принимаю постоянно разные значения
UART налажен нармально - до этого тестился.
CPU_cloc 7.3728
baund rate 9600
UBBR 47

Посоветуйте что нить, а то уже сил нет !
Master
Цитата(URANst @ Jan 22 2008, 11:36) *
...
После этого принимаю постоянно разные значения
UART налажен нармально - до этого тестился.
CPU_cloc 7.3728
baund rate 9600
UBBR 47

Посоветуйте что нить, а то уже сил нет !
Во-первых, научитесь при создании сообщения вставлять исходный текст с помощью соответствующей кнопки (#) - она ведь для этого и создана.
Во-вторых, приведите полный исходник. В данном случае не понятно, что делается в main().
В-третьих, убедитесь сами (а не предлагайте другим считать делители) раз и навсегда, что данные по UART'у передаются корректно: киньте посылку из разных байт и проверьте её приём на другом конце (можете дополнительно сделать это в цикле).
Ну и в-четвёртых, а какие собственно разные данные приходят от ADS1242?

P.S. Для корректности ставьте DESELECT по окончании работы с SPI.
URANst
Выкладываю полный текст программы. После прихода комманды 0x32 и еще чего нибудь
нужно выполнить запись и чтение из АЦП. Подозрение что не работает задержка.
Код
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>



#define UBRRVAL 47

#define SPI_PORT PORTB
#define SPI_DDR DDRB

#define MOSI_P PB3
#define MISO_P PB4
#define SCK_P PB5
#define SS_P PB2

#define SELECT() SPI_PORT &= ~(1 << SS_P)
#define DESELECT() SPI_PORT |= (1 << SS_P)

unsigned char command,statbuf,buf;


[code]void USART_init(void) {
    //Set baud rate
Код
[/code]
    UBRRL=UBRRVAL;            //low byte
    UBRRH=(UBRRVAL>>8);    //high byte
    //Set data frame format: asynchronous mode,no parity, 1 stop bit, 8 bit size
    UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);    
    //Enable Transmitter and Receiver and Interrupt on receive complete
    UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}
void USART_Transmit(unsigned char data) {

    while ( !( UCSRA & (1<<UDRE)) ) {};
    UDR = data;
}

void SPI_init(void) {

    SPI_DDR = (1 << MOSI_P)|(1 << SCK_P)|(1 << SS_P);
    SPI_PORT = (1 << SS_P); // Чипселект в еденице - приемник неактивен
    SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR1)|(1 << SPR0); // F_CPU/128
    
}
unsigned char spi_shift_byte(unsigned char data) {
    
    SPDR = data;
    while(!(SPSR & (1 << SPIF)));    
    return SPDR;
}

unsigned char RREG(unsigned char start_address) {
    unsigned char buffer;
    SELECT();
    spi_shift_byte(0x10 | (start_address)); // 0001 rrrr
    spi_shift_byte(0x01); // xxxx nnnn, почему "минус 1" - написано в документации
    _delay_loop_2(250);
    buffer = spi_shift_byte(0xAA); // Читаем count регистров в массив buffer
    DESELECT();
    return buffer;
}

void WREG(unsigned char address, unsigned char value) {
    SELECT();
    spi_shift_byte(0x50 | (address)); // 0101 rrrr
    spi_shift_byte(0x00); // xxxx nnn, почему "минус 1" - написано в документации
    spi_shift_byte(value); // Передаем count значений из массива buffer
    DESELECT();
}

ISR (USART_RXC_vect) {
    
    while ( !(UCSRA & (1<<RXC)) );
    buf=UDR;
    statbuf=0x01;
}

void processing (void) {

    unsigned char SPI_buf;
    
    if ((statbuf==0x01) && (command==0x00)) {
            command=buf;
            buf=0x00;
            statbuf=0x00;
    }
    if  (command!=0x00) {
        switch (command) {
                case 0x31: {
                            USART_Transmit(0x01);
                            command=0x00;
                            break;    
                }
                case 0x32: {
                            if (statbuf==0x01) {
                                                USART_Transmit(0x02);
                                                
                                                SELECT();
                                                
                                                SPDR = 0x51;
                                                while(!(SPSR & (1 << SPIF)));
                                                SPDR = 0x01;
                                                while(!(SPSR & (1 << SPIF)));    
                                                SPDR = 0x05;
                                                while(!(SPSR & (1 << SPIF)));    
                                                SPDR = 0x07;
                                                while(!(SPSR & (1 << SPIF)));
                                                
                                                DESELECT();
                                                
                                                _delay_ms(10000);
                                                
                                                SELECT();
                                                
                                                SPDR = 0x11;
                                                while(!(SPSR & (1 << SPIF)));
                                                SPDR = 0x01;
                                                while(!(SPSR & (1 << SPIF)));
                                                _delay_ms(25);
                                                SPDR = 0xAB;
                                                while(!(SPSR & (1 << SPIF)));    
                                                SPI_buf=SPDR;
                                                USART_Transmit(SPI_buf);
                                                SPDR = 0xAC;
                                                while(!(SPSR & (1 << SPIF)));
                                                SPI_buf=SPDR;
                                                USART_Transmit(SPI_buf);
                                                
                                                DESELECT();
                                                
                                                    buf=0x00;
                                                    statbuf=0x00;
                                                    command=0x00;
                                                }
                            break;                    
                }
                
                default: {
                           command=0x00;
                           break;
                          }
        }                  
    
    }
}


int main (void) {

    USART_init();
    SPI_init();
    sei();
    
    while (1) {
        processing ();
    }
}
Aesthete Animus
Цитата(URANst @ Jan 22 2008, 16:28) *
Выкладываю полный текст программы. После прихода комманды 0x32 и еще чего нибудь
нужно выполнить запись и чтение из АЦП. Подозрение что не работает задержка.

Кстати, очень может быть - у меня вечно с задержкой _delay_us/_delay_ms были разные проблемы. Лучше пользоваться _delay_loop_2 и вручную рассчитывать задержку. Скажите, какая у вас частота кварца контроллера и кварца ацп?
aesok
Цитата(Aesthete Animus @ Jan 22 2008, 18:03) *
Кстати, очень может быть - у меня вечно с задержкой _delay_us/_delay_ms были разные проблемы. Лучше пользоваться _delay_loop_2 и вручную рассчитывать задержку.


Если у Вас были проблеммы с , то это не причина рекомендовать людям ими не пользоваться.

2 URANst:

1. Совпадат ли значения макроса F_CPU в makefile с реальной частотой контроллера?

2. Какой уровень оптимизации вы используете. Для корректного использования макросов _delay_us/_delay_ms должна быть не менее -01. (Перед включением оптимизации не забудте что в стандарте языка С есть слово 'volatile').

3. В описании функци _delay_ms обратите внимание на предложение:
The maximal possible delay is 262.14 ms / F_CPU in MHz.

Анатолий.
proba
исползую ADS1243 ( 2,43MHz) с Mega16 ( 4,0MHz ).
режим SPI : SPCR = 0x55; ( перечитаите в зависимости частоты atmega) SPSR=0;.
я тоже немного мучился с SPI перед тем как нормально работать стал.

так должно работать, но задержки перечитаите в зависимости частоты atmega.

PORTB&=(~(1<<2));//выбор чипа SS=0;
SPI_Transmit(0x10);//читать регистр с номером 0x00
delay !!! a = 6; while (a--); // @ 4MHz
SPI_Transmit(0x01);// читать 2 регистра начиная с первого
delay !!! a= 60 ; While (a--); // @4MHz
SPI_Transmit(0);
delay a =6; while (a--) // @4MHz
PORTB|=(1<<2);//SS выставляю в 1 для сброса
USART_Transmit(SPDR);//пытаюсь прочитать присланные данные
URANst
Уважаемый proba, что вы имели ввиду под

Код
delay !!! a = 6; while (a--); // @ 4MHz

Код
delay !!! a= 60; While (a--); // @4MHz


Я так понимаю что
Код
a = 6
и
Код
a= 60
- это задержка в периодах, тока подскажите
в периодах чего ? тактовой ATmega8 (7.3728 MHz) или ADS1242 (2.4576 MHz) или частоты SPI (7.3728 MHz/128).
proba может вы мне вышлите какую нить вашу схемку с ADS1242 и файл прошивки (.с) (очень интересно посмотреть) mail:URANstin@mail.ru
А зачем задержка
Код
delay !!! a = 6; while (a--); // @ 4MHz
, в даташите вроде ненаписано что
такую нада использовать.


Подскажите как описать задержку.
Я делаю так:
Код
#include <avr/delay.h> или #include <util/delay.h>
_delay_loop_2(100) ? - 100 в каких единицах ?
_delay_us(50);

Похоже что не работает.

aesok !

Код
1. Совпадат ли значения макроса F_CPU в makefile с реальной частотой контроллера?
да

Код
2. Какой уровень оптимизации вы используете.
s

Код
3. В описании функци _delay_ms обратите внимание на предложение:
The maximal possible delay is 262.14 ms / F_CPU in MHz.
то есть у меня макс 262,14/7,3728=35 ms, а если мне нужна задержка в 1 сек так что цикл лепить.
Как делаете вы задержки.

Извините за ламерские вопросы с WinAVR тока начал работать, сразу понравильсь а ща вот так smile.gif)
И еще подскажите какой WinAVR вы пользуетесь, и где ее можно скачать ? мож у меня версия кривая.
aesok
Код
#include <avr/delay.h> или #include <util/delay.h>
_delay_loop_2(100) ? - 100 в каких единицах ?

в циклах контроллера.

Цитата(URANst @ Jan 22 2008, 22:06) *
Код
3. В описании функци _delay_ms обратите внимание на предложение:
The maximal possible delay is 262.14 ms / F_CPU in MHz.
то есть у меня макс 262,14/7,3728=35 ms, а если мне нужна задержка в 1 сек так что цикл лепить.
Как делаете вы задержки.


Если у вас старая версия WinAVR, то да лепить циклы, или дополнительную функцию задержки. Если WinAVR 20071221 то возможно нет, недавно меняли макрос _delay_ms, и возможно он сам вставит цикл. Посмотрите описание или код _delay_ms в файле util/delay.h
Цитата
И еще подскажите какой WinAVR вы пользуетесь, и где ее можно скачать ? мож у меня версия кривая.

WinAVR

Анатолий.
proba
переписал в более пoнятныи формат.
в даташите там многого нет либо трудно понимат.
но без этих маленких задержек не работал.
в вашем случае вместо 6 > 12 , 60>110.

{
unsigned char a;
PORTB&=(~(1<<2));//выбор чипа SS=0;
SPI_Transmit(0x10);//читать регистр с номером 0x00
a = 6;
while (a--); // delay @ 4MHz
SPI_Transmit(0x01);// читать 2 регистра начиная с первого
a= 60 ;
While (a--); // delay @4MHz
SPI_Transmit(0);
a =6;
while (a--); // delay @4MHz
PORTB|=(1<<2);//SS выставляю в 1 для сброса
USART_Transmit(SPDR);//пытаюсь прочитать присланные данные
}
aesok
Цитата(proba @ Jan 22 2008, 22:19) *
{
unsigned char a;
....
a = 6;
while (a--); // delay @ 4MHz
....
}


Этот код не являеться задержкой на оптимизируещем С компиляторе.

Анатолий.
Aesthete Animus
Отвечу выборочно:

Цитата(URANst @ Jan 22 2008, 22:06) *
Подскажите как описать задержку.
Я делаю так:
Код
#include <avr/delay.h> или #include <util/delay.h>
_delay_loop_2(100) ? - 100 в каких единицах ?
_delay_us(50);

Во первых, именно так (во всяком случае, в верссии 1.4.3)
Код
#include <util/delay.h>


_delay_loop_2(N) соответствует задержке в 4N тактов процессора, плюс задержка на инициализацию цикла. Таким образом, при частоте кварца контроллера 16МГц, _delay_loop_2(4) даст задержку в одну микросекунду. Советую прочитать внимательно документацию, во избежании непредвиденных эфектов.
proba
Цитата(aesok @ Jan 22 2008, 23:23) *
Этот код не являеться задержкой на оптимизируещем С компиляторе.

Анатолий.


и Вы используюте максимальную оптимизацию даже на этапе началного дебаггинга ?
умныи читател понимает что в этих местах надо делать задержки , каким образом это выгядит в оконечном коде, не важно.
URANst
Код
Написал вот такой код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define UBRRVAL 47

#define SPI_PORT PORTB
#define SPI_DDR DDRB

#define MOSI_P PB3
#define MISO_P PB4
#define SCK_P PB5
#define SS_P PB2

#define SELECT() SPI_PORT &= ~(1 << SS_P)
#define DESELECT() SPI_PORT |= (1 << SS_P)

unsigned char command,statbuf,buf;

void delay (unsigned int d,char s) {
    unsigned int i;
    if (s=='u') {
        for(i=0;i<d;i++) _delay_us(1);
    }
        if (s=='m') {
        for(i=0;i<d;i++) _delay_ms(1);
    }
}

void USART_init(void) {
    
    UBRRL=UBRRVAL;            
    UBRRH=(UBRRVAL>>8);    
    UCSRC=(1<<URSEL)|(0<<UMSEL)|(0<<UPM1)|(0<<UPM0)|(0<<USBS)|(0<<UCSZ2)|(1<<UCSZ1)|(1<<UCSZ0);    
    UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
}
void USART_Transmit(unsigned char data) {

    while ( !( UCSRA & (1<<UDRE)) ) {};
    UDR = data;
}

void SPI_init(void) {

    SPI_DDR = (1 << MOSI_P)|(1 << SCK_P)|(1 << SS_P);
    SPI_PORT = (1 << SS_P);
    SPCR = (1 << SPE)|(1 << MSTR)|(1 << SPR1)|(1 << SPR0); // F_CPU/128
    
}
/*
unsigned char spi_shift_byte(unsigned char data) {
    
    SPDR = data;
    while(!(SPSR & (1 << SPIF)));    
    return SPDR;
}

unsigned char RREG(unsigned char start_address) {
    unsigned char buffer;
    SELECT();
    spi_shift_byte(0x10 | (start_address)); // 0001 rrrr
    spi_shift_byte(0x01); // xxxx nnnn, почему "минус 1" - написано в документации
    _delay_loop_2(250);
    buffer = spi_shift_byte(0xAA); // Читаем count регистров в массив buffer
    DESELECT();
    return buffer;
}

void WREG(unsigned char address, unsigned char value) {
    SELECT();
    spi_shift_byte(0x50 | (address)); // 0101 rrrr
    spi_shift_byte(0x00); // xxxx nnn, почему "минус 1" - написано в документации
    spi_shift_byte(value); // Передаем count значений из массива buffer
    DESELECT();
}
*/
ISR (USART_RXC_vect) {
    
    while ( !(UCSRA & (1<<RXC)) );
    buf=UDR;
    statbuf=0x01;
}

void processing (void) {

    unsigned char SPI_buf,SPI_buf1;
    
    if ((statbuf==0x01) && (command==0x00)) {
            command=buf;
            buf=0x00;
            statbuf=0x00;
    }
    if  (command!=0x00) {
        switch (command) {
                case 0x31: {
                            USART_Transmit(0x01);
                            command=0x00;
                            break;    
                }
                case 0x32: {
                            
                                                
                                                
                                                /*
                                                SELECT();
                                                    SPDR = 0x50;
                                                    while(!(SPSR & (1 << SPIF)));
                                                    delay(5,'u');
                                                    SPDR = 0x01;
                                                    while(!(SPSR & (1 << SPIF)));
                                                    delay(5,'u');
                                                    SPDR = 0x03;
                                                    while(!(SPSR & (1 << SPIF)));
                                                    delay(5,'u');
                                                    SPDR = 0x03;
                                                    while(!(SPSR & (1 << SPIF)));
                                                    delay(5,'u');
                                                DESELECT();
                                                */
                                                
                                                
                                                SELECT();
                                                
                                                SPDR = 0x10;
                                                while(!(SPSR & (1 << SPIF)));
                                                delay(5,'u');
                                                SPDR = 0x01;
                                                while(!(SPSR & (1 << SPIF)));
                                                delay(250,'u');
                                                SPDR = 0xAB;
                                                while(!(SPSR & (1 << SPIF)));
                                                SPI_buf=SPDR;
                                                delay(5,'u');
                                                SPDR = 0xAB;
                                                while(!(SPSR & (1 << SPIF)));
                                                SPI_buf1=SPDR;
                                                delay(5,'u');
                                                
                                                
                                                DESELECT();
                                                
                                                
                                                USART_Transmit(SPI_buf);
                                                USART_Transmit(SPI_buf1);
                                                SPI_buf=0x00;    
                                                SPI_buf1=0x00;
                                                buf=0x00;
                                                statbuf=0x00;
                                                command=0x00;
                            break;                    
                }
                
                default: {
                           command=0x00;
                           break;
                          }
        }                  
    
    }
}


int main (void) {

    USART_init();
    SPI_init();
    sei();

    while (1) {
        processing ();

    }
}

Задержки работают
Читаю постоянно то 0x00 0x80 то 0x80 0x80
proba ! а какие вы делали настройки SPI контроллера ?
Aesthete Animus
Цитата(URANst @ Jan 23 2008, 12:18) *
Код
unsigned char RREG(unsigned char start_address) {
    unsigned char buffer;
    SELECT();
    spi_shift_byte(0x10 | (start_address)); // 0001 rrrr
    spi_shift_byte(0x01); // xxxx nnnn, почему "минус 1" - написано в документации
    _delay_loop_2(250);
    buffer = spi_shift_byte(0xAA); // Читаем count регистров в массив buffer
    DESELECT();
    return buffer;
}


Строчкой "spi_shift_byte(0x01)" вы даете команду чтения двух регистров, но потом строчкой "buffer = spi_shift_byte(0xAA)" читаете всего один.
URANst
Извините не удалил это функции.
Я их пока не использую.
Для работы пишу сразу в case 32:

Что то вроде и читается но не несовсем то что нужно ? Во засел.

Уважаемый proba покажите плиз кусок схемы с применением этой ацп и код для контроллера на .с, а то засада, а вы победиили эту ацп. URAnstin@mail.ru
proba
Цитата(URANst @ Jan 23 2008, 13:18) *
Задержки работают
Читаю постоянно то 0x00 0x80 то 0x80 0x80
proba ! а какие вы делали настройки SPI контроллера ?

я уже сказал настроики SPI. нет особо времени глубоко смотрет Ваш код но вроде там нет проверки флага готовности ацп.
URANst
ВЫ имеете ввиду DRDY ? Поправте меня если я не правильно понял, но это флаг устанавливается тогда , когда данные оцифрованы и записаны в регистры данных и готовы к чтению ?
Если ВЫ имеете ввиду не этот флаг, то тогда какой ?

И еще вопрос MISO контроллера нужно настраивать как вход с подтяжкой pull-up ?
Могут ли быть глюки с моей АЦП если не подключены выводы на которые должен подаваться аналоговый сигнал (щас они у меня в воздухе висят) ?
mdmitry
Иногда проблемы возникают из-за инициализации SPI (всего 4 режима). Вы уверены в правильной инициализации?
URANst
УРААААААААА !!!!!
Да действительно вся проблема была в том, что для данная АЦП работает в режиме SPI mode 1 (SPOL=0, SPHA=1).
Вот что делает невнимательность !
Всем большое спасибо за советы и помощь !!!
URANst
Возникло еще парочку вопросов. Когда выставляю оцифровку для униполярного сигнала (бит 6 регистра ACR), то выдаваемое значение в два раза больше настоящего, при биполярном режиме выдает то что надо, сигнал измеряю постоянный, че такое ?
Для чего и когда нужно применять команду DSYNC и нужно ли вообще.
Правильно ли я понимаю, что при включенном буффере макс. входное напряжение Vcc-1.5 ? и как это обойти , если с датчика у меня нормированный сигнал 0-5 V.
Могут ли выставляться разные коээфициенты после внутренней коллибровки, или у меня что , если у меня , то что может быть неправильно ?
Напомню что все вопросы о АЦП ADS1242. Даташит в первом посте.
kostik2
пытаюсь работать с ads1243ipwt квару ads 4.9152, кварц M64 - 11.0592

spi_init();
LED1_ON;
dl=1000;
Del();
while(1)
{
ADC_CS_ON;
while(PING & BIT(2)){};//wait ready
LED1_OFF;
SPI_Write_Byte(0x11);
SPI_Write_Byte(0x00);
a=26; while(a--){};//~22MKS
SPI_Write_Byte(0x00);
a=26; while(a--){};
ADC_CS_OFF;
TxData1(0x77);
TxData1(SPDR);
while(1)
{
LED2_ON;
}
}
ВЫДАЕТ 0

spcr=0x56;

могет кто скинет схему как подключали ads1243 на kostiapan@mail.ru
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.