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

ADC do not work after the use of getc()

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



Joined: 21 Jan 2012
Posts: 2

View user's profile Send private message

ADC do not work after the use of getc()
PostPosted: Sat Jan 21, 2012 2:00 pm     Reply with quote

Hello all!

I'm trying to read a adc value and after that reads a rs232 input. The serial input works fine, but the adc stops to work when I try to use both functions. If I comment the line where I state "c = getc();" the code works fine and I can read analog inputs with no problem. I'm running this code on a PIC12F675.

What I want to do?

I want to read adc values and at the same time read serial input to control internal pic funcions and the code bellow ins't working.

Can anyone help me?

Code:

void main()
{

#include <12F675.h>

#device ADC=10

#fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOCPD

#byte ADCON0   = 0x1F
#byte ANSEL    = 0x9F
#byte CMCON    = 0x19
#byte TRISIO   = 0x85

#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_A2, rcv=PIN_A1)

#include <string.h>
#include <input.c>

//#use rs232(baud=31250, xmit=PIN_A2)

#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5

#byte OSCCAL = 0x80

void midiout(int cc_data, int c_num, int c_val){
   putc(cc_data);
   delay_ms(1);
   putc(c_num);
   delay_ms(1);
   putc(c_val);
   delay_ms(30);
}

void main()
{
 
 #asm
   movlw 00010011
   movwf TRISIO
 #endasm
 
   int16 Value = 300;

   ADCON0 =    0; // ADC off
   ANSEL =     0;  // GPIO pins 0,1,2 and 4 set to all digital
   CMCON =     7;  // Comparators off
 
   setup_adc_ports( AN0_ANALOG );
   setup_adc(ADC_CLOCK_INTERNAL );
   set_adc_channel(0);
   delay_ms(150);                     // Allow the channel to be aquired

   Value = 0;
   
   output_high( GP5 );
      delay_ms(500);
   output_low( GP5 );
      delay_ms(500);
     
   int pad = 35;
   int16 velocity = 0;
   
   puts("Online\r");
   
   delay_ms(1000);
   
   char c;

   while(1)
   { // infinite loop
 
     Value=read_adc();
     c = getc();
     if (Value > 3)
     {
         output_high( GP5 );
         velocity = (0,127 * Value);
         midiout(150, pad, 127);
         
         output_low( GP5 );
     }
 }
Ttelmah



Joined: 11 Mar 2010
Posts: 19499

View user's profile Send private message

PostPosted: Sat Jan 21, 2012 3:11 pm     Reply with quote

First comment - learn to program in _C_.
In C, variables can only legally be defined at the start of code sections. CCS, doesn't complain about them being defined elsewhere, _but_ they often don't work, resulting in memory being corrupted. So, move your variable declarations to the C location....

Now, you cannot do anything 'at the same time', using the software UART. When you call 'getc', the processor will _stop_ and wait for a character to arrive. If while other operations are being performed, the start bit has been missed, and another character doesn't arrive, it may well wait for ever. This is where the hardware UART wins by a factor of millions of times, over the software implementation. With a fast enough clock rate, and a slow enough baud rate, you can give operation that will catch characters when they arrive, by using an interrupt, but I doubt if your chip is fast enough to do this at 31250bps.

There are also several bits of code that are just 'wrong'. For instance:
velocity = (0,127 * Value);

The '0' here does nothing. When two things are bracketed together separated by a ',' the first is evaluated, then the second, and the value returned is the value of the second. So the '0' is just sitting wasting space.

Best Wishes
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 6:26 am     Reply with quote

And a few other comments, less important but will help to improve your program:

1)
Code:
void main()
{
This is at the start of your post. I guess it is a copy/paste error? Two main functions aren't going to work.

2) The program doesn't compile because of a missing '}' and the earlier mentioned placement of variable defines.

3)
Code:
#asm
   movlw 00010011
   movwf TRISIO
 #endasm

Using assembly code inside C is ugly and unnecessary. The C-way would be:
Code:
set_tris_a( 0b00010011 );


4) A tricky bug in your original version is caused by the notation 00010011, the compiler sees this as the C-notation for an octal value and compiles into 0X09. The correct notation is 0b00010011 and results into the desired 0x13.

5) By default the CCS compiler will handle the TRIS register settings for you, see the paragraph on STANDARD_IO in the manual chapter 'General Purpose I/O' (page 61).
Initializing the TRIS register without changing the default compiler I/O mode is useless. Either remove the TRIS line or add one of the other preprocessor options for the I/O mode, for example #use fast_io(A).

6)
Code:
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
Great that you rename the useless pin names to something different. But why rename them to something that is just as useless?? For example, when you connected a LED to the GP5 pin, then name the PIN for example LED. Results into much easier code reading.

7)
Code:
   ADCON0 =    0; // ADC off
   ANSEL =     0;  // GPIO pins 0,1,2 and 4 set to all digital
   CMCON =     7;  // Comparators off
This works but is not the easiest way of writing code in CCS, see how much comment you had to add to explain what the code is doing. Another problem is that the code is not portable to another processor. The CCS way would be:
Code:
   setup_adc(ADC_OFF);
   setup_adc_ports(NO_ANALOGS);
   setup_comparator(NC_NC_NC_NC);
Which makes me wonder why you have this init code because two lines lower I see you enable the ADC again, now using the CCS functions. Confused

8)
Code:
velocity = (0,127 * Value);
You must've meant 0.127 (with a dot).
You know that floating point calculations are very 'expensive' in a PIC processor? They take up a lot of memory and processing power. Dividing by 8 (a power of 2) is the same as multiplying by 0.125. About 1% error from your original calculation but as most electronic circuits use components with 10% error this small additional error is often acceptable. You loose little in precision but will save 200 program words (20% ROM capacity).
mfmolina



Joined: 21 Jan 2012
Posts: 2

View user's profile Send private message

PostPosted: Sun Jan 22, 2012 1:11 pm     Reply with quote

Everything I'm reading here is very usefull as I'm just starting to learn about microcontrollers by myself. Actually, there's a lot of things that I must learn.

This code above is a kind of "frankenstein" that I composed based on researching a lot of post throughout this forum. My purpose by now is to make little things and to learn simultaneously. I got some impressive results even all thoses coding erros that you pointed -- at least on my own eyes. I'll spend more time learning how to better code using ccs.

Now I'm trying to make a blinking led with the PIC16F877A.

By now, I'm very happy with your experience. Thanks for your reply!
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