| View previous topic :: View next topic | 
	
	
		| Author | Message | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				| Writing variable Port Pins with one statement |  
				|  Posted: Mon Apr 14, 2008 11:57 pm |   |  
				| 
 |  
				| Hello, 
 how can I write on variable Port Pins with one statement.
 E.g. I use PortA0..3, PortB0..3 on a PIC. Now I will write these ports with one 8bit value like: PortAB=0xFF (PortA0..3 is the high nibble, PortB0..3 the low nibble). The problem is that I have to change the value of this "PortAB" very often and setting every port discrete is not very nice.
 
 How can I do this?
 
 Best Regards
 
 Olaf
 
 Edit:
 Compiler PCM 3.223
 MPlab 8.02
 |  | 
	
		|  | 
	
		| crystal_lattice 
 
 
 Joined: 13 Jun 2006
 Posts: 164
 
 
 
			    
 
 | 
			
				| Something like this?? |  
				|  Posted: Tue Apr 15, 2008 12:44 am |   |  
				| 
 |  
				|  	  | Code: |  	  | Output_AB(int8 byte)
 {
 output_a((byte << 4));
 output_b((byte >> 4));
 }
 
 | 
 |  | 
	
		|  | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Apr 15, 2008 4:46 am |   |  
				| 
 |  
				| Hello, 
 I think it’s just the opposite.
 I want a variable called PortAB (e.g. char).
 
 If I write:
 
 PortAB=0xFF;
 
 PortA should be 0x0F (PortPinA0..3=1)
 PortB should be 0x0F (PortPinB0..3=1)
 
 
 Olaf
 |  | 
	
		|  | 
	
		| sohailkhanonline 
 
 
 Joined: 06 Mar 2008
 Posts: 35
 Location: pakistan
 
 
			          
 
 | 
			
				| Re: Something like this?? |  
				|  Posted: Tue Apr 15, 2008 5:07 am |   |  
				| 
 |  
				|  	  | crystal_lattice wrote: |  	  |  	  | Code: |  	  | Output_AB(int8 byte)
 {
 output_a((byte << 4));
 output_b((byte >> 4));
 }
 
 | 
 | 
 can you explain it please.
 
  |  | 
	
		|  | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Apr 15, 2008 6:17 am |   |  
				| 
 |  
				| I think the question was easy to misunderstand. I want to define a variable with different ports. It wasn't good to define it with two Ports with increasing Pin-Numbers. 
 
 I think it should be like this
 
 
  	  | Code: |  	  | char ISR_Flags=0x00;
 #Locate ISR_Flags = 0x00A0
 #bit INTF_START = ISR_FLAGS.0
 #bit INTF_RB = ISR_FLAGS.1
 #bit INTF_DATOK = ISR_FLAGS.2
 #bit INTF_Light = ISR_FLAGS.3
 #bit INTF_TMREND = ISR_FLAGS.4
 
 | 
 
 Can I do similar things with the port.
 For example
 
  	  | Code: |  	  | char PortAB=0x00;
 #bit Enable=PortA.0
 #bit Disable=PortA.1
 #bit Data_0=PortA.2
 #bit Data_1=PortA.3
 #bit Data_2=PortA.4
 #bit Data_3=PortB.2
 #bit Data_4=PortB.4
 #bit Read_Write=PortC.1
 
 | 
 
 Or how do I have to do it
 
 Best Regards
 
 Olaf
 |  | 
	
		|  | 
	
		| ckielstra 
 
 
 Joined: 18 Mar 2004
 Posts: 3680
 Location: The Netherlands
 
 
			    
 
 |  | 
	
		|  | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Apr 15, 2008 11:36 am |   |  
				| 
 |  
				| Hi, 
 I tried the following
 
 PIN-Description in the header-file
 
  	  | Code: |  	  | #define LCD_DB0   PIN_A0
 #define LCD_DB1   PIN_A1
 #define LCD_DB2   PIN_A2
 #define LCD_DB3   PIN_A3
 #define LCD_DB4   PIN_A4
 #define LCD_DB5   PIN_A5
 #define LCD_DB6   PIN_C0
 #define LCD_DB7   PIN_C1
 
 | 
 
 in the *.c I defined the databyte
 
  	  | Code: |  	  | #define databyte(x) \
 LCD_DB0 = x & 1; \
 LCD_DB1 = (x >> 1) & 1; \
 LCD_DB2 = (x >> 2) & 1; \
 LCD_DB3 = (x >> 3) & 1; \
 LCD_DB4 = (x >> 4) & 1; \
 LCD_DB5 = (x >> 5) & 1; \
 LCD_DB6 = (x >> 6) & 1; \
 LCD_DB7 = (x >> 7) & 1;
 
 | 
 
 then I want to set the databyte with the new value.
 
 
 but if I compile the program I get the following error message 8 times. I think for every statement below the "#define databyte"
 
 Expecting LVALUE such as a variable name  or  * expression
 
 |  | 
	
		|  | 
	
		| crystal_lattice 
 
 
 Joined: 13 Jun 2006
 Posts: 164
 
 
 
			    
 
 | 
			
				| Spliting bytes |  
				|  Posted: Tue Apr 15, 2008 12:02 pm |   |  
				| 
 |  
				| There are many ways of doing this i suppose but this is what i came up with given limited free time... 
 
 
 [/code] 	  | Code: |  	  | Port_AB(int8 byte)   //you can call this function anything you like
 {
 output_a(byte && 0x0f));   //Mask the nibble on LSB side to get a output of 0000XXXX and ignore the high nibble
 output_b((byte >> 4));     //Shift the MSB side nibble to the LSB side
 }
 
 // to use the function
 
 Port_AB(0xff);
 
 //or
 
 Port_AB(any_int8_variable);
 
 | 
 |  | 
	
		|  | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Apr 15, 2008 12:22 pm |   |  
				| 
 |  
				| Thanks, 
 but with this code I have the problem, that output_b() sets the whole output. But the other pins of the output should be unchanged.
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Apr 15, 2008 12:48 pm |   |  
				| 
 |  
				| You can read the value of the port into a temporary variable, change the bits that you want to change, and then write the byte variable back
 to the port register.
 
 You didn't say what PIC you're using.   The 18F series have an important
 advantage over the 16F.  The 18F PICs have "Latch" registers for the
 i/o ports.   Example:  LATB is the latch register for Port B.
 The latch register isn't directly connected to the i/o pins, so when
 you do a read-modify-write operation on the Latch register, the value
 can't be corrupted due to whatever load you may have on the i/o pin.
 
 Read the LATB register into a temporary variable (int8) and modify the
 desired bits in it, and write the value back to the LATB register.  All of
 the PortB i/o pins will be updated at the same time.
 |  | 
	
		|  | 
	
		| ckielstra 
 
 
 Joined: 18 Mar 2004
 Posts: 3680
 Location: The Netherlands
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Apr 15, 2008 2:16 pm |   |  
				| 
 |  
				| Have a closer look at the code from the provided link, you didn't make an exact copy. The defined values PIN_xx are constants, you can't assign a value to a constant and that is why you got the error message. 	  | Quote: |  	  | but if I compile the program I get the following error message 8 times. I think for every statement below the "#define databyte" 
 Expecting LVALUE such as a variable name or * expression
 | 
 
 You could have written the code as:
  	  | Code: |  	  | // The addresses shown below are for a PIC18 processor. // PIC16 processors don't have a Latch register so you
 // will have to write directly to the Port registers
 // running into the risk of the read-modify-write problem.
 #byte LATA = 0xF89
 #byte LATC = 0xF8B
 
 // Define the bit addresses of the spare pins.
 #bit LCD_DB0 = LATA.0
 #bit LCD_DB1 = LATA.1
 #bit LCD_DB2 = LATA.2
 #bit LCD_DB3 = LATA.3
 #bit LCD_DB4 = LATA.4
 #bit LCD_DB5 = LATA.5
 #bit LCD_DB6 = LATC.0
 #bit LCD_DB7 = LATC.1
 
 
 #define databyte(x) \
 LCD_DB0 = x & 1; \
 LCD_DB1 = (x >> 1) & 1; \
 LCD_DB2 = (x >> 2) & 1; \
 LCD_DB3 = (x >> 3) & 1; \
 LCD_DB4 = (x >> 4) & 1; \
 LCD_DB5 = (x >> 5) & 1; \
 LCD_DB6 = (x >> 6) & 1; \
 LCD_DB7 = (x >> 7) & 1;
 | 
 |  | 
	
		|  | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2008 1:24 pm |   |  
				| 
 |  
				| Hi again, 
 I use a 16F873A. I had a look at the flex_lcd
 I think the following code fragment defines the output-data
 
  	  | Code: |  	  | struct lcd_pin_map
 {
 BOOLEAN dummy;      // PinA0 is not used
 BOOLEAN enable;     // PinA1
 BOOLEAN rw;         // PinA2
 BOOLEAN rs;         // PinA3
 int unusedA  : 4;   // The rest of portA
 int unusedB;        // portB is not used
 int unusedC;        // portC is not used
 int     data : 4;   // lower nibble of portD is used for data lines
 int unusedD  : 4;   // The rest of portD
 } lcd;
 
 | 
 
 But how is the port defined? I do not see how the ports are set to the variables.
  Where is the statement that PINA1 is "enable"? In the header-file is the statement for PIN_A0 as follows. 
 
 How is this made in the struct?
 
 Olaf
 |  | 
	
		|  | 
	
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2008 1:31 pm |   |  
				| 
 |  
				| That code is from Mark's lcd driver in the Code Library, here: http://www.ccsinfo.com/forum/viewtopic.php?t=20182
 
 
 
  	  | Quote: |  	  | But how is the port defined? I do not see how the ports are set to the variables. | 
 Look at the #locate statements below the structure, as shown in bold
 below.  That's where it's done.
 
  	  | Quote: |  	  | struct lcd_pin_map {
 BOOLEAN dummy;      // PinA0 is not used
 BOOLEAN enable;     // PinA1
 BOOLEAN rw;         // PinA2
 BOOLEAN rs;         // PinA3
 int unusedA  : 4;   // The rest of portA
 int unusedB;        // portB is not used
 int unusedC;        // portC is not used
 int     data : 4;   // lower nibble of portD is used for data lines
 int unusedD  : 4;   // The rest of portD
 } lcd;
 #if defined(__PCH__)
 #locate lcd = 0xF80
 #else
 #locate lcd = 5
 #endif
 | 
 
 
  	  | Quote: |  	  | Where is the statement that PIN A1 is "enable"? | 
 The structure base addresses is set to the register address of Port A. So
 the first byte in the structure is for Port A, the next byte is for Port B, etc.
 A "boolean" is a bit.  The first bit, "dummy", is for bit 0 of port A.  The
 next one, "enable", is for bit 1 of Port A, and so on.
 |  | 
	
		|  | 
	
		| _olaf_ 
 
 
 Joined: 24 Feb 2005
 Posts: 32
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 16, 2008 11:45 pm |   |  
				| 
 |  
				| Just to say it with my own words. It is the same as I do it with my ISR_Flags? 
  	  | Code: |  	  | char ISR_Flags=0x00;
 #Locate ISR_Flags = 0x00A0
 #bit INTF_START = ISR_FLAGS.0
 #bit INTF_RB = ISR_FLAGS.1
 #bit INTF_DATOK = ISR_FLAGS.2
 #bit INTF_Light = ISR_FLAGS.3
 #bit INTF_TMREND = ISR_FLAGS.4
 
 | 
 
 for the 16F873 I have to locate the struct in the first PORT Address (0x05). The used bit address range of each Port is 8Bit. If I start with Port_A. I define the 6 Port_A Bit (A0..A5) and then 2 unused bits. And then continuing with Port_B... .
 
 Olaf
 |  | 
	
		|  | 
	
		|  |