Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PIC16F877 UART software, delays, interrupts, sleep mode...

Status
Not open for further replies.

Clemen89

Newbie level 2
Joined
Jul 10, 2012
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,310
Hello,

I'm using the microcontroller PIC16F877, and I need use two UART, this PIC only has got one UART, so I need design a UART software.

Well, I designed the UART, and before work fine, without WDT, without sleep, only receive date and send date directly.

Now I need save the dates received in a char[] for send after. I need use sleep and wdt too, and now dont work fine. I think for delays or something.

DATES:

-I use RB0/INT = RX in UART software, because when start the communication generates a interrupt and wake up.

This is the parts of code importants:

Code:
if(INTF==1){
		__delay_us(25);	
		for(i=0;i<8;i++){
			recibido=recibido>>1;
			if(RB0==1){
				recibido = recibido | 0x80;
			}
			if(RB0==0){
				__delay_us(3);
			}
			if(i!=7)__delay_us(83);
		}
		probando[indice]=recibido;
		control_uart=1;
		indice++;
		CLRWDT();
}

Well, generated the interrupt, delay 25us because I read in datasheet that OST generates a delay of 1024 cycles, I using XTAL of 10MHz, Tosc*1024=102us.

102us+25us for the instruccion delay+delay of interrupt = approximately 156 us.

Why 156us?

qOTAG.png



Generates the interrupt --> delay 156us approximately ----> take the date in mid of signal for more efficiency ----------> delay 104us -------------> take the next bit -----> .....


But dont work fine. Some help?

.......................................................................

Other parts of code:

Send the received in software UART:

Code:
for(i=0;i<=indice;i++){
		while(TRMT==0);
		TXREG=probando[i];
	}

Infinite main:

Code:
void main(){

	PSA=1;
	PS0=1;
	PS1=1;
	PS2=1;
	CLRWDT();
	T1CON=0b00110000;
	TMR1H=0;
	TMR1L=0;
	TMR1IF=0;
	TMR1IE=1;
	GIE=1;
	PEIE=1;
	INTF=0;
	INTEDG=0;
	INTE=1;
	RB1=1;
	TRISB=0b11111101;
	TRISC=0b10111111;
	BRGH=0;
	TXEN=1;
	SPBRG=15;
	SPEN=1;
	CREN=1;
	RCIE=1;
	[b]while(1){
		if(control_perro==0){
			SLEEP();
		}
		if(nTO==0&&control_uart==1){
			enviar();
		}
		CLRWDT();
	}
}

If you need all code only say me :), is short, the program only is this:

Device 1 send to PIC using UART software, PIC send device 2 using UART hardware, device 2 send PIC using UART hardware and PIC send device 1 using UART software:

Device 1 <----> PIC <-----> Device 2



Thanks and congratulation for the forum!

Clemente
 
Last edited:

Hello,

I'm using the microcontroller PIC16F877, and I need use two UART, this PIC only has got one UART, so I need design a UART software.

Well, I designed the UART, and before work fine, without WDT, without sleep, only receive date and send date directly.

Now I need save the dates received in a char[] for send after. I need use sleep and wdt too, and now dont work fine. I think for delays or something.

DATES:

-I use RB0/INT = RX in UART software, because when start the communication generates a interrupt and wake up.

This is the parts of code importants:

Code:
if(INTF==1){
		__delay_us(25);	
		for(i=0;i<8;i++){
			recibido=recibido>>1;
			if(RB0==1){
				recibido = recibido | 0x80;
			}
			if(RB0==0){
				__delay_us(3);
			}
			if(i!=7)__delay_us(83);
		}
		probando[indice]=recibido;
		control_uart=1;
		indice++;
		CLRWDT();
}

Well, generated the interrupt, delay 25us because I read in datasheet that OST generates a delay of 1024 cycles, I using XTAL of 10MHz, Tosc*1024=102us.

102us+25us for the instruccion delay+delay of interrupt = approximately 156 us.

Why 156us?

qOTAG.png



Generates the interrupt --> delay 156us approximately ----> take the date in mid of signal for more efficiency ----------> delay 104us -------------> take the next bit -----> .....


But dont work fine. Some help?

.......................................................................

Other parts of code:

Send the received in software UART:

Code:
for(i=0;i<=indice;i++){
		while(TRMT==0);
		TXREG=probando[i];
	}

Infinite main:

Code:
void main(){

	PSA=1;
	PS0=1;
	PS1=1;
	PS2=1;
	CLRWDT();
	T1CON=0b00110000;
	TMR1H=0;
	TMR1L=0;
	TMR1IF=0;
	TMR1IE=1;
	GIE=1;
	PEIE=1;
	INTF=0;
	INTEDG=0;
	INTE=1;
	RB1=1;
	TRISB=0b11111101;
	TRISC=0b10111111;
	BRGH=0;
	TXEN=1;
	SPBRG=15;
	SPEN=1;
	CREN=1;
	RCIE=1;
	[b]while(1){
		if(control_perro==0){
			SLEEP();
		}
		if(nTO==0&&control_uart==1){
			enviar();
		}
		CLRWDT();
	}
}

If you need all code only say me :), is short, the program only is this:

Device 1 send to PIC using UART software, PIC send device 2 using UART hardware, device 2 send PIC using UART hardware and PIC send device 1 using UART software:

Device 1 <----> PIC <-----> Device 2



Thanks and congratulation for the forum!

Clemente

Hi,

I think you need to describe more on what's not happening :)
 

Ok jeje

Well, my project is MODEM GSM <---> PIC <---> Meteorologic station

In sleep mode, the interrupt of the UART ( hardware in pic ) dont wake up PIC, so I need connect modem gsm to UART software, because RB0 (RX in my UART software) wake up PIC.

When the communication is over between PIC and modem GSM, PIC start communication with station meteorologic, station meteorologic responds to PIC and PIC responds to Modem gsm.

Well, the while in main loop is this:

Code:
	while(1){
		if(control_perro==0){
			if(nTO==1){
				SLEEP();
			}
		}
		if(control_uart==1){
			enviar();
		}
		CLRWDT();
	}

When the RB0 interrupt is activated, goto to:

Code:
void interrupt isr(void){
	CLRWDT();
	if(INTF==1){
		__delay_us(35);	
		for(i=0;i<8;i++){
			recibido=recibido>>1;
			if(RB0==1){
				recibido = recibido | 0x80;
			}
			if(RB0==0){
				__delay_us(3);
			}
			if(i<7)__delay_us(83);
		}
		probando[indice]=recibido;
		control_uart=1;
		indice++;
		CLRWDT();
	}
.
.
.
.

Well, when the communicatión is over, WDT wake up PIC and the bit nTO=1, also control_uart=1 ( in interrupt function ) and the function "enviar()" is called, this function is here:

Code:
void enviar(){
	CLRWDT();
	control_perro=1;
	control_uart=0;
	indice--;
	CLRWDT();
	for(i=0;i<=indice;i++){
		while(TRMT==0);
		TXREG=probando[i];
	}
	CLRWDT();
	indice=0;		
	
}

This function send all received in UART software, the received is in probando[]. But dont work fine this communication, i was doing tests and i think that the fail is in the reception of UART software, in delays.

WDT generates delay in interrupt RB0? Sleep generates some delay in interrupts? The rest of program work fine.
 

Ok jeje

Well, my project is MODEM GSM <---> PIC <---> Meteorologic station

In sleep mode, the interrupt of the UART ( hardware in pic ) dont wake up PIC, so I need connect modem gsm to UART software, because RB0 (RX in my UART software) wake up PIC.

When the communication is over between PIC and modem GSM, PIC start communication with station meteorologic, station meteorologic responds to PIC and PIC responds to Modem gsm.

Well, the while in main loop is this:

Code:
	while(1){
		if(control_perro==0){
			if(nTO==1){
				SLEEP();
			}
		}
		if(control_uart==1){
			enviar();
		}
		CLRWDT();
	}

When the RB0 interrupt is activated, goto to:

Code:
void interrupt isr(void){
	CLRWDT();
	if(INTF==1){
		__delay_us(35);	
		for(i=0;i<8;i++){
			recibido=recibido>>1;
			if(RB0==1){
				recibido = recibido | 0x80;
			}
			if(RB0==0){
				__delay_us(3);
			}
			if(i<7)__delay_us(83);
		}
		probando[indice]=recibido;
		control_uart=1;
		indice++;
		CLRWDT();
	}
.
.
.
.

Well, when the communicatión is over, WDT wake up PIC and the bit nTO=1, also control_uart=1 ( in interrupt function ) and the function "enviar()" is called, this function is here:

Code:
void enviar(){
	CLRWDT();
	control_perro=1;
	control_uart=0;
	indice--;
	CLRWDT();
	for(i=0;i<=indice;i++){
		while(TRMT==0);
		TXREG=probando[i];
	}
	CLRWDT();
	indice=0;		
	
}

This function send all received in UART software, the received is in probando[]. But dont work fine this communication, i was doing tests and i think that the fail is in the reception of UART software, in delays.

WDT generates delay in interrupt RB0? Sleep generates some delay in interrupts? The rest of program work fine.

Try removing the watchdog. See if the sleep is giving you the problem or the watchdog. did your system resets?
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top