Форум мікро-чіп - як записати і порахувати імпульси в пам'ять pic16f877

Як записати і порахувати імпульси в пам'ять PIC16F877

Є завдання. З датчика Холла SS443А формуються імпульси різної ширини в залежності від частоти обертання магніту.

Треба. Ці імпульси треба вважати PIC16F877 і записати кількість імпульсів в пам'ять PIC-а.
Друга умова - необхідно в залежності від зовнішньої температури (як вважати температуру я написав код - використовую датчик DS18S20) імпульси вважати і записувати кількість імпульсів в різні області пам'яті (як я розумію або це не можливо?) Сам алгоритм як я розумію: вважали значення температури , порахували імпульси до наступного зчитування температури, в завімості від величини температури - записали кудись мікроконтролер, і так далі цикл.

Проблема. Я не сильний в програмуванні. З цього прошу допомоги:
- в роз'ясненні алгоритму запису;
- приклади програми записи імпульсів в пам'ять;
- як потім ці імпульси використовувати при математичних розрахунках.

Програмувати намагаюся на Сі (використовуючи microC Pro), моделюю в протеус.

Заздалегідь Дякую всім за роз'яснення!

Re: Як записати і порахувати імпульси в пам'ять PIC16F877

Повідомлення від lagent (повідомлення 154369)

Є завдання. З датчика Холла SS443А формуються імпульси різної ширини в залежності від частоти обертання магніту.

Треба. Ці імпульси треба вважати PIC16F877 і записати кількість імпульсів в пам'ять PIC-а.
Друга умова - необхідно в залежності від зовнішньої температури (як вважати температуру я написав код - використовую датчик DS18S20) імпульси вважати і записувати кількість імпульсів в різні області пам'яті (як я розумію або це не можливо?) Сам алгоритм як я розумію: вважали значення температури , порахували імпульси до наступного зчитування температури, в завімості від величини температури - записали кудись мікроконтролер, і так далі цикл.

Проблема. Я не сильний в програмуванні. З цього прошу допомоги:
- в роз'ясненні алгоритму запису;
- приклади програми записи імпульсів в пам'ять;
- як потім ці імпульси використовувати при математичних розрахунках.

Програмувати намагаюся на Сі (використовуючи microC Pro), моделюю в протеус.

Заздалегідь Дякую всім за роз'яснення!

Кудись в мікроконтролер.
Ну да ладно, краще поясни що з зібраними даними то робити треба?

Re: Як записати і порахувати імпульси в пам'ять PIC16F877

Повідомлення від Eminem (повідомлення 154385)

Кудись в мікроконтролер.
Ну да ладно, краще поясни що з зібраними даними то робити треба?

Якби я знав в яку область пам'яті і як записати. я б не писав "кудись".


Ідея така. роблю саморобний лічильник води з урахуванням температури води. На РК-екран виводити сумарне значення витрати води за різними діапазонами температури.

Я маю кілька температурних діапазонів - відповідно до цих діапазонами треба порахувати і записати в пам'ять імпульси, а в потрібний момент: я міг вважати ці значення з пам'яті.

Сьогодні намагався написати просту програму (роблю в microC Pro), яка б вважала зовнішні імпульси і виводила на ЖК-екран.

// Налаштування LCD-модуля
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

int cnt_tmp = 0;
long cnt = 0; // Лічильник
int TMR1 = 0;

PORTB = 0xFF;
TRISB = 0xFF;

Lcd_Init (); // ініціалізація LCD-модуля
Lcd_Cmd (_LCD_CLEAR); // очищення екрана
Lcd_Cmd (_LCD_CURSOR_OFF); // відключити курсор
Lcd_Out (1, 1, "SCHETCHIK:");

T1CON.TMR1ON = 1; // вкл. TMR1
T1CON.TMR1CS = 1; // зовнішнє джерело такт. сигналів
T1CON.T1SYNC = 1; // не виконувати синхронізацію зовнішній такт.сігнал
T1CON.T1OSCEN = 0; // вкл. такт.генератор TMR1

PIR1.TMR1IF = 0; // скидання прапора переривання по переповнення TMR1
PIE1.TMR1IE = 1; // переривання від TMR1 дозволено
INTCON.PEIE = 1; // дозволені всі переривання від периферії
INTCON.GIE = ​​1; // дозволені всі глобальні переривання

cnt = 0; // Обнуляємо змінні
cnt_tmp = 0; // лічильника


// ОСНОВНИЙ ЦИКЛ
while (1)
if (RA1_bit) // Якщо натиснули на кнопку Скидання
Delay_ms (40);
cnt = 0; // Обнуляємо змінні
cnt_tmp = 0; // лічильника
TMR1 = 0;
>

if (PIR1.TMR1IF PIE1.TMR1IE) // Якщо від таймера
PIR1.TMR1IF = 0; // Очищаємо прапор
cnt_tmp ++; // Інкремент старших байт лічильника
>

// cnt = (long) (cnt_tmp * 65536) + TMR1;
cnt = (long) (cnt_tmp + TMR1);
// cnt = cnt_tmp + TMR1; // вважати все в змінну
LongToStr (cnt, text);
Lcd_Out (2, 1, text);

Результат. Чи не хоче вважати.
По-моєму проблема в умова:

if (PIR1.TMR1IF PIE1.TMR1IE) // Якщо від таймера
PIR1.TMR1IF = 0; // Очищаємо прапор
cnt_tmp ++;
>

Пробував як в даташіте - враховувати тільки умова: if (PIR1.TMR1IF = 1). В результаті все підряд вважає, навіть коли імпульсів немає.

Підкажіть що не так?

Додатково вклав архів проекту в протеус і мій код!

Заздалегідь дякую за допомогу!

Re: Як записати і порахувати імпульси в пам'ять PIC16F877

Начебто все працює - імпульси вважає, обробка переривань теж працює.
Але є питання. Чому іноді або 1 імпульс відстає свідчення на РК-екрані від показань Лічильника, або навпаки випереджає на 1 імпульс, або все правильно збігається. У чому може бути проблема, або це подхові Протеуса?

// Налаштування LCD-модуля
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

char text [10]; // символи для чисел лічильника
long cnt_tmp = 0; // для підрахунку переривань
long cnt = 0; // лічильник імпульсів

PORTB = 0xFF;
TRISB = 0;

Lcd_Init (); // ініціалізація LCD-модуля
Lcd_Cmd (_LCD_CLEAR); // очищення екрана
Lcd_Cmd (_LCD_CURSOR_OFF); // відключити курсор
Lcd_Out (1, 1, "SCHETCHIK:");

T1CON.TMR1ON = 1; // вкл. TMR1
T1CON.TMR1CS = 1; // зовнішнє джерело такт. сигналів
T1CON.T1SYNC = 1; // не виконувати синхронізацію зовнішній такт.сігнал
T1CON.T1OSCEN = 0; // вкл. такт.генератор TMR1

PIR1.TMR1IF = 0; // скидання прапора переривання по переповнення TMR1
PIE1.TMR1IE = 1; // переривання від TMR1 дозволено
INTCON.PEIE = 1; // дозволені всі переривання від периферії
INTCON.GIE = ​​1; // дозволені всі глобальні переривання

TMR1L = 0b00000000; // обнулити TMR1
TMR1H = 0b00000000;

cnt = 0; // обнулити змінні лічильника
cnt_tmp = 0;

// *************** ОСНОВНИЙ ЦИКЛ ***********************
while (1) if (RA1_bit) // Кнопка Скидання
Delay_ms (30);
cnt = 0; // обнулити змінні лічильника
cnt_tmp = 0;
TMR1L = 0b00000000; // обнулити TMR1
TMR1H = 0b00000000;
>

cnt = ((TMR1H<<8)+TMR1L)+(cnt_tmp*65536); // считать всё в переменную
LongToStr (cnt, text);
Lcd_Out (2, 1, text);

if (PIR1.TMR1IF) // Переривання від TMR1
cnt_tmp ++; // збільшити змінну на 1
PIR1.TMR1IF = 0; // скинути прапор
TMR1L = 0b00000000; // обнулити TMR1
TMR1H = 0b00000000;
>
>
>

І ще питання. Як я зрозумів з попередніх повідомлень - я записати даних можу тільки в EEPROM-пам'ять мікроконтролера або ставити окрему згадку, інших варіантів немає?