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 support@ccsinfo.com

Serial communication and pic 12f - problem and questions
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
matheusmestres28



Joined: 30 Apr 2013
Posts: 20

View user's profile Send private message

Serial communication and pic 12f - problem and questions
PostPosted: Fri Jun 14, 2013 4:25 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Jun 14, 2013 7:47 pm     Reply with 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:
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: 19350

View user's profile Send private message

PostPosted: Sat Jun 15, 2013 1:40 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 17, 2013 9:26 am     Reply with quote

[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

View user's profile Send private message

PostPosted: Mon Jun 17, 2013 9:32 am     Reply with quote

Quote:
PCM programmer wrote:
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:


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

View user's profile Send private message

PostPosted: Mon Jun 17, 2013 1:58 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jun 17, 2013 2:18 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 20, 2013 11:26 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 20, 2013 11:50 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 20, 2013 12:09 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 20, 2013 1:43 pm     Reply with quote

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: 1324

View user's profile Send private message

PostPosted: Thu Jun 20, 2013 2:04 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Jun 20, 2013 3:49 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Jun 25, 2013 5:34 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Jul 01, 2013 10:58 am     Reply with quote

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);
           
 
  }

}
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