Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Программный SPI (для карты памяти MMC)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
sergeus
Здравствуйте!
Уже больше часа бьюсь с программной реализацией SPI. При аппаратной реализации карточка памяти инициализировалась и даже читалась, все было нормально. Встала задача реализовать сей интерфейс программно. Вот кусок кода:
Код
unsigned char spi_transmit(unsigned char data){
  unsigned char value,i;
  for (i=0;i<8;i++){
    asm("nop");
    SCK_0;
    asm("nop");
    if ((data & 0b10000000) != 0) SPI_PORT |= (1<<MOSI);
    asm("nop");
    data = data << 1;
    asm("nop");
    value = value << 1;
    SCK_1;
    asm("nop");
    if ((SPI_PIN & (1<<MISO)) != 0){
      value |=0b00000001;
    }
  }
  return value;
}

Может кто свежим взглядом заметит баг.
Тактовая контроллера 8 МГц, контроллер - ATmega48.

Забыл добавить, вот дефайны:
Код
#define MOSI    5
#define MISO    4
#define SCK        3
#define SS        2
#define SPI_DDR    DDRC
#define SPI_PORT PORTC
#define SPI_PIN PINC

#define cbi(reg, bit) (reg&=~(1<<bit))
#define sbi(reg, bit) (reg|= (1<<bit))

#define MMC_CS_1         sbi(SPI_PORT, SS)
#define MMC_CS_0         cbi(SPI_PORT, SS)

#define SCK_1         sbi(SPI_PORT, SCK)
#define SCK_0         cbi(SPI_PORT, SCK)


заметил баг в первом else, ща попробую скомпилить
aaarrr
Тут не хватает установки "0":
Код
if ((data & 0b10000000) != 0) SPI_PORT |= (1<<MOSI);


Переменную value можно спокойно заменить на data. И подумайте, нужны ли вам на самом деле nop'ы.
sergeus
Да, спасибо Вам rolleyes.gif.
Я уже это исправил, тоже заметил.
вот как у меня получилось:
Код
unsigned char spi_transmit(unsigned char data){
  unsigned char value,i;
  for (i=0;i<8;i++){
    asm("nop");
    SCK_0;
    asm("nop");
    if ((data & 0b10000000) != 0) SPI_PORT |= (1<<MOSI);
    else SPI_PORT &=~(1<<MOSI);
    asm("nop");
    data = data << 1;
    asm("nop");
    value = value << 1;
    SCK_1;
    asm("nop");
    if ((SPI_PIN & (1<<MISO)) != 0){
      value |=0b00000001;
    }
  }
  return value;
}


Да, наверное, nop`ы излишне, с переменной value Вы тоже правы. Но главное, что заработало!!!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.