|
|
View previous topic :: View next topic |
Author |
Message |
ufkyldrm
Joined: 21 May 2018 Posts: 27
|
Delay and timer1 problem pic16f877a |
Posted: Mon May 21, 2018 1:07 pm |
|
|
Hi guys i'm 15 years old, and I decide to learn pic, So i respect to all of u
I started with pic16f877a . But some problems are exist.
My pic do not notice delay function and timer interrupts.
In my program i try to count pulses with timer1 interrupt and control variables with lcd display.
Everything is ok on Proteus 8 but on board only outputs which I can only see.
I don't know what is problem, I use 20MHZ crystal with 22pf cap, in datasheet of 16f877a these items are used.
my code is
Code: | #include<16f877A.h> //picin özelliklerini al
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD //BAZİ özellikleri iptal ediyoruz.
#use delay(clock=20M) // osilatör hızı
#include<lcd.c>
#include<modbus.c>
#include<stdio.h>
#use fast_io(b)
#use fast_io(c)
//int toplamadres=0; // programınGt en sonunda eklenecek epron
//int pulseadres=5; // programın en sonunda eklenecek epron
#include <stdlib.h>
float pulse=1.123f;
float toplam=0.0001f;
int sayici=0;
float modbusno=10.0;
int editsayici=0;
int kontrol2=7;
int kontrol3=7;
int kontrol4=7;
int kontrol5=7;
int editimlec=0;
Boolean secildi2=false;
void Write_Float_Eeprom(address, float data) //epron write float
{
int8 i;
for(i = 0; i < 16; ++i){
write_eeprom(address + i, *((int8 *)(&data) + i));
}
}
float Read_Float_Eeprom( address) //epron read float
{
int8 i;
float data;
for(i = 0; i < 16; ++i)
{
*((int8 *)(&data) + i) = read_eeprom(address + i);
}
return data;
}
//Write_Float_Eeprom(toplamadres, toplam); // programın en sonunda eklenecek epron
//char buffer[17];
int i=0; // Tamsayı tipinde değişken tanımlanıyor
//****************** Timer1 Kesmesi *****************************
#int_timer1 // Timer1 kesmesi
void timer1_kesme () // Kesme fonksiyonu ismi
{
lcd_init();
set_timer1(65533); // TMR1 değeri belirleniyor
i++; // i değeri 1 arttırılıyor
if (i==1) // i değeri 1'ye eşit olursa RB0 lojik-1 olsun
{
output_high(pin_b0);
/*
int f=21;
char buf[8];
printf(lcd_putc,"%u",f);
*/
toplam=toplam+pulse;
// Write_Float_Eeprom(toplamadres, toplam);
}
if (i==2) // i değeri 100'e eşit olursa RB0 lojik-0 ve i=0 olsun
{
output_low(pin_b0);
i=0;
}
secildi2=true;
}
void main()
{
setup_psp(PSP_DISABLED); // PSP birimi devre dışı
setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
setup_adc(ADC_OFF); // ADC birimi devre dışı
setup_CCP1(CCP_OFF); // CCP1 birimi devre dışıetup_CCP2(CCP_OFF); // CCP2 birimi devre dışı
set_tris_b(0b00111100); // B portu komple çıkış b1 dışında
set_tris_a(0b00000000); // B portu komple çıkış b1 dışında
output_b(10000010); // B portu çıkışı ilk anda sıfırlanıyor
output_a(00000000); // B portu çıkışı ilk anda sıfırlanıyor
output_high(pin_b1);
output_high(pin_b7);
output_low(pin_b6);
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); // Timer1 ayarları yapılıyor
set_timer1(65533); // TMR1 değeri belirleniyor
enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
enable_interrupts(INT_timer1); // int_timer0 kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
while(1)
{
output_high(pin_b6);
delay_ms(2000);
output_low(pin_b6);
delay_ms(2000);
////////-------------- korumalı menü bölümü
if(sayici==1)
{
if(secildi2)
{
output_high(pin_b1);
lcd_putc("\f----:PULSE:----\n");
printf(lcd_putc,"%.4f",pulse);
secildi2=false;
lcd_cursor_on(FALSE);
}
}
else if(sayici==0)
{
if(secildi2)
{
output_high(pin_b1);
lcd_putc("\f----:TOPLAM:----\n");
printf(lcd_putc,"%.4f",toplam);
secildi2=false;
lcd_cursor_on(FALSE);
}
}
else if(sayici==2)
{
if(secildi2)
{
output_high(pin_b1);
lcd_putc("\f---:MODBUS NO:---\n");
printf(lcd_putc,"%f",modbusno);
secildi2=false;
lcd_cursor_on(FALSE);
}
}
////////-------------- korumalı edit menü bölümü
if(!(input(pin_b2))&&kontrol2==7)
{
lcd_cursor_on(FALSE);
sayici++;
if(sayici==3)
{
sayici=0;
}
kontrol2=1;
secildi2=true;
}
else
{
kontrol2=7;
}
if(!(input(pin_b3))&&kontrol3==7)
{
if(editsayici==0)
{
lcd_cursor_on(true);
output_low(pin_b1);
lcd_putc("\f--:PULSE:EDIT---\n");
printf(lcd_putc,"%.4f",pulse);
kontrol3=1;
editsayici++;
}
else if(editsayici==1)
{
lcd_cursor_on(true);
output_low(pin_b1);
lcd_putc("\f:MODBUS NO:EDIT-\n");
printf(lcd_putc,"%f",modbusno);
kontrol3=1;
editsayici++;
}
if(editsayici==2)
editsayici=0;
}
else
{
kontrol3=7;
}
int sayac=0;
if(!(input(pin_b4))&&kontrol4==7)
{
sayac++;
editimlec++;
lcd_gotoxy(editimlec,2);
lcd_cursor_on(TRUE);
if(editsayici==1)
{
if(editimlec==6)
editimlec=0;
}
if(editsayici==0)
{
if(editimlec==2)
editimlec=0;
}
output_high(pin_b7);
kontrol4=1;
}
else if((input(pin_b4))&&kontrol4==1)
{
kontrol4=7;
}
if(!(input(pin_b5))&&kontrol5==7)
{
char a=lcd_getc(editimlec, 2);
a++;
if(a==58)
a=48;
if(a==33)
a=32;
if(a==47)
a=46;
lcd_gotoxy(editimlec,2);
if(!(a==32&&a==46))
{
lcd_putc(a);
lcd_gotoxy(1,2);
//pulse=printf(lcd_getc,"%.4f",pulse);
lcd_gotoxy(editimlec,2);
}
char ch_lcd[15];
int cnt=0;
for(cnt=1; cnt<6; cnt++)
{
ch_lcd[cnt-1]= lcd_getc(cnt,2);
}
if(editsayici==1)
{
pulse = atof(ch_lcd);
}
if(editsayici==0)
{
modbusno = atof(ch_lcd);
}
output_high(pin_a0);
kontrol5=1;
}
else if((input(pin_b5))&&kontrol5==1)
{
kontrol5=7;
}
}
//output_high(pin_b1);
//toplam=Read_Float_Eeprom(toplamadres); // programın en sonunda eklenecek epron
//pulse=Read_Float_Eeprom(pulseadres); // programın en sonunda eklenecek epron
// Sonsuz döngü
}
|
My Proteus pic
https://ibb.co/mRAdY8
please help me :( |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 21, 2018 1:57 pm |
|
|
Quote: |
#include<16f877A.h> //picin özelliklerini al
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD //BAZİ özellikleri iptal ediyoruz.
#use delay(clock=20M) // osilatör hızı
|
For a 20 MHz crystal, the HS fuse is required. XT is only good up to 4 MHz. |
|
|
ufkyldrm
Joined: 21 May 2018 Posts: 27
|
|
Posted: Mon May 21, 2018 2:11 pm |
|
|
PCM programmer wrote: | Quote: |
#include<16f877A.h> //picin özelliklerini al
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD //BAZİ özellikleri iptal ediyoruz.
#use delay(clock=20M) // osilatör hızı
|
For a 20 MHz crystal, the HS fuse is required. XT is only good up to 4 MHz. |
thank u for your interest
i deleted #fuses XT and i set #fuses HS nothing change. :(
i delete enable interrupts ( global ) and delay function work good. I guess i should not use timers with delay. Now timer1 dont work ::((( whuuuyy
Last edited by ufkyldrm on Mon May 21, 2018 4:04 pm; edited 1 time in total |
|
|
ufkyldrm
Joined: 21 May 2018 Posts: 27
|
|
Posted: Mon May 21, 2018 4:03 pm |
|
|
i delete enable interrupts ( global ) and delay function work good. I guess i should not use timers with delay. now timer1 dont work ::((( whuuuyy |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9245 Location: Greensville,Ontario
|
|
Posted: Mon May 21, 2018 4:28 pm |
|
|
just a comment...
The general rule for using interrupts is to make the code small and fast inside the ISR ( Interrupt Service Routine )
You should ONLY set a few flags, maybe change a register or two.
You should NOT use delays or prints inside the ISR.
Jay |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon May 21, 2018 4:44 pm |
|
|
Quote: | set_timer1(65533); |
The timer rolls over to 0 in the next clock after it counts up to 65535.
It causes an interrupt when the timer rolls over. You are setting it to
65533. This will not work. You can't make it interrupt that often.
With a load value of 65533, you will get a new interrupt when you have
not finished the #int_timer1 code for the previous one.
Also don't do any lcd operations inside the Timer1 interrupt.
They are too slow. Do them in the main() code. Remove lcd_init()
from the Timer1 interrupt routine.
Quote: | Write_Float_Eeprom(toplamadres, toplam); |
Also, don't write to eeprom inside the #int_timer1 routine. Eeprom
write operations take too long to do. (up to 5 ms each byte. There are
4 bytes for each float).
Quote: | enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
enable_interrupts(INT_timer1); // int_timer0 kesmesini aktif yapar
enable_interrupts(GLOBAL); // Aktif edilen kesmelere izin ver
|
Also, you are enabling interrupts for #int_timer0, but you don't have an
interrupt routine for Timer0. Don't do that. Remove the line in bold. |
|
|
ufkyldrm
Joined: 21 May 2018 Posts: 27
|
|
Posted: Sun May 27, 2018 1:37 pm |
|
|
problem is solved than uuuu!! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|