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

Need help with TRIS on Port C, PIC16F76

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
eyewonder300



Joined: 09 Jun 2004
Posts: 52

View user's profile Send private message

Need help with TRIS on Port C, PIC16F76
PostPosted: Sat Nov 29, 2014 4:03 pm     Reply with quote

I'm getting frustrated with not knowing how to toggle bits on Port C. Sure seems like a simple thing, but I can not make it work on Port C, but it DOES work on Port A.

Each Port A pin drives a FET, which turns on an LED.
All Port C pins have 10k pull-up to Vcc.

This test program will just turn on all LEDs, and drive low the even numbered Port C pins, and hold it for ~1 sec (so that I can scope out what's working & what's not), then it will turn off all the LEDs, and drive high the even numbered Port C pins.

Logic probe shows the even numbered Port C pins remain low all the time, the odd numbered ports are all high, but the LEDs driven by Port A are toggling, as expected

Compiler is 4.069
Using USB ICD-U40

Here is the simple prog & headers.
Cheers,
Steve

Code:

#include "X:\CCS_Projects\CAT5_Cable_Tester\NET_TST.h"

void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);

   set_tris_A(0x00);       // All bits OUTPUTS, to drive LEDs
   set_tris_c(0b10101010);    //bits 0, 2, 4, 6 as outputs, bits 1, 3, 5, 7 inputs   
   
   while (1==1)
      {
   Failed_LED_On;             // Port A.0 drives a FET, turning on LED   
   Straight_LED_On;           // ""
   Crossed_LED_On;            // ""
   Unplugged_LED_On;          // ""
   output_bit(white_green,0);    // ALL Port C pins have 10k pullups
   output_bit(white_orange,0);
   output_bit(white_blue,0);
   output_bit(white_brown,0);
   delay_ms(100);
     
   Failed_LED_Off;       
   Straight_LED_Off;
   Crossed_LED_Off;     
   Unplugged_LED_Off;
   output_bit(white_green,1);
   output_bit(white_orange,1);
   output_bit(white_blue,1);
   output_bit(white_brown,1);
   delay_ms(100);
      }
   
 
}



Code:

#include <16F76.h>
#device *=16
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected

#use delay(clock=10000000,RESTART_WDT)


//--------- Port register defines/usage
// Port A bits turn on the status LED's
#bit Unplugged_LED   =  5.0      //Port A, bit 0
#bit Failed_LED      =  5.1      //Port A, bit 1
#bit Straight_LED    =  5.2      //Port A, bit 2
#bit Crossed_LED     =  5.3      //Port A, bit 3


#define Failed_LED_On         Failed_LED = 1
#define Failed_LED_Off        Failed_LED = 0
#define Straight_LED_On       Straight_LED = 1
#define Straight_LED_Off      Straight_LED = 0
#define Crossed_LED_On        Crossed_LED = 1
#define Crossed_LED_Off       Crossed_LED = 0
#define Unplugged_LED_On      Unplugged_LED = 1
#define Unplugged_LED_Off     Unplugged_LED = 0


// Port C bits used to both drive & read lines of cable
// All lines have 47k-ohm pull-up resistors

#byte Cable_Data = 7             //Port C

#bit White_Green     =  7.0      //Port C, bit 0
#bit Green           =  7.1      //Port C, bit 1
#bit White_Orange    =  7.2      //Port C, bit 2
#bit Blue            =  7.3      //Port C, bit 3
#bit White_Blue      =  7.4      //Port C, bit 4
#bit Orange          =  7.5      //Port C, bit 5
#bit White_Brown     =  7.6      //Port C, bit 6
#bit Brown           =  7.7      //Port C, bit 7
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Nov 29, 2014 9:08 pm     Reply with quote

Quote:
#bit White_Green = 7.0 //Port C, bit 0

output_bit(white_green, 0);


You are giving the output_bit() function an invalid value for the first
parameter. It must be a CCS pin number.

Here is the CCS manual section:
Quote:
output_bit( )

Syntax:
output_bit (pin, value)

Parameters: Pins are defined in the devices .h file. The actual number is a bit address. For example, port a (byte 5 ) bit 3 would have a value of 5*8+3 or 43 . This is defined as follows: #define PIN_A3 43 . The PIN could also be a variable. The variable must have a value equal to one of the constants (like PIN_A1) to work properly. The tristate register is updated unless the FAST_IO mode is set on port A. Note that doing I/O with a variable instead of a constant will take much longer time.
eyewonder300



Joined: 09 Jun 2004
Posts: 52

View user's profile Send private message

Success
PostPosted: Sun Nov 30, 2014 8:13 am     Reply with quote

Thanks PCM. As expected it was a simple answer - once I recognized it.

Cheers,
Steve
muhibraza1



Joined: 26 Jul 2013
Posts: 23

View user's profile Send private message

PostPosted: Tue Dec 02, 2014 12:29 am     Reply with quote

Also consider the read-modify-write problem.

here's the reference manual for I/O ports :
http://ww1.microchip.com/downloads/en/DeviceDoc/31009a.pdf

take a look on the I/O Programming Considerations, Initialization and Design Tips sections.
_________________
PCWHD Compiler v4.124
ICD U-64 Hardware Rev 2 & 3
CCSLOAD 4.053
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Dec 02, 2014 4:16 am     Reply with quote

I assume you're familiar with some other version of C for the PICs or with assembler. CCS C has a much simpler syntax and provides much more support than most other PIC Cs. Due to this, there are a number of points to think about:

CCS C provides port direction management by default. TRIS won't work out of the box, you have to use fast_io. As you don't specify fast_io in your code, your set_tris_x() calls are redundant and won't do anything. They should be simply deleted. The direction of each IO pin will automatically be set when they are used.

In general, try not to think "how do I translate what I used to do into CCS?", but instead try to learn the CCS way. Its far simpler and easy to learn, but you need to drop some "old ways".

As you've been told, you should be using the CCS defined pin constants:

Code:

//--------- I/O Pin defines/usage
// Port A bits turn on the status LED's
#define Unplugged_LED   PIN_A0
#define Failed_LED      PIN_A1
#define Straight_LED    PIN_A2      //Port A, bit 2
#define Crossed_LED     PIN_A3      //Port A, bit 3


Port register addresses change from device to device. Using the CCS pin defines is more portable than specifying addresses. If you really want to use a port address and #bit then use getenv(), which also comparitively portable. #bit is rarely used for port IO in CCS C.

output_bit() is rarely used and is slow. Its only used when the bit value really has to be a variable. Instead, whenever the value is a constant, as in your posted code, use output_low() or output_high() as appropriate. Even when the value is a variable its often better to use an if to select the relevant constant version:

Code:

if (Bit_Value)
{
   output_high(Failed_LED);
}
else
{
   output_low(Failed_LED);
}


CCS C provides defines for TRUE and FALSE, and a boolean type. It's generally more readable to use these in place of 1 and 0.

Using defines to replace C code is usually considered a "obfuscation" tactic as it makes the code more difficult to understand. Where the idea is to abstract the function from the implementation - for example to simplify inverted logic and sequences of statement to achieve one action, e.g. setting SPI DACs to a voltage - then personally I prefer to use abstraction routines: simple routines, possibly defined as in-line. Doing it in macros (defines) is often not a great idea.

The 16F76 is one of the oldest PICs still generally available. There are plenty of newer ones with much better performance, more peripherals and memory and at lower cost. The 16F76 is fine if its all you've got, but there are other, far better PICs out there.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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