• Объявления

    • admin

      Просьба всем принять участие!   24.11.2017

      На форуме разыгрывается спектроанализатор Arinst SSA-TG LC (цена 18500 руб). Просьба всем перейти по ссылке ниже и принять участие!
GDK

Советы для грамотной архитектуры прошивки.

32 сообщения в этой теме

IMXO    1 096
3 часа назад, oldmao сказал:

 Отдельно делаем опрос датчиков, например 1-Wire, где критичны временные интервалы, с запретом остальных прерываний на время работы с датчиком. Это миллисекунды, пропуск даже пары тактов динамической индикации глазом будет не заметен. 

не заметен, говорите? на форуме как минимум можно найти 5-6 тем , где все заметно и даже очень...

к слову прием/передача одной команды в  ds18b20  составляет  9,6мс этого вполне достаточно получить мигание индикатора, при неправильно составленном коде.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Быстрый заказ печатных плат

Полный цикл производства PCB по низким ценам!

  • x
    мм
Заказать Получить купон на $5.00
IMXO    1 096
17 часов назад, GDK сказал:

@IMXO , там 3 октавы, я не разбираюсь в этом, это до 2 кГц? Ну и МК там... напр.   14кбайт - память программ, 368 байт - опер. память, а у меня 4к и 168 байт соответственно. Там ОСРВ, в мой МК наверное не влезет.

суть не в этом, по ссылю очень хорошо расписано как получить синусоиду при помощи ШИМ , ЦАП это хорошо, но потребует танцы с бубном для согласования МК с нагрузкой, для ШИМ это будет всего один транзисторный ключ.

ОСРВ влазит даже в pic10f222

а вот нужна она вам или нет это решать вам, в конечном счете ваша хотелка все равно придет к использованию конечных автоматов или ОСРВ,

потому как когда прога будет написана и отлажена , внесение в нее каких либо изменений будет вызывать головняк в плоть до полного переписывания кода

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
ARV    252
53 минуты назад, IMXO сказал:

к слову прием/передача одной команды в  ds18b20  составляет  9,6мс этого вполне достаточно получить мигание индикатора, при неправильно составленном коде

Вот именно, при неправильно составленном.

А неправильно составляется он обычно при невнимательном чтении документации.

А при внимательном становится ясно, что критичным для протокола 1-wire интервалом является всего-навсего от 15 до 65 микросекунд. Запрет прерываний на такое время заметить невозможно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
oldmao    1 287

У меня между циклами динамической индикации и опроса кнопок (каждые 20 мсек) программа успевает опросить DS18B20, преобразовать значение в готовые байты для засылки в 74HC595 (сегменты индикатора), проверить состояние кнопок. При тактовой 8 МГц не было ни одного пропуска циклов индикации, при тактовой 1 МГц один цикл пропускается. Но поскольку опрашиваю термодатчик 1 раз в 3 секунды, то это абсолютно незаметно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
GDK    2
1 час назад, IMXO сказал:

ОСРВ влазит даже в pic10f222

Посмотрел осю. Там нет компилятора моего и ничего не нашёл про спящий режим МК, а это важно. В моём понимании, с точки зрения питания, лучше не ограничивать потребление снижением частоты, а настроить на максимальную и ложить спать, тогда просто при добавлении новых хотелок уменьшится время сна, задержки и настройки, зависящие от т. частоты, не придётся искать и переписывать.

Изменено пользователем GDK

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
oldmao    1 287

В ОС реального времени спящего режима не может быть по определению. Интересно, что будет удерживать реле управления насосом во время сна процессора? И сколько там по даташиту требуется тактов для гарантированного запуска кварцевого или встроенного RC-генератора при выходе из сна?
Экономить энергопотребление имеет смысл только при батарейном питании, а тут явно сетевое, смысла нет.

Изменено пользователем oldmao

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Vovka    23
13 часа назад, GDK сказал:

Мне показалось, что 16LF1823 справится

Легко. Сразу запускайте на 32 МГц и будет много свободного времени ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Похожие публикации

    • Автор: gsclock
      Всем привет. Подскажите, пожалуйста, простые статьи по ИИП на английском языке, было бы хорошо если бы были с переводом и подлиннее, задали по английскому языку перевод. Сам я нашел несколько, но возникают проблемы с переводом. Спасибо!
    • Автор: TIGER53501
      Привет, никак не могу разобраться с таймером в режиме сброса по внешнему событию,
      сам сброс работает, таймер сбрасывается, вопрос вот в чём, могу ли я в этом режиме использовать захват на оставшихся каналах?
      т.е. по внешнему событию сбрасывать таймер, и потом внешними событиями записывать сколько он протикал с момента сброса?
      STM32F429ZI
      СИ + VisualGDB + HAL + Cube
    • Автор: balistik
      Всем доброго времени суток. Я реальный нуб в ATMEGA. Могу более-менее понять чужой код и из кусков сделать целое. Вопрос такой: реально ли на ATMEGA8 сделать 2 ШИМ (таймер 1 и2) и внутреннее прерывание (по таймеру 0) для чтения данных с DS18B20 на 8Мгц чтобы еще осталось на опрос кнопок и небольшую логику? Я выложу пример кода. По отдельность: ШИМ, прерывания, логика, запись в ЕПРОМ работает. Собираю все вместе - не работает. Пробовал в Протеусе, тоже глючит, да и протеус тормозит. Может кто чего подскажет.
      //#define F_CPU 8000000UL // устанавливаем рабочую частоту контроллера #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <avr/eeprom.h> #include "ds18x20.h" #include "onewire.h" #define MAXSENSORS 1 unsigned int tempint = 0; // переменная для целого значения температуры unsigned int subzero = 0; // переменная отрицательных значений температуры unsigned int clock = 0; //задержка для опроса датчика температуры unsigned int termo_error = 0; //флаг ошибки термодатчика unsigned char regim, R1_SHIBER, R1_VENT, R2_SHIBER, R2_VENT, R3_SHIBER, R3_VENT; //переменные режимов работы volatile char press = 0, pr = 0, pr1 = 0, set = 0; //дополнительные переменные для кнопок #define SHIBER_PB 1 //шибер подачи топлива #define SHIBER_PWM OCR1A #define VENT_PB 2 //вентилятор подачи воздуха #define VENT_PWM OCR1B #define LED1_ON PORTD |= _BV(PD3) // светодиод режим 1 #define LED1_OFF PORTD &= ~_BV(PD3) #define LED2_ON PORTD |= _BV(PD4) // светодиод режим 2 #define LED2_OFF PORTD &= ~_BV(PD4) #define LED3_ON PORTD |= _BV(PD6) // светодиод режим 3 #define LED3_OFF PORTD &= ~_BV(PD6) #define LED4_ON PORTD |= _BV(PD7) // светодиод 4 программирование #define LED4_OFF PORTD &= ~_BV(PD7) #define BUT_M PIND & (1 << PD1) // кнопка MENU #define BUT_U PIND & (1 << PD2) // кнопка UP #define BUT_D PIND & (1 << PD0) // кнопка DOWN unsigned char eep1 EEMEM; // режим работы unsigned char eep2 EEMEM; // режим 1 ШИМ вентилятор unsigned char eep3 EEMEM; //режим 1 ШИМ шибер unsigned char eep4 EEMEM; // режим 2 ШИМ вентилятор unsigned char eep5 EEMEM; // режим 2 ШИМ шибер unsigned char eep6 EEMEM; // режим 3 ШИМ вентилятор unsigned char eep7 EEMEM; // режим 3 ШИМ шибер unsigned char eep8 EEMEM; // флаг первого запуска uint8_t Temperature, szero; //-255 uint8_t nSensors, j; uint8_t cel_frac_bits; uint8_t gSensorIDs[MAXSENSORS][OW_ROMCODE_SIZE]; uint8_t search_sensors(void) // поиск DS18B20 { uint8_t i; uint8_t id[OW_ROMCODE_SIZE]; uint8_t diff, nSensors; nSensors = 0; for( diff = OW_SEARCH_FIRST; diff != OW_LAST_DEVICE && nSensors < MAXSENSORS ; ) { DS18X20_find_sensor( &diff, &id[0] ); if( diff == OW_PRESENCE_ERR ) { Temperature = 255; szero = 1; break; } if( diff == OW_DATA_ERR ) { Temperature = 255; szero = 1; break; } for (i=0; i<OW_ROMCODE_SIZE; i++) gSensorIDs[nSensors][i]=id[i]; nSensors++; } return nSensors; } void get_temp(int sensor){ // получаем температуру с датчиков DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); j = gSensorIDs[0][sensor]; // family-code for conversion-routine if (DS18X20_read_meas_single(j, &szero, &Temperature, &cel_frac_bits) != DS18X20_OK) { //если не прочиталось то -255 Temperature = 255; szero = 1; } if (DS18X20_read_meas_single(j, &szero, &Temperature, &cel_frac_bits) != DS18X20_OK) { //если не прочиталось то -255 Temperature = 255; szero = 1; } tempint=(int)Temperature; subzero=(int)szero; } void pin_init(void) { //инициализация портов ШИМ DDRB |= (1<<SHIBER_PB) | (1<<VENT_PB); PORTB &= ~((1<<SHIBER_PB) | (1<<VENT_PB)); } void timer0_init(void) { //инициализация таймера для термодатчика TCCR0 |= (1<<CS00); TIMSK |= ( 1 << TOIE0); TCNT0 = 0xFF; } void timer1_init(void) { //инициализация таймера ШИМ шибера TCCR1A |= (1 << COM1A1) | (1 << COM1B1) | (1 << WGM11); TCCR1B |= (1 << WGM13) | (1 << WGM12) | (1 << CS10); TCNT1 = 0x00; ICR1 = 0xFF; OCR1A = 0x00; OCR1B = 0x00; } void timer2_init(void) { //инициализация таймера ШИМ вентилятора TCCR2 |= (1 << COM21) | (1 << WGM21) | (1 << WGM20) | (1 << CS20); TCNT2 = 0x00; OCR2 = 0x00; } ISR(TIMER0_OVF_vect){ //прерывание таймера 0 для термодатчика if (clock != 4294967295){_delay_us(50);clock++;}else{get_temp(0);clock=0;} } //***************** обработка нажатия кнопок ********************** void buttons(){ if(~BUT_U){if(set == 0)pr++; // кнопка UP if(pr == 10){ // долгое нажатие } _delay_ms(100); }else{ if(pr >= 1 && pr < 10){ // короткое нажатие regim++; if (regim>3){regim=0;} eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom set = 0; pr = 0; } pr = 0; } if(~BUT_D){if(set == 0)pr1++; // кнопка DOWN if(pr1 == 10){ // длинное нажатие } _delay_ms(100); }else{ if(pr1 >= 1 && pr1 < 10){ // короткое нажатие. //set = 20; regim--; if (regim<0){regim=3;} eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom _delay_ms(100); set = 0; pr1 = 0; } pr1 = 0; } if(~BUT_M){ // кнопка MENU press++; if(press == 1 && set != 0){set++;} // переход по настройкам if(press >= 100 && set == 0){set = 1; _delay_ms(200);} // ход в настройки if(set == 1) eeprom_write_byte(&eep2, R1_VENT); if(set == 2) eeprom_write_byte(&eep3, R1_SHIBER); if(set == 3) eeprom_write_byte(&eep4, R2_VENT); if(set == 4) eeprom_write_byte(&eep5, R2_SHIBER); if(set == 5) eeprom_write_byte(&eep6, R3_VENT); if(set == 6) eeprom_write_byte(&eep7, R3_SHIBER); if(set > 6){ _delay_ms(100); set = 0; press = 0;} // если включена настройка даты, }else{ if(set == 0 && press >= 1){ // если не вошли в настройки regim++; if (regim>3){regim=0;} eeprom_write_byte(&eep1, regim); // сохранение настройки в eeprom } press = 0; } } //*****************режим настроек******************** void settings(){ //визуальное подтверждение настроек if(press >= 1 && set == 1) { LED1_ON; LED2_OFF; LED3_OFF; LED4_ON; SHIBER_PWM = R1_VENT;} //ШИМ шибер 0-255 if(press >= 1 && set == 2) { LED1_ON; LED2_OFF; LED3_OFF; LED4_ON; VENT_PWM = R1_SHIBER;} //ШИМ вентилятор 0-255 if(press >= 1 && set == 3) { LED1_OFF; LED2_ON; LED3_OFF; LED4_ON; SHIBER_PWM = R2_VENT;} //ШИМ шибер 0-255 if(press >= 1 && set == 4) { LED1_OFF; LED2_ON; LED3_OFF; LED4_ON; VENT_PWM = R2_SHIBER;} //ШИМ вентилятор 0-255 if(press >= 1 && set == 5) { LED1_OFF; LED2_OFF; LED3_ON; LED4_ON; SHIBER_PWM = R3_VENT;} //ШИМ шибер 0-255 if(press >= 1 && set == 6) { LED1_OFF; LED2_OFF; LED3_ON; LED4_ON; VENT_PWM = R3_SHIBER;} //ШИМ вентилятор 0-255 switch(set) // включена настройка { case 1: // настройка R1_VENT if(~BUT_U){R1_VENT++; if(R1_VENT > 254) R1_VENT = 0; _delay_ms(100);} if(~BUT_D){R1_VENT--; if((~BUT_D) && R1_VENT == 0) R1_VENT = 254; _delay_ms(100);} break; case 2: // настройка R1_SHIBER if(~BUT_U){R1_SHIBER++; if(R1_SHIBER > 254) R1_SHIBER = 0; _delay_ms(100);} if(~BUT_D){R1_SHIBER--; if((~BUT_D) && R1_SHIBER == 0) R1_SHIBER = 254; _delay_ms(100);} break; case 3: // настройка R2_VENT if(~BUT_U){R2_VENT++; if(R2_VENT > 254) R2_VENT = 0; _delay_ms(100);} if(~BUT_D){R2_VENT--; if((~BUT_D) && R2_VENT == 0) R2_VENT = 254; _delay_ms(100);} break; case 4: // настройка R2_SHIBER if(~BUT_U){R2_SHIBER++; if(R2_SHIBER > 254) R2_SHIBER = 0; _delay_ms(100);} if(~BUT_D){R2_SHIBER--; if((~BUT_D) && R2_SHIBER == 0) R2_SHIBER = 254; _delay_ms(100);} break; case 5: // настройка R3_VENT if(~BUT_U){R3_VENT++; if(R3_VENT > 254) R3_VENT = 0; _delay_ms(100);} if(~BUT_D){R3_VENT--; if((~BUT_D) && R3_VENT == 0) R3_VENT = 254; _delay_ms(100);} break; case 6: // настройка R3_SHIBER if(~BUT_U){R3_SHIBER++; if(R3_SHIBER > 254) R3_SHIBER = 0; _delay_ms(100);} if(~BUT_D){R3_SHIBER--; if((~BUT_D) && R3_SHIBER == 0) R3_SHIBER = 254; _delay_ms(100);} break; } } int main(){ /*******************************настройка переферии******************************/ cli(); ow_set_bus(&PIND, &PORTD, &DDRD, PD5); // иництализация протокола 1-wire nSensors = search_sensors(); // поиск датчиков DS18B20 DS18X20_start_meas(DS18X20_POWER_EXTERN, NULL); //включаем преобразование температуры pin_init(); //timer0_init(); timer1_init(); timer2_init(); _delay_ms(5); if(eeprom_read_byte(&eep8) != 1){ // читаем eeprom, если там мусор (первый запуск), пишем свои данные eeprom_write_byte(&eep1, 0); // режим работы eeprom_write_byte(&eep2, 150); // режим 1 ШИМ вентилятор eeprom_write_byte(&eep3, 100); //режим 1 ШИМ шибер eeprom_write_byte(&eep4, 200); //режим 2 ШИМ вентилятор eeprom_write_byte(&eep5, 150); //режим 2 ШИМ шибер eeprom_write_byte(&eep6, 230); //режим 3 ШИМ вентилятор eeprom_write_byte(&eep7, 200); //режим 3 ШИМ шибер eeprom_write_byte(&eep8, 1); // флаг первого запуска } //читаем настройки из памяти regim = eeprom_read_byte(&eep1); // читаем режим работы из eeprom R1_VENT = eeprom_read_byte(&eep2); // читаем режим 1 ШИМ вентилятор из eeprom R1_SHIBER = eeprom_read_byte(&eep3); //читаем режим 1 ШИМ шибер R2_VENT = eeprom_read_byte(&eep4); //читаем режим 2 ШИМ вентилятор R1_SHIBER = eeprom_read_byte(&eep5); //читаем режим 2 ШИМ шибер R3_VENT = eeprom_read_byte(&eep6); //читаем режим 3 ШИМ вентилятор R1_SHIBER = eeprom_read_byte(&eep7); //читаем режим 3 ШИМ шибер sei(); _delay_ms(5); /**********************************инициализация ШИМ*************************************/ while(1){ //if (tempint=255) {LED1_ON;LED2_OFF;LED3_ON;termo_error=1;} else {termo_error=0;}//выводим код ошибки датчика темппературы buttons();//обработик нажатия кнопок if (termo_error == 0){//блокировка по термодатчику if(set == 0) { //нормальный режим работы if (regim == 0){ //режим работы 0 LED1_OFF; LED2_OFF; LED3_OFF; LED4_OFF; SHIBER_PWM = 0; //ШИМ шибер 0-255 VENT_PWM = 0; //ШИМ вентилятор 0-255 } if (regim == 1){ //режим работы 1 LED1_ON; LED2_OFF; LED3_OFF; LED4_OFF; VENT_PWM = R1_VENT; //ШИМ вентилятор 0-255 if (tempint >=40) { //блокировка по температуре SHIBER_PWM = 0; //ШИМ шибер 0-255 }else{ SHIBER_PWM = R1_SHIBER; //ШИМ шибер 0-255 } } if (regim == 2){ //режим работы 2 LED1_OFF; LED2_ON; LED3_OFF; LED4_OFF; VENT_PWM = R2_VENT; //ШИМ вентилятор 0-255 if (tempint >=60) { //блокировка по температуре SHIBER_PWM = 0; //ШИМ шибер 0-255 }else{ SHIBER_PWM = R2_SHIBER; //ШИМ шибер 0-255 } } if (regim == 3){ //режим работы 3 LED1_OFF; LED2_OFF; LED3_ON; LED4_OFF; VENT_PWM = R3_VENT; //ШИМ вентилятор 0-255 if (tempint >=80) { //блокировка по температуре SHIBER_PWM = 0; //ШИМ шибер 0-255 }else{ SHIBER_PWM = R3_SHIBER; //ШИМ шибер 0-255 } } } }else{ SHIBER_PWM=0; VENT_PWM=0; } if(set != 0) settings();//вход в настройки } //return 0; }  
    • Автор: sdkdenis
      Возник вопрос теории интерпретатора кода микропроцессора микроконтроллером
      Возьмём к примеру, всеми любимый КР580ИК80, (опустим сейчас споры зачем, не хватит скорости и т.д.), интересна теория построения такой «Виртуальной машины».
      В моём понимании алгоритм такой:
      1-      В памяти микроконтроллера создаётся массив с адресами подпрограмм кодов процессора (в нашем случае КР580ИК80);
      2-      Ячейки массива имеют названия идентичные соответствующим командам процессора
      3-      Микроконтроллер выставляет на определённых портах (допустим порт А и В) адрес извлекаемой из внешней памяти команды программы;
      4-      Считывает данные с порта (допустим С);
      5-      Выбирает ячейку массива с именем идентичным считанному значению из порта С;
      6-      Переходит к подпрограмме по адресу записанному в соответствующей ячейке массива;
      7-      В процессе выполнения подпрограммы происходят соответствующие действия и увеличение (или иное изменение) счетчика команд;
      8-      Процесс повторяется с шага 3.
      Так вот если и вправду алгоритм построения данного решения соответствует описанному выше, то у меня возникает вопрос, неужели микроконтроллеру на каждую команду процессора приходится перечёсывать массив ища соответствие, или есть иной путь прямого перехода к соответствующей подпрограмме?
      Возможно я неправильно понимаю реализацию интерпретатора кода микропроцессора микроконтроллером?
    • Автор: KushlaVR
      Здраствуйте. Возникла необходимовсть управления несколькими устройствами разных производителей с помощю одного елемента управления.
      В качестве управлялки нужно использовать Sony RM-X6. и сенсорний монитор с виходом формата NEC (на дисплее есть кнопки и когда в их нажымать - транслирується команда)
      Управление осуществляєтся с помощю устройства (которое мне нежно разработать). С протоколом NEC - разобратся получилось (есть куча примеров).
      А вот протокол Sony rm-X6 темный ящик. Такое ощущение что ето обичний UART...
      Значит вопрос собственно такой:
      1) Помогите распознать что за протокол?
      2) Помогите составить алгоритм по распознанию (контроллер Atmega8 тактовая частота внутреннего генератора 8МГц)
      3)Возможнор ктото уже работал с ним, и готов поделится примерами...
      П.С.
      Усилографа нет... Снял сигнал с помощю звуковой карточки (в формате waw). Результат можна посмотреть вот тут:
      drive.google.com/folderview?id=0B-SmX6iwS8HeT3NYSXlYQzJMY2M&usp=sharing
      (извините, waw не могу прикрепить к теме, потому разшарил папку. Если у модераторов есть возможность, то прикрепите, буду благодарен)
      Спасибо всем за внимание и помощь....