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

AndreyS

Участник*
  • Постов

    234
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о AndreyS

  • Звание
    Местный
    Местный
  • День рождения 07.01.1980

Контакты

  • Сайт
    Array
  • ICQ
    Array

Информация

  • Город
    Array

Посетители профиля

2 233 просмотра профиля
  1. Начните последовательно (не все скопом), иначе не выясните что было основным. Первый пункт думаю будет решающим. + снижение частоты работы шины Вы Матрешку Малинку проверяли, на какой она скорости с удлинителем взаимодействует с SD картой? Хотя да, осца же нет.
  2. При точном измерении углов подобная калибровка необходима, но в данном случае не объясняется непосредственно причина формирования 245 ед на 1g в режиме +/- 24 g Я все же ожидал видеть с датчика число хотя бы как-то приближенно соответствующее паспортному значению по чувствительности (для диапазона +/- 24g = 0,012 g на ед). Иначе мне совершено непонятно, что же тогда делается на заводе и заливается в регистры? И зачем оно восстанавливается при запуске чипа (boot)? Хотелось бы получить понимание в чем именно моя ошибка. Или в большинстве MEMS датчиков данная характеристика никак не нормируется, данные идущие с датчика никогда и близко не соответствуют паспортным и даже для неточных измерений углов или ударов, требуется калибровка?
  3. Добрый день всем. Перерыл форум и инет, но ответа на свой вопрос не нашел. Работаю с 3-х осевым датчиком ускорения ST LIS331HH, в режиме SPI 4-х проводном. По документации (в коменте к общей таблице) сказано, что он 12-и битный. Данные при этом выдаются в 16 битном формате. Опытным путем выяснил, что 4 младших бита незначащих, т.е. данные прижаты к старшему биту (влево). Углы измеряются отлично, все ок. Но вот проблема не могу пересчитать полученные цифры в абсолютное значение ускорения свободного падения (конкретно просто в g, т.е. не в m/c2) При повороте датчика так, что бы на одну из осей спроецировалось ускорение свободного падения получаю число, при пересчете которого получаю не 1g, а 2.9g Смотрел на нескольких датчиках, цифры везде идут одинаковые. Проверял в разных диапазонах, в пересчете на g все равно получается 2.9g. Нахожусь в нормальных условиях - статично. В диапазоне +/- 24g получаю 245 единиц в максимальной проекции. В диапазоне +/-6g получаю 950 единиц в максимальной проекции. (в диапазоне +/-12g цифр не помню, но в пересчете получаю те же 2.9g Соответственно паспортная погрешность смещения 70mg видна на разных датчиках - в единицах это получается +/- 5 ед в диапазоне +/- 24g (в зависимости от диапазона величина разная) Пересчет в g делаю так: пример для диапазона +/-24g 245ед*48.0/4096=2.87g Для того что бы получить что-то в районе 1g число на входе должно быть в районе 85 единиц - получается смещение 159 единиц (это соответственно для диапазона +/-24g). Про такую величину смещения в документации я что-то ничего не находил. Это уже всяко больше 70mg паспортных. В принципе при калибровке - это становится не важным, но хотелось бы быть уверенным, что относительные величины g считаться будут верно. К сожалению я не могу сформировать эталонное воздействие, нет соответствующей измерительной аппаратуры. Соответственно если 4096 в формуле заменить на 65536 - (а прочитанные данные не сдвигать вправо на 4 бита) получаем тоже значение 2.9g в пересчете. Может быть кто-нибудь, кто работал с этим датчиком укажет мне на ошибку?
  4. Добрый день. Исходя из того, что ИОН для АЦП сделан на делителе, то в таком случае сдвиг нуля операционника дешевле сделать по первому варианту.
  5. Настройка BL51 Linker.

    Добрый день. BL51 не настраивал, он не позволяет работать с банками свободно. Работаю с LX51 Вот настройки для мое проги под бутзагрузчик идем в настройки проекта LX51 locate Там есть поле USER segment в нем можно задать конструкции по размещению в фиксированной области памяти (или в диапазоне адресов) ваших сегментов. Вот мой пример ?BANK?SELECT(C:0x7100),?BANK?SWITCH(C:0x7110),?CO?FORBOOTDATA (C:0x70F0) Тут зафиксированы три процедуры. ?BANK?SELECT ?BANK?SWITCH ?CO?FORBOOTDATA префиксы указывают на модуль (читайте описание на кейл ?CO? область кода). ?BANK? из асмового стартапа. Для переменных тут будет муторно все прописывать Можно просто переопределить классы в поле User class (для этого надо снять галочку Use Memory Layout from Target Dialog). Пропишите что у вас диапазон внешней памяти меньше чем может быть. Я например прописал себе класс для данных модуля обработчиков прерывания CODE_INTR (C:0x7000-C:0x7FFF) и вставил в модуль переопределение #pragma userclass (CODE = INTR) таким образом у меня после линковки модуль обработчикв прерываний лег в коде по фиксированному диапазону кода. С данными все тоже самое. Определите себе диапазон и пропишите его в линковщке. А все что работает с внешними ОЗУ данными положите в один модуль. Вот примерно так В модуле ставим #pragma userclass (xdata = MyClass) В настройках линкера XDATA_MYCLASS (X:0x0000-C:0x0050) PS Пример вы нашли правильный. Вы в настройках линкера уберите галочку использовать данные из диалога и в классе измените только строку XDATA(0x0000-0x0FFF)
  6. Хорошая мысль. Правда в кейле заложено 32 прерывание для 51 контроллера (вернее 32 вектора), не знаю что будет с ним если указать номер больше чем 31. А так было бы хорошо. В контроллере с 21 вектором прерываний продублировать их в старшие от 21 и до 42. И вот старшие - это прерывания бутзагрузчика. Тогда стартап файл будет короче. Попробовал сделать более 32 вектора. Ругается кейл А мысль хорошая. Главное потом в бутзагрузчике не забыть что вектор номер 10, скажем, это на самом деле вектор номер 0 :)
  7. Добрый день всем. Спасибо Всем за ответы. Значит оставлю все определения в стартапе на асме. Вот только как заставить Кеил для процедур сохранить используемые регистры в стек? А то он в моих процедурах (которые на самом деле прерывания) не сохранил в стек ничего. Видимо думает что процедура не вызывается под другой (и время жизни регистра A и R7 маленькое). Пробовал вызвать процедуру через указатель, в надежде что Кеил вставит сохранение регистров. Ничего подобного не произошло. Пока добавил в макрос определения прерывания полное сохранение в стек регистров и их восстановление. Просто таблица прерываний бутзагрузчика стала большой.
  8. Добрый день. Поясняю. Решил написать бузагрузчик с максимальным использованием Си. Для этого выбрал следующий путь для себя: 1. Удобнее всего объявить прерывания в Си и все в одном файле, тогда всегда легко можно обработчик найти (спустя время) и подкорректировать. 2. Для того что бы прерывания передавались внешней прошивке зафиксировал в битовой области флаг состояния бутзагрузчика (внешняя/бут) и это определение также дал коду внешней прошивки (что бы она его не меняла). 3. В обработчике прерывания, всех прерываний проца, (который на си объявлен) хотел поставить простую конструкцию if (IN_BOOT) { процедура бутзагрузчика, если она есть } else { #pragma asm JMP OFFSET_EXT_PROGRAM+"адрес вектора прерывания" #endasm } Что получилось. Компилятор на пустое объявление прерывания тут же вставляет PUSH ACC и POP ACC На объявление прерывания с using еще и PSW На мою конструкцию вставляет полный набор всех регистров и DPTR (даже в случае отсутствия процедуры обработки прерывания в бутзагрузчике (ну просто if и else с asmовой вставкой). Решил пока переписать все объявления прерываний на ассемблере в стартапе и там на каждый обработчик поставил свой макрос Interrupt MACRO COUNTER,VECTOR_BOOT_INT JNB BOOT_in_boot_f,$+4 LCALL VECTOR_BOOT_INT RETI LJMP BASE_ADR_EXT_PROG+COUNTER COUNTER SET COUNTER+8 ENDM Ни и пришлось описать заранее названия всех обработчик прерываний на Си (которые теперь в Си стали просто процедурами) и в стартап файл их EXTRN"ить :) Но это мне не нравится, потому как идея была изначально делать на асме все по минимуму ибо видимо лень мне нажимать на клавиатуру (хотелось больше сделать все средствами компилятора). Я правильно понимаю что нет (пока я не нашел об этом информации) возможности в Keil x51 для прерываний (и видимо для функций) запретить автоматическое сохранение регистров в стек (понятно что это рукоблудство может развалить всю прогу, но я надеялся что можно настройкой или прагмой для определенной области это сделать).
  9. Добрый день. Подскажите пожалуйста, как заставить Keil (проект на Си) не укладывать сохранение в стек регистров и соответственно не восстанавливать их из стека? Пояснение: Объявляю функцию с параметром interrupt 0 и в теле ее вызываю проверку с битовой переменной, если переменная возведена, то делаю прямой переход (через #pragma asm) на требуемый внешний обработчик. Если нет, то хочу отсюда выйти. В конце внешнего обработчика конечно стоит RETI (средствами Си, потому что этот внешний обработчик есть другая прошивка) и по нему прерывание нормально завершится. Но вот при такой конструкции Кеил упорно обрамляет вызов прерывания сохранением полного набора регистров в стек и соответственно его полного восставноления. Как это обрамление отключить??
  10. Добрый день. Появился второй вопрос (по сравнению с первым, как мне кажется более существенный). Перешел на изучение I2C. Конкретно работу в режиме передающий мастер. Настроил I2C, включил в CMU синхросигнал, реализовал обработчик прерывания I2C, настроил NVIC. Передаю данные. Вопрос по значениям состояний I2C регистра STATE. Хочу прочитать значение данных по некому адресу из EEPROM. После успешного выставления состояния START на шину в регистре должно (по документации) появиться значение 0x57. Но появляется 0x53 (2 бит TRANSMITTER) не возводится. В обработчике прерывания я ожидал 0x57 для продолжения работы, добавил 0x53. Дальше все согласно даташиту отрабатывает и приходит обратно в состояние. Т.е. я передаю 7 битный адрес с признаком записи и он подтверждается EEPROM (приходит ACK) состояние 0x97. Затем я передаю два байта адреса EEPROM (тут они уже идут как данные I2C) и получаю на каждый STATE= 0xD7. После этого посылаю Repeat START и в ответ опять получаю 0x53 (а не 0x57), после этого передаю адрес с признаком чтения данных и после этого вижу на шине осциллографом, что CLK отработало видимо не только передачу адреса, но еще что-то (количество клоков 17 штук). В регистре STATE лежит при этом 0xB3 и есть данные в регистре RXDATA. Видимо сразу за адресом прошел запрос и данных, но я не включал авто подтверждений и по идее должно было прийти сначала состояние 0x93, а уже затем я бы перешел в состояние принять байт. Ну даже если и принял байт, то почему на шине количество клоков не кратно 9 (17 вместо необходимых 18)? И в регистре RXDATA лежит 0xEE (EEPROM пустая и я еще туда ничего не записывал) ожидалось 0xFF. 0. Как правильно сбросить прерывание I2C шины? 1. Почему при выставлении START на шину (посыл команды в регистр CMD I2C_CMD_START) в регистре STATE 0x53, вместо 0x57? 2. Почему не выставляется бит TRANSMITTER? Как гарантированно перевести I2C в режим Master Transmitter? 3. Почему после отправки адреса микросхемы с признаком чтение (после RSTART) происходит передача адреса на шину и прием чего, то (клоков на шине 17)? Возвращается STATE не 0x97, а сразу 0xB3, Почему так? Инициализация I2C шины. /* Настройка I2C */ // Настройка GPIO I2C /* Pin PD14 is configured to Open-drain with pull-up and filter */ GPIO->P[3].MODEH = (GPIO->P[3].MODEH & ~_GPIO_P_MODEH_MODE14_MASK) | GPIO_P_MODEH_MODE14_WIREDANDPULLUPFILTER; /* Pin PD15 is configured to Open-drain with pull-up and filter */ GPIO->P[3].MODEH = (GPIO->P[3].MODEH & ~_GPIO_P_MODEH_MODE15_MASK) | GPIO_P_MODEH_MODE15_WIREDANDPULLUPFILTER; // Включаем 3 альтернативное рассположение (там в ките висит EEPROM) I2C0->ROUTE = (I2C0->ROUTE & ~_I2C_ROUTE_LOCATION_MASK) | I2C_ROUTE_LOCATION_LOC3; // Разрешение шины на GPIO I2C0->ROUTE |= I2C_ROUTE_SDAPEN | I2C_ROUTE_SCLPEN; // Настраиваем частоту рабоыт I2C 100кГц // div = ((14000000 - (4 * freq)) / (n * freq)) - 1; // freq= 100000 частота I2C I2C0->CLKDIV; // Настраиваем режим работы I2C I2C0->CTRL=(I2C_CTRL_CLHR_STANDARD | I2C_CTRL_EN ) & ~I2C_CTRL_SLAVE;// | I2C_CTRL_AUTOSN;// | I2C_CTRL_AUTOACK; // Определяем прерывания I2C I2C0->IFC = _I2C_IFC_MASK; I2C0->IEN = I2C_IEN_MSTOP|I2C_IEN_NACK|I2C_IEN_ACK|I2C_IEN_RSTART|I2C_IEN_BUSHOLD|I2C_IEN_ST ART; Инициация передачи данных if (I2C0->STATE & I2C_STATE_BUSY) { I2C0->CMD=I2C_CMD_ABORT; } I2C0->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX; if (I2C0->IF & I2C_IF_RXDATAV) { I2C0->RXDATA; } I2C0->IFC = _I2C_IFC_MASK; I2C0->CMD=I2C_CMD_START; Обработчик прерывания // обработчик IIC прерывания void I2C0_IRQHandler(void) { dword SMB0STA; SMB0STA=I2C0->IF; I2C0->IFC=SMB0STA; SMB0STA=I2C0->STATUS; SMB0STA=I2C0->STATE; if (!iic.cycle) {// выход на шину if ((SMB0STA==MTM_START) || (SMB0STA==MTM_RSTART)) { I2C0->TXDATA=*(byte *)(&iic); //SMB0DAT=*(byte *)(&iic); // передаем адрес с признаком //IIC_CLR_START iic.cycle++; iic.ptr=0; } else IIC_GET_ERR_ } else { if (iic.work==_WRITE) {// цикл записи switch (iic.cycle) { case 1 : if (SMB0STA==MTM_SLAW_ACK) { if (iic.len--) { I2C0->TXDATA=iic.dat[iic.ptr++]; iic.cycle++; } else IIC_STOP_ } else IIC_GET_ERR_ break; case 2 : if (SMB0STA==MTM_DATA_ACK) { if (iic.len--) I2C0->TXDATA=iic.dat[iic.ptr++]; else { if (!iic.len_rd) IIC_STOP_ else { iic.work=_READ; iic.len=iic.len_rd; iic.ptr=0; iic.cycle=0; IIC_START } } } else IIC_GET_ERR_ break; default : break; } } else {// цикл чтения switch (iic.cycle) { case 1 : if (SMB0STA==MRM_SLAR_ACK) { if (iic.len) { iic.cycle++; if (--iic.len) IIC_SEND_ACK else IIC_SEND_NACK } else IIC_STOP_ } else IIC_GET_ERR_ break; case 2 : if (SMB0STA==MRM_DATA_ACK) { iic.dat[iic.ptr++]=(byte)(I2C0->TXDATA); if (--iic.len) IIC_SEND_ACK else IIC_SEND_NACK } else { if (SMB0STA==MRM_DATA_NACK) { iic.dat[iic.ptr++]=(byte)(I2C0->TXDATA); IIC_STOP_ } else IIC_GET_ERR_ } break; default : break; } } } } Макросы #define IIC_START I2C0->CMD=I2C_CMD_START; // Посыл START на линию #define IIC_STOP I2C0->CMD=I2C_CMD_STOP; // Посыл STOP на линию #define IIC_SEND_ACK I2C0->CMD=I2C_CMD_ACK; // Посылка подтверждения #define IIC_SEND_NACK I2C0->CMD=I2C_CMD_NACK; // Посылка не подтверждения #define IIC_ABORT I2C0->CMD=I2C_CMD_ABORT; // Сброс шины
  11. EnergyMicro EFM32GG Cortex-M3

    Добрый день. Начал разбираться со зверем EFM32GG от EnergyMicro На стадии изучения прерывания (NVIC) от GPIO не могу понять чем отличается прерывание (GPIO) ODD от EVEN (обработчики GPIO_ODD_IRQHandler и GPIO_EVEN_IRQHandler)? Настроил два пина порта A на прерывания по переднему фронту и включил их. В main'е меняю значение на одной ноге и вываливаюсь в прерывание EVEN. В нем проверяю GPIO->IF на предмет вызова по пину из main и тогда меняю состояние второй ноги. Но при этом почему то вываливаюсь не в EVEN, а в ODD прерывание (в GPIO->IF вижу что сработало прерывание от ноги измененной в EVEN обработчике). Почему? В чем их разница? В документации в качестве примера (похож на мой) сказано что должен быть выход в ODD обработчик. Я включил только его и ниразу в него не вошел. PS. Хотя наверное я понял. Это обработчики четных и нечетных внешних прерываний?
  12. А зря (по моему лучшего нет)! Какие требования к дизассемблеру?
  13. Добрый день. Вы смотрели содержимое массива именно в Watch? Проверьте содержимое в окне memory, и введите там адрес вашего массива (только префикс типа памяти не забудьте). Если там верная информация (а она должна быть именно такой, потому что через ваши указатели ptr_massiv информация отображается правильная), то не беспокойтесь. Это глюк кейла. Я помню напарывался на подобный эффект, когда в ватчах отображалось не то что там реально находилось. Так что дамп ОЗУ лучший инструмент. Ну и посмотрите карту памяти, реально переменная попала в нужную область или нет (это как второй инструмент контроля над компилятором). Удачи.
  14. добрый день. Посмотрите cypress Cy68013, оно же FX2. Если не изменяет память, то там есть инт2 и помоему еще инт4 (кроме инт0 и инт1). Правда в нем еще и USB, но есть и I2C.
  15. Добрый день. Видимо все это проверялось под ОС Винда. Очень хотелось бы услышать результаты таких исследований под любой другой ОС. У меня есть подозрение что это шалит драйвер usbd.sys под виндой. Потому как обнаружили в своей системе следующую проблему. При некоторых обстоятельствах (одно из них, 100% приводящее к этой проблеме, это огромная помеха по шине USB соответственно ведущая к потери пакетов) происходит как бы зависание USB устройства в операционной системе (физически же само исполнительное устройство device продолжает нормальное функционирование, подвисает USB шина). Это подвисание может быть кратковременным, а может быть длительным. В таком случае спасает reset_port с abort_pipe. Но вот в этот момент подвисания любой запрос к драйверу usbd.sys (посредством драйвера ezusb.sys) не приводит в появлению данных на самой шине. Производили сканирование аппаратным анализатором и обнаружили эту проблему. На шине кроме SOF пакетов ничего больше нет. А в диспетчере устройств оно доступно. Происходит это редко (при длительной эксплуатации USB шины в течении нескольких суток), но может залипнуть так, что спасает только перезагрузка. Причем вылезла эта проблема в лабораторных условиях, т.е. помех по USB шине небыло, сканер их не показал. Рысканье по инету привело к тому что в разных виндах требования на максимальный объем запрашиваемой информации в драйвере usbd.sys разный. В нашем случае мы удовлетворяем этому требованию под винду ХП, 2000 и 7 с вистой. Но само это наводит на мысль возможных глюках в работе usbd.sys под виндой.
×
×
  • Создать...