Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to do this in CCS PICC ?

Status
Not open for further replies.

Okada

Banned
Joined
Jun 16, 2016
Messages
1,159
Helped
129
Reputation
252
Reaction score
129
Trophy points
63
Activity points
0
How to do this in CCS PICC ?

Code:
PORTC = (PORTC & 0x04) | digits[0];
 

Didn't work with CCS ? What error compiler issued ?
The above construcs sounds somewhat standard ANSI C.
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
It is underlining that line in RED and it gives error related to PORTC.
 

Ok, perhaps there should have a better way to do that with a single step, but an alternative is to create a variable to store the actual state of the port, such as :

Code:
PORTC = (PORTC & 0x04) | digits[0];

output_c (  PORTC  ) ;

You have to check if the 'PORTC' variable is already defined somewhere in the .h files, otherwise change it to another name.
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
The general answer is: Read the CCS C user manual.

CCS is using built-in functions to access the ports. You can either use it, or define PORTC and similar missing symbols yourself. CCS C has a feature to make an include file with all or only selected SFR symbols, under View/Registers/Make Include File.

Code:
#byte PORTC = 0xF82
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
I have to use

Code:
#byte PORTC = 0x08

???

PORTC address for PIC16F527 is 0x08 datasheet page no.17.

How to do this
Code:
PORTB.6 = (digits[0] & 0x04) >> 2;


I am getting not enough RAM error.

How much ROM and RAM PIC16F527 has ? 2048 bytes ROM and 68 bytes RAM ?

Page no. 9 of datasheet tells 1024 words ROM = 2048 bytes ROM ?

What is 64 bytes Flash bytes ?

This is the code I am porting. It is written by me. It didn't compile in MPLAB X XC8.

Code:
#define _XTAL_FREQ 4000000UL

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>

#pragma config FOSC = INTRC_IO      // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF           // Watchdog Timer Enable bit (WDT disabled)
#pragma config MCLRE = OFF          // Master Clear Enable bit (MCLR disabled)
#pragma config IOSCFS = 4MHz        // Internal Oscillator 4 MHz
#pragma config BOREN = ON           // Brown-out Reset Enable bit (BOR disabled)
#pragma config CPSW = OFF           // Code Protection Self Write disabled
#pragma config DRTEN = OFF          // Device Reset Timer Enable (disabled)
#pragma config CP = ON              // Flash Program Memory Code Protection bit (Code protection off)

#define SSD_DATA_PORT    PORTC

#define OPAMP_OUTPUT 0

#define DECIMAL_POINT_MASK 0x80

#define ON    1
#define OFF   0

#define SET   1
#define CLEAR 0

#define TRUE  1
#define FALSE 0

bit run_once_flag = 0;
unsigned char digit = 0;
unsigned char digits[3] = {0, 0, 0};
double raw_adc_value = 0;

const unsigned char cc_mask[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};

void InitTimer0(void);
void Get_Mask(double fpNum);

//Timer0
//Prescaler 1:8; TMR0 Preload = 6; Actual Interrupt Time : 2 ms
//Place/Copy this part in declaration section
void InitTimer0(void) {
    OPTION = 0x82;
    TMR0 = 6;
    INTCON0 = 0x01;
}
 
void interrupt isr(void) {
    if(INTCON0bits.T0IF) {
        //Enter your code here
        SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | 0xFF;
        PORTBbits.RB6 = 1;
        PORTAbits.RA1 = 1;
        PORTAbits.RA2 = 1;
        PORTBbits.RB7 = 1;

        switch(digit) {
             case 0:
                  SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[0];
                  PORTBbits.RB6 = (digits[0] & 0x04) >> 2;
                  PORTAbits.RA1 = 0;
                  break;
             case 1:
                  SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[1];
                  PORTBbits.RB6 = (digits[1] & 0x04) >> 2;
                  PORTAbits.RA2 = 0;
                  break;
             case 2:
                  SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[2];
                  PORTBbits.RB6 = (digits[2] & 0x04) >> 2;
                  PORTBbits.RB7 = 0;
                  break;
        };

        if(++digit == 3) {
            digit = 0;
        }

        INTCON0bits.T0IF = 0;
        TMR0 = 6;
    }
}

unsigned char ADC_Read(unsigned char channel) {
    if(channel > 7)              //Channel range is 0 ~ 7
        return 0;

    ADCON0 &= 0xC5;              //Clearing channel selection bits
    ADCON0 |= channel<<3;        //Setting channel selection bits
    __delay_ms(2);               //Acquisition time to charge hold capacitor
    GO_nDONE = 1;                //Initializes A/D conversion
    while(GO_nDONE);             //Waiting for conversion to complete
    
    return ADRES;                //Return result
}

void Get_Mask(double fpNum) {    
    unsigned char whole_num = 0, fraction = 0;
    double f_fraction = 0.0;
    
    if((fpNum >= 0.0) && (fpNum < 1.0)) {
        f_fraction = (unsigned char)fpNum * 100.0;
        fraction = (unsigned char)f_fraction;
                  
        digits[0] = cc_mask[0] | DECIMAL_POINT_MASK;
        digits[1] = cc_mask[fraction / 10];
        digits[2] = cc_mask[fraction % 10];
    }
    else if((fpNum >= 1.0) && (fpNum < 10.0)) {
        whole_num = (unsigned char)fpNum;
        f_fraction = (fpNum * 100.0) - (whole_num * 100.0);
        fraction = (unsigned char)f_fraction;
                  
        digits[0] = cc_mask[whole_num] | DECIMAL_POINT_MASK;
        digits[1] = cc_mask[fraction / 10];
        digits[2] = cc_mask[fraction % 10];
    }
    else if((fpNum >= 10.0) && (fpNum < 100.0)) {
        whole_num = (unsigned char)fpNum;
        f_fraction = (fpNum * 10.0) - (whole_num * 10.0);
        fraction = (unsigned char)f_fraction;
                  
        digits[0] = cc_mask[whole_num / 10];
        digits[1] = cc_mask[whole_num % 10] | DECIMAL_POINT_MASK;
        digits[2] = cc_mask[fraction];
    }
    else if((fpNum >= 100.0) && (fpNum < 1000.0)) {
        whole_num = (unsigned char)fpNum;
                  
        digits[0] = cc_mask[whole_num / 100];
        digits[1] = cc_mask[(whole_num / 10) % 10];
        digits[2] = cc_mask[whole_num % 10];
    }        
}

int main(void) {
    
    CM1CON0 = 0x00;
    CM2CON0 = 0x00;
    
    ANSEL = 0x01;
    ADCON0 = 0x00;
    
    TRISA = 0x01;
    TRISB = 0x30;
    TRISC = 0x00;
    
    PORTA = 0x06;
    PORTB = 0x80;
    PORTC = 0x00;
    
    __delay_ms(200);
    
    OPACON = 0x01;
    
    InitTimer0();

    while(1) {

        raw_adc_value = (double)ADC_Read(OPAMP_OUTPUT) * 150.0 / 255.0;
        __delay_ms(5);
                                                                 
        Get_Mask(raw_adc_value);

        if(run_once_flag == 0) {
            INTCON1bits.T0IE = 1;
            run_once_flag = 1;
        }              
             
    }
    
    return (0);
}

This is the CCS PICC Code

Code:
#include <main.h>

#byte PORTC = 0x08

#define OPAMP_OUTPUT 0
#define DECIMAL_POINT_MASK 0x80

unsigned char run_once_flag = 0;
unsigned char digit = 0;
unsigned char digits[3] = {0, 0, 0};
double raw_adc_value = 0;
const unsigned char cc_mask[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};

void Get_Mask(double fpNum);

#int_timer0  
void TIMER0_isr() { 
   
   //Enter your code here
   output_c((PORTC & 0x04) | 0xFF);
   output_high(PIN_B6);
   output_high(PIN_A1);
   output_high(PIN_A2);
   output_high(PIN_B7);
   
   switch(digit) {
        case 0:
              output_c((portc & 0x04) | digits[0]);
              //PORTB.6 = (digits[0] & 0x04) >> 2;
              output_low(PIN_A1);
              break;
        case 1:
              output_c((portc & 0x04) | digits[1]);
              //PORTB.6 = (digits[1] & 0x04) >> 2;
              output_low(PIN_A2);
              break;
        case 2:
              output_c((portc & 0x04) | digits[2]);
              //PORTB.6 = (digits[2] & 0x04) >> 2;
              output_low(PIN_B7);
              break;
        };

        if(++digit == 3) {
            digit = 0;
        }

        clear_interrupt(INT_TIMER0);   
}


void Get_Mask(double fpNum) {    
    unsigned char whole_num = 0, fraction = 0;
    double f_fraction = 0.0;
    
    if((fpNum >= 0.0) && (fpNum < 1.0)) {
        f_fraction = (unsigned char)fpNum * 100.0;
        fraction = (unsigned char)f_fraction;
                  
        digits[0] = cc_mask[0] | DECIMAL_POINT_MASK;
        digits[1] = cc_mask[fraction / 10];
        digits[2] = cc_mask[fraction % 10];
    }
    else if((fpNum >= 1.0) && (fpNum < 10.0)) {
        whole_num = (unsigned char)fpNum;
        f_fraction = (fpNum * 100.0) - (whole_num * 100.0);
        fraction = (unsigned char)f_fraction;
                  
        digits[0] = cc_mask[whole_num] | DECIMAL_POINT_MASK;
        digits[1] = cc_mask[fraction / 10];
        digits[2] = cc_mask[fraction % 10];
    }
    else if((fpNum >= 10.0) && (fpNum < 100.0)) {
        whole_num = (unsigned char)fpNum;
        f_fraction = (fpNum * 10.0) - (whole_num * 10.0);
        fraction = (unsigned char)f_fraction;
                  
        digits[0] = cc_mask[whole_num / 10];
        digits[1] = cc_mask[whole_num % 10] | DECIMAL_POINT_MASK;
        digits[2] = cc_mask[fraction];
    }
    else if((fpNum >= 100.0) && (fpNum < 1000.0)) {
        whole_num = (unsigned char)fpNum;
                  
        digits[0] = cc_mask[whole_num / 100];
        digits[1] = cc_mask[(whole_num / 10) % 10];
        digits[2] = cc_mask[whole_num % 10];
    }        
}
 
void main() {

   setup_comparator(NC_NC_NC_NC);
       
   setup_adc_ports(sAN0);
   setup_adc(ADC_CLOCK_INTERNAL);
    
   set_tris_a(0x01);
   set_tris_b(0x30);
   set_tris_c(0x00);
   
   output_a(0x06);
   output_b(0x80);
   output_c(0x00);
   
   delay_ms(200);
   
   setup_opamp1(OPAMP_ENABLED);
   
   setup_timer_0(T0_INTERNAL | T0_DIV_8 | T0_8_BIT);
   
   while(TRUE) {
   
      //TODO: User Code
      raw_adc_value = (double)read_adc(OPAMP_OUTPUT) * 150.0 / 255.0;
      delay_ms(5);
                                                                 
      Get_Mask(raw_adc_value);

      if(run_once_flag == 0) {
            enable_interrupts(INT_TIMER0);
            run_once_flag = 1;
      }
   }
}
 
Last edited:

#byte PORTC = 0x08

Should be better you think about something like that, which turns the code portable to any other PIC micro which has the same port but mapped into another address:

Code:
#byte PORTC = getenv("sfr:PORTC ")
 
  • Like
Reactions: Okada

    Okada

    Points: 2
    Helpful Answer Positive Rating
I am confused by what exactly is your question. In the original post you ask about using the CCS compiler but the code you mention that does not compile in post #6 is for the XC8 compiler.
The code example you provide in the first post uses code from the XC8 version! There is no reason it should not compile.
You mention that the code is underlined in red. I assume this is within the IDE (the compiler itself does not report errors this way) and possibly MPLAB(x). If so then this could well be a long-standing problem with the MPLAB(x) IDEs in that they underline code that is not actually faulty as they use their own parsers (that supposedly allow for badly defined code and consequential errors).
The real test is whether the compiler throws up an error or warning.
It seems to me that you need to solve the actual problem you have (and not told us - all you have said is that it does not compile but not told us the error on the offending line of code) rather than complicating things by switching compilers.

Looking at your code in the ISR where the problematic code lies, I'm wondering how it can work the way you think it will.
Given the line:
Code:
    SSD_DATA_PORT = (SSD_DATA_PORT * 0x04) | 0xff;
this will always set all bits of SSD_DATA_PORT (or PORTC) on because of the 'bit-wise or'ing with 0xff. The part on the left of the 'bit-wise or' will effectively be ignored.
Later on in the switch statements you have similar code to:
Code:
    SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[0];
As any of the 'case' statements must follow the first one (that has SSD_DATA_PORT with all bits set), you could replace this with
Code:
    SSD_DATA_PORT = 0x04 | digits[0];
None of your code uses anything defined in the 'stdio' and 'stdlib' includes and these can be removed (as they are almost never needed for embedded systems).
Susan
 

Hello,
I couldn't see the pic16f527.h and pic16f527_registers.h in your codes.
(The second one, you should generate in the Ccs c ide, with the name you will give). The portc etc. are defined in one of these.
 

Thank you andre_teprom.

@Aussie Susan

The original code was written for PIC16F1708 using mikroC PRO PIC and for Common Cathode Display. I had to port it for PIC16F527 and I admit I made some mistake in the ISR code used for display because Proteus and mikroC PRO PIC doesn't support PIC16F527 and I was not provided the hardware for testing.

I now made a code for PIC16F1708 using mikroC PRO PIC and for Common Anode Display (required) and it is working fine. The project is attached.
In Circuit R8, R10 and R12 are only for Simulation.

This code I have to port to PIC16F527. As mikroC doesn't support PIC16F527 yet I have to use XC8 or CCS PICC to port it. I tried both XC8 and CCS PICC but it is telling "Not Sufficient RAM".

I don't know what is consuming so much RAM. PIC16F527 has 68 bytes of RAM.

I couldn't see the pic16f527.h and pic16f527_registers.h in your codes.

I have to admit that I have not used CCS PICC much and hence I am not familiar with it. I mainly use mikroC PRO PIC.

Here are the contents of main.h file of CCS PICC project.

Code:
#include <16F527.h>
#device ADC=8

#FUSES NOWDT                      //Watch Dog Timer

#use delay(crystal=4000000)
#use FIXED_IO( A_outputs=PIN_A2,PIN_A1 )
#use FIXED_IO( B_outputs=PIN_B7,PIN_B6 )
#use FIXED_IO( C_outputs=PIN_C7,PIN_C6,PIN_C5,PIN_C4,PIN_C3,PIN_C2,PIN_C1,PIN_C0 )


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#define SSD_DATA_PORT      LATC
#define OPAMP_OUTPUT          0
#define DECIMAL_POINT_MASK 0x7F
 
const unsigned char ca_mask[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
unsigned char myFlags = 0;
unsigned char digit = 0;
unsigned char digits[3] = {0, 0, 0};
unsigned int whole_num = 0, fraction = 0;
double f_fraction = 0.0;
double raw_adc_value = 0.0, previous_raw_adc_value = -1.0;
 
sbit run_once_flag at myFlags.B0;
 
//Timer1
//Prescaler 1:1; TMR1 Preload = 63536; Actual Interrupt Time : 2 ms
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0xF8;
    TMR1L = 0x30;
    INTCON = 0xC0;
}
 
void interrupt() {
    if(TMR1IF_bit) {
        //Enter your code here
        //SSD_DATA_PORT = (SSD_DATA_PORT | 0x04) & 0xFB;
        LATA.F1 = 1;
        LATA.F2 = 1;
        LATB.F7 = 1;
 
        switch(digit) {
             case 0:
                  //SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[0];
                  SSD_DATA_PORT = digits[0];
                  LATB.F6 = (digits[0] & 0x04) >> 2;
                  LATA.F1 = 0;
                  break;
             case 1:
                  //SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[1];
                  SSD_DATA_PORT = digits[1];
                  LATB.F6 = (digits[1] & 0x04) >> 2;
                  LATA.F2 = 0;
                  break;
             case 2:
                  //SSD_DATA_PORT = (SSD_DATA_PORT & 0x04) | digits[2];
                  SSD_DATA_PORT = digits[2];
                  LATB.F6 = (digits[2] & 0x04) >> 2;
                  LATB.F7 = 0;
                  break;
        };
 
        if(++digit >= 3) {
            digit = 0;
        }
 
        TMR1IF_bit = 0;
        TMR1H = 0xF8;
        TMR1L = 0x30;
    }
}
 
void main() {
 
    //OPTION_REG = 0x8F;
    asm clrwdt
 
    CM1CON0 = 0x00;
    CM2CON0 = 0x00;
 
    ANSELA = 0x01;
    ANSELB = 0x00;
    ANSELC = 0x00;
    
    ADCON1 = 0b11010000;
    ADCON2 = 0x00;
 
    TRISA = 0x01;
    TRISB = 0x30;
    TRISC = 0x00;
 
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    
    LATA = 0x06;
    LATB = 0x80;
    LATC = 0xFB;
    
    asm clrwdt
    Delay_ms(200);
    asm clrwdt
    
    OPA1CON = 0xC0;
    OPA2CON = 0x00;
    
    InitTimer1();
 
    while(1) {
 
          asm clrwdt
          raw_adc_value = ADC_Read(OPAMP_OUTPUT) * 150.0 / 1023.0;
          Delay_ms(5);
          
          if(previous_raw_adc_value != raw_adc_value) {
              if((raw_adc_value >= 0.0) && (raw_adc_value < 1.0)) {
                  f_fraction = (unsigned int)raw_adc_value * 100.0;
                  fraction = (unsigned int)f_fraction;
                  asm clrwdt
                  digits[0] = ca_mask[0] & DECIMAL_POINT_MASK;
                  digits[1] = ca_mask[fraction / 10];
                  digits[2] = ca_mask[fraction % 10];
              }
              else if((raw_adc_value >= 1.0) && (raw_adc_value < 10.0)) {
                  whole_num = (unsigned int)raw_adc_value;
                  f_fraction = (raw_adc_value * 100.0) - (whole_num * 100.0);
                  fraction = (unsigned int)f_fraction;
                  asm clrwdt
                  digits[0] = ca_mask[whole_num] & DECIMAL_POINT_MASK;
                  digits[1] = ca_mask[fraction / 10];
                  digits[2] = ca_mask[fraction % 10];
              }
              else if((raw_adc_value >= 10.0) && (raw_adc_value < 100.0)) {
                  whole_num = (unsigned int)raw_adc_value;
                  f_fraction = (raw_adc_value * 10.0) - (whole_num * 10.0);
                  fraction = (unsigned int)f_fraction;
                  asm clrwdt
                  digits[0] = ca_mask[whole_num / 10];
                  digits[1] = ca_mask[whole_num % 10] & DECIMAL_POINT_MASK;
                  digits[2] = ca_mask[fraction];
              }
              else if((raw_adc_value >= 100.0) && (raw_adc_value < 1000.0)) {
                  whole_num = (unsigned int)raw_adc_value;
                  asm clrwdt
                  digits[0] = ca_mask[whole_num / 100];
                  digits[1] = ca_mask[(whole_num / 10) % 10];
                  digits[2] = ca_mask[whole_num % 10];
              }
 
              if(run_once_flag == 0) {
                  TMR1IE_bit = 1;
                  run_once_flag = 1;
              }
              
              asm clrwdt
              previous_raw_adc_value = raw_adc_value;
          }
    }
}

 

Attachments

  • Load Cell Measurement.rar
    77.1 KB · Views: 79
Last edited:

Your RAM issue may be because the 64 bytes are spread across 4 16-byte banks. With the XC8 compiler and linker, look at the listing and map outputs to see how it is allocating the space.
Also for a very limited capability MCU such as the one you are using I would highly recommend that you don't use double values; the ADC output is an 8-bit integer. Rather than scaling it to (what I assume are) the appropriate units (your *150.0 / 1023.0 - I think that 2nd value should be 256 as there are only 8 bits in the original value), I would recommend that you do all of the value manipulations with the raw integer values and then do the final value output based on a scaled integer approach. Floating point operations are slow and take a lot of code (yes you have 1024 words in total but you don't want to waste those unnecessarily).
Also I would not simply pepper the code with the CLRWDT instructions - you have turned off the WDT. If you later use the WDT then you can probably get away with one somewhere in the main loop.
Susan
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top