Програмирование pic на СИ.

Поклонники продукции Microchip Technology Inc тусуются тут.
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

Написал програму тахометра. Несовсем получилось с 1 секундой, но эт не так важно.
сам код:

Код: Выделить всё

#include <pic.h>
__CONFIG (LP & UNPROTECT & LVPDIS & BOREN & MCLRDIS & PWRTEN & WDTDIS);
unsigned long seconds;
unsigned long tmp;
unsigned long oboroti;
int tmr0_temp;
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 = 0b11110000; // направление работы ножек порта А.
TRISB = 0b00000000; // направление работы ножек порта В.
CMCON = 0x07; // отключение компараторов.
PORTA = 0; // очищаем порт А
PORTB = 0; // очищаем порт Б.
T0IE = 1; //разрешитьть прерывания от TMR0 .
GIE = 1; //разрешить глобальные прерывания .
PEIE = 1;
// OPTION BIT
RBPU = 1;  // подтягивающие R (0-вкл, 1-выкл).
INTEDG = 1; //Прерывания INT по пер. фронту.
T0CS = 1; // внешний тактовый сигнал
T0SE = 0; // задний фронт преращения сигнала.
PSA = 1; // Предделитель перед wdt.
PS2 = 0;
PS1 = 0;
PS0 = 0; // предделитель 32.
//T1CON BIT
T1CKPS1 = 1;
T1CKPS0 = 0; //предделитель 1:4
T1OSCEN = 0; // внутренний тактовый генератор выкл.
T1SYNC = 1; // не синхронизировать внешний сигнал
TMR1CS = 0; // Внутреннй источник тактового сигнала.
TMR1ON = 1; // таймер включен.

/////////
TMR1IE = 1; // прерывание от 1 таймера разрешено.
}
void main (void)
{
podgot ();
TMR0=0;
TMR1H=0;
TMR1L=0;
TMR1H=0b01001011;
TMR1L=0b01000000;

while (1)
{
// === массив констант с описанием 7-сегментных символов
const int arr_seg[12]=
{    // начало массива
// 0bABCDEFGH <– расположение сегментов по битам
   0b00111111, // 0й элемент, символ «0»
   0b00000110, // 1й элемент, символ «1»
   0b10011011, // 2й элемент, символ «2»
   0b10001111, // 3й элемент, символ «3»
   0b10100110, // 4й элемент, символ «4»
   0b10101101, // 5й элемент, символ «5»
   0b10111101, // 6й элемент, символ «6»
   0b00000111, // 7й элемент, символ «7»
   0b10111111, // 8й элемент, символ «8»
   0b10101111, // 9й элемент, символ «9»
   0b10100011, //10й элемент, символ градуса
   0b00000000, //11й элемент, пробел
}; // конец массива
RB6 = 0;
PORTB = arr_seg[num10000];
pauza ();
RB6 = 1;
RA0 = 0;
PORTB = arr_seg[num1000];
pauza ();
RA0 = 1;
RA1 = 0;
PORTB = arr_seg[num100];
pauza ();
RA1 = 1;
RA2 = 0;
PORTB = arr_seg[num10];
pauza ();
RA2 = 1;
RA3 = 0;
PORTB = arr_seg[num1];
pauza ();
RA3 = 1;
}
}
void  interrupt timer0_isr (void)
{
if (T0IF==1)
    {
    T0IF=0;
    oboroti=oboroti+1;
    }
if(TMR1IF==1)
{
TMR1IF=0;
seconds=seconds+1;
if (seconds==19)
      {
      tmr0_temp=TMR0;
      seconds=0;
      TMR1H=0b01001011;
      TMR1L=0b01000000;
      TMR0=0;
      tmp=oboroti*256;
      tmp=tmp+tmr0_temp;
      tmp=tmp*60;
      num10000=tmp/10000;   
      tmp %=10000;               
      num1000=tmp/1000;      // количество тысяч
      tmp %=1000;            // остаток от деления на 1000
      num100=tmp/100;      // количество сотен
      tmp %=100;            // остаток от деления на 100
      num10=tmp/10;         // кол-во десятков
      num1=tmp%10;         // остаток - единицы
      TMR1H=0;
      TMR1L=0;
      oboroti=0;
      }
}
}

Также в архиве проэкт протеуса и прошивка и всё остальное.
Суть: считает 0м таймером сколько было импульсов с датчика коленвала за секунду. Умнажаем на 60 и выводим.:)
За секунду ддо 300 импульсов не больше и то многго.
Вложения
Новая папка (4).rar
(476.38 КБ) 218 скачиваний
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение urry »

Небольшие рекомендации
----------
1. Никаких умножений делений в прерывании, для этого есть основной цикл.
2. Если у Вас секунды - число 20 макс, зачем туда пихать лонг - оно 4-х байтовое ??? Достаточно 1 байта.
То же касается разного рода интов, когда достаточно чара.
3. Есть еще 1 таймер, на котором можно сделать регенерацию дисплея, его и юзайте, что за кишка в основном цикле.
4. Никаких абсолютных значений в тексте программы, дефайните все, что можно.
5. Не указана частота контроллера.
Последний раз редактировалось urry Вт май 24, 2011 18:05:32, всего редактировалось 1 раз.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Юр, может не стОит так вот, сразу "мордой в грязь" ? :) Начинающий, получилась программа, радость, захотелось поделиться.....
misterkuk, Вы сделали всё с точностью до наоборот. То, что нужно было запихнуть в прерывание, Вы запихнули в основной цикл, и наоборот.
По поводу умножение на 60. Учтите, шаг измерения/показания у Вас будет тоже = 60. Т.е. цифры будут прыгать по 60 едениц.
ИМХО, для таких вещей нужно мерить период и из него уже вычислять обороты. INT + таймер Вам в помощь.....
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение urry »

Уже исправился :)
Да, секунду подкорректировать не проблема, фронт по инту засинхронизировать как бы тоже.
vovik15
Опытный кот
Сообщения: 768
Зарегистрирован: Сб ноя 08, 2008 18:32:36
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение vovik15 »

1. Никаких умножений делений в прерывании, для этого есть основной цикл.

эт почему это?
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

urry писал(а):Небольшие рекомендации
----------
1. Никаких умножений делений в прерывании, для этого есть основной цикл.
2. Если у Вас секунды - число 20 макс, зачем туда пихать лонг - оно 4-х байтовое ??? Достаточно 1 байта.
То же касается разного рода интов, когда достаточно чара.
3. Есть еще 1 таймер, на котором можно сделать регенерацию дисплея, его и юзайте, что за кишка в основном цикле.
4. Никаких абсолютных значений в тексте программы, дефайните все, что можно.
5. Не указана частота контроллера.

1. Буду знать:).
2. Мне нужно было чтоб программа заработала. Я както не задумался что можно и другое выбрать. В мк места осталось всё равно много:)
3. Про регенерацию я так и не понял. Смотрел ваш исходник вольт мера. Пока не вдуплил.
4.Что за абсолютные значения и что такое "дефайните"?
5. Я так понял не указана для информационности читателям. Исправлюсь.
............
Это моя первая дельная програма которую можно применять. Я рад был как ребёнок когда она заработала.
И ещё я заметил ошибку. Я обнуляю таймер и кладу в него число 19264.
Тоесть 65536*4=262144. (предделитель тошо на 4)
далее. сколько полных 262144 влезит в 5000000. Делим второе на первое и получаем 19.073486328125. тоесть полных 19 рас. берём и умножаем 262144 на 199 = 4 980 736. от этого отнимаем 5000000 и получаем остаток 19 264.
секунды не получится. И я шото не пойму зачем я 19 раз инкрементировал секондс при прерывании 1 таймера.
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

Аlex писал(а):Юр, может не стОит так вот, сразу "мордой в грязь" ? :) Начинающий, получилась программа, радость, захотелось поделиться.....
misterkuk, Вы сделали всё с точностью до наоборот. То, что нужно было запихнуть в прерывание, Вы запихнули в основной цикл, и наоборот.
По поводу умножение на 60. Учтите, шаг измерения/показания у Вас будет тоже = 60. Т.е. цифры будут прыгать по 60 едениц.
ИМХО, для таких вещей нужно мерить период и из него уже вычислять обороты. INT + таймер Вам в помощь.....

А еслиб я отображение запихнул в прерываня, оноб мерцало мне кажется.
Мерять периуд и из него чтото вычислять, я тока с таймерами разобрался и тут вы такое пишите. Я пока незнаю как это делать.
Но думаю для начала пойдёт и это:)
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Код: Выделить всё

В мк места осталось всё равно много:)
А как же время выполнения кода ? Тем более в прерывании.
Про регенерацию я так и не понял.
Настраиваете прерывание по таймеру, например 1 мс, в прерывании переустанавливаете его. Что бы получился переодический вызов. А там уже обновляете каждый индикатор.
что такое "дефайните"?
#define :)
Я так понял не указана для информационности читателям.
Не только.
А если кто-нибудь захочет Вашу программу подогнать под свой МК и свою частоту ? Столько будет гемору, что-бы это сделать.... А тут поменял значение в одной строке и всё.

А еслиб я отображение запихнул в прерываня, оноб мерцало мне кажется.
Наоборот не будет. А в Вашем случае возможно, и не только мерцание, но и плавание яркости, погасание индикаторов и т.д... Потому что Вы вешаете основной цикл бешаными вычислениями в прерывании.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение urry »

что мог, поправил. тоже не шедевр, конечно, но секунда там на что-то похожа.
Вложения
kaz_krik.zip
(67.6 КБ) 239 скачиваний
FlySnake
Мучитель микросхем
Сообщения: 429
Зарегистрирован: Пт ноя 20, 2009 20:38:12
Откуда: Калининград (Koenigsberg)
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение FlySnake »

Аlex писал(а):ИМХО, для таких вещей нужно мерить период и из него уже вычислять обороты. INT + таймер Вам в помощь.....

Лучше CCP в режиме Capture
что мог, поправил. тоже не шедевр, конечно, но секунда там на что-то похожа.

Позвольте несколько вопросов-замечаний? :)
1. if(TMR2IF && TMR2IF) - в чем фишка такого выражения? Просто if(TMR2IF) или для наглядности if(TMR2IF==1). Неужели такое выражение компилится в более эфективный код?
2. в свитче нет default. Если по каким-то причинам (статика, помехи) ни один из кейсов не подходит то не произойдёт ничего, а прога может посчитать чего неверно
3. if (seconds==TMR1_MAX) опять же гуру рекомендуют в таких случаях вместо == делать >= ибо случайная помеха, перевёрнутый нолик в старшем разряде и прога заглючит
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение urry »

FlySnake
1. if(TMR2IF && TMR2IF) Фишка такого выражения (или лучше - сакральный смысл этого заклинания) состоит в том, что флаг устанавливается, даже когда маской прерывание запрещено. Обязательно !!! анализировать как флаг, так и маску
Не удержусь от цитирования testera - его статьи, расположенной здесь http://www.pic24.ru/

Код: Выделить всё

Должен обрабатывать только активные (xxIE = «1») прерывания
Микроконтроллеры PIC16 имеют всего один вектор прерывания (PIC18 – два), что вынуждает
программиста одним обработчиком обрабатывать прерывания, возникшие от нескольких источников.
Т.е., попадая в обработчик, требуется по очереди перебрать все предусмотренные программой флаги,
чтобы выяснить, какое именно прерывание произошло, и обработать именно его. Здесь кроется
небольшой подвох, связанный с тем, что некоторые источники прерываний могу временно запрещаться.
Типичный пример – прерывание по завершению передачи байта через USART. Флаг TXIF
устанавливается сразу же при установке бита разрешения передачи (TXEN), т.е. тогда, когда еще ни
один байт не передан. Поэтому, если программой предусмотрена отправка данных через USART из
обработчика прерывания (кстати, очень правильный подход), то когда данных на передачу нет, чтобы
прерывание не генерилось вхолостую, его запрещают TXIE = 0 (напомню, что бит события TXIF не
может быть сброшен вручную; он сбрасывается автоматически только при записи данных в регистр
передачи TXREG).
Неправильно:
CODE 0x0004
Interrupt:
;... сохранение контекста
;----------
; Прерывание по таймеру 0
;----------
T0IF_Check:
btfss intcon, T0IF ; было ли прерывание по таймеру?
goto T0IF_Skip
bcf intcon, T0IF
;...
;... код обработки
;...
T0IF_Skip:
;----------
; Прерывание по завершению передачи USART
;----------
TXIF_Check:
btfss pir1, TXIF ; Даже при TXIE=0 программа попадет в обработчик
goto TXIF_Skip
;...
;... код

Допустим, в приведенном выше примере в обработчик попали по прерыванию при переполнении
TMR0. Т.е. пока этого прерывания не было, мы в обработчик не попадали даже при установленном TXIF,
т.к. бит разрешения был сброшен (TXIE = 0). Но все попадания внутрь обработчика будут вызывать
одновременно и обработку TXIF
Правильно:
CODE 0x0004
Interrupt:
;... сохранение контекста
;----------
; Прерывание по таймеру 0
;----------
T0IF_Check:
btfsс intcon, T0IF ; было ли прерывание по таймеру?
btfss intcon, T0IE ; разрешено ли прерывание?
goto T0IF_Skip
bcf intcon, T0IF
;...
;... код обработки
;...
T0IF_Skip:
;----------
; Прерывание по завершению передачи USART
;----------
TXIF_Check:
banksel pie1
btfss pie1, TXIE
goto TXIF_Skip
banksel pir1
btfss pir1, TXIF ; Теперь на эту проверку попадем только при TXIE = 1
goto TXIF_Skip
;...
;... код обработки
.

По поводу пунктов 2 и 3 - на случай ядерной войны, когда биты местами поменяются - никаких возражений нет. :)
Кстати, Вы бы здесь сразу выложили Ваш вариант, я же вчера час своего времени убил...
FlySnake
Мучитель микросхем
Сообщения: 429
Зарегистрирован: Пт ноя 20, 2009 20:38:12
Откуда: Калининград (Koenigsberg)
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение FlySnake »

1. if(TMR2IF && TMR2IF) Фишка такого выражения (или лучше - сакральный смысл этого заклинания) состоит в том, что флаг устанавливается, даже когда маской прерывание запрещено. Обязательно !!! анализировать как флаг, так и маску

А, ну это да. Просто у вас видимо очепятка потому что должно быть (TMR2IE && TMR2IF), и с TMR1 тоже.
Кстати, Вы бы здесь сразу выложили Ваш вариант, я же вчера час своего времени убил...

В лом же, и времени жалко, к тому же нет педагогического смысла помогать вопрощающему полным переписыванием кода, гораздо полезнее указать на ошибки чтобы сам исправил. Я просто как начинающий ради обмена опытом поинтересовался ;)
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение urry »

да, "очепятка", естественно.
По поводу педагогики - ошибки были указаны - и я не писал свой код, я тасовал код ТС, у него, кстати, маска не учитывалась.
Ну не удержался, чтобы не переписать какой-то кусок :(
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

Вот говорят что лучше ССР использовать. Там есть Захват\ сравнение\шим. ШИМ отпадает. Чтоб посчитать количество импульсов за секунду как использовать ССР? Читал даташит но там не понятно как его применять. помогите. Принцип использования в данном направлении какоов?.
FlySnake
Мучитель микросхем
Сообщения: 429
Зарегистрирован: Пт ноя 20, 2009 20:38:12
Откуда: Калининград (Koenigsberg)
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение FlySnake »

Кол-во импульсов за секунду можно считать с помощью таймера в режиме асинхронного счётчика и прервание каждую секунду от другого таймера т.е. измеряем частоту. CCP в режиме capture считает время между импульсами т.е. период. В большинстве случаев (где частота и длительность импульсов не меняеются мгновенно в большом диапазоне) можно использовать оба метода т.к. это по сути взаимообратные вещи.
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

FlySnake писал(а):Кол-во импульсов за секунду можно считать с помощью таймера в режиме асинхронного счётчика и прервание каждую секунду от другого таймера т.е. измеряем частоту. CCP в режиме capture считает время между импульсами т.е. период. В большинстве случаев (где частота и длительность импульсов не меняеются мгновенно в большом диапазоне) можно использовать оба метода т.к. это по сути взаимообратные вещи.

Я написал программу. но там показывается со скачков в 60. А возможно чтоб обороты показывались точно? Я думаю это может особо и не нужно, но дело не в этом. Просто хочу разобратся и попробовать сделать. Захват я понял что по событию копируются значения с 1го таймера в Ячейки модуля захвата. Но зачем и что по событию на ноге захвата , выпрерывание прерывание. Тоесть тоже что я и делал до этого токо проще. Вобщем как им пользоватся?
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Вам нужно мерить не частоту, а период. А из него уже высчитывать об/мин.
Для измерения периода потребуется внешнее прерывание и один таймер.
Думаю что Вам алгоритм понятен и Вам его расписывать не придётся....
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

Информацию брал от сюда http://sarge.pp.ua/pic-mk-eksperiment-10-ispolzovanie-modulya-ccp-capturecompare/. А там сказано что В этом режиме содержимое регистров TMR1H и TMR1L копируется в регистры CCPR1H и CCP1L в следующих ситуациях:

По каждому спаду на RB3
По каждому возрастающему импульсу на RB3
По каждому 4 возрастающему импульсу на RB3
По каждому 16 возрастающему импульсу на RB3
. Тоесть я понимаю так. Появился импульс, В TMR1H и TMR1L какоето значение Х. Оно помещается в CCPR1H и CCP1L. Ну непойму зачем тудда перемещать, но припустим. Первый таймер считает дальше. Что делать с регистрами CCPR1H и CCP1L. Ну наверна кудась скопировать потому как при следующем импульсе занесётся новое значение. Тут приходит новый импульс и заносится новое значение в CCPR1H и CCP1L с 1таймера. Если отнять от второго значения что в CCPR1H и CCP1L то что было перед ним и точто мы сохранили, то мы получи некое число которое можна привязать к времени. Но при маленьких частотах на входе 1й таймер сможет несколько рас сделать несколько кругов, тода надо круги ещё считать.
Я так понял что захват работает так- Кода импульс то об этом свидетельствует флаг и можно уйти в прерывание. Чем тода INT отличается от этого или прерывание по событию на какойто линии ввода- вывода.
Или вообще я не в том направлении думаю?
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение Аlex »

Да не путайте Вы себя этими захватами. Сделайте для начала на внешнем прерывании. А потом уже и захват осилите...
misterkuk
Мучитель микросхем
Сообщения: 400
Зарегистрирован: Сб апр 17, 2010 10:30:13
Контактная информация:

Re: Програмирование pic на СИ.

Сообщение misterkuk »

Я просто не вижу разницы между захватом и внешним прерыванием. INT я понял вы имеете в виду. И никак это инт не отличается от захвата. Тоесть вы имеете в виду сделать тоже самое что и захват делает тока сигнал на инт подавать?
И не пойму, почему ИНТ только 1. а если нужно 2 или таких входов?
Ответить

Вернуться в «PIC»