Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC1114 + Keil
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
swisst
Доброго времени суток !

1. Подскажите как разместить переменную в памяти программы ? [разобрался]

под С51 было так...
Код
const uint8_t code var_name;


сейчас достаточно так...
Код
const uint8_t var_name;

____________________________________________________________________
ViKo
А
Код
static const uint8_t var_name;

работает?
toweroff
unsigned int const my_variable = 0x55555555;

если нужно по конкретному адресу, то, например, так:

unsigned int const secure __attribute__((at(0x1FC))) = 0x43218765;
swisst
ничего из предложенного не работает - переменная в секции .constdata, тип -data...

ЗЫ по конкретному адресу размещает - с этим вопросов нет.
ViKo
Цитата(swisst @ Nov 24 2010, 16:17) *
переменная в секции .constdata, тип -data...

Не уверен, что это означает, что переменная размещена в ОЗУ. Но я в этом небольшой специалист.
swisst
Судя по всему тему создал с горяча...

Код
const uint8_t Symbol[10] = {SYMBOL_0, SYMBOL_1, SYMBOL_2, SYMBOL_3, SYMBOL_4, SYMBOL_5, SYMBOL_6, SYMBOL_7, SYMBOL_8, SYMBOL_9};


Код
Symbol                                   0x00000d48   Data          10  indic.o(.constdata)


что говорит о том, что массив лежит во флэш и спецификатора const вполне достаточно...
ViKo
Цитата(swisst @ Nov 24 2010, 17:12) *
говорит о том, что массив лежит во флэш и спецификатора const вполне достаточно...

для локальных переменных может и не хватить...
swisst
Вопрос 2: Аппаратный I2C LPC1114 + EEPROM (AT24C01? например)

Вопрос несколько общий - кто поборол и у кого пошлО ?
rezident
А чего там бороть-то? Взял пример I2C из папки \arm\examples\NXP\LPC11xx\IAR-LPC-1114-SK в IAR EWARM 5.50.5 и с полпинка завел этот I2C. Правда у меня не EEPROM была подключена, а LCD на PCF8535.
swisst
дык...первым делом - мануал, вторым - примеры NXP...просто так сюда не пишу, в основном - читаю...

Код
//=====================================================================

void Init_I2C (){
    LPC_IOCON->PIO0_4 |= ((1<<0));            //Selects I2C function SCL (open-drain pin)
    LPC_IOCON->PIO0_5 |= ((1<<0));            //Selects I2C function SDA (open-drain pin)

    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);            //Enables clock for I2C
    LPC_SYSCON->PRESETCTRL |= (1<<1);                //De-asserts reset for I2C
    LPC_I2C->SCLL = 480;
    LPC_I2C->SCLH = 480;

    LPC_I2C->CONCLR = ((1<<2) | (1<<3) | (1<<5));
    NVIC_EnableIRQ(I2C_IRQn);
    LPC_I2C->CONSET |= (1<<6);
}

//================================================================================
=======

void I2C_IRQHandler (){
    uint8_t StatValue = LPC_I2C->STAT;
    test_i2c = StatValue;
    switch(StatValue){
        case 0x08:
            LPC_I2C->DAT = 0xA1;
            LPC_I2C->CONCLR |= ((1<<3) | (1<<5));
            break;
        case 0x10:
            LPC_I2C->DAT = 0xA1;
            LPC_I2C->CONCLR |= ((1<<3) | (1<<5));
            break;
        case 0x18:
            LPC_I2C->DAT = 0xFF;
            break;
        default:
            LPC_I2C->CONCLR |= (1<<3);    
    }
    SW_1_TOG;
}


проблема состоит в том, что нет я не вижу сигнала START (осцил-ом), но он как-бы есть (test_i2c = 8 - слежу через модбас, зажигается SW_1) - а дальше тишина...
swisst
Цитата(rezident @ Nov 26 2010, 11:42) *
А чего там бороть-то? Взял пример I2C из папки \arm\examples\NXP\LPC11xx\IAR-LPC-1114-SK в IAR EWARM 5.50.5 и с полпинка завел этот I2C. Правда у меня не EEPROM была подключена, а LCD на PCF8535.


если не сложно - прицепите тестовый проект ИАРа

START condition увидел...mdk-ARM симулирует...в железе - не работает...все еще нуждаюсь в пинкЕ...
toweroff
swisst, а резисторы-то к питанию притянуты?
rezident
Цитата(swisst @ Nov 29 2010, 17:03) *
если не сложно - прицепите тестовый проект ИАРа
Не уверен, что вы сможете это очень просто адаптировать под Keil, но попробуйте.
swisst
Цитата(toweroff @ Nov 29 2010, 20:57) *
swisst, а резисторы-то к питанию притянуты?


разумеется - обе линии (и SCL, и SDA)...

Цитата(rezident @ Nov 30 2010, 00:36) *
Не уверен, что вы сможете это очень просто адаптировать под Keil, но попробуйте.


спасибо - поковыряю...
esaulenka
Лень создавать тему, спрошу про LPC111x здесь.
Что такое "Unique device serial number for identification" и где его посмотреть, кроме как в разделе "features" user manual'а ?
swisst
Код
3.5.35 Device ID register
This device ID register is a read-only register and contains the part ID for each
LPC111x/LPC11C1x part. This register is also read by the ISP/IAP commands


User manual Rev. 2 — 2 November 2010 31 of 407

Цитата(rezident @ Nov 30 2010, 00:36) *
Не уверен, что вы сможете это очень просто адаптировать под Keil, но попробуйте.


поковырял...такой же алгоритм я стянул с сайта NXP...пока стою на месте...
esaulenka
Цитата(swisst @ Nov 30 2010, 18:08) *
3.5.35 Device ID register

Спасибо. Блин, а я уже губу раскатал, что это уникальный номер каждого отдельно взятого контроллера...
rezident
Цитата(swisst @ Nov 30 2010, 20:08) *
поковырял...такой же алгоритм я стянул с сайта NXP...пока стою на месте...
Функцией Bus clear свой алгоритм дополнили?
GetSmart
Цитата(esaulenka @ Nov 30 2010, 20:32) *
Спасибо. Блин, а я уже губу раскатал, что это уникальный номер каждого отдельно взятого контроллера...

В 1114 есть уникальный номер у каждого проца.
swisst
Цитата(rezident @ Nov 30 2010, 22:08) *
Функцией Bus clear свой алгоритм дополнили?


нет...можно подробнее ?

Цитата(GetSmart @ Nov 30 2010, 22:09) *
В 1114 есть уникальный номер у каждого проца.


таки да...
rezident
Цитата(swisst @ Dec 1 2010, 20:25) *
нет...можно подробнее ?
Подробнее в спецификации I2C. Раздел 3.16 Bus clear. Функцию Bus clear нужно выполнять после подачи питания до начала обращения мастера к слейвам и/или при большом таймауте занятости шины каким-либо слейвом.
swisst
Цитата(rezident @ Dec 2 2010, 06:37) *
Подробнее в спецификации I2C. Раздел 3.16 Bus clear. Функцию Bus clear нужно выполнять после подачи питания до начала обращения мастера к слейвам и/или при большом таймауте занятости шины каким-либо слейвом.


добавил функцию bus clear...без изменений...

Цитата
In the unlikely event where the clock (SCL) is stuck LOW, the preferential procedure is to
reset the bus using the HW reset signal if your I2C devices have HW reset inputs. If the
I2C devices do not have HW reset inputs, cycle power to the devices to activate the
mandatory internal Power-On Reset (POR) circuit.
If the data line (SDA) is stuck LOW, the master should send 9 clock pulses. The device
that held the bus LOW should release it sometime within those 9 clocks. If not, then use
the HW reset or cycle power to clear the bus.


функция bus clear применяется в случаях, если залипает линия SDA в ноль. в моем случае - после резета обе линии в единице.

не с того я начал.
Дано: LPC1114+AT24C01A (больше на I2C ничего не висит). SDA и SCL не перепутаны и обе подтянуты к питанию через 3K3.
Задача: используя аппаратный I2C добиться записи/чтения от AT24

Проблема:
после ресета делаю Bus Clear (обычным дрыганием ног). START CONDITION отправляю по нажатию кнопки (так проще синхронизироваться). после отправки START CONDITION попадаю в прерывание, где анализирую STAT (он равен 8 - тут все хорошо) switch'eм. загружаю SLA+W (0xA0), сбрасываю STA и SIC - вываливаюсь из прерывания и все...в прерывание я больше не попадаю...

Код
//================================================================================
====

void Init_I2C (){
    LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5);            //Enables clock for I2C
    LPC_SYSCON->PRESETCTRL |= (1<<1);                //de-asserts I2C reset

    LPC_IOCON->PIO0_4 = 1;                            //Selects I2C function SCL (open-drain pin)
    LPC_IOCON->PIO0_5 = 1;                            //Selects I2C function SDA (open-drain pin)

    LPC_I2C->SCLH = 64000;
    LPC_I2C->SCLL = 64000;

    LPC_I2C->CONCLR = ((1<<2) | (1<<3) | (1<<5) | (1<<6));        //CON clear;
    NVIC_EnableIRQ(I2C_IRQn);                                    //I2C IRQ enable
    LPC_I2C->CONSET |= (1<<6);                                    //I2C enable

    test_i2c = LPC_I2C->STAT;

    I2C_State = CLEAR_BUS;
}

//================================================================================
====

void I2C_IRQHandler (){
    uint8_t StatValue = LPC_I2C->STAT;
    test_i2c = StatValue;
    switch(StatValue){
        case 0x08:                                        //START condition has been transmitted
            LPC_I2C->DAT = 0xA0;                        //Load SLA+W
            LPC_I2C->CONCLR |= ((1<<3) | (1<<5));        //Clear SIC, STA
            break;
        case 0x10:                                        //Repeated START condition has been transmitted
            LPC_I2C->DAT = 0xA0;                        //Load SLA+W
            LPC_I2C->CONCLR |= ((1<<3) | (1<<5));        //Clear STA
            break;
        case 0x18:                                        //SLA+W has been transmitted; ACK has been received
            LPC_I2C->DAT = 0xFF;
            LPC_I2C->CONSET |= (1<<4);
            break;
        case 0x20:                                        //SLA+W has been transmitted; NOT ACK has been received
            LPC_I2C->DAT = 0xFF;
            LPC_I2C->CONSET |= (1<<4);
            break;
        case 0x28:                                        //Data byte in DAT has been transmitted; ACK has been received
            break;
        case 0x30:                                        //Data byte in DAT has been transmitted; NOT ACK has been received
            break;
        case 0x38:                                        //Arbitration lost in SLA+R/W or Data bytes
            break;
        default:
            I2C_State = CLEAR_BUS;
            LPC_I2C->CONCLR |= (1<<3);
    }
    SW_1_TOG;
}
Andrei0686
Привет всем! Столкнулся с небольшой проблемой использовал такие же конструкции с AVR под компиляторо IAR все работало, попробывал под LPC1114 контроллер уходит в аварийное прерывание как под iar так и под KEIL-ом.
Суть следующая:
пусть у нас есть массив с данными типа unsigned char mas[10]{0,1,2,3,4,5,6,7,8,9};
и есть переменная unsigned short LenData=0x0302;
Мне необходимо 2 и 3 байт массива сравнить с переменной LenData,
под AVR я делал так
if (LenData == *(unsigned short*)&mas[2])
{} и все работало, а как только я подставил данную конструкцию под LPC1114 То он сразу ушел в прерывание по сбою работы программы.
Причем при использовании эмулятора от KEIL все работает как надо но в реальном микроконтроллере не работает. Подскажите что я делаю не так?
esaulenka
Цитата(Andrei0686 @ Sep 22 2011, 09:23) *
if (LenData == *(unsigned short*)&mas[2])
...

Подскажите что я делаю не так?

1. Вы понапрасну пользуетесь приведением типов.
2. Вы не учитываете, что контроллер 32-битный.
3. Вы не приводите дизассемблер проблемного куска с указанием, на какой инструкции происходит ошибка.

Краткий экскурс в АРМы.
Давным-давно, буквально пару лет назад, переменные в памяти ARM'ов могли лежать только по выровненным адресам:
short'ы - по адресам 0, 2, 4, 6, 8, ..., long'и - по адресам 0, 4, 8, 0x0c, 0x10 и т.д.
С появлением кортексов ситуация улучшилась: это ограничение убрали. Разве что ограничение осталось на некоторых инструкциях (push/pop, ldrex/strex, ldr/str на несколько регистров). И обращение к такой переменной занимает больше тактов процессора (т.к., по сути, производится два обращения к памяти).

Итого: приведение типов - зло, может привести к странным граблям.
Лучше действовать в лоб:
Код
__inline short char2short (char *in)
{
return in[0] + (in[1] << 8);
}
Andrei0686
if (LenData == *(__packed unsigned short*)&mas[2])
Такая конструкция работает!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.