Weird result regarding interrupt

Status
Not open for further replies.

MrNobody

New Member
What I intend to do is as follows
Everytime interrupt occur, UARTSendF = 1and cnt80002 will increase by 1. Whenever UARTSendF = 1, cnt80002 value will be sent through UART. If everything works well, i will receive values from 0 upto 7999 from serial port. At the same time, cnt8000 will keep tract how many times PIC have sent to UART. So, if everything is correct, cnt8000 should equals to cnt80002 at all times.

Below is the cnt80002 i received from UART:
1
21
54
87
120
162
204

What i hope to receive is as follows:
1
2
3
4
5
6
7

Here is my code:
Code:
#pragma config OSC=HSPLL 
#pragma config PWRT=ON
#pragma config BOREN=OFF
#pragma config WDT=OFF
#pragma config MCLRE=ON
#pragma config PBADEN=OFF
#pragma config LVP=OFF
#pragma config XINST=OFF
#define CLOCK_FREQ		(40000000)      // Hz 

/////////////////////////////////////
// FUNCTION PROTOTYPE
/////////////////////////////////////
void low_isr();
void InitInterrupt();
void InitTimer2();
void InitADC();
void InitUART();
void Test();


/////////////////////////////////////
// GLOBAL VARIABLE
/////////////////////////////////////
char results;
char UARTSendF = 0;
unsigned int cnt8000;
unsigned int cnt80002;


/////////////////////////////////////
// SETUP ISR VECTOR
/////////////////////////////////////
#pragma code low_vector=0x18    //setup the ISR vector
void low_interrupt (){
    _asm GOTO low_isr _endasm    //jump to interrupt handler
}
#pragma code


/////////////////////////////////////
// ISR
/////////////////////////////////////
#pragma interruptlow low_isr    //the ISR
void low_isr()
{
    if (PIR1bits.TMR2IF == 1)
    {
	PIR1bits.TMR2IF=0;
        Test();
    }
}
#pragma code

void main()
{
	InitInterrupt();
	InitTimer2();
	InitADC();
	InitUART();
	TRISB = 0x00;
	while (1)
	{
		if (UARTSendF)
		{
			if (cnt8000 < 8000)
			{
				printf("%d\r\n", cnt80002); 
				UARTSendF = 0;
				cnt8000 +=1;
			}
			else 
			printf("STOP"); 
		}
	}
}

void InitInterrupt()
{
	PIE1bits.TMR2IE = 1;	//enable Timer2 interrupt
	INTCONbits.PEIE = 1;    //enable peripheral interrupts
	INTCONbits.GIE = 1;     //enable glogal interrupts
	IPR1bits.TMR2IP = 0;	// low priority
}	

void InitTimer2()
{
	T2CON = 0b01001000;
	PR2 = 124;				// 125 counts including 0
	T2CONbits.TMR2ON = 1;
}	

void InitADC()
{
	ADCON0 = 0b00000001;
	ADCON1 = 0b00001110;
	ADCON2 = 0b00010010;
	DDRAbits.RA0 = 1;
}
	
void InitUART()
{
	DDRCbits.RC6 = 0;
	DDRCbits.RC7 = 1;
	SPBRG = 64;
	TXSTA = 0b00100010;
	RCSTA = 0b10010000;
	BAUDCON = 0b00000000;
	TRISC = 0b10000001;
}		
	
void Test()
{
	UARTSendF = 1;
	cnt80002 += 1;
}

I know i did something wrong but I do not know what it is..
 
Hmm.. actually, what I was hoping to do is to sample ADC at 8kHz and then send the sampled byte through UART. Since the sample frequency is 8kHz, i hope to receive 8000 sampled values from UART.

Anybody has a better way of sending 8000 samples values through UART..?
Thanks..
 
You appear to be transmitting at 9600 baud. At this rate the maximum byte rate is around 900 bytes per second. As your not checking if the previous byte has been sent then you are loosing values. If you increase your baud rate to 115K then you will manage 8000 samples per second. At this rate you could have it free running. Wait for a timer, do conversion, send byte, loop. The normal way to check that the previous byte has gone is to wait for PIR1bits.TXIF.

Mike.
Edit, just noticed your sending ascii. The calculations above assume 1 byte per sample. Looks like you'll be pushing it to do 8000 samples/S
 
Last edited:
Yeah.. 8000 samples.. is it possible..?
 
oh.. lets say 1 byte per sample.. 8000 samples = 64000 bits/s
If I use 115k baudrate then should be possible right..?
Hmm.. but why would I be pushing it..? I don't quite understand..
If I send 64kbits/s, will I still be able to do other things like using ADC and TCP/IP stack..? Or will all the PIC resources be tied up..? How do I tell..?
 
If you can manage with 1 byte per sample then it is very doable. Doing other things like ADC will be no problem. The TCP/IP stack I have no experience of.

BTW, 1 byte is typically 10 bits - 1 start, 8 data & 1 stop.

I assumed that you needed the full 10 bits and that's why I said you would be pushing it.

Mike.
 

Yes, my thought as well - and obviously you need to send the byte as binary, and not as ASCII values.
 
Oh... i see.. i forgot about the stop bit and start bit..
Eventhough I send 10bits per sample (8 data, 1 stop bit and 1 start bit), for a baudrate of 115K, it is still possible right because 8000 x 10 = 80000 bits/s.
Is there any rule regarding serial transmission..?

I still don't understand the difference between sending byte as binary and sending byte as ASCII. Lets say i send 65 (decimal), isn't it the same as sending 0b1000001 (binary), 0x41 (hexadecimal) or 'A' (ASCII)..?
I still don't quite get it..
Can give some example please..? Thanks..
 
If you send 65 as binary then 65 (a single byte) gets sent, if you send it as ASCII then "6" is sent followed by "5" and then possibly 0d, 0a (if you use printf). When Hyperterminal receives the binary it will display "A". When it receives the ASCII it displays "65" and may move down a line.

Mike.
 
Are these sending as byte..?
printf(65);
printf(0b1000001);
printf('A');
printf(0x41);


Are these sending as ASCII..?
printf("A");

BTW, when I send the first 4 printf, I don't see anything on the hyperterminal.. Hmm.. still abit lost..
 
Can you do that with printf?

I would do,
Code:
    while(PIR1bits.TXIF==0);
    TXREG=65;
To make hyperterminal display "A".

Mike.
 
Oh... Now I get it.. Sending as binary means directly writing the data into TXREG. On the other hand, sending as ASCII means using the printf command. Am I right..?
 
MrNobody said:
Oh... Now I get it.. Sending as binary means directly writing the data into TXREG. On the other hand, sending as ASCII means using the printf command. Am I right..?

To see something printed on hyperterm it needs to be converted to ascii.
 
Hi,
Attached is the picture showing what I sent from PIC and what I received from HyperTerminal.
Below is the code that I use to write to UART. cnt80002 is an unsigned char and it increases by 1 from 0x00 to 0x0A.
Baudrate I used is 115K.
Any idea why I am not getting the same thing as what I have sent..?

Code:
while(PIR1bits.TXIF==0);
    TXREG=cnt80002;

EDITED: I have check with the watch window to make sure that what I send is correct..
 

Attachments

  • UART Results.png
    26.9 KB · Views: 140
That looks like your pic is transmitting too fast. What values have you used for BRGH, BRG16 and SPBRG. If you have BRGH=0 and BRG16=0 then you will be transmitting at 125K instead of 115.

Mike.
 
Oh.. I see the error..
I have changed the BRGH=1, BRGH16=1, SPBRG=86 and it is working fine now.
Thanks alot..
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…