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