Используя AVR Atmega32 SPI без штырьков SPI

Я довольно новичок в программировании микроконтроллеров. У меня есть некоторый опыт работы с Arduino, но после того, как я почти закончил свой проект, я решил перевести свой текущий проект на что-то более дешевое и меньшее. Поэтому я сейчас использую AVR ATmega32 со студией Atmel.

Я пытаюсь использовать ATmega32 для связи с чипом MAX7219 для мультиплексирования со светодиодной матрицей. однако у меня есть несколько разных устройств, с которыми я хочу общаться.

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

Вот ссылка на техническое описание MA7219

//test

#include <avr/io.h>


int main(void)
{

DDRB = 0b00000111; // pin 1(data), 2(clock) and 3(latch) are outputs

PORTB = 0 << PINB0; // data pin 1 is low
PORTB = 0 << PINB1; // clock pin 2 is low
PORTB = 0 << PINB2; // latch pin 3 is low

uint16_t data;
data = 0b0000110000000000; // data to shift out to the max7219

 //read bit
uint16_t mask;
 for (mask = 0b0000000000000001; mask>0; mask <<= 1) 
{ 
    //iterate through bit mask
    if (data & mask)
    { // if bitwise AND resolves to true
        // send one
        PORTB = 1 << PINB0;
        // tick
        PORTB = 1 << PINB1;
        // tock
        PORTB = 0 << PINB1;
    }
     else{ //if bitwise and resolves to false
        // send 0
        // send one
        PORTB = 0 << PINB0;
        // tick
        PORTB = 1 << PINB1;
        // tock
        PORTB = 0 << PINB1;
    }

}

PORTB = 1 << PINB2; // latch all the data
PORTB = 1 << PINB0; // data pin 1 is high
PORTB = 0 << PINB1; // clock pin 2 is low
PORTB = 0 << PINB2; // latch pin 3 is low
}

1 ответ

Решение

Да, у вашего кода побитового удара есть проблема в том, что вы каждый раз присваиваете полное значение регистра без сохранения существующего значения. Следовательно, вы стираете свой сигнал данных в тот момент, когда вы управляете часами, нарушая время удержания приемника и приводя к непредсказуемой работе.

Вместо того, чтобы назначать контакты с =, вы должны установить их с |= или очистить их &= ~(value)

Например:

     PORTB = 1 << PINB0;      //drive data
    // tick
    PORTB |= 1 << PINB1;      //clock high PRESERVING data
    // tock
    PORTB &= ~(1 << PINB1);   //clock low

Вам также может понадобиться вставить небольшую задержку между операциями с булавками.

Технически, учитывая, что вы уже используете if для состояния данных вы также можете переопределить сигнал данных с помощью ИЛИ в назначении, например

if (data & mask)
{ // if bitwise AND resolves to true
    // send one
    PORTB = 1 << PINB0;
    // tick
    PORTB = (1 << PINB1) | (1 << PINB0);
    // tock
    PORTB = 0 << PINB1 | (1 << PINB0);
}
 else{ //if bitwise and resolves to false
    // send 0
    // send one
    PORTB = 0 << PINB0;
    // tick
    PORTB = 1 << PINB1;
    // tock
    PORTB = 0 << PINB1;
}
Другие вопросы по тегам