termostat: Все сообщения за 10 Марта 2004 года

 
ПнВтСрЧтПтСбВс
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

termostat

аксакал

Serge77, 10.03.2004 00:53:36 :
Датчик ускорения в таком корабле будет показывать 1 g (по одной из осей).
 


потому как карабль движется с ускорением 1 Ж по вертикали. А вот акселерометр может быть по разному расположен - соответсвенно показывать будет разное.

termostat

аксакал

По поводу серий АЦП на каждый отсчет я нашел АпликНоут у Тексас Инстраментс - прикрепил таблицу что это дает.

в этом документе (Oversampling Techniques using the
TMS320C24x Family spra461.pdf) ниже есть таблица с результатами метода наложения на измеряемый сигнал треугольного напряжения - это похоже на то что у нас за время пачки измерений происходит некоторое изменение величины реального давления.

termostat

аксакал

Благодарю всех почтивших данное мероприятие вниманием!

В Москве 20-00 мы можем начать.

Чуда не обещаю, просто постараюсь показать как писать прогу для МК на Си.

Не оставляйте "белых пятен" - формулируйте свои вопросы и задавайте
здесь если, что то из происходящего не понятно.

Постараюсь ответить.

Устройство 007 и кратко алгоритм его работы описаны здесь:

Форумы Авиабазы

Этот алгоритм мы попытаемся переложить на язык понятный компилятору.

///////////////////////

Где взять компилятор Си для AVR CodeVision и как его правильно
установить описано в прикрепленном файле.

Где взять Эмулятор МК AVR - VMLAB было сообщено в топике "Курс МК ..."

Сейчас они не понадобятся!

///////////////////////


Программ будет сопровождаться коментариями:

В Си есть два типа коментариев:

1) /* комент. /
2) // комент.

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

строки можно пропускать */

// после двух черточек пишутся коментарии только в одну строчку


///////////////////////

В Си нет нумерации строк как в Бэйсике например, в компиляторе CodeVision
есть с лева нумерация строчек не включаемая в файл программы.

Нам нумерация будет полезна чтоб можно было указать о каком
месте программы идет речь.

Давайте для нумерации использовать Лэйблы - метки инструкции goto

///////////////////////

_lable: // Метка должна начинаться с буквы или подчеркивания,
// заканчиваться : На строчку программы с этой меткой мы
// попадем после выполнения инструкции goto _lable;


goto _lable; // перейти на строчку програмы с меткой _lable

///////////////////////

Нумерция будет такой:

_00100: // Метки без соотв goto при компиляции просто

_00200: // вызовут Вонинги - предупреждения.

_00300:

_00400:

_01320:

соответственно в вопросах и пояснениях будем указывать: "в строке 1320 ..."

.......................................


Программу я буду писать в топике "текст программы 007" в одном сообщении,
постоянно обновляя его редактированием.
Возможно с увеличением текста программы я добавлю сообщения.

Не делайте постингов ТАМ пожалуйста!

Вопросы и ответы здесь!!!


Смотрите, читайте "текст программы 007" и спрашивайте... здесь.

///////////////////////

CV.zip (скачать) [29 кБ]
 
 

termostat

аксакал

ПРОШУ не делать сюда ПОСТИНГИ!

Вопосы и ответы: Сайт расходящихся тропок

"Пишем прогу для МК AVR в он-лайн"

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\


// программа наконец-то 007

/////////////////////// - это отбивка!

/* 007 micro Дата логер - это заголовок программы

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

/

///////////////////////

// инклуды #include - подробнее о них

/
Это директивы - указания препроцессору вставить (перед компиляцией только) в
текст написаной вами программы тексты любых других ТЕКСТОВЫХ файлов.

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

#include // из директории INC компилятора

#include "math.h" // вместо этой строки компилятор вствит текст файла math.h
// из директории вашего проекта! а если его там нет то из INC


#include "delay.h" // если мы собираемя использовать готовые временные задержки
// например: delay_ms(25); delay_us(186);

Внимание - различные компиляторы могут иметь различные правила
вызова функций не входящих в стандартный набор реализации языка Си.

Всегда читайте мануал и просматривайте примеры
к компилятору который вы используете! /

///////////////////////

// дефайны #define



///////////////////////

// константы и переменные

///////////////////////

// прототипы функций

///////////////////////

// главная функция main - обязательна в Си

void main(void)
{

}

///////////////////////

// описания функций


/////////////////////// ВСЕ - конец программы!


/
Уфф! написали.

Удивительно но это уже программа для МК, выполнение программы
начинается со строчки void main(void)

Программа как бы ни чего не делает, но если ее откомпилировать то
уже займет некоторый объем флэш памяти МК :-)

Итак минимально возможная програама на Си выглядит так:

void main(void)

{
}

и все.

*/

termostat

аксакал

Я попросил час внимания и хочу предложить свой метод - мы не будем сечас рассматривать МК какие ноги какие сигналы, поверь мы напишем программу, а потом привяжем ее.

termostat

аксакал

// дефайны #define


/* Это очень мощная и полезная директива препроцессора - она
позволяет делать программу более легко читаемой и адаптируемой.

Например мы задаем частоту измерений с датчиков 100 раз в сек:

#define sample_times 100

И мы использовали это знчение (число 100) в нескольких местах программы.
Но нам потребовалось изменить частоту измерений на 50.

Значит нам потребуется найти все места где написано 100 и поменять на 50, причем мы можем заменить и числа "100" не относящиеся к делу!

А если мы применили Дефайн как выше, то нам нужно просто заменить в этой одной строке 100 на 50:

#define sample_times 50

Все - теперь везде в программе sample_times препроцессор заменит на 50 перед компиляцией.

Смысл директивы понятен: текст после #define заменяется на то что стоит правее, после пробела.

В директиве могут производится и вычисления! и использоваться
переменные х у ...

Подробней в мануале к компилятору.

termostat

аксакал

Итак СЕКЛЕТ программы на Си для МК:


/* 007 micro Дата логер - это заголовок программы

краткое описание устройства, алгоритма его
работы

*/

///////////////////////
// инклуды #include


///////////////////////
// дефайны #define



///////////////////////
// константы и переменные



///////////////////////
// прототипы функций



///////////////////////
// главная функция main

void main(void)
{

}

///////////////////////
// описания функций




////// конец программы


Будем наращивать мясо!

termostat

аксакал

///////////////////////
// главная функция main Что в ней будет?

void main(void)
{

первое это инициализация МК, его устройств в нужном нам режиме:

init_device(); // Название может быть любым, желательно понятное
// Мы просто вызвали функцию которю напишем позже

// Вспомним алгоритм работы устройства - после включения МК должен
// выбрать режим работы - для выбора в Си есть инструкция if ... else

if (recording_data)
{


}

else

{


}



}

termostat

аксакал

///////////////////////
// главная функция main Что в ней будет?

void main(void)
{

первое это инициализация МК, его устройств в нужном нам режиме:

init_device(); // Мы просто вызвали функцию инициализации
// которю напишем позже


// Название Функций может быть любым, желательно
// напоминающее что она делает!

// Вспомним алгоритм работы устройства - после включения МК должен
// выбрать режим работы - для выбора в Си есть инструкция if ... else


// Что мы написали ниже? Если значение "recording_data" не равно нулю

if (recording_data) // recording_data - понятно связан с
// положением переключателя перед
// включением питания
{
Если значение "recording_data" не равно нулю, то выполняется
программа расположеная сдесь.

}

else

{
В противном случае, ваполнять программу сдесь.

}



} // скобка закрывающая для функции Мэйн!

termostat

аксакал

///////////////////////
// главная функция main Что в ней будет?

void main(void)
{

первое это инициализация МК, его устройств в нужном нам режиме:

init_device(); // Мы просто вызвали функцию инициализации
// которю напишем позже


// Название Функций может быть любым, желательно
// напоминающее что она делает!

// Вспомним алгоритм работы устройства - после включения МК должен
// выбрать режим работы - для выбора в Си есть инструкция if ... else


// Что мы написали ниже? Если значение "recording_data" не равно нулю

if (recording_data) // recording_data - понятно связан с
_000200: { // положением переключателя перед
// включением питания


//Если значение "recording_data" не равно нулю, то выполняется
// программа расположеная сдесь. от _000200: до _000500:

У нас есть два режима записи - в кольцевой буфер и до конца памяти!

while(!start)
{

Пока мы не зафиксировали старт - т.е. значение "start" = 0 или ложно,
и соответственно (!start) - истинно делаем прогу здесь!

}

Через скобку мы перешагнем, когда акселерометр обнаружит старт



_000500: // просто нумерация

}


else
{
В противном случае, ваполнять программу сдесь.


}



} // скобка закрывающая для функции Мэйн!
Это сообщение редактировалось 10.03.2004 в 20:41

termostat

аксакал

Кусок программы - в режиме записи:

if (recording_data) // recording_data - понятно связан с
_000200: { // положением переключателя перед
// включением питания


//Если значение "recording_data" не равно нулю, то выполняется
// программа расположеная сдесь. от _000200: до _000500:

У нас есть два режима записи - в кольцевой буфер и до конца памяти!

while(!start)
{

// Пока мы не зафиксировали старт - т.е. значение "start" = 0 или ложно,
// и соответственно (!start) - истинно делаем прогу здесь!

// Нам нужно делать измерения через равные промежутки времени, для их отсчета используем таймер МК.

подождем пока таймер насчитает очередное время измерения:

while(!go_get_data); // в этой строке просидим пока "go_get_data" не станет "1" - а "go_get_data" мы в начале программы определим флаг прерывания таймера МК. Знчит при отсчете интервала времени будет возникать прерывание таймера МК и мы сможем проскочить этот WHILE !!!





}

Через скобку мы перешагнем, когда акселерометр обнаружит старт



_000500: // просто нумерация

}

termostat

аксакал

Кусок программы - в режиме записи (до старта!):

if (recording_data) // recording_data - понятно связан с
_000200: { // положением переключателя перед
// включением питания


//Если значение "recording_data" не равно нулю, то выполняется
// программа расположеная сдесь. от _000200: до _000500:

У нас есть два режима записи - в кольцевой буфер и до конца памяти!

while(!start)
{

// Пока мы не зафиксировали старт - т.е. значение "start" = 0 или ложно,
// и соответственно (!start) - истинно делаем прогу здесь!

// Нам нужно делать измерения через равные промежутки времени, для их отсчета используем таймер МК.

подождем пока таймер насчитает очередное время измерения:

while(!go_get_data);

// здесь мы окажемся когда "go_get_data" станет "1" - значит пора мерить

get_pressure(); // вызываем функцию измерения давления


get_axeleration(); // вызываем функцию измерения ускорения


save_data_kolzo(); // сохранить данные в кольцевой буфер

send_data_rs232(); // отправить данные на ПК


}

Через скобку мы перешагнем, когда акселерометр обнаружит старт



_000500: // просто нумерация

}

termostat

аксакал

Кусок программы - в режиме записи - После старта

}

Через скобку мы перешагнем, когда акселерометр обнаружит старт

в функции get_axeleration() происходит сравнение ускорения с пороговым значением и как только оно будет превышено, мы преодолеваем скобку и выполняем запись с сохранением уже до конца памяти.

ЗАБЫЛ !!! здесь нужно воткнуть проверку что память не закончилась!

while (!memory_full)
{ // скобка 4567 - пока память не заполнена находимся
// между скобками 4567

опять ждем команды пора мерить!

while(!go_get_data);

// здесь мы окажемся когда "go_get_data" станет "1" - значит пора мерить







} // скобка 4567


_000500: // просто нумерация

}
Это сообщение редактировалось 10.03.2004 в 21:03

termostat

аксакал

Serge77, 10.03.2004 20:52:06 :
флаг - это вроде 1 бит. Значит можно переменную go_get_data как-то приравнять к этому биту?
 


не успеваю отвечать, я написал - привяжем дефайном.

termostat

аксакал

Demonos, 10.03.2004 20:26:58 :
Извините, если задерживаю.
А что есть */прототипы функций
 


Это просто их пересичления для удобства чтения программы. будет позже!

termostat

аксакал

Кусок программы - в режиме записи - После старта

}

Через скобку мы перешагнем, когда акселерометр обнаружит старт

в функции get_axeleration() происходит сравнение ускорения с пороговым значением и как только оно будет превышено, мы преодолеваем скобку и выполняем запись с сохранением уже до конца памяти.

ЗАБЫЛ !!! здесь нужно воткнуть проверку что память не закончилась!

while (!memory_full)
{ // скобка 4567 - пока память не заполнена находимся
// между скобками 4567

опять ждем команды пора мерить!

while(!go_get_data);

// здесь мы окажемся когда "go_get_data" станет "1" - значит пора мерить

// все функции как и до старта только сохранение обычное:

get_pressure(); // вызываем функцию измерения давления


get_axeleration(); // вызываем функцию измерения ускорения


save_data(); // сохранить данные НЕ в кольцевой буфер

send_data_rs232(); // отправить данные на ПК



} // скобка 4567


_000500: // просто нумерация

}

termostat

аксакал

Когда память закончится и "memory_full" станет "1" мы окажемяся за этой скобкой:

} // скобка 4567

// Пусть устройство мигает и пищит противно, стоб его найти можно было.


While(1) // бесконечный цикл !!! БЕЗ ;
{
blink_led(fast);

beep_protivno();
}




_000500: // просто нумерация

} // скобка закрывающая для куска проги с записью данных

termostat

аксакал

Andrei, 10.03.2004 21:08:26 :
Функция go_get_data, или в данном случае флаг, как результат выполнения данной функции, где-то должна быть определена как настройка таймера на требуемый интервал, запуск таймера и ожидание его переполнения
 


go_get_data - это не функция, так мы назовем в начале программы флаг по прерыванию таймера:

#define go_get_data бит.флаг.таймера (я не помню как он называется)

termostat

аксакал

Теперь напишем кусок воспроизведения данных, он гораздо проще и будет расположен между скобок 5732 (ранее я не обозначил к сожалению)

было:

else
{ // щас обознчаю - скобка 5732

// здесь мы находимся при воспроизведении данных

} // скобка 5732




termostat

аксакал

программа воспроизведения данных расположена между скобок 5732
было:

else
{ // скобка 5732

while(memory_end) // делаем пока не дойдем до конца памятти
{

restore_data_byte();

send_byte_rs232();

}

// все память прочитана - просигналим об этом

blink_led(slow); // вызвали функцию мигания светодиодом и
// "сказали" мигать медленно!


} // скобка 5732

termostat

аксакал

///////////////////////
// прототипы функций

init_device();

restore_data_byte();

send_byte_rs232();

blink_led(char);

beep_protivno();

get_pressure();

get_axeleration();


save_data_kolzo();

send_data_rs232();

perekluchit_led();

turn_off_led();



// вроде все собрал





Это сообщение редактировалось 10.03.2004 в 21:44

termostat

аксакал

Andrei, 10.03.2004 21:24:01 :
#define go_get_data TIFR,TOV0
 


Спасибо, хотя возможно разрешено и просто название бита указать:

#define go_get_data TOV0

надо смотреть конкретный компилятор - хелп и мануал.

termostat

аксакал

Давайте поправим ошибку в алгоритме, после условия if на запуск записи нужно добавит задержку в 10 секунд и мигание орание для предохранения от случайного стирания

termostat

аксакал

Вот кусок программы - режим записи:

if (recording_data) // recording_data - понятно связан с
_000200: { // положением переключателя перед
// включением питания

Дадим 10 секунд одуматься:

char ctr=0; // объявили переменную для счета

while(ctr<50) // сделаем 50 раз
{
perekluchit_led(); // изменить состояние светодиода

delay_ms(200);

ctr++; // увеличим по просьбе Сергея счетчик


}

turn_off_led(); // выключить наверняка - такую функцию конечно заменим операциейнад соотв битом, когд будем знать куда подключен светодиод.


//Если значение "recording_data" не равно нулю, то выполняется
// программа расположеная сдесь. от _000200: до _000500:

У нас есть два режима записи - в кольцевой буфер и до конца памяти!

while(!start)
{

Пока мы не зафиксировали старт - т.е. значение "start" = 0 или ложно,
и соответственно (!start) - истинно делаем прогу здесь!

}

Через скобку мы перешагнем, когда акселерометр обнаружит старт



_000500: // просто нумерация

}

Это сообщение редактировалось 10.03.2004 в 21:53

termostat

аксакал

Serge77, 10.03.2004 21:28:50 :
А зачем вообще прототипы? В чём идея? Без них вообще нельзя? Или так почему-то удобнее? Почему?
 


Без них можно, не во всех компиляторах - в ICC помнишь я в адаче обнаружил что ему не обязательно.

Но это очень удобно ведь прототипы с права имеют краткое пояснение, я не сделал из экономии времени.

Когд ты читаешь МЭЙН у тебя перед глазами все используемые функции и ты понимаешь алгоритм программы.

termostat

аксакал

Andrei, 10.03.2004 21:44:07 :
Извини, но чем это до сих пор отличается от нормально структурированной прораммы на Ассемблере?
 


Я не против АСМа, я за Си.

Я не говорю что асм хуже, но вот продаются хорошо компиляторы, значит нужны они народу...
Это сообщение редактировалось 10.03.2004 в 21:54

termostat

аксакал

Будем заканчивать.

Программа структурно набросана.

Теперь нужно расписать "тело" каждой функции, объявить все переменные использованые в программе, вобщем осталось начать и закончить.

Нужна схема устройства.

Сегодняшнее занятие это первый блин - не знаю кому он как.

Выскажитесь если будет настроение, только не здесь!

Я буду рботать над программой. Постарайтесь тоже делать что-то, спрашивайте.

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru