View previous topic :: View next topic |
Author |
Message |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 20, 2009 9:59 pm |
|
|
Quote: |
My question is, to which pins in the PIC, I need to connect the TX and RX
pins? Can I connect them to Pin11 (RB5) and Pin12 (RB6)? |
RB6 and RB7 are used by the ICD programmer, so it's best not use
those pins for anything else (if possible).
The 16F819 doesn't have a hardware UART, so you can use any free
i/o pins for a software UART. In fact, you don't currently need to
receive data from the PC, so you really only need a transmit (Tx) pin.
You could use RB5 for that.
Here are the connections:
1. Connect the Vcc pin on the RS232 board to +5 volts.
2. Connect the GND pin on the RS232 board to ground.
3. Connect the TXD pin on the RS232 board to pin RB5 on the PIC.
Here are some instructions on how to use HyperTerminal:
http://www.ccsinfo.com/forum/viewtopic.php?t=9253
Note: The instructions say to set it for 4800 baud. Instead, set it for 9600.
After you have connected everything, and after you have configured
and are running HyperTerminal, and after you have connected your
RS232 board to your PC with a serial cable, then you can compile
and load this program into your PIC. It should display "Hello World"
in the Hyperterminal window:
Code: | #include <16F819.H>
#fuses INTRC_IO, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_B5)
//================================
void main()
{
printf("Hello World \n\r");
while(1);
} |
|
|
|
nizar445
Joined: 09 Jun 2009 Posts: 23
|
|
Posted: Sun Jun 28, 2009 5:09 am |
|
|
Dear PCM programmer
Thank you very much for your help and instructions, I’ve managed to get your testing programme to work on my PIC and it did display "Hello World" in the Hyperterminal window, then I put the printf command in different places in my programme and it also worked, but when I tried to display the frequency it didn’t work, all what I got is some strange letters sometimes and sometimes nothing. I used the following command to display the frequency:
Code: | printf ("\n", frequency); |
Thanks again for your help |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Sun Jun 28, 2009 5:22 am |
|
|
nizar445 wrote: | I used the following command to display the frequency:
Code: | printf ("\n", frequency); |
Thanks again for your help |
Assuming that your frequency is 16 bit value, try like that:
Code: | printf("F= %lu \n",frequency) |
Problem in your code is that you do not specify where you want to put your variable and how should be represented.
%lu <--- means: here will be variable that is long unsigned value. |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Sun Jun 28, 2009 2:34 pm |
|
|
Need comment on code. It works I'm just not sure it is accurate. I'm using external 20.000000Mhz quartz oscillator to get accurate stable clock for PIC.
I tested 1kHz source and it is measured as 1000Hz. When I measure another 10.000Mhz quartz oscillator I get result 9999800Hz....
My dilemma: is it possible due to the code that higher frequencies would be measured incorrectly. (Don't have freq. counter to compare )
Hardware:
PIC16F916 - Had it on test board so I used this one
LCD - classic 2x16 on PortB
Input on RC6 - T1CKI
Code: | #include <16F916.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES EC_IO //External clock
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=20M)
#define use_portb_lcd TRUE
#define LCD_DATA_PORT B
#define LCD_TYPE 2
#define LCD_TRIS_LOCATION B
#include "lcd.c"
int16 gCount=0;
int16 gFreqL=0;
int16 gFreqH=0;
int32 gFreq;
#int_TIMER1
void TIMER1_isr(void)
{
gFreqH++;
}
#int_TIMER2
void TIMER2_isr(void)
{
int16 _tmp;
gCount++;
if (gCount>=1000)
{
gFreqL=get_timer1();
_tmp=gFreqH;
set_timer1(0);
gFreq=make32(_tmp,gFreqL);
gFreqH=0;
gCount=0;
}
}
void setup()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_OFF);
setup_spi(SPI_SS_DISABLED);
setup_lcd(LCD_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_4,124,10); // Interrupt every 100.0000ms
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_TIMER2);
enable_interrupts(GLOBAL);
lcd_init();
}
void main()
{
setup();
while (1)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"F:%12LUHz",gFreq);
delay_ms(200);
}
}
|
Last edited by bungee- on Sun Jun 28, 2009 3:20 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 28, 2009 2:46 pm |
|
|
Why don't use the CCP to capture the Timer1 value ? That's what it's
intended to be used for. |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Sun Jun 28, 2009 3:19 pm |
|
|
PCM programmer wrote: | Why don't use the CCP to capture the Timer1 value ? That's what it's
intended to be used for. | As I understand CCP there should be an external event on pin to trigger capture. Or am I wrong?
If it is possible to do it programatically please advise.
Thank you for your help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 28, 2009 3:22 pm |
|
|
Quote: | I tested 1kHz source.
Input on RC6 - T1CKI |
Isn't that what you have ? You have a 1 KHz input signal.
Why not connect it to the CCP1 pin and use the CCP tachometer code
that I have posted, and that is available in various threads, including
this one. |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Sun Jun 28, 2009 4:45 pm |
|
|
Well I tried your code. I also rewrite it so it is 24bit CCP according to your posts.
.... it will show 1kHz signal, but with 10MHz input signal all I'm getting on display is 0Hz. And I want to measure frequencies even higher. So my original code is for now better. Question that remains is ... is it accurate or is ther flaw in coding that will be affecting the measurement. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jun 28, 2009 5:02 pm |
|
|
OK, I didn't understand that you wanted to measure an input signal
of up to 10 MHz. (I thought you meant you were using 10 MHz as the
PIC's oscillator frequency). An input signal of 10 MHz is too high for
the CCP method of measuring frequency. |
|
|
bungee-
Joined: 27 Jun 2007 Posts: 206
|
|
Posted: Mon Jun 29, 2009 8:52 am |
|
|
I probably was not clear in my first post. I want to be able to measure frequencies as high as it goes, but I don't want to loose accuracy. I just wanted an second opinion of my code. If there are maybe some accuracy issues because of code it self. |
|
|
nizar445
Joined: 09 Jun 2009 Posts: 23
|
|
Posted: Mon Jun 29, 2009 1:38 pm |
|
|
Dear bungee
Thanks a lot for the explanations I’ve managed to get it to work now.
Dear PCM programmer
Thank you very much for your help and advice. It did really help me, especially about adding the “RS-232 capability” to my board. It was very useful and it did make it much
easier for me to fix the problems in my code as you said before.
I just have one more little question, I’ve changed all the variables in the program to “float” instead of “int16” and I am getting the following output in the HyperTerminal window:
Code: | 62.5073 Hz
62.5074 Hz
6&.5073 Hz ------------
.5073 Hz ------------
62.5074 Hz |
My question is why my readings some times not so correct? (6&.5073 Hz, .5073 Hz instead of 62.5074 Hz) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jun 29, 2009 1:58 pm |
|
|
That's because the 16F819 doesn't have a hardware UART. Therefore
you are using a software UART on pin RB5.
A software UART transmits pulses on the Tx line by "bit banging" the
i/o port output latch. The pulse durations are created by sofware delay
loops. If an interrupt occurs while a bit is being transmitted, the
pulse duration will be increased, and incorrect data will be received
by the PC.
You could disable interrupts while transmitting each byte, by adding
the DISABLE_INTS parameter to your #use rs232() statement, as
shown below:
Code: | #use rs232(baud=9600, xmit=PIN_B5, DISABLE_INTS) |
This shouldn't cause any interference with the INT_CCP interrupt,
because with a 70 Hz input signal, the interval between edges is 14.3 ms.
The disabling of interrupts for a 1 ms period would only be an issue if
you were trying to measure an input signal greater than 1 KHz (with a
period of 1 ms or less). Then you could miss an INT_CCP interrupt. |
|
|
nizar445
Joined: 09 Jun 2009 Posts: 23
|
|
Posted: Thu Aug 20, 2009 4:43 pm |
|
|
Dear PCM programmer
Thanks a lot for all of your previous help to get my frequency reading device working and thanks for the other people who tried to help me before. I’m sorry because I keep using the same post to ask questions but your tips and advices were really useful to me and I did learn quite a lot from this wonderful forum.
My problem this time is that, I have changed the old PIC (16F819) with new one (16F87) as the new one has very similar pins with more memory. I’ve used the same old previous program which it was working perfectly but I have only changed the header file to “#include <16F88.h>” and fed my square wave input to PIN 6 instead of pin 8 in the old PIC.
Every thing seems to be working nicely apart from that, every nearly 20 readings I have one wrong reading which is very low one and sometimes negative!! and I don’t know why is that happening, my question is that, is there anything special about PIC 16F87 that I need to consider?
Another question, PIC 16F87 has RX and TX pins, do I still need to disable the interrupts while transmitting each byte of data?
Code: | #use rs232(baud=9600, xmit=PIN_B5, DISABLE_INTS |
PIC pins can be found below:-
http://www.mcu.hk/GIF/PIC16F87.gif
Thanks a lot and I look forward for your suggestions and advices. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 20, 2009 4:57 pm |
|
|
Quote: |
I have changed the old PIC (16F819) with new one (16F87)
but I have only changed the header file to “#include <16F88.h>” and |
If you're using a 16F87, why are you including 16F88.h in your program ?
Why not include 16F87.h ?
Quote: |
Every thing seems to be working nicely apart from that, every nearly 20
readings I have one wrong reading which is very low one and sometimes
negative!! and I don’t know why is that happening, my question is that, is
there anything special about PIC 16F87 that I need to consider?
|
What is the frequency of the input signal during this test ?
What is the crystal frequency of the PIC ?
Quote: | Another question, PIC 16F87 has RX and TX pins, do I still need to disable the interrupts while transmitting each byte of data?
#use rs232(baud=9600, xmit=PIN_B5, DISABLE_INTS
|
No, you don't need to disable interrupts if you are using the hardware
UART pins. You can remove the DISABLE_INTS parameter. |
|
|
nizar445
Joined: 09 Jun 2009 Posts: 23
|
|
Posted: Thu Aug 20, 2009 5:07 pm |
|
|
Dear PCM Programmer
Thanks a lot for your quick reply.
Quote: | Why not include 16F87.h ? |
Sorry, that was a typing error I have included the “16F87.h” file.
Quote: | What is the frequency of the input signal during this test? |
40Hz
Quote: | What is the crystal frequency of the PIC? |
External crystal with 4MHz frequency and two 22pF capacitors.
Thanks again. |
|
|
|