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

Problem the use two max 7219 with pic 18f4553

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



Joined: 29 May 2014
Posts: 18
Location: Brasil

View user's profile Send private message

Problem the use two max 7219 with pic 18f4553
PostPosted: Tue Apr 26, 2016 1:11 pm     Reply with quote

Hello, I have a pic 18f4553 , where I'll read the AN0 and AN1 channels. They must show the values in two chip MAX7219 and the max1 show the value of AN0 channel and max2 show the value of AN1 channel. I made some modifications in the code with the help of our friend pcm programmer which gave me some policies that will help a lot but had no effect. I put the code here so you guys can analyze and see where I'm going wrong.
Obs . I closed the other topic as it was very messy and I did not understand anything.
Code:
#include <18F4553.h>          // Includes header file PIC 18F4553
#device ADC = 12              //Sets 12 bits for the result of the AD conversion
#use delay (clock=20000000)   /*Set the frequency of the crystal to calculate
                              ..of delays */

#use spi(do=pin_D0,clk=pin_D2,bits=16,load_active=1,load=pin_D1,idle=1, stream=MAX1)

#use spi(do=pin_C0,clk=pin_C2,bits=16,load_active=1,load=pin_C1,idle=1, stream=MAX2)

//bits control configuration
#fuses HS         //High Speed Crystal Oscillator
#fuses NOWDT      //Watch Dog Timer disabled
#fuses PUT
#fuses BROWNOUT
#fuses NOLVP      //Single-Supply ICSP disabled
 
// It shows the value of the AD converter
int32 hc1, hc2;       

// It shows the value of Conversion
int32 hc1result; 
int32 hc2result; 

// The bits to display configuration in the 7-segment display
int address, data, adqnum, digit[5];
int16 packetmax;

// Packet transmission via spi to the max
void maxsend(int8 channel)
{                                //routine for send information to the max
packetmax=make16(address,data);  //make a 16 bit variable direcc byte high, dato byte low
if(channel == 1)
spi_xfer(MAX1, packetmax);       //transfer using spi software
if(channel == 2)
spi_xfer(MAX2, packetmax);
}

// Configuration properties MAX7219
void maxsetup()
{
   // Initialize the first MAX7219. The channel parameter = 1.
   
   address=0x00, data=0x00,  maxsend(1);  // No-Operation
   address=0x09, data=0xff,  maxsend(1);  // Decode-Mode Register Examples (Address (Hex) = 0xX9)
   address=0x0a, data=0x0f,  maxsend(1);  // Intensity Register Format (Address (Hex) = 0xXA)
   address=0x0b, data=0x05,  maxsend(1);  // Scan-Limit Register Format (Address (Hex) = 0xXB)
   address=0x0f, data=0x01,  maxsend(1);  // Display-Test Register Format(Address (Hex) = 0xXF)
   address=0x0c, data=0x01,  maxsend(1);  // Shutdown Register Format (Address (Hex) = 0xXC)
   
   // Initialize the second MAX7219. The channel parameter = 2.
   
   address=0x00, data=0x00, maxsend(2);   // No-Operation
   address=0x09, data=0xff, maxsend(2);   // Decode-Mode Register Examples (Address (Hex) = 0xX9)
   address=0x0a, data=0x0f, maxsend(2);   // Intensity Register Format (Address (Hex) = 0xXA)
   address=0x0b, data=0x05, maxsend(2);   // Scan-Limit Register Format (Address (Hex) = 0xXB)
   address=0x0f, data=0x01, maxsend(2);   // Display-Test Register Format(Address (Hex) = 0xXF)   
   address=0x0c, data=0x01, maxsend(2);   // Shutdown Register Format (Address (Hex) = 0xXC)
}

// The following lines are used for the digits
void algebra_digits()
{   
   // Initialize the first line 7 segments display.. The channel parameter = 1.
   digit[0] = hc1result/1000;
   digit[1] = ((hc1result % 1000)*10)/1000;
   digit[2] = ((((hc1result % 1000)*10) % 1000)*10)/1000;
   digit[3] = ((((((hc1result % 1000)* 10) % 1000) * 10) % 1000 )* 10) / 1000;
   digit[4] = ((((((((hc1result % 1000)* 10) % 1000) * 10) % 1000) * 10) % 1000)* 10) / 1000;
   
   // Initialize the second line 7 segments display. The channel parameter = 2.
   digit[0] = hc2result/1000;
   digit[1] = ((hc2result % 1000)*10)/1000;
   digit[2] = ((((hc2result % 1000)*10) % 1000)*10)/1000;
   digit[3] = ((((((hc2result % 1000)* 10) % 1000) * 10) % 1000 )* 10) / 1000;
   digit[4] = ((((((((hc2result % 1000)* 10) % 1000) * 10) % 1000) * 10) % 1000)* 10) / 1000;
   
}


#INT_TIMER0       // Policy int the indetificação . Timer 0

void Trata_t0()   // Function for treatment of Timer 0
{
tempo++;          // Increments the variable time every 25ms
if (tempo >= 80)  // If time > = 80 <=> 2 seconds ?
    {
   
    tempo = 0;    // Returns the variable time 0
    }
SET_TIMER0(61);   // Returns the initial value to the Timer 0
}

void main()                   
{
// Set the analog inputs AN0 to AN1
SETUP_ADC_PORTS(AN0_TO_AN1|VSS_VREF);   
// Use the internal clock to the time of acquisition
SETUP_ADC(ADC_CLOCK_Internal);
// Enable global interrupt
Enable_Interrupts(GLOBAL);
// Enables interruption by receiving data in serial
Enable_Interrupts(INT_RDA);
// Enables interruption by overflow of Timer 0
ENABLE_INTERRUPTS(INT_TIMER0);
/* Set Timer 0 Prescaler to increase the machine cycle of 1 : 256 and
mode 8 bits */
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
// Start the Timer 0 with the value 61 - Interruption every 25ms
SET_TIMER0(61);

maxsetup();
delay_ms(3000); // Delays the start of the display

/* Makes cleaning all the rec variable and makes the controleb maga indexes 0 */
for(cont = 0; cont < 5; cont++) rec[cont] = '\0';
cont = 0;

//Loop principal
while(true)                           
   {
     
  for(adqnum=1;adqnum<=100;adqnum++)
  {   //collect 100 samples, I usually do this, u can use your favorite method
         hc1=hc1+read_adc();     //for acquisition.
         delay_us(20);
         
         hc2=hc2+read_adc();     //for acquisition.
         delay_us(20);
  }   
      hc1=hc1*10;
      algebra_digits();           //call algebra routine to get each digit
      address=0x01, data=(digit[0] | 0b10000000), maxsend(1);   //use OR for adding decimal point
      address=0x02, data=digit[1], maxsend(1);
      address=0x03, data=digit[2], maxsend(1);   
      address=0x04, data=digit[3], maxsend(1);
      address=0x05, data=digit[4], maxsend(1);
     
      hc1=0;                      //clean hc1
     
      hc2=hc2*10;
      algebra_digits();           //call algebra routine to get each digit
      address=0x01, data=(digit[0] | 0b10000000), maxsend(2);   //use OR for adding decimal point
      address=0x02, data=digit[1], maxsend(2);
      address=0x03, data=digit[2], maxsend(2);   
      address=0x04, data=digit[3], maxsend(2);
      address=0x05, data=digit[4], maxsend(2);
         
      hc2=0;                      //clean hc2
     
 
   SET_ADC_CHANNEL(0);     //Sets the read channel 0
   delay_us(100);          //Channel adjustment time (required)
   hc1 = READ_ADC();       //Does the AD conversion and saves it in the variable ad0
   
   SET_ADC_CHANNEL(1);     //Sets the read channel 1
   delay_us(100);          //Channel adjustment time (required)
   hc2 = READ_ADC();       //Does the AD conversion and saves it in the variable ad1
   
   hc1result = (hc1 * 5000) /4095;
   hc2result = (hc2 * 5000) /4095;
 
           
   delay_ms(100);          //Delay 100ms
   }
}   
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Apr 26, 2016 6:05 pm     Reply with quote

1. You didn't compile your program and fix the compiler errors before
you posted it. It gives these errors:
Quote:

*** Error 12 "PCH_Test.c" Line 84(1,6): Undefined identifier tempo
*** Error 12 "PCH_Test.c" Line 85(5,10): Undefined identifier tempo
*** Error 12 "PCH_Test.c" Line 88(5,10): Undefined identifier tempo
*** Error 12 "PCH_Test.c" Line 115(5,9): Undefined identifier cont
*** Error 12 "PCH_Test.c" Line 115(15,19): Undefined identifier cont
*** Error 12 "PCH_Test.c" Line 115(25,29): Undefined identifier cont
*** Error 12 "PCH_Test.c" Line 116(1,5): Undefined identifier cont
7 Errors, 0 Warnings.
Build Failed.


2. You didn't tell us what is wrong with the program output. What do
you see on the 5-digit, 7-segment displays ? What do expect to see, if it
was working correctly ?

3. The following code reads 100 samples from each A/D channel,
but there is no code to change the A/D channel between 0 and 1.
You left out the set_adc_channel() lines.
Code:

  for(adqnum=1;adqnum<=100;adqnum++)
  {   //collect 100 samples, I usually do this, u can use your favorite method
         hc1=hc1+read_adc();     //for acquisition.
         delay_us(20);
         
         hc2=hc2+read_adc();     //for acquisition.
         delay_us(20);
  }   
 


4. A 12-bit A/D has a maximum possible output of 4095.
The result of adding 100 samples (and then multiplying the result * 10)
will give you a maximum value of 4095 * 100 * 10 = 4095000.
That's 7 digits. But your display can only show 5 digits. It won't work.

5. Below, you are enabling Rx interrupts for the hardware UART:
Code:
Enable_Interrupts(INT_RDA);

But you don't have an #int_rda function to handle the interrupts. In fact,
you don't even have a #use rs232() statement to enable the UART.
Why enable INT_RDA ? You're not even using the UART.

6. There are other minor bugs.

7. You are now on your 3rd PIC. First was 12F683, next was 16F877A,
now you have 18F4553. This really looks like a Proteus project.
rosiley



Joined: 29 May 2014
Posts: 18
Location: Brasil

View user's profile Send private message

PostPosted: Tue Apr 26, 2016 6:19 pm     Reply with quote

My friend good night .

Sorry about the mess but now follows the complete code and running but with the errors said at the beginning of the post, I will make the changes that you mentioned and see what will happen.
At first I started using the 12F683, 16F877A, but the final is the 18f4553 .

Code:


#include <18F4553.h>          // Includes header file PIC 18F4553
#device ADC = 12              //Sets 12 bits for the result of the AD conversion
#use delay (clock=20000000)   /*Set the frequency of the crystal to calculate
                              ..of delays */

#use spi(do=pin_D0,clk=pin_D2,bits=16,load_active=1,load=pin_D1,idle=1, stream=MAX1)

#use spi(do=pin_C0,clk=pin_C2,bits=16,load_active=1,load=pin_C1,idle=1, stream=MAX2)

//bits control configuration
#fuses HS         //High Speed Crystal Oscillator
#fuses NOWDT      //Watch Dog Timer disabled
#fuses PUT
#fuses BROWNOUT
#fuses NOLVP      //Single-Supply ICSP disabled

//Settings for serial communication
#use RS232 (Baud=9600, xmit = PIN_C6, rcv = PIN_C7)
 
// It shows the value of the AD converter
int32 hc1, hc2, tmp, prs;       

// It shows the value of Conversion
int32 hc1result; 
int32 hc2result; 
int32 tmpresult;
int32 prsresult; 

// The bits to display configuration in the 7-segment display
int address, data, adqnum, digit[5];
int16 packetmax;

// Packet transmission via spi to the max
void maxsend(int8 channel)
{                                //routine for send information to the max
packetmax=make16(address,data);  //make a 16 bit variable direcc byte high, dato byte low
if(channel == 1)
spi_xfer(MAX1, packetmax);       //transfer using spi software
if(channel == 2)
spi_xfer(MAX2, packetmax);
}

// Configuration properties MAX7219
void maxsetup()
{
   // Initialize the first MAX7219. The channel parameter = 1.
   
   address=0x00, data=0x00,  maxsend(1);  // No-Operation
   address=0x09, data=0xff,  maxsend(1);  // Decode-Mode
   address=0x0a, data=0x0f,  maxsend(1);  // Intensity
   address=0x0b, data=0x05,  maxsend(1);  // Scan-Limit
   address=0x0f, data=0x01,  maxsend(1);  // Display-Test
   address=0x0c, data=0x01,  maxsend(1);  // Shutdown
   
   // Initialize the second MAX7219. The channel parameter = 2.
   
   address=0x00, data=0x00, maxsend(2);   // No-Operation
   address=0x09, data=0xff, maxsend(2);   // Decode-Mode
   address=0x0a, data=0x0f, maxsend(2);   // Intensity
   address=0x0b, data=0x05, maxsend(2);   // Scan-Limit
   address=0x0f, data=0x01, maxsend(2);   // Display-Test   
   address=0x0c, data=0x01, maxsend(2);   // Shutdown 
}

// The following lines are used for the digits
void algebra_digits()
{   
   // Initialize the first line 7 segments display.. The channel parameter = 1.
   digit[0] = hc1result/1000;
   digit[1] = ((hc1result % 1000)*10)/1000;
   digit[2] = ((((hc1result % 1000)*10) % 1000)*10)/1000;
   digit[3] = ((((((hc1result % 1000)* 10) % 1000) * 10) % 1000 )* 10) / 1000;
   digit[4] = ((((((((hc1result % 1000)* 10) % 1000) * 10) % 1000) * 10) % 1000)* 10) / 1000;
   
   // Initialize the second line 7 segments display. The channel parameter = 2.
   digit[0] = hc2result/1000;
   digit[1] = ((hc2result % 1000)*10)/1000;
   digit[2] = ((((hc2result % 1000)*10) % 1000)*10)/1000;
   digit[3] = ((((((hc2result % 1000)* 10) % 1000) * 10) % 1000 )* 10) / 1000;
   digit[4] = ((((((((hc2result % 1000)* 10) % 1000) * 10) % 1000) * 10) % 1000)* 10) / 1000;
   
}

/******************************************************************************
Control variables:
cont = index of control for serial reception ;
time = time information within 2 seconds
*******************************************************************************/
int cont=0, tempo=0;
                     
int rec[5];          // For serial data reception Variable

#INT_RDA             // Identficação Policy w / int . the serial reception

void rec_serial()    // Receiving data processing function
{
rec[cont] = getc();  /* Read the data from the serial and stores it in the rec position
                     (Index) informed cont */

if (rec[cont] == 0x0D)  // Check if the data received is equal to CR ( 0x0D )
   {
  /* After received all serial data, it makes cleaning the whole variable and rec
returns the contents of control in cont 0 */

   for(cont = 0; cont < 5; cont++) rec[cont] = '\0';
   cont = 0; 
   }
else
/* If not yet received all of the data control increments the variable maga index */

    cont++;   
}

#INT_TIMER0       // Policy int the indetificação . Timer 0

// Make the LED on the door D3 blinking, indicating that the processor is running
void PiscaLED()
{
   static boolean PiscaLed;   // To flash the LED.
   static int contador;       // To tell the time of 1 second.
   set_timer0(131-get_timer0());
   contador++;
   if(contador == 125)        //If said 125 (1 second ) .
   {
      contador=0;             // Zero count.
      PiscaLed = !PiscaLed;   // Invert bit;
      output_bit(pin_D3, PiscaLed); // On / Off LED .
   }
}
void Trata_t0()   // Function for treatment of Timer 0
{
tempo++;          // Increments the variable time every 25ms
if (tempo >= 80)  // If time > = 80 <=> 2 seconds ?
    {   
    tempo = 0;    // Returns the variable time 0
    }
SET_TIMER0(61);   // Returns the initial value to the Timer 0
}

// Protocol Format = HC1:0000 : HC2:0000 : TMP:0000 : depht:0000

void escreve_serial()            // Protocol sending function for serial
{
printf("HC1:%4lu",hc1result);    // Send conversion data A/D to display voltage
printf(":");                     // Protocol Control
printf("HC2:%4lu",hc2result);    // Send conversion data A/D to display voltage
printf(":");                     // Protocol Control
printf("TMP:%4lu",tmpresult);   // Send conversion data A/D to display voltage
printf(":");                     // Protocol Control
printf("DEPHT:%4lu",prsresult);  // Send conversion data A/D to display voltage
printf("\n\r");                  // Protocol Control
}

void main()                   
{
// Set the analog inputs AN0 to AN4
SETUP_ADC_PORTS(AN0_TO_AN4|VSS_VREF);   
// Use the internal clock to the time of acquisition
SETUP_ADC(ADC_CLOCK_Internal);
// Enable global interrupt
Enable_Interrupts(GLOBAL);
// Enables interruption by receiving data in serial
Enable_Interrupts(INT_RDA);
// Enables interruption by overflow of Timer 0
ENABLE_INTERRUPTS(INT_TIMER0);
/* Set Timer 0 Prescaler to increase the machine cycle of 1 : 256 and mode 8 bits */
SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
// Start the Timer 0 with the value 61 - Interruption every 25ms
SET_TIMER0(61);

maxsetup();
delay_ms(3000); // Delays the start of the display

/* Makes cleaning all the rec variable and makes the controleb maga indexes 0 */
for(cont = 0; cont < 5; cont++) rec[cont] = '\0';
cont = 0;

//Loop principal
while(true)                           
   {
     
  for(adqnum=1;adqnum<=100;adqnum++)
  {   
  //collect 100 samples, I usually do this, u can use your favorite method
         hc1=hc1+read_adc();     //for acquisition.
         delay_us(20);
         
         hc2=hc2+read_adc();     //for acquisition.
         delay_us(20);
  }   
      hc1=hc1*10;
      algebra_digits();           //call algebra routine to get each digit
      address=0x01, data=(digit[0] | 0b10000000), maxsend(1);   //use OR for adding decimal point
      address=0x02, data=digit[1], maxsend(1);
      address=0x03, data=digit[2], maxsend(1);   
      address=0x04, data=digit[3], maxsend(1);
      address=0x05, data=digit[4], maxsend(1);
     
      hc1=0;                      //clean hc1
     
      hc2=hc2*10;
      algebra_digits();           //call algebra routine to get each digit
      address=0x01, data=(digit[0] | 0b10000000), maxsend(2);   //use OR for adding decimal point
      address=0x02, data=digit[1], maxsend(2);
      address=0x03, data=digit[2], maxsend(2);   
      address=0x04, data=digit[3], maxsend(2);
      address=0x05, data=digit[4], maxsend(2);
         
      hc2=0;                      //clean hc2
     
 
   SET_ADC_CHANNEL(0);     //Sets the read channel 0
   delay_us(100);          //Channel adjustment time (required)
   hc1 = READ_ADC();       //Does the AD conversion and saves it in the variable ad0
   
   SET_ADC_CHANNEL(1);     //Sets the read channel 1
   delay_us(100);          //Channel adjustment time (required)
   hc2 = READ_ADC();       //Does the AD conversion and saves it in the variable ad1
   
   SET_ADC_CHANNEL(2);     //Sets the read channel 2
   delay_us(100);          //Channel adjustment time (required)
   tmp = READ_ADC();       //Does the AD conversion and saves it in the variable ad2
   
   SET_ADC_CHANNEL(4);     //Sets the read channel 4
   delay_us(100);          //Channel adjustment time (required)
   prs = READ_ADC();       //Does the AD conversion and saves it in the variablel ad4
   
   hc1result = (hc1 * 5000) /4095;
   hc2result = (hc2 * 5000) /4095;
   tmpresult = (tmp * 5000) /4095;
   prsresult = (prs * 5000) /4095;
     
   escreve_serial();       //Sends data over a serial   
           
   delay_ms(100);          //Delay 100ms
   }
}

temtronic



Joined: 01 Jul 2010
Posts: 9246
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Apr 26, 2016 7:22 pm     Reply with quote

this...
SETUP_ADC(ADC_CLOCK_Internal)

If memory serves me right this is usually ONLY for when a PIC is asleep. Be sure to read the valid options for ADC clock selection, in the ADC chapter of the data sheet. Microchip print a chart or table of processor speed vs adc clock speeds.

then there's this 'math'...
Code:
digit[1] = ((hc2result % 1000)*10)/1000;

it looks like *10/1000 should be reduced, though perhaps the compiler does it for you...it just 'looks' complicated.

same holds true for the *5000/4095 ; math



Jay
rosiley



Joined: 29 May 2014
Posts: 18
Location: Brasil

View user's profile Send private message

PostPosted: Fri Apr 29, 2016 10:35 am     Reply with quote

Good afternoon everyone.

With the help of I managed to solve the problem here and also did cleaning in the code that was much useless information, then I ask the moderator to close this topic.

And before it is closed, do the following question: How do I get the max2 receive information from other analog inputs when I trigger a button on RB0 input of the pic ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19553

View user's profile Send private message

PostPosted: Fri Apr 29, 2016 12:45 pm     Reply with quote

Topics are never 'closed' (except if wildly off topic etc.).
All that is needed is for _you_ as the author, to edit the title, to include [Solved]. Smile
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Fri Apr 29, 2016 1:42 pm     Reply with quote

rosiley wrote:
How do I get the max2 receive information from other analog inputs when I trigger a button on RB0 input of the pic ?


Hi,

First, I would look for PCM programmers 'Button' function. This is a routine that does switch debouncing on the signal generated by an electromechanical switch. Use this function to toggle a variable that determines which A/D channel you are reading. I'd also make a function for your A/D reading code to eliminate a lot of redundancy and clean up your code a bit.

Something like this:

Code:

int16 Read_Analog(int8 Channel)
{
SET_ADC_CHANNEL(Channel);     //Sets the read channel
delay_us(100);          //Channel adjustment time (required)
hc1 = READ_ADC();       //Does the AD conversion
return(hc1);
}


to use this code you would do this:

Code:

hc1 = Read_Analog(0);

_________________
John

If it's worth doing, it's worth doing in real hardware!
rosiley



Joined: 29 May 2014
Posts: 18
Location: Brasil

View user's profile Send private message

PostPosted: Sat Apr 30, 2016 7:08 am     Reply with quote

Sorry, I'm not understand your explanation.
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Sun May 01, 2016 11:29 am     Reply with quote

Hi,

Which part? What did you try?

Here is PCM's 'button' function: http://www.ccsinfo.com/forum/viewtopic.php?t=23837&highlight=button

To use it you could do something like this:

Code:

if(button(PIN_B0, 0, 50, 10, B0, 1)) 
{
 if (bInputFlag)
    bInputFlag = False;
 else
    bInputFlag = True;
}


This will toggle a variable, bInputFlag, which you would then use to determine which analog input you were sampling:

Code:

 if(bInputFlag)
   hc1 = Read_Analog(0);
 else
   hc1 = Read_Analog(1);


There are more compact ways to write this code, but I'm doing it this way so it's (hopefully) very clear!
_________________
John

If it's worth doing, it's worth doing in real hardware!
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