Точно также грызлись на Казусе с HHIMERA, dosikus и др. по теме "а нахрена нам этот арм, если авров хватает и наработок уже до хрена" (извиняюсь за выражения), потом попробовал и перешел на сторону зла (или добра?).
Цитата:
Мы себе давали слово Не сходить с пути прямого, Но так уж суждено, И уж если откровенно - всех пугают перемены, Но тут уж все равно. Вот новый поворот и мотор ревет, Что он нам несет: пропасть или взлет, Омут или брод - и не разберешь, Пока не повернешь.
Наверное надо сделать что нибудь на армовом микроконтроллере, чтоб так сказать, понять темную (или светлую?) сторону силы.
Цитата:
Существуют две противоположные философии использования Силы — Светлая сторона и Тёмная сторона. Сторона выбирается в зависимости от личных морально-этических принципов. Выбор стороны — важнейший шаг в жизни любого разумного существа, умеющего направлять Силу. Философию Светлой стороны воплощают в жизнь Джедаи.
О господи!!! Никогда бы не догадался, что мерилом камня выступает танчики-игруха... :)))
Нет, тут дело не в танчиках вовсе. Я лично Ведущего специалиста оценил, когда он много и играючи щелкал протоколы ЖКИ-шек еще лет 8 (10?) назад. Это сейчас всяк пионер с копеечным китайским Saleae (возможно) бы справился с тем, что он делал еще тогда. А судя по тому, что на форуме до сих пор эта тема чуть ли не в топе - видно, что не всяк.
К чему это ? К упоминавшимся уже "способам и отмазкам".
Специальное предложение от Atmel и Rainbow Electronics: полнофункциональный микроконтроллер на базе ядра Cortex-M0+ по цене $0.90 от 1 шт. Основные характеристики микроконтроллера ATSAMD20G16A-AU: 64 КБ Flash-памяти и 8 КБ ОЗУ, Тактовая частота до 48 МГц, 6 универсальных коммуникационных модулей SERCOM (конфигурируемых как UART/USART, SPI или I2C), 8 16-битных таймеров/счетчиков, 14-канальный 12-битный АЦП, 1-канальный 10-битный ЦАП, 8-канальная система событий, Периферийный контроллер емкостных сенсоров касания, поддерживающий до 120 каналов, Напряжение питания от 1.62 В до 3.63 В 48-выводной корпус TQFP.
Дополнительное условие специальной акции – все клиенты приобретшие микроконтроллер ATSAMD20G16A-AU, также могут приобрести оценочный комплект SAM D20 Xplain PRO и платы расширения к нему со скидкой 50% Базовая оценочная плата SAM D20 Xplained Pro на базе микроконтроллера ATSAMD20J18, содержит встроенный отладчик цена $23
Продолжение. Конструкция вечера выходного дня. Решил, для так сказать, преемственности поколений микроконтроллеров проверить будет ли работать код для температурного датчика DS18B20, прекрасно работающий на устаревших микроконтроллерах PIC, AVR и на STM32. Конечно можно решить задачу аппаратным путем с помощью USART и DMA, но подобная работа была уже проведена товарищами с другого форума - повторять не очень интересно. Да и хотелось решить задачу простым ногодрыгом (любимое занятие 8-ми битных микроконтроллеров), например это может пригодится для малоногих микроконтроллеров у которых USART возможно занят. Предыстория кода для DS18B20. Когда деревья еще были маленькими и интернет еще не изобиловал кучами примеров работы с этим датчиком, взял код от самого производителя датчика для 51 микроконтроллера и приспособил к PIC16F628 с динамической индикацией.Все прекрасно работало, но потом увидел в интернете (спасибо автору, что выложил) код, который чем то мне понравился и в дальнейшем стал применять его - прекрасно тоже работал на множестве PIC и AVR. И вот пришла пора проверить - будет ли работать на армовых микроконтроллерах, а если не будет - сразу в топку их, зачем они нужны без банального ногодрыга . Так как в предыдущей поделке микроконтроллерное ядро ничего не делало - немного озадачим его посылками и приемом данных с датчика, плюс небольшая арифметика. Микросекундные задержки сделаны на таймере том же TIM3, DMA теперь управляет 15 таймер - освободил каналы 2 и 3 на будущее для USART. Вывод часов на индикацию закомментирован, но можно добавить кнопку или тумблер для переключения часы/термометр. Спойлер
void Configure_RTC(void) { /* Enable the peripheral clock RTC */ /* (1) Enable the LSI */ /* (2) Wait while it is not ready */ /* (3) Enable PWR clock */ /* (4) Enable write in RTC domain control register */ /* (5) LSI for RTC clock */ /* (6) Disable PWR clock */ RCC->CSR |= RCC_CSR_LSION; /* (1) */ while((RCC->CSR & RCC_CSR_LSIRDY)!=RCC_CSR_LSIRDY) /* (2) */ { /* add time out here for a robust application */ } RCC->APB1ENR |= RCC_APB1ENR_PWREN; /* (3) */ PWR->CR |= PWR_CR_DBP; /* (4) */ RCC->BDCR = (RCC->BDCR & ~RCC_BDCR_RTCSEL) | RCC_BDCR_RTCEN | RCC_BDCR_RTCSEL_1; /* (5) */ RCC->APB1ENR &=~ RCC_APB1ENR_PWREN; /* (7) */ }
void Init_RTC(uint32_t Time) { /* RTC init mode */ /* Configure RTC */ /* (1) Write access for RTC registers */ /* (2) Enable init phase */ /* (3) Wait until it is allow to modify RTC register values */ /* (4) set prescaler, 40kHz/128 => 312 Hz, 312Hz/312 => 1Hz */ /* (5) New time in TR, 24-hour format */ /* (6) Disable init phase */ /* (7) Disable write access for RTC registers */ RTC->WPR = 0xCA; /* (1) */ RTC->WPR = 0x53; /* (1) */ RTC->ISR |= RTC_ISR_INIT; /* (2) */ while((RTC->ISR & RTC_ISR_INITF)!=RTC_ISR_INITF) /* (3) */ { /* add time out here for a robust application */ } RTC->PRER = 0x007F0137; /* (4) */ RTC->TR = RTC_TR_PM | Time; /* (5) */ RTC->ISR &=~ RTC_ISR_INIT; /* (6) */ RTC->WPR = 0xFE; /* (7) */ RTC->WPR = 0x64; /* (7) */ }
void Copy2Buffer() { uint16_t n, k = 0x00FF, c = 3; DigitIndex = 0x01; for (n = 0; n < 28; n++) { if(n==7) { k = 0x017F; c = 2; DigitIndex = 0x01; } if(n==14) { k = 0x027F; c = 1; DigitIndex = 0x01; } if(n==21) { k = 0x047F; c = 0; DigitIndex = 0x01; } if(DigitBuffer[c] & DigitIndex) DataBuffer[n] = ~((uint16_t)DigitIndex) & k ; else DataBuffer[n] = k; if(n==0) DataBuffer[n] ^= DotMask; DigitIndex <<= 0x01; } }
void delay_us(uint16_t delay) { TIM3->PSC = 48-1; //устанавливаем предделитель TIM3->ARR = delay; //устанавливаем значение переполнения таймера, а значит и значение при котором генерируется Событие обновления TIM3->EGR |= TIM_EGR_UG; //Генерируем Событие обновления для записи данных в регистры PSC и ARR TIM3->CR1 |= TIM_CR1_CEN|TIM_CR1_OPM; //Запускаем таймер записью бита CEN и устанавливаем режим Одного прохода установкой бита OPM while ((TIM3->CR1 & TIM_CR1_CEN)!=0); }
uint8_t OneWire_Init() { DQ_0; //Low LINE delay_us(480); DQ_1; //Hi LINE delay_us(70); if(!(DQ)) //Если ведомое уст-во ответило (PRESENCE PULSE) - заканчиваем этот тайм-слот (480мкс). { delay_us(400); if(!(DQ)) //Если линия так и продолжает быть в низком уровне - значит это либо ошибка, return 0; //либо на линии нет устр-в, а PRESENCE был ложным и вызван просто низким уровнем на линии. else //В таком случае естественно возвращаем 0 (ошибка / нет устр-в на шине), return 1; //либо 1 если все в порядке и это был "настоящий" PRESENCE PULSE. } else //Возвращаем 0 если отсутствовал вообще какой-либо намек на PRESENCE. return 0; }
for(i=0; i<8; i++) //Цикл передачи 8 бит. { data_bit = data; //Определяем текущий, передаваемый бит посредством сдвига и логического "И". data_bit = (data>>i) & (uint8_t)0x01; //Для первого передаваемого бита алгоритм следующий: //Так как при первом выполнении цикла i=0, значит все биты переменной data (она хранит передаваемый нами байт) //сдигаются вправо на 0 позиций, т.е не сдвигаются вообще, теперь выполняем логическое "И" //с получившимся числом, так как второй операнд равен единице, то все остальные //7 бит переменной Data попросту обнулятся, независимо от того какими они были до //этого. Следующий цикл (i=1) проделает эту же самую операцию со вторым битом Data и т.д.
DQ_0; //Low LINE //Любой тайм-слот начинается ведущим уст-вом с передачи низкого уровня. //Далее в зависимости от текущего бита для передачи, формируются временные последовательности, //состоящие всегда из двух частей (условно):
if(data_bit == (uint8_t)0x01) //"Первая часть" тайм-слота передачи 1. { delay_us(1); //1мкс состояния линии "в ноль". } else //"Первая часть" тайм-слота для передачи 0. { delay_us(90); //Для передачи 0, задержим линию "в низком уровне" некоторое время. }
DQ_1; //Возващаем линию в выс. ур.
if(data_bit == (uint8_t)0x01) //"Вторая часть" тайм-слота передачи 1, подержим линию "в единице" подольше. { delay_us(90); } else //"Вторая часть" тайм-слота передачи 0, краткий импульс вверх. { delay_us(1); }
DQ_1; //По завершении передачи каждого бита линию необходимо переводить в выс. ур. delay_us(1); //Выдерживаем минимальную задержку между тайм-слотами (1мкс.(продолжит. либого тайм-слота = 60-120мкс)). } }
uint8_t OneWire_ReadByte(void) { uint8_t i; uint8_t Data = 0;
for(i=0; i<8; i++) { delay_us(1); DQ_0; //Low LINE //Как всегда перед передачей или приемом либого тайм-слота "опускаем линию", delay_us(5); //давая ведомому устр-ву понять что мы готовы к приему данных.
DQ_1; //Затем возвращаем в 1 и ждем что бы устр-во успело перевести линию в низкий уровень, delay_us(15); //либо если идет передача единицы - оставило состояние шины как есть.
if(DQ) //Если линия так и осталась при высоком уровне: { Data |= ((uint8_t)0x01 << i); //Проведем логическое "ИЛИ" с единицей и номером текущего бита для чтения } //(т.е по-другому говоря установим 1). Таким образом мы получим единицы там где ведомое устр-во пере- //давало 1 и нули во всех оставшихся случаях. Это собственно и будет то число что //передавало ведомое устр-во. delay_us(55); //Заканчиваем текущий тайм-слот и переходим к началу следующего... } return Data; //Возвращаем принятый байт. }
while (1) { Presence = OneWire_Init(); OneWire_WriteByte(SKIP_ROM); OneWire_WriteByte(CONVERT_TEMP);
while(LastSu == Su) { TimeToCompute = RTC->TR; /* get time */ DateToCompute = RTC->DR; /* need to read date also */ Su = (uint8_t)(TimeToCompute & RTC_TR_SU); } LastSu = Su;
Все сразу заработало: Спойлер Практически поручились часы с термометром для автомобиля или дома - прям как китайцы делают. Ну в общем дрыгает нормально как и все остальные. Возможности далеко не все исчерпаны. Ядро опять практически ничего не делает. Так как у нас есть ЦАП в этом микроконтроллере и флэша валом - например можно сделать будильник с человеческим голосом, музыкой или произносить время синтезированным голосом. Для фантазий есть простор... з.ы. Program Size: Code=1344 RO-data=236 RW-data=68 ZI-data=1028 предел тини13 прошли, до предела тини2313 еще далеко
У вас в алгоритме ошибочка, которая будет приводить к неправильному считыванию данных. После OneWire_WriteByte(CONVERT_TEMP) нужно либо подождать фиксированное время на преобразование, либо в цикле проводить опрос и ждать когда датчик будет готов что-либо ответить. Ну и scratchpad очень желательно прочитать целиком чтобы потом посчитать CRC.
да секундная задержка есть. Можно начитаться умных мыслей в интернете, что чтение по готовности (оно готово через ~750мс) приводит к саморазогреву датчика - т.к. регулярно дергаем датчик. Некоторые рекомендации читал, что чем реже опрашиваем датчик, тем лучше и вообще надо 2 раза в минуту, но, например для терморегулятора, это не приемлемо. CRC конечно нужно (а у нас уже есть аппаратный CRC calculation unit), но тут была другая цель - просто проверить работает ли метод, кому будет необходимо - добавит. в военное время значение косинуса может достигать пяти(с)
Решил попробовать откомпилировать предыдущую программу с помощью бесплатного компилятора GCC, а то скажут на ворованном каждый сможет, хотя Keil бесплатно 32K позволяет. Лекарством в предыдущих случаях не пользовался - как говорил известный программист-милиардер 32K "должно быть достаточно для каждого" http://lurkmore.to/640_%D0%BA%D0%B8%D0% ... 0%B9%D1%82 . Ввиду ленивости, чтоб не возиться с эклипсом, установил бесплатную IDE Em::Blocks со встроенным компилятором GCC. Проект создается легко и просто - после создания все аккуратно лежит в папочках, включая ненужную SPL, которая легко убирается. Скопировал код от Keil в Em::Blocks. Все сразу без ошибок скомпилировалось - вот удобно же один и тот же код работает на разных компиляторах (почему то уверен и на IARе тоже все будет хорошо). Помянул AVR-ские компиляторы - там анархия. Дебаг в Em::Blocks почему-то не запустился - "прошил" родной STM-овской утилитой - все также замечательно работает. Только размер немного удивил (оптимизация -OS):
Цитата:
Program size (bytes): 2252 Data size (bytes): 168 BSS size (bytes): 39 Total size (bytes): 2459 (R/W Memory: 207)
Но если все убрать и оставить чистый main(){}:
Цитата:
Program size (bytes): 1016 Data size (bytes): 108 BSS size (bytes): 28 Total size (bytes): 1152 (R/W Memory: 136)
куда ушли байты надо разбираться, а в принципе зачем - их и так девать (пока) некуда.
можно решить задачу аппаратным путем с помощью USART и DMA, но подобная работа была уже проведена товарищами с другого форума - повторять не очень интересно. Да и хотелось решить задачу простым ногодрыгом (любимое занятие 8-ми битных микроконтроллеров), например это может пригодится для малоногих микроконтроллеров у которых USART возможно занят. ................... Микросекундные задержки сделаны на таймере том же TIM3, DMA теперь управляет 15 таймер - освободил каналы 2 и 3 на будущее для USART.
Если USART занят и пару кил флэша не жапко, то можно сделать и на таймере... например TIM3... Там то и надо... один пин, два канала таймера и два канала ДМА... Можно вручную пинать... можно автоматом по кругу, как при динамической индикации на ДМА... По окончанию трансфера ДМА вытаскиваем биты из массива и сбиваем в байты... вуаля...
_________________ "Я не даю готовых решений, я заставляю думать!"(С)
там то и надо... один пин, два канала таймера и два канала ДМА...
Опять ядру не оставляем вообще никакой работы. Да микроконтроллеры на ядре арм позволяют решать обычные задачи нетрадиционными способами за счет развитой периферии. Сделал для себя недавно еще "открытие" (раньше как то не обращал внимания). Для начала предисловие:
Цитата:
STM32. Системный таймер SysTick. Этот таймер не описан подробно в документации на конкретное семейство микроконтроллеров, например в том же Reference manual про него присутствует всего лишь несколько строк. Дело в том, что эти документы в основном объясняют порядок работы с периферией. А таймер SysTick расположен в ядре микроконтроллера и для всех устройств на базе ядра Cortex является стандартным. Этот таймер предназначен для формирования временных интервалов операционной системы реального времени – RTOS. Но и для других целей можно использовать периодические прерывания, формируемые этим таймером. В микроконтроллерах на ядре Cortex время перехода к обработчику прерывания строго детерминировано, что является огромным плюсом этого ядра. Таймер представляет собой 24-разрядный декрементирующий счетчик. Источником тактирования является системная тактовая частота SYSCLK, либо та же частота, но поделенная на 8 – SYSCLK/8.
Для конфигурации таймера в файле CMSIS core_cmX.h есть функция SysTick_Config(uint32_t ticks), в качестве аргумента которой передается коэффициент деления тактовой частоты для получения необходимой временной задержки. То есть если просто напишем
Код:
SysTick_Config(48000); /* 1ms config */
и обработчик прерывания
Код:
void SysTick_Handler(void) { }
Получим 1мс прерывания (любые в широком диапазоне - 24 бита все таки), которые можно использовать для динамической индикации, задания временных интервалов и пр. Очень просто и удобно - и ни один аппаратный таймер не пострадал.
О сколько нам открытий чудных Готовят просвещенья дух И опыт, сын ошибок трудных, И гений, парадоксов друг, И случай, бог изобретатель...
з.ы. интересное маленькое событие из мира 32-битных: NXP решила прекратить выпуск микроконтроллеров LPC1114FN28 в 28-ми выводном радиолюбительском корпусе дип 28. Товарищ ytsuboi написал открытое письмо генеральному директору компании NXP Semiconductors: http://www.ytsuboi.org/wp/archives/2281 корявый перевод: Спойлер
Цитата:
Уважаемый г-н Клеммер,
Около недели назад, я обнаружил невероятную информацию о LPC1114FN28 на Digikey и Mouser. Это было "LPC1114FN28 был помечен как устаревший, в настоящее время прекращено." Я подтвердил LPC1114FN28 в вашем 2014 Mid-Year снятии с производства продукции списке. (На вершине стр. 11), а также я знаю, LPC1114FN28 в списке вашего долголетия, 10-летний списке обещание. К этому списку, дата долговечность LPC1114FN28 является 2022-08-08. Здесь это архив веб-странице.
В этом году, я провел время в порт mbed SDK для некоторых из ваших продуктов. Как вы знаете, компания NXP представляет mbed как один из вашего "Сервис экосистеме". А также я знаю, 1000 + люди используют LPC1114FN28 на онлайн составителя mbed. Мы приобрели LPC1114FN28 через официального дистрибьютора компании NXP, но я никогда не получал точную информацию из этих каналов.
Так, у меня есть несколько вопросов. - Какая информация является правильным? Будете ли вы прекратить, что в конце этого года или нет? - Почему NXP демонстрирует противоречивую информацию? Я думал, прекращение очень важно решить для полупроводников.
Если вы прекратите, что, - Какова ваша "обещание"? Как мы можем верить вы будете держать ваши слова с сегодняшнего дня? - Я знаю, 1k что-то не большое количество для полупроводников, но почему вы игнорируете нас?
Надеюсь услышать ваше искреннее отношение. С уважением, Йошихиро Цубои
Из ответа: Спойлер
Цитата:
Я знаю, долговечность продукта очень важно для вас, так же, как важно NXP. И я очень ценю, что ты вновь подчеркнув важность этого микроконтроллер для проектирования деятельности более чем 1000+ клиентов с использованием mbed платформу. Мы рады сообщить вам, о своем решении немедленно восстановить часть в активную, упорядочиваемой статуса с не планируется в конце срока службы, как было сообщено на середину года список снятии продукции с производства 2014 года. Мы также будем информировать наших Дистрибьюторов этого решения, так состояние доступности на дистрибьютора сайтов должна быть обновлена, как только эта информация принимается и обрабатывается.
Был восстановлен статус LPC1114FN28 на странице NXP. Вот это отношение к клиентам. А Атмел давно сняла с производства мой любимый AT90S1200 (чую с мегами и тинями тоже будет) и в ус не дует - абыдно, да.
Спасибо - полезно почитать, послушаю позже. Чуйка частично подтверждается - похоже с переходом на новые технологии забьют на радиолюбительские дип корпуса. Но новые будут выпускаться еще 12 лет - кому лень изучать 32-битные, могут быть спокойны больше десятка лет и новички могут паять программаторы, только на всякий случай 3-х вольтовые.
Та да... А чё... берём самый дешёвый F030F4... на РВ1 вешаем 18В20... на порт А - 4-ёх разрядный семисегментник... или мелкий TFT дисплей... Всё хардварно... нужно только забрать данные из буфера -> перекодировать -> отослать данные в буфер дисплея... Если взять камень покруче... с 8К SRAM... и по таймеру дрыгать портом (полупортом)... то получаем 16 (8) датчиков 18В20 опрашиваемых одновременно и хардварно... Дёшево и сердито!!!
_________________ "Я не даю готовых решений, я заставляю думать!"(С)
Сейчас этот форум просматривают: МЕХАНИКД и гости: 57
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения