zheka 1 12 мая, 2010 Опубликовано 12 мая, 2010 · Жалоба Проблема решена. Дело было в локализации KEIL в папке озаглавленной русскими буквами. Включать и выключать светодиоды я научился. Не получается почему-то запустить код в RAM ((( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Как же все-таки сложно переделывать заложенные в голове азбучные истины. В АВР было просто - PORTA.1=1, либо PORTA.1=0; В ARM же CODR, SODR. Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот? У меня складывается ассоциация как с кнопками - в АВР одна кнопка которую можно либо нажать либо отжать, а в SAM7 - две кнопки, из которых одновременно может быть нажата только одна, при нажатии одной, вторая автоматом отщелкивается. Я правильно понял логику работы пина? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба В АВР было просто - PORTA.1=1, либо PORTA.1=0;Тяжелое наследие CVAVR. В стандартном С нет записи вида Var.Bit Макросы имени Аскольда Волкова спрячут реализацию - что на AVR, что на ARM, что на PIC, что на MSP: on(LED); off(LED); Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот?Нет. Из SODR читать вообще нельзя. Для чтения состояния там соседний регистр. Логику вы поняли правильно. То есть Вашмим словами - ULINK это не название программатора?Название программатора. Но ведь никто не запрещает этим же названием назвать совокупность значений опций среды, необходимых для сборки и отладки проекта именно этим программатором ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vallav 0 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Как же все-таки сложно переделывать заложенные в голове азбучные истины. В АВР было просто - PORTA.1=1, либо PORTA.1=0; В ARM же CODR, SODR. Объясните, если я пишу в CODR, то в SODR автоматом меняется значение и наоборот? У меня складывается ассоциация как с кнопками - в АВР одна кнопка которую можно либо нажать либо отжать, а в SAM7 - две кнопки, из которых одновременно может быть нажата только одна, при нажатии одной, вторая автоматом отщелкивается. Я правильно понял логику работы пина? Вы полагаете, это плохо, что в ARM кроме записи слова в регистр аппаратно реализованы так же и установка отдельных битов регистра в 1, установка отдельных битов регистра в 0 и побитовая адресация регистров? Вам эти расширенные возможности обращения с регистрами мешают? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GenaSPB 11 13 мая, 2010 Опубликовано 13 мая, 2010 (изменено) · Жалоба Как же все-таки сложно переделывать заложенные в голове азбучные истины. В АВР было просто - 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; } Изменено 13 мая, 2010 пользователем Genadi Zawidowski Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Нет. Из 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. охох..голова кругом, сколько плясок с бубном... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Под соседним регистром вы имеете ввиду 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Ну вот еще одна непонятка. Опять таки сравниваем 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 порта. Подскажите как это сделать, тогда мне будет от чего отталкиваться, а то от макроса в последнем вложении голова кругом пошла. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vallav 0 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Ну вот еще одна непонятка. Опять таки сравниваем 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, остальные не меняются Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 13 мая, 2010 Опубликовано 13 мая, 2010 (изменено) · Жалоба vallav, спасибо за идею, теперь я понял как задать вопрос. Есть ли в SAM7 анало FIOPIN=i ? А то совершенно непонятно, почему я должен обнулять что-то прежде чем записать новое значение. Изменено 13 мая, 2010 пользователем zheka Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Почитайте в мануале про OWER, ODSR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Ну вот еще одна непонятка. Опять таки сравниваем 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? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба С битами 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 целы. Комментирование/раскомментирование Вашей строки не меняет результат. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Тогда переходите на кортекс Там есть все три 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 13 мая, 2010 Опубликовано 13 мая, 2010 · Жалоба Значит так, господа давайте изложу проблему детально. 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться