|
|
View previous topic :: View next topic |
Author |
Message |
Arakel
Joined: 06 Aug 2016 Posts: 107 Location: Moscow
|
Clarification for PIC16F690 |
Posted: Wed Nov 16, 2016 12:56 pm |
|
|
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: 19513
|
|
Posted: Wed Nov 16, 2016 1:22 pm |
|
|
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
|
|
Posted: Thu Nov 17, 2016 6:46 am |
|
|
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: 1349
|
|
Posted: Thu Nov 17, 2016 7:20 am |
|
|
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: 19513
|
|
Posted: Thu Nov 17, 2016 7:43 am |
|
|
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
|
I will learn it, but it is difficult to work and learn. |
Posted: Thu Nov 17, 2016 9:43 am |
|
|
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: 19513
|
|
Posted: Thu Nov 17, 2016 10:03 am |
|
|
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
|
|
Posted: Thu Nov 17, 2016 11:00 am |
|
|
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: 19513
|
|
Posted: Fri Nov 18, 2016 9:22 am |
|
|
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
|
|
Posted: Fri Nov 18, 2016 9:02 pm |
|
|
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: 19513
|
|
Posted: Sat Nov 19, 2016 2:59 am |
|
|
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
|
|
Posted: Sat Nov 19, 2016 6:17 am |
|
|
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
|
|
Posted: Sat Nov 19, 2016 6:30 am |
|
|
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
|
|
Posted: Sat Nov 19, 2016 6:55 am |
|
|
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: 9226 Location: Greensville,Ontario
|
|
Posted: Sat Nov 19, 2016 8:34 am |
|
|
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 |
|
|
|
|
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
|