|
|
View previous topic :: View next topic |
Author |
Message |
gopalakrishnan
Joined: 18 Jun 2010 Posts: 25
|
Using #int_rb for serial port |
Posted: Sun Jul 25, 2010 11:52 pm |
|
|
Kindly explain to me what does this code do. I can't come to the conclusion. Then, why can't we use B4-B7 (#int_rb) and C4-C7 for software uart? Is there any specific reason? Shall we use A0-A5? Kindly explain.
Code: |
#int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Mon Jul 26, 2010 5:06 am |
|
|
This is all down to hardware.
The hardware UART, has a shift register, into which a character is shifted bit by bit as it arrives. Once this register is full, the contents are transferred into a second register, the process starts again, and INT_RDA, is triggered.
The code shown, is triggered when a character of data has already arrived, and been transferred to the holding register. It then reads this character, and stores it into a software 'circular buffer'.
Key here is that the hardware has already received a character before the routine is called.
Now, you can use _one_ 'level' interrupt, and have this trigger when the first 'bit' of an incoming character arrives, then sit and simulate the shift register in software (the software UART), to receive the character. _But_ while you are doing this, nothing else can happen. So you can't use the four bits of INT_RB for four channels, since once one bit arrives of an incoming character, the code has to wait inside the interrupt handler to receive all the remaining bits, and _will_ miss any other characters that are arriving....
You can receive multiple streams using software code, by using a timer interrupt, rather than a level interrupt. However _not_ using the CCS software UART. I have in the post published here an outline of a timer based receive routine, and the same approach can also handle transmission at the same time (which the CCS software UART cannot do).
Best Wishes |
|
|
gopalakrishnan
Joined: 18 Jun 2010 Posts: 25
|
regarding garbage character |
Posted: Tue Jul 27, 2010 6:27 am |
|
|
I had gone through your forum replies it is so resourceful.
This is my experiment. When I transmit a string from the hardware uart, and received that string in software uart B0. Whenever the data is in the receive pin I had been interrupted by #int_ext. Inside the routine I store the received string in an buffer buffer[next_in]. Finally I send the received string to the lcd. This what my experiment is to be. I see my display blank some times I receive an garbage character.
I can able to receive an interrupt, where as I am unable to display the received string. Here is post my code. In the code kindly help me to get out of it. Thanks in advance.
Kindly clarify what to do with this code for getting a transmitted character from hardware uart to software uart. I am receiving a garbage character or undefined character in my display.
Code: |
#include "D:\transinnova\temp\test\rcv_intr.h"
#include <stdlib.h>
#if defined(__PCM__)
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use standard_io(B)
#use standard_io(D)
#endif
#byte PORTB = 0x6
//#USE RS232(BAUD=9600, XMIT=PIN_C6,RCV=PIN_C7)
//#USE RS232(BAUD=9600, RCV=PIN_B0)
//main program starts
void lcd_init();
void lcd_cmd(cmd);
void lcd_data(data);
#define CR 13
#define BUFFER_SIZE 32
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
char k[30]={"transinnova instuments"};
//char j[20];
int i,t;
unsigned char cmd,data,a;
#int_ext
void ext_isr(void)
{
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t;
}
#define bkbhit (next_in!=next_out)
BYTE bgetc()
{
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out % BUFFER_SIZE);
return(c);
}
void main()
{
ext_int_edge(H_TO_L);
enable_interrupts(int_ext);
enable_interrupts(GLOBAL);
set_tris_b(0x00);
set_tris_d(0x00);
output_d(0x00);
output_b(0x00);
lcd_init();
for(i=0;i<=31;i++)
{
delay_ms(1000);
#USE RS232(BAUD=9600, XMIT=PIN_C6,RCV=PIN_C7)
putc(k[i]);
#USE RS232(BAUD=9600, RCV=PIN_B0)
while(bkbhit)
lcd_data(bgetc());
}
}
//end of main program
//modules
//for lcd
//initilaize lcd
void lcd_init()
{
cmd=0x38;
lcd_cmd(cmd);
delay_ms(250);
cmd=0x0E;
lcd_cmd(cmd);
delay_ms(250);
cmd=0x01;
lcd_cmd(cmd);
delay_ms(250);
cmd=0x06;
lcd_cmd(cmd);
delay_ms(250);
return;
}
void lcd_cmd(cmd)
{
output_d(cmd);
output_low(PIN_b2);//rs
output_low(PIN_b1);//read write
output_high(PIN_b3);
delay_ms(250);
output_low(PIN_b3);//enabel
return;
}
//send data
void lcd_data(data)
{
output_d(data);
output_high(PIN_b2);//rs
output_low(PIN_b1);//read write
output_high(PIN_b3);
delay_ms(250);
output_low(PIN_B3);//enable
delay_ms(250);
return;
} |
|
|
|
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Fri Aug 06, 2010 8:56 pm |
|
|
First, rs232 will work on slow speeds, due timing but it will be kind of stable.
Second, first char will be missing because when you send it, then irq kicks on and then program starts collecting data:
Code: |
#INT_RB
void commseth() {
BYTE next_ind = 0;
char d;
do {
d = fgetc(eth);
strntempe[next_ind] = d;
next_ind++;
} while (strntempe[next_ind] != 0x0D);
strntempe[next_ind+1] = 0x0D;
flag_comms_eth_ready = 1;
}
|
So replace first char with anything and do not process it e.g. string[0] = "#", string[1,2,3,4,5...] is going to be your capture.
Then load data into string and process the string. I have stable comms on 9600 and it works well. Problem is that when rs232 is busy then mpu can't do anything else. You need to do kind of push/pull thing to communicate between 2 UARTs.
If you need high speed and efficiency then you need to have 2 UART mpu. No other way. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
|
|
|
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
|