|
|
View previous topic :: View next topic |
Author |
Message |
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
BOB_SANTANA program |
Posted: Tue Dec 05, 2006 3:12 pm |
|
|
Recieve AD1FFFF and check address and toggle pins.
Try to flesh this out. Post the results.
note I use a different processor and speed.
See how main is very simple. 1.do initialization 2. if relay is changed toggle the pins 3.if data is in check it. Code: | #define VER_MINOR 1
#define VER_MAJOR 'S' //Santana
#include <16F877A.h>
#device *=16
#fuses hs,nowdt,noprotect,nolvp,put
#use delay(clock=11059200)
#use rs232(baud=19200,xmit=PIN_E2,invert,stream=DEBUG)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,stream=PC) // Jumpers: 8 to 11, 7 to 1
#case
#zero_ram
//==============//
#define IDLE_TIMER 40
#bit CREN =0x18.4
//=== Prototypes ===//
void init(void);
void update_relays(int16 relay);
void check_data(void);
//=== Globals ===//
#define BUF_SZ 16
#define RXMASK BUF_SZ-1
int8 RX_BUF[BUF_SZ];//SAMPLE DATA AD1FFFF
int8 rx_indx_i,rx_indx_o;
int16 int_count_tmr2;
BOOLEAN idle_bus=FALSE;//flag for when usart is idle for 1sec with data ready
int8 ERRORS;
//=== MAIN ===//
void main(void)
{
int16 old_relay_value,relay;
init();
while(1){
if(relay!=old_relay_value){
old_relay_value=relay;
update_relays(relay);
}
if(idle_bus){//bus is idle and data is waiting
idle_bus=FALSE;
check_data();
}
}
}
void init(void){
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
set_tris_a(0xFF);set_tris_b(0xFF);set_tris_c(0xFF);set_tris_d(0xFF);set_tris_e(0xFF);
fprintf(DEBUG,"Ver. %C_%03u.c\n\r",VER_MAJOR,VER_MINOR);
setup_timer_2(T2_DIV_BY_16, 254,16);
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
}
void update_relays(int16 relay){
//relay is mapped to PIN_RD4,PIN_RD5,PIN_RD6,PIN_RD7,PIN_RA3,PIN_RA2,PIN_RA1,PIN_RA0
//PIN_RB0,PIN_RB1,PIN_RB2,PIN_RB3,PIN_RB4,PIN_RB5,PIN_RB6,PIN_RB7
if(bit_test(relay,0)) output_high(PIN_D4);//test bit 0
else output_low(PIN_D4);
if(bit_test(relay,1)) output_high(PIN_D5);//test bit 1
else output_low(PIN_D5);
if(bit_test(relay,2)) output_high(PIN_D6);//test bit 2 ...
else output_low(PIN_D6);
//. . . go through all pins
}
void check_data(void){
int8 x;
for (x=0;x<sizeof(RX_BUF);x++){
fprintf(DEBUG,"RX_BUF[%2i]=0x%X\n\r",x,RX_BUF[x]);
}
fprintf(DEBUG,"\n\r");
disable_interrupts(INT_RDA);
rx_indx_i=0;rx_indx_o=0;
enable_interrupts(INT_RDA);
}
//=======================RXisr============================//
//Takes RX data from a stream and puts it into a buffer via interrupts
#INT_RDA
void RXisr(void)
{
idle_bus=FALSE;
set_timer2(0);//reset countdown on each rx char
int_count_tmr2=IDLE_TIMER;
enable_interrupts(INT_TIMER2);//when you set a timer, turn on the INT
while(kbhit(PC)){
RX_BUF[rx_indx_i]=fgetc(PC);
rx_indx_i++;
rx_indx_i&=RXMASK;//index is allways 0 to 15
if (rx_indx_i==rx_indx_o) // check for buffer overflow
{
bit_set(ERRORS,2);//set error flag bit 2 for RXbuffer overflow
}
}
}
//========timer 2 ISR===============//
#int_timer2 // This function is called every time
void timer2_isr() { // timer 2 overflows (250->0), which is
if(--int_count_tmr2==0){
idle_bus=TRUE;//set flag
int_count_tmr2 = IDLE_TIMER;//reset count
disable_interrupts(INT_TIMER2);//dont need the timer now
}
}
|
Last edited by treitmey on Tue Dec 05, 2006 4:54 pm; edited 3 times in total |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Tue Dec 05, 2006 3:38 pm |
|
|
Thank treitmey
For taking the time to do this .
i very much appreciate it but i have not ran it yet i am still going through it line by line to understand how it works
i have got my c programming book out and i am really studying it through
i would get back to you with any questions
Thank Again _________________ BOB_Santana |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Tue Dec 05, 2006 3:59 pm |
|
|
The whole trick is that data is rx in the background. and a timmer tells us when it is ready. The only time data can be lost is the 4 inst
Quote: | disable_interrupts(INT_RDA);
rx_indx_i=0;rx_indx_o=0;
enable_interrupts(INT_RDA);
|
You can do whatever in the loop. lcd,math,delays,.. the data still gets in. |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Tue Dec 05, 2006 4:06 pm |
|
|
Hi treitmey
Why is there 2 rs232 defines
Code: |
#use rs232(baud=19200,xmit=PIN_E2,invert,stream=DEBUG,disable_ints)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,stream=PC) // Jumpers:
|
i am using 9600 @ 4Mhz can i change this to
Code: |
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS) // Jumpers: 8 to 11, 7 to 1
|
Also in the init()
should the ports not be set to outputs ?
_________________ BOB_Santana |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Tue Dec 05, 2006 4:24 pm |
|
|
This is great
the buffer is storing the the data when i changed my settings as below
Code: |
#fuses xt,nowdt,noprotect,nolvp,put
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_E2,invert,stream=DEBUG,disable_ints)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,stream=PC) // Jumpers: 8 to 11, 7 to 1
#case
|
_________________ BOB_Santana |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Tue Dec 05, 2006 4:40 pm |
|
|
I have 8 USB serial ports on my PC. 1- I use as debug doing the bit bang
at 19200 on pinE2. The other is standard through hardware USART of PIC and MAX232.
Thats why one says invert and one doesn't. Invert doesn't use the max232
Now add in some of the LCD stuff. remember not to use \b to clear the screen.
goto(0,0) and print 20 spaces.
Last edited by treitmey on Tue Dec 05, 2006 4:50 pm; edited 2 times in total |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Tue Dec 05, 2006 4:46 pm |
|
|
This is how i aim to be.
I would follow the way you layout your coding its so easy to read
now i know what you guys were talking about my coding
Thanks a lot
_________________ BOB_Santana |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Wed Dec 06, 2006 5:27 pm |
|
|
I have just being able to follow what is happening in the program
As i have being on the road all day .
i just need to pass my sorted out data to the update_relays() function
Also if you could be kind enough to explain the following line as i can't get my head around it.
Code: |
printf("RX_BUF[%2i]=0x%X\n\r",x,RX_BUF[x]);
|
which then leads to this question
i can see that the characters are stored in
which is a 16 character array
so in theory should i be able to display the array contents
with say
Code: |
printf("%c",RX_BUF[x]);
|
so i can print the chars to screen horizontal
but when i do that nothing is displayed on screen
but if i put a space like this
Code: | printf("%c ",RX_BUF[x]); |
It print ok but with the space between each like A D 1 F F F F
Am i doing somthing wrong
Regards _________________ BOB_Santana |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Wed Dec 06, 2006 6:02 pm |
|
|
..
Last edited by treitmey on Thu Dec 07, 2006 10:26 am; edited 1 time in total |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Wed Dec 06, 2006 6:20 pm |
|
|
Very Strange
it works with putc
_________________ BOB_Santana |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Dec 07, 2006 10:19 am |
|
|
I figured out your problem.
I was printing to DEBUG window((bit bang))
you printed to hardware and overflowed the TX register of the USART.
printing 1 at a time or with the space gave it idle time and thus didn't overflow.
You could also try tranmitting using an irq and then it won't overflow.
|
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Thu Dec 07, 2006 12:43 pm |
|
|
What do you mean by tranmitting using an irq? _________________ BOB_Santana |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Dec 07, 2006 1:01 pm |
|
|
int=interrupt, irq=interupt request(about the same), isr=interupt service routeen,(what to do when an interupt happens)
Read spec pdf page 101 section 10.2.1.
The hardware usart holds a byte or two and trickles bits out.
When this byte TXREG is empty it throws the IRQ INT_TBE.
sooo.
if you do more than 1 byte you overflow it. but if you add a new byte
every time INT_TBE happens you'll keep the data flowing.
I use two pieces of code. tx_buff OR tx_buffer to put data into a buffer.
and the ISR to trickle the data into TXREG ((fputc))
Code: | //=====================tx_buff======================//
//For transmitting data via USART and using interrupts
//must have #INT_TBE defined, takes a single char
void tx_buff(char data)
{
t_buf[t_i]=data;
t_i++; //increment the index
t_i &= TXMASK;
if(t_i==t_o) //if the indexs match we are full
{
bit_set(ERRORS,1);//set error flag bit 1 for tx overflow
//don't mess with indexs, overwritting oldest data in buf
}
enable_interrupts(INT_TBE);
}
//=====================tx_buffer======================//
//For transmitting data via USART and using interrupts
//must have #INT_TBE defined,takes a pointer to an array and its size
void tx_buffer(char *data,int8 size)
{
int8 x;
for (x=0;x<size;x++,data++)
{
t_buf[t_i] = *data;
t_i++; //increment the index
t_i &= TXMASK;
if(t_i==t_o) //if the indexs match we are full
{
bit_set(ERRORS,1);//set error flag bit 1 for tx overflow
//don't mess with indexs, overwritting oldest data in buf
}
}
enable_interrupts(INT_TBE);
}
//=======================TXisr============================//
//Takes data from buffer and puts it into a TX stream (PC)
//uses interrupts to empty buffer at proper rate
#int_tbe
void tx_isr(void)
{
fputc(t_buf[t_o],PC);
t_o++;
t_o &= TXMASK;
if(t_o==t_i)
{
disable_interrupts(INT_TBE);//nothing left to tx
}
}
|
Last edited by treitmey on Thu Dec 07, 2006 3:49 pm; edited 1 time in total |
|
|
BOB_SANTANA
Joined: 16 Oct 2006 Posts: 110 Location: HOVE, EAST SUSSEX
|
|
Posted: Thu Dec 07, 2006 3:25 pm |
|
|
treitmey
Thanks for the explaination
You have being a credit to the forum and a great help.
one day i would be able to do the same for someone else
Big Cheers _________________ BOB_Santana |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Thu Dec 07, 2006 7:23 pm |
|
|
Well let me comment
this is your code
Code: | printf("%c ",RX_BUF[x]); |
Now lookat this carefully and you'll see there is a space after %c
that means a space will be sent by printf so the output will be
ex a b c d e
To avoid the space just don't include it as follows
Code: |
printf("%c",RX_BUF[x]);
|
|
|
|
|
|
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
|