Форум мікро-чіп - як записати і порахувати імпульси в пам'ять 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-пам'ять мікроконтролера або ставити окрему згадку, інших варіантів немає?