Показаны сообщения с ярлыком Coding. Показать все сообщения
Показаны сообщения с ярлыком Coding. Показать все сообщения
понедельник, 2 декабря 2013 г.
пятница, 15 ноября 2013 г.
воскресенье, 3 ноября 2013 г.
понедельник, 28 октября 2013 г.
пятница, 25 октября 2013 г.
среда, 23 октября 2013 г.
Как писать передаточные функции на Си (Converting Transfer Functions to C Code)
http://www.slideshare.net/DelftOpenEr/ch1-9097263
EMBEDDED CONTROL
- if a feedback control function is to be implemented in software the transfer function can be converted to a C subroutine.
суббота, 12 октября 2013 г.
AVR - как избавиться от чисел с плавающей точкой
Одно из сильных ограничений AVR (на платформе MCS51 это сказывается не так) - быстрый расход памяти при написании программ на Си.
Что поделаешь, за удобства Си и скорость RISC надо платить. Еще больший соблазн - использование для вычислений (например, при измерении напряжений с помощью ADC) чисел float(числа с плавающей запятой). Несмотря на то, что эти вычисления не точны, их слишком просто и удобно применять - можно делить и умножать, не задумываясь о переполнении, и легко представлять результаты вычисления в формате, понятном человеку.
Но плата за float слишком высока - линкер добавляет код библиотек математики, и память программ кончается очень быстро. Другое ограничение - вычисления с float выполняются слишком медленно (если конечно не используется аппаратный перемножитель типа [1]). Если нет возможности реализовать алгоритм программы с применением чисел float (из-за вышеуказанных ограничений по объему кода и скорости), одним из вариантов решения проблемы является переход на числа сфиксированной запятой. Их математические операции (вычитание, сложение, деление, умножение) ничем не отличаются от математических операций с простыми целыми числами, код получается компактный и быстрый.
Число с фиксированной запятой (обычно байт или слово из двух байт) состоит из целой части(находится в старших битах 8 или 16-разрядного числа) и дробной части (находится в младших битах). Пример числа с фиксированной запятой указан на рисунке, с разрядностью в 8 бит (1 байт).

понедельник, 7 октября 2013 г.
пятница, 4 октября 2013 г.
Программатор AVR USB на Atmega8
Источник http://www.getchip.net/posts/040-uartrs-232-to-usb-prostojj-preobrazovatel/
Наконец-то закончились праздники, и пришло время чего-нибудь сделать.
Начнем, пожалуй, с необходимого устройства, облегчающего жизнь рядового электронщика – устройства связи с компьютером. Это нужно для того, чтобы передать данные в компьютер (температура с датчиков, положение дверей, частота вращения двигателя, таблица значений с регистратора …) или принять данные из компьютера (таблицы значений для вычислений, настоечные данные для устройств, новая прошивка для загрузчика…). Для отладки нового устройства (посмотреть что там, в мозгах микроконтроллера, происходит) вообще незаменимая вещь.
Как Вы знаете, существует множество интерфейсов, посредством которых микроконтроллер может общаться с внешним миром. Но если речь идет о связи с компьютером – вне конкуренции интерфейс RS-232 (COM порт). Причина – простота работы с портом со стороны компьютера и наличие большого количества программ для этого предназначенных. Кроме того, почти в каждом микроконтроллере есть аппаратно поддерживаемый интерфейс USART (это тот-же RS-232, только с напряжениями 0 – 5v), что делает процесс связи легко реализуемым.
Для того, чтобы привести уровни сигнала микроконтроллерного USART к уровням COM порта компьютера нужно собрать несложный преобразователь (например, на МАХ232), но можно пойти по более интересному пути
Более интересный путь - собрать преобразователь UART to USB. При этом USB порт воспринимается компьютером как виртуальный COM порт. В этом случае мы убиваем сразу несколько зайцев:
– USB порт есть в любом компьютере (хотя COM порт встречается еще довольно часто, но на ноутбуках его уже нет);
– как оказалось преобразователь UART to COM(RS-232) сделать гораздо сложнее, чем UART to USB (два раза делал программатор для СОМ порта с преобразователем МАХ232 – оба раза неудачно);
– если подключать преобразователь через USB хаб, то мы получаем сразу несколько виртуальных COM портов на одном USB, плюс безопасность для компьютера, так как хаб выступает в роли буфера.
Как Вы знаете, существует множество интерфейсов, посредством которых микроконтроллер может общаться с внешним миром. Но если речь идет о связи с компьютером – вне конкуренции интерфейс RS-232 (COM порт). Причина – простота работы с портом со стороны компьютера и наличие большого количества программ для этого предназначенных. Кроме того, почти в каждом микроконтроллере есть аппаратно поддерживаемый интерфейс USART (это тот-же RS-232, только с напряжениями 0 – 5v), что делает процесс связи легко реализуемым.
Для того, чтобы привести уровни сигнала микроконтроллерного USART к уровням COM порта компьютера нужно собрать несложный преобразователь (например, на МАХ232), но можно пойти по более интересному пути
Более интересный путь - собрать преобразователь UART to USB. При этом USB порт воспринимается компьютером как виртуальный COM порт. В этом случае мы убиваем сразу несколько зайцев:
– USB порт есть в любом компьютере (хотя COM порт встречается еще довольно часто, но на ноутбуках его уже нет);
– как оказалось преобразователь UART to COM(RS-232) сделать гораздо сложнее, чем UART to USB (два раза делал программатор для СОМ порта с преобразователем МАХ232 – оба раза неудачно);
– если подключать преобразователь через USB хаб, то мы получаем сразу несколько виртуальных COM портов на одном USB, плюс безопасность для компьютера, так как хаб выступает в роли буфера.
Вот схема преобразователя UART to USB.
Сразу честно признаюсь – это не мое устройство. Взята данная схема с сайта www.recursion.jp/avrcdc/ . Причина, по которой я ее здесь привожу – это простота схемы и дешевизна изготовления. Собрать схему довольно просто (можно даже на макете).
Готовое устройство я выполнил в форме «флешки» для того, чтобы удобней было пользоваться в «полевых» условиях. Для большего комфорта можно взять USB удлинитель, одним разъемом прицепить к компьютеру, во второй вставить нашу «флешку-преобразователь» и получим мобильное устройство, которое можно без проблем подключить к любой схеме.
четверг, 3 октября 2013 г.
среда, 2 октября 2013 г.
понедельник, 30 сентября 2013 г.
пятница, 27 сентября 2013 г.
четверг, 19 сентября 2013 г.
понедельник, 16 сентября 2013 г.
пятница, 13 сентября 2013 г.
Программирование множества кнопок
http://www.adafruit.com/blog/2009/10/20/example-code-for-multi-button-checker-with-debouncing/
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19 // This handy macro lets us determine how big the array up above is, by checking the size #define NUMBUTTONS sizeof(buttons) // we will track if a button is just pressed, just released, or 'currently pressed' byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS]; void setup() { byte i; // set up serial port Serial.begin(9600); Serial.print("Button checker with "); Serial.print(NUMBUTTONS, DEC); Serial.println(" buttons"); // pin13 LED pinMode(13, OUTPUT); // Make input & enable pull-up resistors on switch pins for (i=0; i< NUMBUTTONS; i++) { pinMode(buttons[i], INPUT); digitalWrite(buttons[i], HIGH); } } void check_switches() { static byte previousstate[NUMBUTTONS]; static byte currentstate[NUMBUTTONS]; static long lasttime; byte index; if (millis() < lasttime) { // we wrapped around, lets just try again lasttime = millis(); } if ((lasttime + DEBOUNCE) > millis()) { // not enough time has passed to debounce return; } // ok we have waited DEBOUNCE milliseconds, lets reset the timer lasttime = millis(); for (index = 0; index < NUMBUTTONS; index++) { justpressed[index] = 0; // when we start, we clear out the "just" indicators justreleased[index] = 0; currentstate[index] = digitalRead(buttons[index]); // read the button /* Serial.print(index, DEC); Serial.print(": cstate="); Serial.print(currentstate[index], DEC); Serial.print(", pstate="); Serial.print(previousstate[index], DEC); Serial.print(", press="); */ if (currentstate[index] == previousstate[index]) { if ((pressed[index] == LOW) && (currentstate[index] == LOW)) { // just pressed justpressed[index] = 1; } else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) { // just released justreleased[index] = 1; } pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed } //Serial.println(pressed[index], DEC); previousstate[index] = currentstate[index]; // keep a running tally of the buttons } } void loop() { check_switches(); // when we check the switches we'll get the current state for (byte i = 0; i < NUMBUTTONS; i++) { if (justpressed[i]) { Serial.print(i, DEC); Serial.println(" Just pressed"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (justreleased[i]) { Serial.print(i, DEC); Serial.println(" Just released"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (pressed[i]) { Serial.print(i, DEC); Serial.println(" pressed"); // is the button pressed down at this moment } } }
#define DEBOUNCE 10 // button debouncer, how many ms to debounce, 5+ ms is usually plenty // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc byte buttons[] = {14, 15, 16, 17, 18, 19}; // the analog 0-5 pins are also known as 14-19 // This handy macro lets us determine how big the array up above is, by checking the size #define NUMBUTTONS sizeof(buttons) // we will track if a button is just pressed, just released, or 'currently pressed' volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS]; void setup() { byte i; // set up serial port Serial.begin(9600); Serial.print("Button checker with "); Serial.print(NUMBUTTONS, DEC); Serial.println(" buttons"); // pin13 LED pinMode(13, OUTPUT); // Make input & enable pull-up resistors on switch pins for (i=0; i< NUMBUTTONS; i++) { pinMode(buttons[i], INPUT); digitalWrite(buttons[i], HIGH); } // Run timer2 interrupt every 15 ms TCCR2A = 0; TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20; //Timer2 Overflow Interrupt Enable TIMSK2 |= 1<<TOIE2; } SIGNAL(TIMER2_OVF_vect) { check_switches(); } void check_switches() { static byte previousstate[NUMBUTTONS]; static byte currentstate[NUMBUTTONS]; static long lasttime; byte index; if (millis() < lasttime) { // we wrapped around, lets just try again lasttime = millis(); } if ((lasttime + DEBOUNCE) > millis()) { // not enough time has passed to debounce return; } // ok we have waited DEBOUNCE milliseconds, lets reset the timer lasttime = millis(); for (index = 0; index < NUMBUTTONS; index++) { currentstate[index] = digitalRead(buttons[index]); // read the button /* Serial.print(index, DEC); Serial.print(": cstate="); Serial.print(currentstate[index], DEC); Serial.print(", pstate="); Serial.print(previousstate[index], DEC); Serial.print(", press="); */ if (currentstate[index] == previousstate[index]) { if ((pressed[index] == LOW) && (currentstate[index] == LOW)) { // just pressed justpressed[index] = 1; } else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) { // just released justreleased[index] = 1; } pressed[index] = !currentstate[index]; // remember, digital HIGH means NOT pressed } //Serial.println(pressed[index], DEC); previousstate[index] = currentstate[index]; // keep a running tally of the buttons } } void loop() { for (byte i = 0; i < NUMBUTTONS; i++) { if (justpressed[i]) { justpressed[i] = 0; Serial.print(i, DEC); Serial.println(" Just pressed"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (justreleased[i]) { justreleased[i] = 0; Serial.print(i, DEC); Serial.println(" Just released"); // remember, check_switches() will CLEAR the 'just pressed' flag } if (pressed[i]) { Serial.print(i, DEC); Serial.println(" pressed"); // is the button pressed down at this moment } } }
суббота, 23 марта 2013 г.
Подписаться на:
Сообщения (Atom)