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

Сбылась мечта идиота - приехали программатор и SAM7S256

Проблема решена. Дело было в локализации KEIL в папке озаглавленной русскими буквами.

Включать и выключать светодиоды я научился.

Не получается почему-то запустить код в RAM (((

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


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

Как же все-таки сложно переделывать заложенные в голове азбучные истины.

В АВР было просто - PORTA.1=1, либо PORTA.1=0;

В ARM же CODR, SODR.

Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот?

У меня складывается ассоциация как с кнопками - в АВР одна кнопка которую можно либо нажать либо отжать, а в SAM7 - две кнопки, из которых одновременно может быть нажата только одна, при нажатии одной, вторая автоматом отщелкивается. Я правильно понял логику работы пина?

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


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

В АВР было просто - PORTA.1=1, либо PORTA.1=0;
Тяжелое наследие CVAVR. В стандартном С нет записи вида Var.Bit

Макросы имени Аскольда Волкова спрячут реализацию - что на AVR, что на ARM, что на PIC, что на MSP: on(LED); off(LED);

Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот?
Нет. Из SODR читать вообще нельзя. Для чтения состояния там соседний регистр. Логику вы поняли правильно.

 

 

То есть Вашмим словами - ULINK это не название программатора?
Название программатора. Но ведь никто не запрещает этим же названием назвать совокупность значений опций среды, необходимых для сборки и отладки проекта именно этим программатором ;)

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


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

Как же все-таки сложно переделывать заложенные в голове азбучные истины.

В АВР было просто - PORTA.1=1, либо PORTA.1=0;

В ARM же CODR, SODR.

Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот?

У меня складывается ассоциация как с кнопками - в АВР одна кнопка которую можно либо нажать либо отжать, а в SAM7 - две кнопки, из которых одновременно может быть нажата только одна, при нажатии одной, вторая автоматом отщелкивается. Я правильно понял логику работы пина?

 

Вы полагаете, это плохо, что в ARM кроме записи слова в регистр аппаратно реализованы так же и установка отдельных битов регистра в 1,

установка отдельных битов регистра в 0 и побитовая адресация регистров?

Вам эти расширенные возможности обращения с регистрами мешают?

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


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

Как же все-таки сложно переделывать заложенные в голове азбучные истины.

В АВР было просто - PORTA.1=1, либо PORTA.1=0;

В ARM же CODR, SODR.

Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот?

У меня складывается ассоциация как с кнопками - в АВР одна кнопка которую можно либо нажать либо отжать, а в SAM7 - две кнопки, из которых одновременно может быть нажата только одна, при нажатии одной, вторая автоматом отщелкивается. Я правильно понял логику работы пина?

 

А мне очень понравилось это расширение от привычной по AVR схемы. Вот как выглядят привычные подпрогаммы выдачи полубайтов:

 

#define LCD_TARGET_PORT_S            (AT91C_BASE_PIOA->PIO_SODR)
#define LCD_TARGET_PORT_C            (AT91C_BASE_PIOA->PIO_CODR)

#define LCD_DIRECTION_PORT_S        (AT91C_BASE_PIOA->PIO_OER)
#define LCD_DIRECTION_PORT_C        (AT91C_BASE_PIOA->PIO_ODR)
#define LCD_INPUT_PORT            (AT91C_BASE_PIOA->PIO_PDSR) // was PINA 

#define STROBE_BIT AT91C_PIO_PA31
#define WRITEE_BIT AT91C_PIO_PA1
#define ADDRES_BIT AT91C_PIO_PA0
#define DATAS_BITS (AT91C_PIO_PA26 | AT91C_PIO_PA25 | AT91C_PIO_PA24 | AT91C_PIO_PA23)
#define DATA_BIT_LOW 23        // какой бит данных младшй в слове считанном с порта


// sent four bits from d7..d4 of argument v
static void 
ws1602_send4_high(uint_fast8_t v)
{
    LCD_TARGET_PORT_S = (v << (DATA_BIT_LOW - 4)) & DATAS_BITS;
    LCD_TARGET_PORT_C = ~ (v << (DATA_BIT_LOW - 4)) & DATAS_BITS;
}

// send four bits from d3..d0 of argument v
static void 
ws1602_send4_low(uint_fast8_t v)
{
    LCD_TARGET_PORT_S = (v << (DATA_BIT_LOW - 0)) & DATAS_BITS;
    LCD_TARGET_PORT_C = ~ (v << (DATA_BIT_LOW - 0)) & DATAS_BITS;
}

static uint_least8_t 
ws1602_pulse_strobe(void)
{
    uint_fast8_t v;

    LCD_TARGET_PORT_S = STROBE_BIT;     // activate EN signal
    ws1602_delay();
    v = (LCD_INPUT_PORT & DATAS_BITS) >> DATA_BIT_LOW;
    LCD_TARGET_PORT_C = STROBE_BIT;     // deactivate EN signal
    ws1602_delay();
    return v;
}

Изменено пользователем Genadi Zawidowski

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


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

Нет. Из SODR читать вообще нельзя. Для чтения состояния там соседний регистр. Логику вы поняли правильно.

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

Под соседним регистром вы имеете ввиду ODSR?

 

Вы полагаете, это плохо,

 

Я понимаю, что более гибкий доступ к функциям камня это хорошо, мне непонятно, почему так сделано. Ведь в любом слчуае выполняется оперция присваивания. Ну ведь логически проще написать ВЫХОД_Х=1, чем писать ПРИЗНАК_ВКЛЮЧЕННОСТИ=БИНАРНОЕ_ЧИСЛО_ОПРЕДЕЛЯЮЕЕ_НОМЕРА_ВЫХОДОВ_ПРИЗНАК_ВКЛЮЧЕННО

СТИ_КОТОРЫХ_НАСТРАИВАЕТСЯ или ПРИЗНАК_ВЫКЛЮЧЕННОСТИ=БИНАРНОЕ_ЧИСЛО_ОПРЕДЕЛЯЮЩЕЕ_НОМЕРА_ВЫХОДОВ_ПРИЗНАК_ВЫКЛЮЧЕ

ННОСТИ_КОТОРЫХ_НАСТРАИВАЕТСЯ. Опять таки, если я правильно понял логику работы.

 

 

аппаратно реализованы так же и установка отдельных битов регистра в 1,

установка отдельных битов регистра в 0 и побитовая адресация регистров?

Разве в AVR такого не было?

 

Вопрос такой, каковы преимущества порта в ARM по сравнению с AVR, кроме того, что можно читать состояние пинов, как пишет Редькин, непосредственно на выходе?

 

Вот скажем, в ODSR откуда берется информация? Она попадает туда во время записи в регистр SODR, или же состояние ODSR зависит от фактического состояни пина? Ну скажем, что-то на выходе порта выгорело, или на выходе значительная просадка напряжения, мы пишем в него единичку, а результата не имеем, можно ли это диагностировать с помощью ODSR ?

 

Посмотрел я макросы Аскольда. А не слишком ли громоздко?

Например

#define _setL(port,bit)         do { AT91C_BASE_PIO##port##->PIO_CODR = (1 << bit); } while(0)

 

Не до хрена ли это тактов займет?

 

Или вот еще круче - одно и то ж действие по-разному обзывается:

#define _setH(port,bit)         do { AT91C_BASE_PIO##port##->PIO_SODR = (1 << bit); } while(0)
#define _clrL(port,bit)         do { AT91C_BASE_PIO##port##->PIO_SODR = (1 << bit); } while(0)

 

Ведь как я понял, по принципу двух исключающих друг друга конпок, SetH автоматом делает ClearL.

 

охох..голова кругом, сколько плясок с бубном...

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


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

Под соседним регистром вы имеете ввиду ODSR?
Да. И в него можно писать состояние всего порта, как и в PORTx в AVR (записав единицы в нужные биты OWSR).

Я понимаю, что более гибкий доступ к функциям камня это хорошо, мне непонятно, почему так сделано. Ведь в любом слчуае выполняется оперция присваивания.

Ну ведь логически проще написать ВЫХОД_Х=1, чем писать

Это вам на С кажется, что PORTC.1=1 это одна операция присваивания. На ассемблере (без оптимизации или для портов, не попавших в IO space, как PORTE) это операция чтения, наложения маски по "или" и запись обратно в порт. А перед этим еще загрузка маски в регистр, потому что AVR умеет "или" только с регистром. А в случае SODR/CODR это будет действительно одна операция записи (и одна загрузки маски в регистр). Причем если надо одной командой установить до восьми соседних битов, то даже загрузку маски можно уместить в эту же команду за счет использования аппаратного сдвигателя ARM.

 

Вопрос такой, каковы преимущества порта в ARM по сравнению с AVR, кроме того, что можно читать состояние пинов, как пишет Редькин, непосредственно на выходе?
Хотелось бы спросить у Редькина - а что, у AVR чтение PINx/PORTx работает по-другому?

Вот скажем, в ODSR откуда берется информация? Она попадает туда во время записи в регистр SODR, или же состояние ODSR зависит от фактического состояни пина? Ну скажем, что-то на выходе порта выгорело, или на выходе значительная просадка напряжения, мы пишем в него единичку, а результата не имеем, можно ли это диагностировать с помощью ODSR ?
Нет, нельзя. Выкиньте Редькина, откройте даташит (на худой конец его перевод с gaw.ru), посмотрите картинку 15-3 и сразу увидете, что ODSR - это то, что вы хотите вывести на ноги (аналог PORTx в AVR). А PDSR - то, что читается с ног, аналог PINx у AVR.

Посмотрел я макросы Аскольда. А не слишком ли громоздко?

Например

#define _setL(port,bit)         do { AT91C_BASE_PIO##port##->PIO_CODR = (1 << bit); } while(0)

Не до хрена ли это тактов займет?

Нет. Быстрее точно никак. К тому же сдвиг вычисляется на этапе компиляции.

Или вот еще круче - одно и то ж действие по-разному обзывается:
Да, с тех пор утекло много времени, все развивается. Вот более оптимальный с точки зрения исходника вариант для ARM под gcc (но компилится он в абсолютно те же команды).

pin_macros.zip

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


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

Ну вот еще одна непонятка. Опять таки сравниваем c AVR

PORTA=0xF0;

PORTA=0x0F;

На выходе будет 0x0F, сразу же;

 

Если же работать с SAM7:

AT91C_BASE_PIOA->PIO_SODR = 0xFFFF0000;

AT91C_BASE_PIOA->PIO_SODR = 0x0000FFFF;

 

То на выходе будет 0xFFFFFFFF. Для того чтобы получить искомые 0x0000FFFF нужно сначала обнулить, а это лишние такты. А если я хочу это сделать быстро, как мне быть?

 

МОжно ли как-то записать 32битное число в порт, чтобы не беспокоиться о том что же в этот момент в порту записано, или нужно взять за правило обнулять порт перед записью нового числа?

Прошу прощения за чайниковые вопросы.

 

 

Выкиньте Редькина, откройте даташит

 

А есть что-нибудь такое же правильное как даташит, но такое же русское, как Редькин?

 

В общем я чувствую что запутываюсь окончательно. Вы правы - тяжелое наследие работы с CodeVision. Еще тогда кто-то сказал, что COdeVision для новичка - лучший способ испортить стиль программирования.

 

У меня к присутствющим просьба: вот задача - есть PIOA c его 32 ножками. Есть два 8-ми битных числа a и b. Мне нужно поместить биты числа а в биты №№0-7 порта, а биты числа b вы биты №№24-31 порта.

 

Подскажите как это сделать, тогда мне будет от чего отталкиваться, а то от макроса в последнем вложении голова кругом пошла.

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


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

Ну вот еще одна непонятка. Опять таки сравниваем c AVR

PORTA=0xF0;

PORTA=0x0F;

На выходе будет 0x0F, сразу же;

 

Если же работать с SAM7:

AT91C_BASE_PIOA->PIO_SODR = 0xFFFF0000;

AT91C_BASE_PIOA->PIO_SODR = 0x0000FFFF;

 

То на выходе будет 0xFFFFFFFF. Для того чтобы получить искомые 0x0000FFFF нужно сначала обнулить, а это лишние такты. А если я хочу это сделать быстро, как мне быть?

 

МОжно ли как-то записать 32битное число в порт, чтобы не беспокоиться о том что же в этот момент в порту записано, или нужно взять за правило обнулять порт перед записью нового числа?

Прошу прощения за чайниковые вопросы.

 

А разве вSAM7 нет вывода в регистр?

Тогда переходите на кортекс

Там есть все три

LPC_GPIO0->FIOPIN=i // выводит значение i в регстр0

LPC_GPIO0->FIOSET=i // устанавливает в регстре0 в 1 те биты, которые в i равны 1, остальные не меняются

LPC_GPIO0->FIOCLR=i // устанавливает в регстре0 в 0 те биты, которые в i равны 1, остальные не меняются

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


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

vallav, спасибо за идею, теперь я понял как задать вопрос. Есть ли в SAM7 анало FIOPIN=i ? А то совершенно непонятно, почему я должен обнулять что-то прежде чем записать новое значение.

Изменено пользователем zheka

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


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

Ну вот еще одна непонятка. Опять таки сравниваем c AVR

PORTA=0xF0;

PORTA=0x0F;

На выходе будет 0x0F, сразу же;

 

Если же работать с SAM7:

AT91C_BASE_PIOA->PIO_SODR = 0xFFFF0000;

AT91C_BASE_PIOA->PIO_SODR = 0x0000FFFF;

 

То на выходе будет 0xFFFFFFFF. Для того чтобы получить искомые 0x0000FFFF нужно сначала обнулить, а это лишние такты. А если я хочу это сделать быстро, как мне быть?

Читать даташит. В крайнем случае его перевод на русский язык с сайта gaw.ru.
AT91C_BASE_PIOA->PIO_OWER = 0xFFFFFFFF; // <-- один раз в начале программы
AT91C_BASE_PIOA->PIO_ODSR = 0x12345678;        // Записали 32 бита в порт

У меня к присутствющим просьба: вот задача - есть PIOA c его 32 ножками. Есть два 8-ми битных числа a и b. Мне нужно поместить биты числа а в биты №№0-7 порта, а биты числа b вы биты №№24-31 порта.
А что вы хотите сделать с остальными битами (8-23)? Если не хотите их менять:
// Вариант А:
uint32_t Tmp = AT91C_BASE_PIOA->PIO_OWSR;
AT91C_BASE_PIOA->PIO_OWER = 0xFF0000FF;
AT91C_BASE_PIOA->PIO_OWDR = ~0xFF0000FF;
AT91C_BASE_PIOA->PIO_ODSR = (b << 23) | (a<<0); 
AT91C_BASE_PIOA->PIO_OWER = Tmp;
AT91C_BASE_PIOA->PIO_OWDR = ~Tmp;
// Вариант B:
AT91C_BASE_PIOA->PIO_SODR = (b << 23) | (a<<0);
AT91C_BASE_PIOA->PIO_CODR = ~((b << 23) | (a<<0) | (0xFFFF << 8));

А как бы вы записали по 2 бита из каждой переменной в биты 0,1 и 6,7 на AVR?

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


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

С битами 8-23 я ничего не собирался делать. А в АВР я делал бы точно так же как и с АРМ, так как вы написали с этим то проблем не было, я даже в симулятор гонял. В от только когда в 0-7 записано 0xFF, а затем 0xAA, то все равно остается 0xFF. Ваш ответ про OWDR я прочел, сейчас буду пробовать.

 

// Вариант B:
AT91C_BASE_PIOA->PIO_SODR = (b << 23) | (a<<0);
AT91C_BASE_PIOA->PIO_CODR = ~((b << 23) | (a<<0) | (0xFFFF << 8));

 

А второй строкой вы что хортели сделать? НИже код - наличие/присутствие строки ничего в симуляторе не изменило.

 

 

AT91C_BASE_PIOA->PIO_SODR = 0x00AAAA00; //записываем AAAA в биты 8-23, неузявимость которых хотим проверить
      AT91C_BASE_PIOA->PIO_SODR = (0xFF << 23) | (0xFF<<0); ///записываем 0xFF по краям.
      //AT91C_BASE_PIOA->PIO_CODR = ~((0xFF << 23) | (0xFF<<0) | (0xFFFF << 8) );   ///Ваша строка
       AT91C_BASE_PIOA->PIO_SODR = (0xAA << 23); // Записываем 0xAA в биты 24-31, чтобы проверить, затирается ли 0xFF после записи и остается ли сохранной информация в битах 8-23. Результат - в битах 24-31 остается 0xFF, биты 8-23 целы. Комментирование/раскомментирование Вашей строки не меняет результат.

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


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

Тогда переходите на кортекс

Там есть все три

LPC_GPIO0->FIOPIN=i // выводит значение i в регстр0

LPC_GPIO0->FIOSET=i // устанавливает в регстре0 в 1 те биты, которые в i равны 1, остальные не меняются

LPC_GPIO0->FIOCLR=i // устанавливает в регстре0 в 0 те биты, которые в i равны 1, остальные не меняются

А причем тут какое-либо ядро к организации GPIO конкретного контроллера? В отношении Cortex-M3, ну там разве только от ядра bit-band может быть использован для частичной эмуляции помянутых Вами LPC-шных SET/CLR

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


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

Значит так, господа давайте изложу проблему детально.

1. Записываю информацию в серединку 8-23, записываю, скажем так, навсегда.

2. Пишу в биты 0-7 и 23-31 числа 0xFF.

3. Убеждаюсь что биты 8-23 не тронуты.

4. Снова пишу другое число - 0xAA в биты 0-7 и 23-31. Очень хочу, чтобы там оказались AA - чередование 0 и 1. Можно ли это сделать без предварительной очистки в ноль битов 0-7 и 23-31 ???

Пока сделал так:

AT91C_BASE_PIOA->PIO_PER  = 0xFFFFFFFF;
  AT91C_BASE_PIOA->PIO_OER  = 0xFFFFFFFF;
  AT91C_BASE_PIOA->PIO_OWER  = 0xFFFFFFFF;


      AT91C_BASE_PIOA->PIO_SODR = 0x00AAAA00;
      AT91C_BASE_PIOA->PIO_SODR = (0xFF << 24) | (0xFF<<0);
      //AT91C_BASE_PIOA->PIO_CODR = ~((0xFF << 24) | (0xFF<<0) | (0xFFFF << 8) );
       AT91C_BASE_PIOA->PIO_SODR = (0xAA << 24) | (0xAA<<0);

 

Средние биты защищены. А вот в крайних так и остается 0xFF.

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


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

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

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

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

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

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

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