Проблемы с аппаратным spi

Тема в разделе "Arduino & Shields", создана пользователем Stinger, 3 фев 2022.

Метки:
  1. Stinger

    Stinger Нуб

    Добрый день! Я захотел подключить сдвиговый регистр 74hc595n по интерфейсу SPI. В итоге я столкнулся с проблемой - SPI просто не работает.
    Код (C++):

    #define CS 4
    #define SCK 5
    #define DS 3
    void setup()
    {
      DDRD =  (1 << CS);
      PORTD |= (1 << CS); // Init
      DDRB |= (1 << DS) | (1 << SCK);
      SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
    }


    void transmit(char data){
      PORTD &= ~(1 << CS);
      SPDR = data;
      while(!(SPSR & (1<<SPIF)));
      PORTD |= (1 << CS);
    }

    void loop()
    {
      for(int i = 0; i < 8; ++i){
          char data = 1 << i;
        transmit(data);
        delay(1000);
      }
    }
    Проверил на клонах Ардуино от разных производителей, в Tinkercad - результат везде одинаковый. Проверил логическим анализатором - на выводах SPI вообще ничего не происходит. В чем может быть проблема?
     
  2. Stinger

    Stinger Нуб

    Вот что выдает логический анализатор:
    [​IMG]
     
  3. issaom

    issaom Гуру

    Посмотрите ТУТ. Развлекался с SPI давно - сюда перепостивать лень.
     
  4. parovoZZ

    parovoZZ Гуру

    Где-то в своих темах описывал, как правильно инициализировать SPI на старых авр.
     
  5. parovoZZ

    parovoZZ Гуру

    Кстати, пин CS должен быть выходом. Если он будет входом и на него прилетит минус, то SPI перейдёт в режим SLAVE сразу же.
     
  6. akl

    akl Гуру

    кстати где-то там как раз и подсмотрел когда в атмеге 8 запускал
    вот так получилось - вроде работает

    Код (C++):
    #define SPI_PORT PORTB
    #define SPI_DDR DDRB
    #define SPI_SS 2
    #define SPI_MOSI 3
    #define SPI_MISO 4
    #define SPI_SCK 5

    void SPI_Init(void){//все выводы, кроме MISO выходы
       SPI_DDR |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
       SPI_PORT |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS);//|(1<<SPI_MISO);
       //без прерываний,разрешение spi,старший бит вперед, мастер, режим 1:0, скорость минимум
       SPCR = (0<<SPIE)|(1<<SPE)|(0<<DORD)|(1<<MSTR)|(1<<CPOL)|(0<<CPHA)|(1<<SPR1)|(1<<SPR0);
       SPSR = (0<<SPI2X);
    }
    void SPI_sendArray(uint8_t num, uint8_t *data_out){
        SPI_PORT &= ~(1<<SPI_SS);
        _delay_ms(1);
        while(num--){
            SPDR = *data_out;
            while(!(SPSR & (1<<SPIF)));
            *data_out++=SPDR;
        }
        _delay_ms(1);
        SPI_PORT |= (1<<SPI_SS);
    }
     
     
  7. Asper Daffy

    Asper Daffy Иксперд

    В том, что "летать не умеете, а выпендриваетесь".
    Кто или что мешает пользоваться библиотекой SPI? Вы же не умеете работать с регистрами.
    В общем, так,
    1. Какой контроллер (если ардуина, то какая и на каком контроллере)?
    2. Как всё подключено?
    А то без ответов на эти вопросы я буду полчаса бить пальцы об клавиши, чтобы потом услышатт, что там всё не то и не так.
     
    DetSimen, b707 и SergeiL нравится это.
  8. Stinger

    Stinger Нуб

    Спасибо, не заметил эту особенность в Datasheet. Изменил на выход - всё стало работать как надо.
     
  9. Stinger

    Stinger Нуб

    Научите работать с регистрами?
     
  10. b707

    b707 Гуру

    вы бы начали с ардуино - там для сдвигового регистра готовые методы есть
     
  11. parovoZZ

    parovoZZ Гуру

    Внимательнее надо читать. И лучше в оригинале.