Jump to content

    

AndreyS

Участник
  • Content Count

    235
  • Joined

  • Last visited

Community Reputation

0 Обычный

About AndreyS

  • Rank
    Местный
  • Birthday 01/07/1980

Контакты

  • Сайт
    http://
  • ICQ
    0

Информация

  • Город
    Санкт-Петербург
  1. MicroSD длина дорожек (SDIO)

    Цитата(AVStech @ Jan 9 2018, 15:15) Попробую, спасибо! Да они подключены к VCC карты !!! НО Сейчас ключика нет и питание идет напрямую от камня 3V3 к слоту карты памяти к этой же линии подключены все подтягивающие резисторы и конденсаторы. Это интересно. 1. Уменьшу сопротивление до 10-4,7 кОм 2. Попробую тантал на 100 мкФ 3. Добавлю ка я ключик на питание. А питание карты подведу отдельным источником 3V3. Ключик будет управлять подачей питания от отдельного источника. Верно? 4. Если не заработает буду смотреть осцилом всё. Спасибо! Начните последовательно (не все скопом), иначе не выясните что было основным. Первый пункт думаю будет решающим. + снижение частоты работы шины Вы Матрешку Малинку проверяли, на какой она скорости с удлинителем взаимодействует с SD картой? Хотя да, осца же нет.
  2. Цитата(_4afc_ @ Aug 20 2016, 12:31) Может вычесть 0,9 и разделить на 2? Sensitivity describes the gain of the sensor and can be determined e.g. by applying 1 g acceleration to it. As the sensor can measure DC accelerations this can be done easily by pointing the axis of interest towards the center of the earth, noting the output value, rotating the sensor by 180 degrees (pointing to the sky) and noting the output value again. By doing so, ±1 g acceleration is applied to the sensor. Subtracting the larger output value from the smaller one, and dividing the result by 2, leads to the actual sensitivity of the sensor. This value changes very little over temperature and also time. The sensitivity tolerance describes the range of Sensitivities of a large population of sensors. При точном измерении углов подобная калибровка необходима, но в данном случае не объясняется непосредственно причина формирования 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. Цитата(sealbi @ May 16 2013, 10:47) Опору для АЦП делаю из питания датчика делителем. Для того, чтобы отодвинуть от нуля выход, на вход REF операционника надо подать около 0.25 вольта. Не могу сообразить что лучше: 1) сделать это напряжение из питания датчика делителем 2)поставить какой нибудь источник опорного напряжения? Подскажите! Добрый день. Исходя из того, что ИОН для АЦП сделан на делителе, то в таком случае сдвиг нуля операционника дешевле сделать по первому варианту.
  5. Настройка BL51 Linker.

    Цитата(DO_SL @ Feb 8 2013, 17:21) вырезал Добрый день. 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. Keil C51 прерывания

    Цитата(редактор @ Sep 5 2012, 09:54) Можно обмануть всех. Допустим в МК используется 5 аппаратных векторов прерывания (IRQ0...IRQ4) Тогда можно объявить функцию обработки прерывания по вектору IRQ5 Хорошая мысль. Правда в кейле заложено 32 прерывание для 51 контроллера (вернее 32 вектора), не знаю что будет с ним если указать номер больше чем 31. А так было бы хорошо. В контроллере с 21 вектором прерываний продублировать их в старшие от 21 и до 42. И вот старшие - это прерывания бутзагрузчика. Тогда стартап файл будет короче. Попробовал сделать более 32 вектора. Ругается кейл А мысль хорошая. Главное потом в бутзагрузчике не забыть что вектор номер 10, скажем, это на самом деле вектор номер 0
  7. Keil C51 прерывания

    Добрый день всем. Спасибо Всем за ответы. Значит оставлю все определения в стартапе на асме. Вот только как заставить Кеил для процедур сохранить используемые регистры в стек? А то он в моих процедурах (которые на самом деле прерывания) не сохранил в стек ничего. Видимо думает что процедура не вызывается под другой (и время жизни регистра A и R7 маленькое). Пробовал вызвать процедуру через указатель, в надежде что Кеил вставит сохранение регистров. Ничего подобного не произошло. Пока добавил в макрос определения прерывания полное сохранение в стек регистров и их восстановление. Просто таблица прерываний бутзагрузчика стала большой.
  8. Keil C51 прерывания

    Добрый день. Поясняю. Решил написать бузагрузчик с максимальным использованием Си. Для этого выбрал следующий путь для себя: 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. EnergyMicro EFM32GG Cortex-M3

    Добрый день. Появился второй вопрос (по сравнению с первым, как мне кажется более существенный). Перешел на изучение 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. Цитата(011119xx @ Nov 21 2011, 15:04) Пробовал. Не впечатлило А зря (по моему лучшего нет)! Какие требования к дизассемблеру?
  13. Цитата(Kenelm @ Oct 29 2011, 19:25) Среда Keil uVision2. Поверх поставлен CC1010IDE. Выбрано устройство "CC1010_debug". В результате при дебаггинге в окне "Watch" смотрю на содержание массива "massiv" - пустой (все элементы равны нулю). Смотрю на *ptr_massiv и *(ptr_massiv + 1) - отображается, что там содержится 0xAA и 0xBB, соответственно!!! При этом ptr_massiv указывает именно на "голову" массива "massiv"! PS. Если массив запихнуть в data или xdata, то все работет ок. Добрый день. Вы смотрели содержимое массива именно в Watch? Проверьте содержимое в окне memory, и введите там адрес вашего массива (только префикс типа памяти не забудьте). Если там верная информация (а она должна быть именно такой, потому что через ваши указатели ptr_massiv информация отображается правильная), то не беспокойтесь. Это глюк кейла. Я помню напарывался на подобный эффект, когда в ватчах отображалось не то что там реально находилось. Так что дамп ОЗУ лучший инструмент. Ну и посмотрите карту памяти, реально переменная попала в нужную область или нет (это как второй инструмент контроля над компилятором). Удачи.
  14. Помогите выбрать мк

    Цитата(Студент @ Oct 24 2011, 10:55) у меня есть смутное сомненье что 8разрядных МК с 3мя внешними прерываниями нет в природе... добрый день. Посмотрите cypress Cy68013, оно же FX2. Если не изменяет память, то там есть инт2 и помоему еще инт4 (кроме инт0 и инт1). Правда в нем еще и USB, но есть и I2C.
  15. Цитата(loginser @ Jun 22 2011, 13:23) Проблему я нашел. Я использую BULK пакеты размером 1024 и на USB 2.0(всех) контроллерах мое устройство работает отлично, но похоже что драйвер контроллера USB 3.0 жестко проверяет это условие и возврашиет ERROR_INVALID_PARAMETER. Как решить подобную проблему я незнаю к сожалению. -Al- спасибо за ответ. Добрый день. Видимо все это проверялось под ОС Винда. Очень хотелось бы услышать результаты таких исследований под любой другой ОС. У меня есть подозрение что это шалит драйвер usbd.sys под виндой. Потому как обнаружили в своей системе следующую проблему. При некоторых обстоятельствах (одно из них, 100% приводящее к этой проблеме, это огромная помеха по шине USB соответственно ведущая к потери пакетов) происходит как бы зависание USB устройства в операционной системе (физически же само исполнительное устройство device продолжает нормальное функционирование, подвисает USB шина). Это подвисание может быть кратковременным, а может быть длительным. В таком случае спасает reset_port с abort_pipe. Но вот в этот момент подвисания любой запрос к драйверу usbd.sys (посредством драйвера ezusb.sys) не приводит в появлению данных на самой шине. Производили сканирование аппаратным анализатором и обнаружили эту проблему. На шине кроме SOF пакетов ничего больше нет. А в диспетчере устройств оно доступно. Происходит это редко (при длительной эксплуатации USB шины в течении нескольких суток), но может залипнуть так, что спасает только перезагрузка. Причем вылезла эта проблема в лабораторных условиях, т.е. помех по USB шине небыло, сканер их не показал. Рысканье по инету привело к тому что в разных виндах требования на максимальный объем запрашиваемой информации в драйвере usbd.sys разный. В нашем случае мы удовлетворяем этому требованию под винду ХП, 2000 и 7 с вистой. Но само это наводит на мысль возможных глюках в работе usbd.sys под виндой.