|
|
View previous topic :: View next topic |
Author |
Message |
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
Serial communication and pic 12f - problem and questions |
Posted: Fri Jun 14, 2013 4:25 pm |
|
|
Hello guys, I'm using pic 12F1822 and its internal oscillator.
Questions:
There is any problem if I use delay function with it's internal oscillator??
A friend told me CCS usually presents a problem with this.
I have other question too, MPLAB says I must not use both internal mclr (#fuses nomclr) and internal oscillator(#fuses intrc_io).. is that right???
Problem:
In my project, I want to receive some values via serial, but I'm not receiving those values. I have already checked the hardware and it seems ok, that's why I think it's a problem with my code.
I would be very thankfull if someone could look at it and tell me what am I doing wrong or something I could change.
Code: |
#include <12f1822.h>
#device adc=10
#FUSES NOWDT
#FUSES INTRC_IO
#FUSES NOMCLR
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=PIN_A4)
#use fast_io(a)
float vx,ax,vy,ay,vz,az;
void PrintAccel(char ca,float a)
{
printf("A ac. no eixo %c e': %f \n\r",ca,a);
}
void main() {
set_tris_a(0b00011000);
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE){
set_adc_channel(0);
delay_us(100);
vx = read_adc();
vx = vx*0.0048875855327468;
ax = (vx-1.65)*12.25;
PrintAccel('x',ax);
delay_ms(1000);
set_adc_channel(1);
delay_us(100);
vy=read_adc();
vy = vy*0.0048875855327468;
ay = (vy-1.65)*12.25;
PrintAccel('y',ay);
delay_ms(1000);
set_adc_channel(2);
delay_us(100);
vz=read_adc();
vz = (vz*0.0048875855327468);
az = (vz-1.65)*12.25;
PrintAccel('z',az);
delay_ms(1000);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jun 14, 2013 7:47 pm |
|
|
Quote: | #use rs232(baud=9600,xmit=PIN_A4)
#use fast_io(a)
set_tris_a(0b00011000);
|
In your code above you're setting Pin A4 to be an input pin in the
set_tris_a() line. In a TRIS value, a '1' means the pin is set as an input.
But the 12F1822 data sheet clearly says the TX pin must be configured
as an output:
Quote: | 25.1.1.1 Enabling the Transmitter
The programmer must set the corresponding TRIS bit to configure the
TX/CK I/O pin as an output.
|
Quote: | #use rs232(baud=9600,xmit=PIN_A4) |
In the line above, by specifying only the xmit pin, you are telling the
compiler to create a software UART, and to not use the hardware UART.
Is that what you want to do ? It should still work, but is it what you want ?
Quote: | setup_adc_ports(ALL_ANALOG); |
In the line above, you are setting pin A4 to be an analog pin. Pin A4
is AN3 when it's configured as an analog input. But the UART, whether
software or hardware, sends and receives digital signals. Why then are
you setting pin A4 as analog ?
Also read this thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=46160
It may help. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19510
|
|
Posted: Sat Jun 15, 2013 1:40 am |
|
|
Some other comments:
There is no difference in CCS, between the internal oscillator and any other oscillator regarding delays. The only difference, is accuracy. Many of the PIC's have internal oscillators with 'guaranteed' accuracies that are often tens of percent. As such, a 'one second' delay, or a RS232 baud rate, will be poor, or unacceptable. This is not a CCS problem, but fundamental to understanding the chip..
vx = vx*0.0048875855327468;
ax = (vx-1.65)*12.25;
First, just how accurate are 'float' types in CCS?. Answer typically about 6 digits. You are typing loads of digits, that are doing nothing. Then, think.
Simplify your maths _yourself_, before starting.
Now, your number arriving from the ADC, is 0 to 1023. Representing on your chip, 0 to 5v. 4 digits of accuracy 'at best'.
Your maths gives potentially, 41.0375 for 1023 in, and -20.2125 for 0 in, and is linear between. So, simplify. A total range, of 61.25. To the accuracy you actually 'have', just subtract 337, and multiply by 6, then print as 'hundredths'. using signed int16 arithmetic.
Faster, smaller, and will give better results with numbers not jumping around so badly.....
Best Wishes |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Mon Jun 17, 2013 9:26 am |
|
|
[quote="PCM programmer"] Quote: |
Quote: | #use rs232(baud=9600,xmit=PIN_A4) |
In the line above, by specifying only the xmit pin, you are telling the
compiler to create a software UART, and to not use the hardware UART.
Is that what you want to do ? It should still work, but is it what you want ?
|
So if I want to use the hardware UART, the correct thing to do would be:
Code: | #use rs232(baud=9600, UART1, xmit=PIN_A4, rcv=PIN_A5) |
Is that it?
I'll only need to transmit information, thats why I thought I didn't have to specify the rcv pin. I'll try that way and do the other changes too.. Thank you a lot guys. |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Mon Jun 17, 2013 9:32 am |
|
|
Quote: | Quote: | #use rs232(baud=9600,xmit=PIN_A4)
#use fast_io(a)
set_tris_a(0b00011000);
|
In your code above you're setting Pin A4 to be an input pin in the
set_tris_a() line. In a TRIS value, a '1' means the pin is set as an input.
But the 12F1822 data sheet clearly says the TX pin must be configured
as an output:
|
Once I'm using pins 0, 1 and 2 as analog inputs, the correct tris would be
Code: | set_tris_a(0b00101111); |
Right??
I'm sorry for the dumb questions, it's because i'm a begginer and my english level isn't high, so there's a lot of information in the datasheet I don't understand. |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Mon Jun 17, 2013 1:58 pm |
|
|
I've changed my code, but it still doesn't work. I checked the signal with the oscilloscope and period was 500ns, which obviously does not match with my delay. Anyway, the signal of pin a4 looks like a clock signal, and I don't know why is that.
My current code is this:
Code: |
#include <12f1822.h>
#device adc=10
#FUSES NOWDT
#FUSES INTRC_IO
#FUSES MCLR
#FUSES NOBROWNOUT
#FUSES NOIESO
#FUSES NOFCMEN
#use delay(clock=4000000)
#use rs232(baud=9600,UART1, xmit=PIN_A4, rcv=PIN_A5)
#use fast_io(a)
float vx,ax,vy,ay,vz,az;
void PrintAccel(char ca,float a)
{
printf("A ac. no eixo %c e': %f \n\r",ca,a);
}
void main() {
set_tris_a(0b00101111);
setup_adc_ports(sAN0|sAN1|sAN2|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE){
set_adc_channel(0);
delay_us(100);
vx = read_adc();
vx = vx*0.0048875855327468;
ax = (vx-1.65)*12.25;
PrintAccel('x',ax);
delay_ms(1000);
set_adc_channel(1);
delay_us(100);
vy=read_adc();
vy = vy*0.0048875855327468;
ay = (vy-1.65)*12.25;
PrintAccel('y',ay);
delay_ms(1000);
set_adc_channel(2);
delay_us(100);
vz=read_adc();
vz = (vz*0.0048875855327468);
az = (vz-1.65)*12.25;
PrintAccel('z',az);
delay_ms(1000);
}
}
|
Any light?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 17, 2013 2:18 pm |
|
|
Quote: | I've changed my code, but it still doesn't work.
|
What's your CCS compiler version ? Look at the top of the .LST file
in your project directory to see the version. It will be a 4-digit number
like 4.141 or 4.140, or 4.065, or 3.249 or something like that. Post it. |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Thu Jun 20, 2013 11:26 am |
|
|
PCM programmer wrote: | Quote: | I've changed my code, but it still doesn't work.
|
What's your CCS compiler version ? Look at the top of the .LST file
in your project directory to see the version. It will be a 4-digit number
like 4.141 or 4.140, or 4.065, or 3.249 or something like that. Post it. |
My version is 4.105. Should I update it??
I think I'll try to do the same with pic12f683. Simulation worked in proteus.
Just waiting for the arrival of the devices. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 20, 2013 11:50 am |
|
|
Your version is totally screwed up. The fuses are wrong. Also, the CCS
functions are quite different, and I suspect wrong, in many cases.
Here are the fuses listed at the end of the .LST file in vs. 4.105.
Note that there is only one line, for Config Word 1:
Code: | Configuration Fuses:
Word 1: 30E4 NOWDT NOCPD NOPROTECT MCLR PUT INTRC_IO NOBROWNOUT NOIESO NOFCMEN |
Here are the fuses for vs. 4.141. Note that there are two lines now
(which is correct) and note that the settings are different:
Code: |
Configuration Fuses:
Word 1: 09C4 INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT NOIESO NOFCMEN
Word 2: 1EFF NOWRT PLL_SW STVREN BORV19 NODEBUG NOLVP |
Your version (4.105) disables the CLKOUT function in the config bits,
but vs. 4.141 does it correctly and enables it.
My advice is if you want to use the 12F1822, get rid of your version. |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Thu Jun 20, 2013 12:09 pm |
|
|
PCM programmer wrote: | Your version is totally screwed up. The fuses are wrong. Also, the CCS
functions are quite different, and I suspect wrong, in many cases.
Here are the fuses listed at the end of the .LST file in vs. 4.105.
Note that there is only one line, for Config Word 1:
Code: | Configuration Fuses:
Word 1: 30E4 NOWDT NOCPD NOPROTECT MCLR PUT INTRC_IO NOBROWNOUT NOIESO NOFCMEN |
Here are the fuses for vs. 4.141. Note that there are two lines now
(which is correct) and note that the settings are different:
Code: |
Configuration Fuses:
Word 1: 09C4 INTRC_IO NOWDT PUT MCLR NOPROTECT NOCPD NOBROWNOUT NOCLKOUT NOIESO NOFCMEN
Word 2: 1EFF NOWRT PLL_SW STVREN BORV19 NODEBUG NOLVP |
Your version (4.105) disables the CLKOUT function in the config bits,
but vs. 4.141 does it correctly and enables it.
My advice is if you want to use the 12F1822, get rid of your version. |
Ok, man. Thank you very much! I'll do what you suggested |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Thu Jun 20, 2013 1:43 pm |
|
|
I've updated my version to 4.114
Serial communication is finally functioning (thank you pcm!). I'm receiving the strings, but there is something with my values. I must receive floats in a range of -9.8 to +9.8 and the same value is being printed all the time, something irrelevant like -7%$...
Is there something wrong in the way I'm treating my floats?? Maybe something to do with Ttelmah said (I didn't understand well what he said) ??
Besides that, I think my delay is not being respected, once I'm receiving the strings within a small period of time, but I'll try to change my delay and see if it works.. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1348
|
|
Posted: Thu Jun 20, 2013 2:04 pm |
|
|
How are you sending the floats? ASCII, binary? If in binary, did you convert the floats to the format that CCS uses? |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Thu Jun 20, 2013 3:49 pm |
|
|
Hi,
Basic troubleshooting. You should start by printing the value(s) returned by the read_adc() function to see if the A/D is working as you expect. Vary the input signal(s), and see if these results track your expectations....
Basically, Ttelmah said not to use floats at all. Floating point arithmetic is horribly inefficient on a small processor like the PIC. Instead of using floats, use 'scaled integers' instead, and then get creative with how you format your output to see the results you want! Search the forum, this topic has been covered many, many times!
John |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Tue Jun 25, 2013 5:34 pm |
|
|
ezflyr wrote: | Hi,
Basic troubleshooting. You should start by printing the value(s) returned by the read_adc() function to see if the A/D is working as you expect. Vary the input signal(s), and see if these results track your expectations....
Basically, Ttelmah said not to use floats at all. Floating point arithmetic is horribly inefficient on a small processor like the PIC. Instead of using floats, use 'scaled integers' instead, and then get creative with how you format your output to see the results you want! Search the forum, this topic has been covered many, many times!
John |
I just did it, I printed vx, vy and vz as the return of function read_adc, and
when I did this using ints (declaring vx, vy and vz as ints) everything went just fine. I got my expected results from adc.
But when I used those variables as floats, I got garbage.
It seems that I must not use floats at all, just like Ttelmah said, but I still didn't get it how I'm going to do this in an accurate way.
I'll try to do what he said with int16 type and see if it works. |
|
|
matheusmestres28
Joined: 30 Apr 2013 Posts: 20
|
|
Posted: Mon Jul 01, 2013 10:58 am |
|
|
Something strange is happening and I have no idea why.
First of all, I used the code above, with floats, and I just received crap.
Then, I wrote a test program with 2 printf's. In the first one I sent a float variable and in the second I sent an integer variable. When I tested it with the serial communication app, I received the integer correctly and the float uncorrectly (garbage as expected).
Then I thought: "If I do what Ttelmah said, maybe I have a chance of receiving my values", that's why I addapted my code to use int32 values.
However, it didn't work. I received garbage just like with the floats variables..
Someone have an idea of what am I doing wrong?
Code: |
#include <12f1822.h>
#device adc=10
#FUSES NOWDT
#FUSES INTRC_IO
#FUSES MCLR
#FUSES NOBROWNOUT
#FUSES NOIESO
#FUSES NOFCMEN
#use delay(clock=4000000)
#use rs232(baud=9600,UART1, xmit=PIN_A4, rcv=PIN_A5)
#use fast_io(a)
long long int vx,vy,vz;
signed long long int ax,ay,az;
//int p1[5],p2[5],p3[5];
//int kx,ky,kz;
void PrintAccel(char ca,long long int a)
{
printf("A aceleracao no eixo %c e': %ld x 10^-8 [m/s^2] \n\r",ca,a);
}
void main() {
set_tris_a(0b00101111);
setup_adc_ports(sAN0|sAN1|sAN2|VSS_VDD);
setup_adc(ADC_CLOCK_INTERNAL);
while(TRUE){
set_adc_channel(0);
delay_us(100);
vx = read_adc();
vx = vx*4887;
ax = (vx-1650000)*1225;
PrintAccel('x',ax);
//printf("A tensao no eixo x e': %d \n\r",vx);
delay_ms(1000);
set_adc_channel(1);
delay_us(100);
vy=read_adc();
vy = vy*4887;
ay = (vy-1650000)*1225;
PrintAccel('y',ay);
//printf("A tensao no eixo y e': %d \n\r",vy);
delay_ms(1000);
set_adc_channel(2);
delay_us(100);
vz=read_adc();
vz = vz*4887;
az = (vz-1650000)*1225;
PrintAccel('z',az);
//printf("A tensao no eixo z e': %d \n\r",vz);
delay_ms(1000);
}
}
|
|
|
|
|
|
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
|