CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

BOB_SANTANA program
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

BOB_SANTANA program
PostPosted: Tue Dec 05, 2006 3:12 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 05, 2006 3:38 pm     Reply with quote

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 Smile
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Dec 05, 2006 3:59 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 05, 2006 4:06 pm     Reply with quote

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 ?


Question
_________________
BOB_Santana Smile
BOB_SANTANA



Joined: 16 Oct 2006
Posts: 110
Location: HOVE, EAST SUSSEX

View user's profile Send private message

PostPosted: Tue Dec 05, 2006 4:24 pm     Reply with quote

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 Smile
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Tue Dec 05, 2006 4:40 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 05, 2006 4:46 pm     Reply with quote

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

Very Happy
_________________
BOB_Santana Smile
BOB_SANTANA



Joined: 16 Oct 2006
Posts: 110
Location: HOVE, EAST SUSSEX

View user's profile Send private message

PostPosted: Wed Dec 06, 2006 5:27 pm     Reply with quote

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
Code:

RX_BUF[BUF_SZ]


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 Smile
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Wed Dec 06, 2006 6:02 pm     Reply with quote

..

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

View user's profile Send private message

PostPosted: Wed Dec 06, 2006 6:20 pm     Reply with quote

Very Strange

it works with putc

Code:

 putc(RX_BUF[x]);

_________________
BOB_Santana Smile
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Dec 07, 2006 10:19 am     Reply with quote

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.
Very Happy
BOB_SANTANA



Joined: 16 Oct 2006
Posts: 110
Location: HOVE, EAST SUSSEX

View user's profile Send private message

PostPosted: Thu Dec 07, 2006 12:43 pm     Reply with quote

What do you mean by tranmitting using an irq?
_________________
BOB_Santana Smile
treitmey



Joined: 23 Jan 2004
Posts: 1094
Location: Appleton,WI USA

View user's profile Send private message Visit poster's website

PostPosted: Thu Dec 07, 2006 1:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Dec 07, 2006 3:25 pm     Reply with quote

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 Smile
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Dec 07, 2006 7:23 pm     Reply with quote

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]);
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
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