Так тахометр и не получается. Может взглянете? Кварц 20 мегагерц. 1 машинный циккл за 200 наносекунт это 10 в -9 степени или 0.0000002 секунды. Алгоритм такой- Считаем время как сигнал упал в 0 до того как он снова упал в ноль, обнуляем таймер1 и считаем заново до следующего падения в 0. С тем что посчитали работаем. Так как 1 цикл 200 наносекунд то то количество циклов что подсчитали умножаем на время 200 наносекунд. знаем время периуда. Формуля 1\Т . Переводим то что помножили в секунды для этого нужно разделить на миллиард. Делим на то что вышло 1. получаем частоту.
но в программе чтото не выходит. Незнаю как арифметикой работать и както ругается на большие числа типа миллиардов. выдаёт кучу ошибок. У меня мозг уже плавится, помогите разобраться
Код:
#include <pic.h> __CONFIG (XT & UNPROTECT & LVPDIS & BOREN & MCLRDIS & PWRTEN & WDTDIS); unsigned shar tmr1temp; unsigned long int tmp; unsigned int tmppr; int num10000; int num1000; int num100; int num10; int num1; void pauza (void) { // начало переменная unsigned int x; // локальная x = 100; // в tmp поместить некое максимальное число while (x-->0); }// конец функции
void podgot (void) { TRISA = 0b00001111; // направление работы ножек порта А. TRISB = 0b10000001; // направление работы ножек порта В. CMCON = 0x07; // отключение компараторов. PORTA = 0; // очищаем порт А PORTB = 0; // очищаем порт Б. GIE = 1; //разрешить глобальные прерывания . PEIE = 1; // OPTION BIT RBPU = 1; // подтягивающие R (0-вкл, 1-выкл). INTEDG = 0; //Прерывания INT по пер. фронту. T0CS = 1; // внешний тактовый сигнал T0SE = 0; // задний фронт преращения сигнала. //T1CON BIT T1CKPS1 = 0; T1CKPS0 = 0; //предделитель 1:1 T1OSCEN = 0; // внутренний тактовый генератор выкл. T1SYNC = 1; // не синхронизировать внешний сигнал TMR1CS = 0; // Внутреннй источник тактового сигнала. TMR1ON = 1; // таймер включен. INTE=1; ///////// TMR1IE = 1; // прерывание от 1 таймера on. tmp=0; } void main (void) { podgot (); while (1) { tmp=tmr1temp*655536; tmp=tmp+tmppr; tmp=tmp*200; tmp=tmp\1000000000; tmp=1\tmp; num10000=tmp/10000; tmp %=10000; num1000=tmp/1000; // количество тысяч tmp %=1000; // остаток от деления на 1000 num100=tmp/100; // количество сотен tmp %=100; // остаток от деления на 100 num10=tmp/10; // кол-во десятков num1=tmp%10; // остаток - единицы // === массив констант с описанием 7-сегментных символов const unsigned char arr_seg1[12]={ // начало массива // 0bABCDEFGH <– расположение сегментов по битам 0b01111100, // 0й элемент, символ «0» 0b01100000, // 1й элемент, символ «1» 0b01011010, // 2й элемент, символ «2» 0b01110010, // 3й элемент, символ «3» 0b01100110, // 4й элемент, символ «4» 0b00110110, // 5й элемент, символ «5» 0b00111110, // 6й элемент, символ «6» 0b01100000, // 7й элемент, символ «7» 0b01111110, // 8й элемент, символ «8» 0b01110110, // 9й элемент, символ «9» 0b01000110, //10й элемент, символ градуса 0b00000000 //11й элемент, пробел } // конец массива
// === массив констант с описанием 7-сегментных символов const int arr_seg2[12]={ // начало массива // 0bABCDEFGH <– расположение сегментов по битам 1, // 0й элемент, символ «0» 0, // 1й элемент, символ «1» 1, // 2й элемент, символ «2» 1, // 3й элемент, символ «3» 0, // 4й элемент, символ «4» 1, // 5й элемент, символ «5» 1, // 6й элемент, символ «6» 1, // 7й элемент, символ «7» 1, // 8й элемент, символ «8» 1, // 9й элемент, символ «9» 1, //10й элемент, символ градуса 0, //11й элемент, пробел }
Заголовок сообщения: Re: Програмирование pic на СИ.
Добавлено: Вт авг 30, 2011 13:13:11
Модератор
Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4581 Откуда: Планета Земля
Рейтинг сообщения:1 Медали: 1
Цитата:
unsigned shar tmr1temp;
Это что за тип такой - shar ? Далее, строки не захотел считать. Смотрите в каких строчках ошибки и ищите их там Видимо tmr1temp Вы хотели объявить как char. Тогда эта сторока
Код:
tmp=tmr1temp*655536;
не проканает. Он же сначала будет умножать, затем присваивать. Разбирайтесь с приведением типов.
Это что за тип такой - shar ? Далее, строки не захотел считать. Смотрите в каких строчках ошибки и ищите их там Видимо tmr1temp Вы хотели объявить как char. Тогда эта сторока
Код:
tmp=tmr1temp*655536;
не проканает. Он же сначала будет умножать, затем присваивать. Разбирайтесь с приведением типов.
Да, точно char. Но это ничег оне дало. а почему сначала умножение а потом присвоение. присвоениеж проводится в самомначале программы. А про чар взял здесь http://www.labkit.ru/html/C_for_PIC?id=251 .Всё равно кучаааа ошибок и не компелируется. строчка tmp=tmp\1000000000; ругается на неё как illegal character (0134). пошол искать ошибки
Заголовок сообщения: Re: Програмирование pic на СИ.
Добавлено: Вт авг 30, 2011 14:51:01
Модератор
Карма: 90
Рейтинг сообщений: 1432
Зарегистрирован: Чт мар 18, 2010 23:09:57 Сообщений: 4581 Откуда: Планета Земля
Рейтинг сообщения:1 Медали: 1
Цитата:
присвоениеж проводится в самомначале программы.
В начале программы не присваивание, а объявление. Присвоить - это символ "=".
Цитата:
строчка tmp=tmp\1000000000; ругается на неё как illegal character (0134).
А что Вы этой строчкой хотите сделать ? Я вот например тоже не понимаю, так-же как и компилятор. Посмотрите на неё внимательнее и поймёте в чём ошиблись.
Умножать в PIC'ах 18-й серии дурной тон... Сколько памяти сразу отъест.
Вы хотели сказать не умножать, а делать арифметику с плавающей точкой Потому что для умножения во всех PIC18 есть железный умножитель 8*8 бит за один машцикл
Несколько замечений: - вместо переменных лучше использовать структуры. У меня прога только из-за этого глючила. - сначала объявляют структуры, переменные, функции, массивы. Потом - подпрограмма обработчика прерываний (ППОП), коей у вас там нет. - паузу делают только через таймер+счетчик. В ППОП. - динамическая индикация (да и все в целом) лучше всего описана тут: http://vrtp.ru/index.php?showtopic=10583&st=0 Она делается без паузы и в ППОП. - состояние общих точек индикаторов проще задавать прямо, а не через массив.
_________________ Кот гуляет сам по себе, но вблизи холодильника.
- вместо переменных лучше использовать структуры. У меня прога только из-за этого глючила.
А структуры - это не переменные? Смею предположить что проблемы растут из отсутствия квалификатора volatile у глобальных переменных изменяемых в прерывании. misterkuk, кстати, это тоже касается. Все глобальные переменные, которые могут быть спонтанно изменены в прерывании должны быть volatile. Во всех книжках/мануалах про Си это написано.
unsigned int tmr1temp; хранит сколько переполнений таймера было. unsigned long int tmp; конечное число которое будет выводится на индикаторы unsigned int tmppr; тут обьеединяются старшиы и младший разряды таймра.
Код:
tmp=tmr1temp*655536; //Считаем количество машинных цыклов (полных) tmp=tmp+tmppr; // Прибовляем то что осталось в таймере на момент прерывания. // Теперь знаем количество машинных цыклов за периуд. зная что 1 цикл =200наносекун, // умножаем количество циклов на 200 наносекунд. tmp=tmp*200; // умножаем. И получается огромное чисо. tmp=tmp/1000000000; // так как Приставка нано это 10 в -9 степени то делим на 1000000000. Тоесть переводим в секунды. tmp=1/tmp; // теперь зная время перриуда, делим 1 на время по фформуле 1/Т
Код обработки молученных цыфр. Но а самом деле всё по другому. В симуляторе такк. Подаём сигнал с частотой 180 Гц. tmr1temp=0 9и при такой частоте всегда =0) tmppr= У нас выводится как 40249 tmp=tmr1temp*655536; тут если 0 умножыть на число то будет 0. всё норм. tmp=tmp+tmppr; Здесь в tmp заносится число 40249 tmp=tmp*200; далее судя по моей локике должно получится что tmp = 40249*200= 8 049 800. но симулятор после этой операцции показывает ччисло 54480 tmp=tmp/1000000000; далее это число 54480 делится на 1000000000 и у нас выходит 4 . как оно может тут выйти!!! А по идее число 8049800/1000000000=0.0080498с. Но это в идеале. tmp=1/tmp;Далее програма 1/4=0 А должно быть 1/0.0080498=124.2266... Я плохо разбираюсь в этом. Может както нуужно обьявлять переменные чтоб с не целыми числами работать?
(c) Даже самая красивая девушка не может дать больше того, что у нее есть... В смысле, если формат числа unsigned int - оно 16 битное - максимально, что можно туда влепить - это число в диапазоне 0-65535 , всего 65536 значений. tmp=tmr1temp*655536; - вот здесь как бы 5 лишняя, не находите ? ---------- tmp = 40249*200= 8 049 800. но симулятор после этой операцции показывает ччисло 54480 ---------- ну а что оно может показать, если макс 65535 ?
Почитайте о формате чисел хотя бы здесь, только там опечатка
unsigned shar (символ без знака) надо читать unsigned сhar (символ без знака) ---------- unsigned long int tmp; - это сколько ? int Или long ? Это же хайтек, а не ццс... Хотя с точки зрения Си запись верная, но unsigned long tmp;
Начал учить си с этого сайта, как на меня самое лучшее что я находил.
urry писал(а):
Хотя с точки зрения Си запись верная
Хоть это радует. спс. Строчка аж придала сил:) Просто если не unsigned long int? 8 миллионов больше не во что не влезет вродебыш. Я пока хочу понять само програмирование. основу, нюансы разные, красиво писать программу пока не рвусь. Сейчас главное чтоб работала.
unsigned long tmp tmp=13/8 ( кк примеру) Такого не хочет делать, в симуляторе прыгает чарез такие действия. Так и не удалось решыть проблему арифметических операций выложеных выше. Не хочит считать и все.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения