View previous topic :: View next topic |
Author |
Message |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
PIC 16F877a No output to hyperterm with printf pls help |
Posted: Sat Oct 13, 2007 11:42 pm |
|
|
I have been messing with this all day, i need to sleep. Hopefully someone can save my sunday. I have made two MAX232 based boards to transmit information from my pics (877a) to the com1 port on the computer. I have tried both boards with the pic, neither produce results.
I have tested the MAX232 boards by shorting the TX/RX and looping my own messages back. However any attempt to print anything to hyperterm shows nothing. I have the TX/RX connected to their corresponding counterparts on the pic C6 and C7. I tried the Simple code :
Code: | #include <16F877A.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES RC //Resistor/Capacitor Osc with CLKOUT
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES WRT_50% //Lower half of Program Memory is Write Protected
#use delay(clock=4M)
#use RS232(baud = 9600, xmit = PIN_C6, rcv = PIN_C7)
// this is my .c
#include <stdio.h>
#include <stdlib.h>
// declare functions
void findnumbers(int temp);
void sendhex(int number, int digit);
void displaynumbers(int hundreds, int tens, int ones);
int getavgtemp();
void main(void)
{
//declartations
int ADC_Num;
int16 total; // the total for avg
int16 realvolts; //adc_num / 204 to get actual voltage
int16 avgnum;
int16 oldtemp = 10;
int16 intvolts; // chop off the tail
char c;
int i = 0;
//adc setup
set_tris_a(0b00000001); //make only pins A0 inputs. 1=input, 0=output.
setup_ADC_ports(RA0_ANALOG); //Make PIN_A0 the only analog input.
//Set the clock source for the ADC. Call with ADC_OFF if ADCs are unused.
setup_ADC(ADC_CLOCK_INTERNAL); //Use the PIC's internal RC oscillator.
set_tris_d(0b11110000);
// what the hell is this ?
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
// internal timers ? they do me a lot of good
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
// no comparator (voltage) NO voltage reference
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// TODO: USER CODE!!
while(1)
{
c = getc();
putc(c);
printf("Testing");
}
|
There is a lot of code after this but its not really relevant. The only thing i can imagine is that my RC oscillator is not working correctly. Im using two 220K resistors in series and a 22pf cap for my rc circuit.
If you have any ideas, ive exhausted all mine, thanks. |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Oct 13, 2007 11:58 pm |
|
|
The RC oscillator is not accurate enough to do RS-232. Your resistor
is probably 5% tolerance and your capacitor is probably 10% tolerance.
The combined tolerance is several times more than the acceptable value.
You should use a crystal.
Also, your program is too complicated. Here's a thread where someone
starts with a program similar to yours, and has problems, and I suggest
a much more simple program, about half-way down the thread.
http://www.ccsinfo.com/forum/viewtopic.php?t=29538 |
|
![](templates/subSilver/images/spacer.gif) |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
thanks |
Posted: Sun Oct 14, 2007 9:30 am |
|
|
Thanks for the reply. Thats about what i thought, the rc circuit is just something i plugged up and made work. Whats worse i just assumed it was about 4mhz (and its probably no where near that). Is the only place i set the clock speed in #use delay(clock = 4M) or do i need to define it somewhere else also (once i get a crystal) ?
If you dont mind ill share my root problem with you. I hate to ask it but i have been looking everywhere trying to get a explination. I have a LM34 hooked up to A_0 it outputs 10mV per Degree F. I have read it with the volt meter at about .70. But when i call read_adc() what kind of result am i getting back ? I try to print it out on the 7seg led and i get like 133 (sometimes). I have read that its a 10bit number and that 0=0 and 5v=1023 but it does not seem to work out.
So i have two questions
1. How can i take the reading from read_adc() and turn it into a integer. Assume im getting like .70v from pin A_0. Does it need to be a int16 or int32 when i tried a int16 i didn't know the flag (%) to try and printf it. If i divide anything doesn't it need to be a float ?
2.) how can i calculate the Hz of a RC circuit ? Isnt it a formula like 1/(r*c) ?
this is my code that actually gets the readings and averages them, the setup of my adc is all ok, i know the port and everything is set up ok and i know im getting a reading back "based" off the output from the LM34.
This is why i was trying to do serial communication because i wanted to printf the adc_num to see what it was !
Code: | output_high(PIN_D3); // light led to tell me im in main
set_ADC_channel(0); //Which pin to read from? In this case, AN0, aka PIN_A0.
// Getting the value from the ADC port
printf("\nStarting");
//read
for(i=0; i<=30; i++)
{
printf("\nadding");
findnumbers(oldtemp);
ADC_Num = read_adc();
delay_us(200);
total += ADC_Num; // add all current temps up in one int;
}
avgnum = (total / i);
avgnum = (5 * avgnum * 100/1024);
intvolts = (int)avgnum;
oldtemp = intvolts;
printf("\nget avg");
//for(i=0; i<200; i++)
//{
findnumbers(intvolts);
//}
printf("\nRaw : %d", ADC_num); |
TIA, you guys are lifesavers, literally saving hours out of my life. But im not asking without trying, believe me ive been messing with this for about 2 weeks now. |
|
![](templates/subSilver/images/spacer.gif) |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
is this supposed to be hard ? |
Posted: Sun Oct 14, 2007 4:36 pm |
|
|
Well i still didnt find a crystal that i can get to work but i did wire up a 555 timer r1=10k r2=22k and cap=22pf or .000022uf which should give me a clock of 12.121212Mhz but i still get NO output on hyper terminal when i wire it all up.
The only thing i changed in the code was
#use delay(clock = 12121212)
And that other guy that had the troubles because his code was "to complicated" would get something on Hyperterminal he just could not do some things his second line is Quote: | Using the following code I can successfully read the output from the PIC in hyperterminal, but pressing a pc key doesn't cause the pic to echo it back as intended: | so he was at least getting something, i dont get anything, not spaces or weird chars nothing.
But of course if i short the rx/tx on my max232 setup i get a echo of whatever i type.
Ive tried to use a few crystals but whenever i hook them up to the clk in and clk out then put a 22pf cap on each leg to ground it dont work.
tia
-mikeAIs |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 14, 2007 4:57 pm |
|
|
1. What is the frequency of the crystals that you have tried ?
2. What oscillator fuse setting did you use for these crystals ?
You can't use "RC" with a crystal. It has to be XT or HS.
Your problem is one of basic electronics. Until that is fixed, nothing
is going to work. |
|
![](templates/subSilver/images/spacer.gif) |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
another day down the drain . . . |
Posted: Sun Oct 14, 2007 10:04 pm |
|
|
Well i found a oscillator, on the outside it says 20.000M I guess that is 20MHz.
I connected it to the clock in/out and each leg goes to a 22pf cap to the ground. I used the same ground that i use for the pic's ground.
this is my "simple" code.
Code: | #include "C:\Documents and Settings\zonemikel\My Documents\serialtest.h"
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,bits=8, parity=N, stop=1, ENABLE=PIN_D2)
//============================
void main()
{
char c;
/*
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
*/
setup_uart(9600);
// TODO: USER CODE!!
c = "t";
putc(c);
while(1)
{
output_high(PIN_D3);
//c = getc();
delay_ms(1000);
putc(c);
output_low(PIN_D3);
delay_ms(500);
printf("test");
}
} |
I can see when the light goes high and it transmits. I can test the db9 connector thats connected to my pc, when it transmits there is a voltage change on the 2nd pin. Also when it transmits i can get a voltage change on pin 11 on the max232. Also In hyperTerm the cursor seems to blink with the tx led, like its receiving something but it never prints anything.
So i know its trying to work, so i can throw out some possibilities could somone please answer these simple questions?
when i short the tx/rx pins on my max232 circut and it echos my input in hyperterm does that mean the circuit is working fine ?
For a simple max232 circut you use 1uf caps, does the voltage on those caps matter ? Mine are 50v.
For hyper terminal do i use none for flow control ?
Can i use polar caps from the crystal to the ground ? (one is polar the other isnt).
for a (crystal) oscillator thats more than 10MHz i would use HS right ? |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Oct 14, 2007 11:12 pm |
|
|
Your code has several things that are not needed, and some things
that are wrong. You're trying to load the character 'c' with a string.
That's not right. Change it to single quotes as shown below.
Code: | #include <16F877A.H>
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
//============================
void main()
{
char c;
c = 't';
putc(c);
while(1)
{
output_high(PIN_D3);
delay_ms(1000);
putc(c);
output_low(PIN_D3);
delay_ms(500);
printf("test");
}
} |
Quote: | Can i use polar caps from the crystal to the ground ? (one is polar the other isnt). |
22pf caps are never polarized. This makes me suspect that you don't
really have 22pf caps. They often look like this:
http://rocky.digikey.com/WebLib/BC%20Components/Web%20Photos/BC%205.0D.jpg
The basic problem is that you really should be using a pre-built demo
board.
Besides the cap, I suspect that connections between the MAX232 and
the PC are probably not correct. See my post in this thread, where
I list the connections between the DB9 on the PIC board and the DB9
connector on the PC. |
|
![](templates/subSilver/images/spacer.gif) |
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Mon Oct 15, 2007 7:47 am |
|
|
Write a simple program to blink an LED once per second and time how long it takes for 100 blinks. This will tell you what your REAL clock speed is. Then insert this value in your #use delay clock statement. As long as your temperature and voltage don't change this should be good enough for RS232 testing until you can get a real crystal working. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
![](templates/subSilver/images/spacer.gif) |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
Thanks guys ! |
Posted: Mon Oct 15, 2007 10:04 am |
|
|
I didnt even notice that ill change the char to = 't'
And yes it would be great to have a pre made demo board ! or a pre made max232 tx/rx board !
When i looked at them on ebay the premade board was like $15 and 5 max232 chips were like $5 so i went the cheep route, if i could do it over i might have done it different. At least i learn more this way.
Im going to make sure i have all the right parts (caps, etc) and try again soon. As far as the wrong connection to the db9 im pretty sure its right pin2 on the db9 is the RX pin and its the one that was shooting all the signals, pin3 was doing nothing but i wasnt trying to receive anything.
As for the input from sherpadoug i like the idea but doesnt the delay go off of what you have in the #use delay(clock=xxx) statement ? so if i was to do a
for(i=0; i<100; i++)
delay_ms(1000);
blink
wouldnt the program calculate the delay based off what i had put in the #use delay(clock = xxx) ? |
|
![](templates/subSilver/images/spacer.gif) |
zonemikel
Joined: 13 Oct 2007 Posts: 53 Location: Texas
|
find hz |
Posted: Mon Oct 15, 2007 8:44 pm |
|
|
Well i counted the time it took for this for loop to finish
Code: | for (i = 0; i < 100; i++)
{
delay_ms(500);
output_high(PIN_D3);
delay_ms(500);
output_low(PIN_D3);
} |
and it was 2min 11 sec or 131 seconds
Im using a 10K resistor and a 22pf cap
I had the #use delay(clock = 30000000); // (3MHz)
Anyone know how i can calculate my actual Mhz from this ? I know a Hz is a cycle a second and we have 133 seconds but how do i know how many cycles passed ? How many cycles are in each of those delay_ms(500) ? |
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Oct 16, 2007 1:34 am |
|
|
Experiment!
You could wait for someone to give you the answer or you could zero in on it on your own in about 5 minutes.
Cut the delay value in half and see if it gets shorter or longer, or vice versa.
As you get closer to your desired 1/2 second pulse, make the pulse longer so it's easier to measure. |
|
![](templates/subSilver/images/spacer.gif) |
|