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

Clarification for PIC16F690
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

Clarification for PIC16F690
PostPosted: Wed Nov 16, 2016 12:56 pm     Reply with quote

Good day! I decided to buy 2 pieces from this pic with a Pickit 3 and a debugger. I want to use 10 bits one the ADC and this PIC should have a 10bit ADC. So when I try to use the functions:
Code:
setup_adc( ADC_CLOCK_DIV_10 );

It shows me an unknown identifier as ADC_CLOCK_DIV_10.
Any ideas?
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Wed Nov 16, 2016 1:22 pm     Reply with quote

Of course it will.....

This is the ADC _clock_ setting. The ADC needs to be fed with a clock that is typically 500KHz or slightly slower. Look at the chip's data sheet. Look at what divisors can be specified for the clock (/4, /8 /16 /32 and /64 typically). This is nothing to do with the ADC resolution.

You can set the value returned by the adc functions, at the top of the code (line after the include for the processor)

#device ADC=8 //specifies to return an 8 bit value from the ADC
#device ADC=10 //same for 10bit
#device ADC=12 //same for chips with a 12bit ADC
#device ADC=16 //returns the value left justified to 16 bits

Choose the setting you want.

Remember you need to be using an int16 variable to handle the results over 8bits.
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Thu Nov 17, 2016 6:46 am     Reply with quote

Device = 10 is already set.

I will try with DIV_16. Since device is 10 it will only read the first 10 bits?

I am sorry for the stupid question, I just am too tired sometimes and I rush.
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
jeremiah



Joined: 20 Jul 2010
Posts: 1357

View user's profile Send private message

PostPosted: Thu Nov 17, 2016 7:20 am     Reply with quote

Arakel wrote:
Device = 10 is already set.

I will try with DIV_16. Since device is 10 it will only read the first 10 bits?

I am sorry for the stupid question, I just am too tired sometimes and I rush.


As stated earlier, the ADC_CLOCK_DIV_XX settings have no effect on the number of bits. No relation whatsoever. It only affects how fast the ADC peripheral operates. Check your data sheet for which clock dividers apply to your chip.
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Thu Nov 17, 2016 7:43 am     Reply with quote

Also don't just 'try' clock settings. Read the data sheet. There is a table of what divisors are recommended for each clock rate. Use the right setting for your clock rate.

The syntax is not #device = 10. Wants #device ADC=10
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

I will learn it, but it is difficult to work and learn.
PostPosted: Thu Nov 17, 2016 9:43 am     Reply with quote

Yes, I know! I am not stupid like I make myself look. I am just too tired sometimes to think. Otherwise I understand the architecture of the processor and the programming I just have to learn to ask the questions in the right way and not to work so I can pay more attention to myself. After 3 shifts by 12 hours I am barely breathing, they put me on the best positions......And the bosses were near me the whole day.....

I do not want to read the datasheet because another 100 or 600 pages is not good for me! I have enough to read for now.

And here is another stupid question..... :D.
How do I disable and use the RC(C) pins on PIC16F690 for digital I/O. I think it is with setup_counters function because it affects the whole register or some other function maybe? This is the bad think of CCS you can not set individual bits on a register.

I just pressed the new topic button instead of the new post button.....
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Thu Nov 17, 2016 10:03 am     Reply with quote

You really do need to read the data sheet. This is the first thing to read before trying to program any chip.....
Once you have read a few, whole sections become repeats, so you can just jump to the actual figures needed.
There is nothing involving counters on the RC pins. If you look at table1 in the data sheet..... this shows what pins are used by what device.

AN4 to 7, and the comparators.

So setup_adc_ports and setup_comparator.

setup_comparator(NC_NC_NC_NC);

Disables the comparators. Then ensure you are only selecting the s_ANx pins you actually want to use with setup_adc_ports, and RC0 to RC7 (C0 to C7) become available for normal I/O.
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Thu Nov 17, 2016 11:00 am     Reply with quote

This is very useful information:
Quote:
Once you have read a few, whole sections become repeats, so you can just jump to the actual figures needed.

Yes I had to disable the comparators. It was this function, not setup_counters. I read it somewhere but I forgot....

It is working, now I need a decipher so I can use 2 common cathode displays and output a number with 2 digits. Something that would decipher the number 25 to say in to binary code for two 7segment displays or one LCD display.
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Fri Nov 18, 2016 9:22 am     Reply with quote

The conversion you need it to Binary Coded Decimal (BCD). So decimal digits, but coded as 0 to 9, rather than as ASCII.

A search here will find lots of 7 segment driver code, and most will include a binary to BCD conversion routine.

In fact if you search for bin2bcd, you should find one. It's commonly done as a macro, rather than a function.
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Fri Nov 18, 2016 9:02 pm     Reply with quote

Ttelmah wrote:
The conversion you need it to Binary Coded Decimal (BCD). So decimal digits, but coded as 0 to 9, rather than as ASCII.

A search here will find lots of 7 segment driver code, and most will include a binary to BCD conversion routine.

In fact if you search for bin2bcd, you should find one. It's commonly done as a macro, rather than a function.


Is it not BCD to 7 segment? I already know this, but I am trying to do it by myself. I got one display running, the difficult part is to make 2 displays running. I know how the diodes work on the display also, I have picked common catode displays. With a macro it would be easy, but by myself it would be difficult. The firs 10 digits, from 0 to 9, from the processor give an accurate result on the display, but after that it becomes a problem.

This brings me to a question which I am not certain of, but still:
What is the difference if I put pull-down resistors and if both ends of the resistor are connected to PIN_B0 and the display.

I am guessing that if we put the resistor directly connected between the two pins we limit the current and if we put it as a pull down resistor we make the voltage stable? The source/sink of the PIC should be 25mA, but depends on the load and a diode should consume 1mA of current so I guess limiting the current is not neccessary and its better to put a pull down resistor because if the voltage is not stable it will be a problem? Or I could put 1 resistor of 330Ohms between the common catode pin and ground?

And second is there any way to combine two binary numbers and get one 8 bit number, but if we have 0b00000001 and 0b00000001 we need to take the last four digits and make 0b00010001 or we can have 0b0001 and 0b0001 and we have to make 0b00010001. I am a little bit on the dark with the binary logic combinations. I know how to do the summing of two variables and other things but I do not know how to take the last 4 digits and make them in to 1 variable.

These are things that are difficult to find within the tons of books and materials available.

Maybe this:
FinalFormOfThePORTCOutput = (BinaryFormOfSecondDigit >> 4) & BinaryFormOfFirstDigit;

The result should be:
FinalFormOfThePORTCOutput = (0b00000001 >> 4) & 0b00000001;

We shift the second digit with four bits and mask with the first digit.

Meaning we get 0b00010001?

I could not find the macro. Perhaps it is in the datasheet of PIC16F690?
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
Ttelmah



Joined: 11 Mar 2010
Posts: 19550

View user's profile Send private message

PostPosted: Sat Nov 19, 2016 2:59 am     Reply with quote

If you start with a number, this has to be converted to BCD, before you get involved with the seven segment.

Think about it. You have the number '88' say. In binary 0b0101 1000
Where are the digits?.

Now convert this to BCD, and in binary you have 0b1000 1000
each 'nibble' here is '8'. This is what needs to feed to each digit.

Now with this, you take just one nibble (say the low one), and then use a look up table to say which segments have to be 'on'. So if you say that bit0 is segment 'a', 1 segment 'b' etc., and your electronics is wired so that a '1' turns the segment on, then you can have a constant table like:

gfedcba
0b00111111, //0
0b00000110, //1
0b01011011, //2

etc.. Then use the BCD digit to select a value and this is the seven segment pattern required.

So binary to seven segment, requires two conversions:

binary to BCD
BCD to seven segment.
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Sat Nov 19, 2016 6:17 am     Reply with quote

I know. This is my table and code:

const unsigned int8 TableForDigits[10] = {0b00000000, 0b00000001, 0b00000010, 0b00000011,
0b00000100, 0b00000101, 0b00000110, 0b00000111, 0b00001000, 0b00001001,};

FirstDigit = Display%10;
SecondDigit = Display/10;

for(i=0; i<=10; i++)
{
if(FirstDigit == i)
BinaryFormOfFirstDigit = TableForDigits[i];
if(SecondDigit == i)
BinaryFormOfSecondDigit = TableForDigits[i];
}
FinalFormOfThePORTCOutput = (BinaryFormOfSecondDigit >> 4) & BinaryFormOfFirstDigit;

output_c(FinalFormOfThePORTCOutput);
delay_us(100);
output_high(PIN_B5);

I am using two 4511 decoders with two 7 segment display.
That is why I find the first digit by dividing to 10 with remainders and getting the remainder, and I find the second digit by normally dividing to 10. I do not know if it will work. But the idea is to output the first digit on 4 pins and the second digit on 4 pins. So I need to make one 8 bit variable from 0b00000001 and 0b00000001 or from 0b0001 and 0b0001 I think.
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Sat Nov 19, 2016 6:30 am     Reply with quote

The other option is 2 tables, but I was trying to save resources.

const unsigned int8 TableForDigits[10] = {0b00000000, 0b00000001, 0b00000010, 0b00000011,
0b00000100, 0b00000101, 0b00000110, 0b00000111, 0b00001000, 0b00001001};

const unsigned int8 TableForSecondDigits[10] = {0b00000000, 0b00010000, 0b00100000, 0b00110000, 0b01000000,
0b01010000, 0b01100000, 0b01110000, 0b10000000, 0b10010000};

FirstDigit = Display%10;
SecondDigit = Display/10;

for(i=0; i<=10; i++)
{
if(FirstDigit == i)
BinaryFormOfFirstDigit = TableForDigits[i];
if(SecondDigit == i)
BinaryFormOfSecondDigit = TableForSecondDigits[i];
}
FinalFormOfThePORTCOutput = (BinaryFormOfSecondDigit | BinaryFormOfFirstDigit;

output_c(FinalFormOfThePORTCOutput);
delay_us(100);
output_high(PIN_B5);
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
Arakel



Joined: 06 Aug 2016
Posts: 107
Location: Moscow

View user's profile Send private message Visit poster's website AIM Address

PostPosted: Sat Nov 19, 2016 6:55 am     Reply with quote

Here is the whole source code:

//A program to scan the values of an ADC and potentiometer and start a heater if they are different with the debouncing routine
#include <16F690.h>

#device ADC=10

#fuses NOMCLR, NOWDT, NOPROTECT, INTRC_IO
#use delay(clock=4M)

void main()
{

int i; //Local variables
unsigned int8 ADC_10bit_Sensor;
unsigned int8 ADC_10bit_Potentiometer;
unsigned int8 Display;
unsigned int8 FirstDigit, SecondDigit;
unsigned int8 BinaryFormOfFirstDigit, BinaryFormOfSecondDigit;
unsigned int8 FinalFormOfThePORTCOutput;

const unsigned int8 TableForDigits[10] = {
0b00000000, //Output for "0" for the first display from "FirstDigit = Display / 10"
0b00000001, //1
0b00000010, //2
0b00000011, //3
0b00000100, //4
0b00000101, //5
0b00000110, //6
0b00000111, //7
0b00001000, //8
0b00001001 //9
};

const unsigned int8 TableForSecondDigits[10] = {
0b00000000, //Output for "0" on the second display from "SecondDigit = Display/10"
0b00010000, //1
0b00100000, //2
0b00110000, //3
0b01000000, //4
0b01010000, //5
0b01100000, //6
0b01110000, //7
0b10000000, //8
0b10010000 //9
};

setup_comparator(NC_NC_NC_NC);

setup_adc_ports( sAN0 | sAN1 ); //Adc functions
setup_adc( ADC_CLOCK_DIV_16 );

while(TRUE)
{

set_adc_channel( 0 ); //We set the ADC to read from CHANNEL 0 (Where the potentiometer is connected)
for(i=0; i<15; i++)
{
delay_ms(1);
ADC_10bit_Potentiometer = read_adc();
if(ADC_10bit_Potentiometer != ADC_10bit_Potentiometer)
i=0;
}

set_adc_channel( 1 ); //We set the ADC to read from CHANNEL 1 (Where the sensor is connected)
for (i=0; i<15; i++)
{
delay_ms(1);
ADC_10bit_Sensor = read_adc();
if (ADC_10bit_Sensor != ADC_10bit_Sensor)
i=0;
}

if (ADC_10bit_Sensor <= ADC_10bit_Potentiometer) //If the potentiometer is lower than the sensor turn OFF the heater
{
delay_ms(1);
output_b(0b00010000);
} else {
output_b(0b00000000);
}
Display = (ADC_10bit_Sensor - 3.13)/0.01;

FirstDigit = Display%10;
SecondDigit = Display/10;

for(i=0; i<=10; i++)
{
if(FirstDigit == i)
BinaryFormOfFirstDigit = TableForDigits[i];
if(SecondDigit == i)
BinaryFormOfSecondDigit = TableForDigits[i];
}
FinalFormOfThePORTCOutput = BinaryFormOfSecondDigit | BinaryFormOfFirstDigit;

output_c(FinalFormOfThePORTCOutput);
delay_us(100);

}//Close while
}

It bothers me if I use "SecondDigit = Display / 10" will it work. It should work because we have int8, meaning we do not record floating point variables with int, if we want floating point we should use float?

I am certain that the binary summing does not work!

Here is the full schematic.

[img]https://drive.google.com/file/d/0B0kVHbb80xxTeHNLQng0cU9VdWM/view?usp=sharing[/img]
_________________
Yo! I love learning and technology! I just do not have experience so do not be angry if I ask a stupid question about a detail! From so much to remember sometimes I forget the details in order to remember the big problems!
temtronic



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

View user's profile Send private message

PostPosted: Sat Nov 19, 2016 8:34 am     Reply with quote

1) this...
Display = (ADC_10bit_Sensor - 3.13)/0.01;

May not give you the numbers you think it should...
Have you sent the 'display' variable to a PC to see what the numbers really are? Confirm that the range and type are correct?

2)since you're using 2 4511s, another fast/accurate way to send the data is to have a simple table that is 100 elements long.Old school, no math is needed,you just have to manually (or eXcel) create the table once.IE element 24 will have 0b00100100 in it, so 0010 goes to 10s digit 4511, 0100 goes to 1s digit 4511. If you've got the code space for it,it is that simple.....

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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