Перейти к содержанию
    

Не работает SPI.

Ситуация такова. К AT91SAM7X256 подключены два датчика. Акселерометр ADIS16201 и гироскоп ADIS16255. Акселерометр 3-х вольтовый(5 вольт выдерживает, раньше к авр 5вольтовому был подключен), гироскоп 5-вольтовый(но 3.3В понимает) ну и SAM7X 3-х вольтовый. Подтяжки аппаратные есть только на чип селектах датчиков. чип селект акселерометра подтянут к 3.3В, чип селект гироскопа к 5В. SPCK,MOSI,MISO никаких подтяжек не имеют. при работе на всех ножках (CS,SPCK,MOSI,MISO) напряжение 3.3В. кабель длинной ~40см ну и плюс какое-то(~10см) расстояние на тоненькие(0.15мм) дорожки на самой плате. Это, что касается железной части SPI. Датчики подключены к SPI0. Чип селекты NPCS0..3 не используются! В качестве CS используются две ножки PB0 и PB1. Дергаются программно. Сам интерфейс вроде запускается, клок идет. какие то данные на MISO и MOSI есть. но читается фигня!

Привожу код работы с SPI0. Посмотри пожалуйста, не могу понять где ошибка. Датчики общаются по 16бит SPI. Чтобы с них что-то прочитать нужно сначала отправить адрес регистра который нужно прочитать, датчик вернет результат предыдущего запроса. потом еще раз отправить что-нибудь и датчик тока датчик вернет то, что мы просили у него в первый раз. сама логика работы с акселерометром прописана на стр15 http://www.analog.com/static/imported-file...s/ADIS16201.pdf

 

Выкладываю свой код. Здесь я пытаюсь прочитать по адресу 0x02 напряжение питания акселерометра. он мне возвращает 16 бит, из них 12 само напряжение в binary format.далее оно умножается на 1.22мВ и получается напр питания. у меня по этому коду, читается через раз. иногда 0, иногда ерунда какая-то. показания зависят от положения датчика! если его крутить то данные меняются, если пытаться читать из других регистров то результат примерно такой же. В общем :help:

я думаю ошибка где то в самом коде работы с SPI.раньше это пара датчиков отлично работала с 5В авр.

 

#define SPI_PCS(npcs)       ((~(1 << npcs) & 0xF) << 16)
#define SCBR(_scbr)         (_scbr<<8)

//функция инициализации SPI
void SPI0_Init(void);
//отправка 16 бит данных по SPI
void SPI0_Send_data(unsigned short data);
//функция принимает 16 бит данных по SPI
unsigned short SPI0_Get_data(void);
//Включение чип селекта акселлерометра PB0=0,
//выключение чип селекта гироскопа PB1=1
void ACCE_ON(void);
//Включение чип селекта гироскопа PB1=0,
//выключение чип селекта акселлерометра PB0=0
void GYRO_ON(void);
//Выключение и гироскопа и акселлерометра PB0=1,PB1=1;
void SENSORS_OFF(void);

int main()
{
  
  //Умножаем 12бит данных из регистра POWER SUPPLY на k = 1.22mV и получаем 
  //напряжение питания акселлерометра
  const float k = 1.22;
  //адрес по которому читаем данные
  unsigned short addr = 0x02; 
  unsigned short dummy = 0;
  unsigned short result;
  float POWER_SUPPLY[100]=0;
  //Инициализируем SPI
  SPI0_Init();
  //Будем читать с акселлерометра регистр POWER SUPPLY по адресу 0x02.
  while(1)
{
    //Включаем акселлерометр   
    ACCE_ON();
    //Отправляем в акселлерометр адрес регистра который надо прочитать
    SPI0_Send_data(addr);
    //Читаем результат основанный на предыдущей команде и игнорируем его
    dummy = SPI0_Get_data();
    //После того как отправили адрес по которому хотим прочитать данные. нужно
    //совершить вторую итерацию чтения, по любому адресу. и акселлерометр выдаст нам 
    //данные запрошенные в первой итерации(т.е по адресу addr)
  
    //Вторая итерация чтения
    //Передергиваем чип селект для начала второй итерации чтения
    //Выключаем датчик
    SENSORS_OFF();
    //Включаем чип селект акселлерометра
    ACCE_ON();    
    //Отправляем в акселлерометр любое число. не имеет значения какое
    SPI0_Send_data(addr);
    //В ответ получаем то что лежит по адресу который отправили в первой итерации 
    //чтения
    result= SPI0_Get_data();
    //Выключаем акселлерометр
    SENSORS_OFF();
    //Значащие данные в result - 12бит. затиравем остальное нулями
    result &= 0x0FFF;
    //тут получаем ответ
    POWER_SUPPLY = result *k;
  }   
  return 0;
}

void SPI0_Init(void)
{
  //--------Настройка чип селектов акселлерометра и гироскопа-----------------//
  
  //аппаратные чип селекты не используются для управления гироскопом и 
  //акселлерометром. для активация/деактивации датчиков используются линии 
  //PIO. PB0-чип селект акселлерометра. PB1-чип селект гироскопа.
  //Включение тактирования PIOB
  AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_PIOB;
  //Инициализация PB0 и PB1
  //включение PB0,PB1 как линии ввода,вывода
  AT91C_BASE_PIOB->PIO_PER |= AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //отключение подтягивающих к плюсу питания резисторов
  AT91C_BASE_PIOB->PIO_PPUDR |= AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //настраиваем PB0 и PB1 на выход
  AT91C_BASE_PIOB->PIO_OER |= AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //разрешаем синхронный вывод данных на PB0 и PB1
  AT91C_BASE_PIOB->PIO_OWER |= AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //выключаем оба датчика. PB0=1 и PB1=1
  SENSORS_OFF();
  
  //--------------------------------------------------------------------------//
  
  //----------------------Настройка SPI0--------------------------------------//
  
  //Отключаем PIO от управления MOSI,SCK,MISO,NPCS0.NPCS0-не используется!
  AT91C_BASE_PIOA->PIO_PDR |= AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO |
                               AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
  //Отключаем подтяжки на линиях MISO,MOSI,SPCK
  AT91C_BASE_PIOA->PIO_PPUDR |= AT91C_PA16_SPI0_MISO |
                               AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
  //конфигурируем MOSI,MISO,SPCK,NPCS0 как перифирию A
  AT91C_BASE_PIOA->PIO_ASR |= AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO |
                              AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
  //Включаем тактирование SPI0
  AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_SPI0;
  //отключение SPI и сброс SPI
  AT91C_BASE_SPI0->SPI_CR |= AT91C_SPI_SPIDIS | AT91C_SPI_SWRST;
  //SPI в режиме Master, фиксированная перефирия,тактирование от MCK
  AT91C_BASE_SPI0->SPI_MR |= AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | SPI_PCS(0);
  //CPOL=1,PHASE=1,16 битный режим, SPCKHMhz/255 = 188,2Khz
  AT91C_BASE_SPI0->SPI_CSR[0]  |= AT91C_SPI_CPOL | AT91C_SPI_NCPHA |
                                                 AT91C_SPI_BITS_16 | SCBR(0xFF);
  //SPI enable
  AT91C_BASE_SPI0->SPI_CR |= AT91C_SPI_SPIEN;
  
  //--------------------------------------------------------------------------//
}

void SPI0_Send_data(unsigned short data)
{
  //Ждем когда TDRE и внутреннее сдвигающие устройство станут пустыми
  while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
  //копируем данные в регистр передачи TDR
  AT91C_BASE_SPI0->SPI_TDR = data | SPI_PCS(0) | AT91C_SPI_LASTXFER;
  //Ждем пока данные скопируются в сдвигающий реситр
  while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_TDRE) == 0);
}

unsigned short SPI0_Get_data(void)
{
  //читаем данные 
  while ((AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF) == 0);
  return AT91C_BASE_SPI0->SPI_RDR & 0xFFFF;
}

//Включаем акселлерометр PB0=0, PB1=1
void ACCE_ON(void)
{
  AT91C_BASE_PIOB->PIO_ODSR = (AT91C_PIO_PB1 & ~AT91C_PIO_PB0);
}

//Включаем гироскоп PB0=1, PB1=0
void GYRO_ON(void)
{
  AT91C_BASE_PIOB->PIO_ODSR = (AT91C_PIO_PB0 & ~AT91C_PIO_PB1);
}

void SENSORS_OFF(void)
{
  AT91C_BASE_PIOB->PIO_ODSR |= AT91C_PIO_PB0 | AT91C_PIO_PB1;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

  //CPOL=1,PHASE=1,16 битный режим, SPCKHMhz/255 = 188,2Khz
  AT91C_BASE_SPI0->SPI_CSR[0]  |= AT91C_SPI_CPOL | AT91C_SPI_NCPHA |
                                                 AT91C_SPI_BITS_16 | SCBR(0xFF);

NCPHA нужно сбросить - у него обратная полярность по сравнению с AVR'ом.

 

AT91C_BASE_PMC->PMC_PCER |= 1 << AT91C_ID_PIOB;

Не нужно читать write-only регистры.

 

void SPI0_Send_data(unsigned short data)
unsigned short SPI0_Get_data(void)

Обе эти процедуры можно заменить на одну такую:

unsigned int spi0_trans(unsigned int data)
{
    AT91C_BASE_SPI0->SPI_TDR = data;
    while(!(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF));
    return (AT91C_BASE_SPI0->SPI_RDR);
}

А в случае повышенных требований скорости еще и заинлайнить.

 

AT91C_BASE_PIOB->PIO_ODSR = (AT91C_PIO_PB1 & ~AT91C_PIO_PB0);

Зачем так сложно? Не проще ли написать:

AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB1;

 

P.S. Спасибо, что не пользуетесь атмеловской библиотекой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем так сложно? Не проще ли написать:
AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB1;

А если есть желание отметить, что значение PB0 не забыто, а в него намеренно записан ноль, то можно так:
AT91C_BASE_PIOB->PIO_ODSR = (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0);

P.S. Спасибо, что не пользуетесь атмеловской библиотекой.
Присоединяюсь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Подправил немного код и железо. все равно не работает зараза! пятый день уже сижу :smile3046:

Сделал следующее. выпаял подтягивающий к 5В резистор на линии CS гироскопа. включил внутренние подтягивающие резисторы на SPCK,MISO,MOSI, CS гироскопа. Исправил все места где читались регистры только для записи. исправил процедуру передачи данных по SPI.сбросил NCPHA. Все. больше не знаю, что делать. ставлю брэйкпоинт на while(1), смотрю, что лежит в POWER_SUPPLY. при первом запуске там все 0. жму ресет, запускаю еще раз, там в основном число 90мв, иногда 246мв,иногда 0. :help:

#include <global.h>

#define SPI_PCS(npcs)       ((~(1 << npcs) & 0xF) << 16)
#define SCBR(_scbr)         (_scbr<<8)

//функция иннициализация SPI
void SPI0_Init(void);
//Фунцкия передачи данных по SPI
unsigned int SPI0_trans(unsigned int data);
//Включение чип селекта акселлерометра PB0=0,
//выключение чип селекта гироскопа PB1=1
void ACCE_ON(void);
//Включение чип селекта гироскопа PB1=0,
//выключение чип селекта акселлерометра PB0=0
void GYRO_ON(void);
//Выключение и гироскопа и акселлерометра PB0=1,PB1=1;
void SENSORS_OFF(void);

int main()
{
  //Умножаем 12бит данных из регистра POWER SUPPLY на 1.22mV и получаем 
  //напряжение питания акселлерометра
  const float k = 1.22;
  unsigned int addr = 0x0200; 
  unsigned int dummy = 0;
  unsigned int result;
  unsigned int i=0;
  float POWER_SUPPLY[100]=0;
  //Инициализируем SPI
  SPI0_Init();
  //Будем читать с акселлерометра регистр POWER SUPPLY по адресу 0x02.
  for(i=0;i<100;i++)
  {
    //Включаем акселлерометр    
    ACCE_ON();
    //Отправляем в акселлерометр адрес регистра который надо прочитать
    dummy = SPI0_trans(addr);
    //После того как отправили адрес по которому хотим прочитать данные. нужно
    //совершить вторую итерацию чтения, по любому адресу. и акселлерометр выдаст нам 
    //данные запрошенные в первой итерации(т.е по адресу addr)
  
    //Вторая итерация чтения
    //Передергиваем чип селект для начала второй итерации чтения
    //Выключаем датчик
    SENSORS_OFF();    
    //Включаем чип селект акселлерометра
    ACCE_ON();    
    //Отправляем в акселлерометр любое число. не имеет значения какое
    //В ответ получаем то что лежит по адресу который отправили в первой итерации 
    //чтения
    result = SPI0_trans(addr);
    //Выключаем акселлерометр
    SENSORS_OFF();
    //Значащие данные в result - 12бит. затиравем остальное нулями
    result &= 0xFFF;
    POWER_SUPPLY[i] = result *k;
    }
  
  while(1);
    
  return 0;
}

void SPI0_Init(void)
{
  //аппаратные чип селекты не используются для управления гироскопом и 
  //акселлерометром. для активация/деактивации датчиков используются линии 
  //PIO. PB0-чип селект акселлерометра. PB1-чип селект гироскопа.
  
  //Включение тактирования PIOB и SPI0
  AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOB) | (1 << AT91C_ID_SPI0);
  //Инициализация PB0 и PB1
  //включение PB0,PB1 как линии ввода,вывода
  AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //отключение подтягивающих к плюсу питания резисторов на PB0,SPCK
  //MOSI,MISO. на PB0-есть аппартная подтяжка 4.7K к 3.3В. на PB1 оставляем
  //включенной встроенную в МК подтяжку к 3.3В. SPCK,MOSI,MISO - без подтяжек
  //AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PIO_PB0 | AT91C_PA16_SPI0_MISO |
    //                   AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
  
  //настраиваем PB0 и PB1 на выход
  AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //разрешаем синхронный вывод данных на PB0 и PB1
  AT91C_BASE_PIOB->PIO_OWER = AT91C_PIO_PB0 |  AT91C_PIO_PB1;
  //выключаем оба датчика. PB0=1 и PB1=1
  SENSORS_OFF();
  //Отключаем PIO от управления MOSI,SCK,MISO,NPCS0.NPCS0-не используется!
  AT91C_BASE_PIOA->PIO_PDR = AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO |
                               AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
  //конфигурируем MOSI,MISO,SPCK,NPCS0 как перифирию A
  AT91C_BASE_PIOA->PIO_ASR = AT91C_PA12_SPI0_NPCS0 | AT91C_PA16_SPI0_MISO |
                              AT91C_PA17_SPI0_MOSI  | AT91C_PA18_SPI0_SPCK;
  //отключение SPI и сброс SPI
  AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIDIS | AT91C_SPI_SWRST;
  //SPI в режиме Master, фиксированная перефирия,тактирование от MCK
  AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | SPI_PCS(0);
  //CPOL=1,16 битный режим, SPCKHMhz/255 = 188,2Khz
  AT91C_BASE_SPI0->SPI_CSR[0]  =  AT91C_SPI_CPOL |
                                  AT91C_SPI_BITS_16 | SCBR(0xFF);
  //SPI enable
  AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
  
  //--------------------------------------------------------------------------//
}

unsigned int SPI0_trans(unsigned int data)
{
    AT91C_BASE_SPI0->SPI_TDR = data;
    while(!(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF));
    return (AT91C_BASE_SPI0->SPI_RDR);
}

//Включаем акселлерометр PB0=0, PB1=1
void ACCE_ON(void)
{
  AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB1;
}

//Включаем гироскоп PB0=1, PB1=0
void GYRO_ON(void)
{
  AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB0;
}
//PB0=1,PB1=0
void SENSORS_OFF(void)
{
  AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB0 | AT91C_PIO_PB1;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Хорошо, а что говорит осциллограф? И Вы не пробовали писать в регистры?

 

Осциллограф в наличии только старый GOS-310. Поэтому я не могу проверить, что конкретно передается и принимается. но клок идет. чип селект дергается. на линиях MOSI и MISO какие то данные есть.

но принимается ерунда. самое интересное что если посмотреть буфер POWER_SUPPLY то там будут 0. нажать ресет, перезапустить программу и посмотреть еще раз - какие то цифры. потом опять нажать на ресет и посмотреть, что пришло - нули будут.и так постоянно. один раз нули.другой данные.

 

что значит писать в регистры?

я даже не могу предположить где может быть ошибка...сейчас посмотрел по осциллу на линии MISO был уровень в ~два раза меньше чем 3.3В. хотя pull up включен. допаял резистор - результат то же самый.

 

Хм. сейчас посмотрел на буфер POWER_SUPPLY там всегда поле PCS = 0!!!. такое может быть только если проц работает как слэйв. иначе там должен быть номер текущего чип селекта. то есть там должно быть записано E.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что значит писать в регистры?

Насколько я понимаю, у ADIS16201 есть регистры для записи, можно записать-прочитать-сравнить.

 

Хм. сейчас посмотрел на буфер POWER_SUPPLY там всегда поле PCS = 0!!!. такое может быть только если проц работает как слэйв. иначе там должен быть номер текущего чип селекта. то есть там должно быть записано E.

POWER_SUPPLY у Вас float.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько я понимаю, у ADIS16201 есть регистры для записи, можно записать-прочитать-сравнить.

POWER_SUPPLY у Вас float.

Писать не пробовал. там технология записи такая же, что и чтения(разница в 16бите). но чтение то не работает. пробовал по разным другим регистрам читать. с гироскопа пробовал читать. не работает и все..

на авр все работало..

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте немного модифицировать инициализацию:

  //SPI enable
  AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
  //SPI в режиме Master, фиксированная перефирия,тактирование от MCK
  AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS;
  //CPOL=1,16 битный режим, SPCKHMhz/255 = 188,2Khz
  AT91C_BASE_SPI0->SPI_CSR[0]  =  AT91C_SPI_CPOL |
                                  AT91C_SPI_BITS_16 | SCBR(0xFF);

 

И сделайте хотя бы аппаратный loopback на удаленном конце.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заработало! :yeah: Проблема была в том, что пауза между двумя передергиваниями чип селекта отсутствовала. Надо было доку на датчики читать, а я на проц грешил. такой код работает.

  
for(i=0;i<100;i++)
  {
    //ждем   
    j=0;
    for(j=0;j<800;j++);
    ACCE_ON();
    dummy = SPI0_trans(addr);
    SENSORS_OFF();    
    //ждем опять
    j=0;
    for(j=0;j<800;j++);
    ACCE_ON();   
    result = SPI0_trans(addr);
    SENSORS_OFF();
    result &= 0xFFF;
    POWER_SUPPLY[i] = result *k;
    }
  
  while(1);

всем спасибо за помощь. aaarrr :a14:

Пока писал этот код возникли четыре вопроса.

1) Есть регистры только для записи. Из них читать нельзя. Допустим я хочу в одном месте включить тактирование PIOB. я пишу

AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PIOB)

 

потом, в другом месте программы, я хочу включить тактирование SPI

я пишу

AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI0);

тем самым затирая бит (1 << AT91C_ID_PIOB) и выключая тактирование PIOB.

писать так

AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_SPI0);

чтобы не трогать ранее записанное в PCER значение я не могу.

Вопрос: Как правильно писать в такие регистры(только для записи), чтобы не затирать ранее записанные в них значения?

 

2)

AT91C_BASE_PIOB->PIO_ODSR = (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0);

каков тайный смысл данного кода?я так понял что 1UL и 0UL- это unsigned long единица и ноль.

а (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0) = AT91C_PIO_PB1. в чем смысл этой записи?

 

3)Кто каким образом делаем задержки в программах? в авр была функция __delay_cycles(). и с помощью нее можно было делать паузы. кто как в арм делает?

 

4)Если мне надо работать с данными от байта до двух. какой тип данных под них лучше резервировать? я так думаю, что если памяти не жалко и нужно быстродействие то лучше все переменные хранить в int. процессор то 32 бита(режим АРМ). а если памяти жалко и скорость не важна то лучше распихивать все по char или short в зависимости от велечины переменной. правильно я думаю?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос: Как правильно писать в такие регистры(только для записи), чтобы не затирать ранее записанные в них значения?

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2)

AT91C_BASE_PIOB->PIO_ODSR = (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0);

каков тайный смысл данного кода?я так понял что 1UL и 0UL- это unsigned long единица и ноль.

а (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0) = AT91C_PIO_PB1. в чем смысл этой записи?

Очень простой. Через месяц-полгода глядя в свои же исходники, в которых написано AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB1; вы будете думать "А ведь микросхема висит на PB1 и PB0, я тут забыл PB0! Потом посмотрите в схему и поймете, что в PB0 здесь надо записать ноль и ошибки нет. А глядя в запись (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0) сразу видно: в PB1 записана 1, в PB0 записан 0. Еще один плюс такой записи: надо внести изменение - меняем одну цифру. В вашем же случае пришлось бы стирать или вписывать "AT91C_PIO_PBx".
3)Кто каким образом делаем задержки в программах? в авр была функция __delay_cycles(). и с помощью нее можно было делать паузы. кто как в арм делает?
В ARM время исполнения инструкции зависит от того, откуда выполняется код (ОЗУ, флеш, кэш), от настроек контроллера флеш и других факторов. Поэтому невозможно реализовать __delay_cycles(). Если нужна точная задержка - используйте таймер. Если точность не важна - for(volatile int i = 0; i < TIME; ++i);
4)Если мне надо работать с данными от байта до двух. какой тип данных под них лучше резервировать? я так думаю, что если памяти не жалко и нужно быстродействие то лучше все переменные хранить в int. процессор то 32 бита(режим АРМ). а если памяти жалко и скорость не важна то лучше распихивать все по char или short в зависимости от велечины переменной. правильно я думаю?
В принципе, да. А еще лучше использовать типы из stdint.h, которые добавляют портируемости.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень простой. Через месяц-полгода глядя в свои же исходники, в которых написано AT91C_BASE_PIOB->PIO_ODSR = AT91C_PIO_PB1; вы будете думать "А ведь микросхема висит на PB1 и PB0, я тут забыл PB0! Потом посмотрите в схему и поймете, что в PB0 здесь надо записать ноль и ошибки нет. А глядя в запись (1UL * AT91C_PIO_PB1) | (0UL * AT91C_PIO_PB0) сразу видно: в PB1 записана 1, в PB0 записан 0. Еще один плюс такой записи: надо внести изменение - меняем одну цифру. В вашем же случае пришлось бы стирать или вписывать "AT91C_PIO_PBx".

Я грешным делом думал, что гораздо логичнее было бы написать соответствующий комментарий :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...