|
|
View previous topic :: View next topic |
Author |
Message |
Sigma
Joined: 03 May 2004 Posts: 48 Location: Sg
|
rs232 communication on 12F629 |
Posted: Wed Oct 06, 2004 1:37 am |
|
|
Hi, all,
I am testing the rs232 communication on PIN_A2 as PBUS. PIN_A2 is connected to a MAX232 transceiver then to one of my comm port. I use a comm port data sniffer to read out the data PIN_A2 has sent out. However, the program only works at 2 volt. When i slowly increase the supply voltage for both the Maxim chip and 12F629, the data reading from the sniffer is not correct.
Followed is my source code.
Code: |
#include "12F629.h"
#fuses INTRC_IO,PUT,NOWDT,NOPROTECT,NOMCLR, BROWNOUT
#define PBUS PIN_A2 //GP2: PBus using RS232 (ext int)
#byte CMCON=0x19
#byte ANSEL=0x9f
#byte GPIO=0x05
/*******************************************************************************************
* PBus - Using RS232 (Half duplex) functions
*******************************************************************************************/
#use delay(clock=4000000)
#use rs232(baud=9600, errors, bits=8, parity=N, xmit=PBUS, rcv=PBUS)
/*******************************************************************************************
* General Functions
*******************************************************************************************/
void cal_Oscillator(void)
{
#asm
call 0x3FF //**Call will return CAL value to W reg
movwf 0x90 //Move CAL value from W to OSCCAL reg
#endasm
}
/*******************************************************************************************
* main
*******************************************************************************************/
void main() {
short done;
GPIO=0;
CMCON=0x07; // Comparator off.
ANSEL=0x00; // All i/o digital.
cal_Oscillator(); //Calibrate internal RC oscillator
ext_int_edge(h_to_l);
disable_interrupts(GLOBAL);
setup_counters(rtcc_internal, rtcc_div_2);
done=FALSE;
while (1) {
if (!done) {
putc(0x65);
putc(0x87);
putc(0x65);
putc(0x43);
putc(0x21);
putc(0x80);
}
}
}
/******************************************************************************************/
|
And the Maxim part number is MAX202CSE. BTW, i also try removing the cal_Oscillator() routine. Same thing happens. And i test the code on 12C672, it working fine. Could anyone help? Thanks.
Sigma |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Wed Oct 06, 2004 4:42 am |
|
|
I suspect your oscillator is running too far off frequency. How about putting the PIC in a continuous loop toggling an output pin and measuring the bit width to derive the oscillator frequency. |
|
|
Sigma
Joined: 03 May 2004 Posts: 48 Location: Sg
|
|
Posted: Wed Oct 06, 2004 8:50 pm |
|
|
Thanks. I tried toogle GP1 every 10us. It does not drift much. But after i put float_high in the #use rs232, it improves. Now from 2 to 2.8 volt, it works properly. but if supply voltage exceeds 2.8 volt, distorted data appears in the sniffer. Why? Did i need a pull-up? but my circuit requires a pull down to wake up another mcu.
Sigma |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Oct 06, 2004 11:42 pm |
|
|
Well if you have a scope, look at the signals and see where the problem lies. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Oct 06, 2004 11:44 pm |
|
|
I'd also check your circuit. Look at the data sheet for the Max232 and make sure that you hooked it up right. Also make sure that if you used polarized caps that you put them in right. |
|
|
Sigma
Joined: 03 May 2004 Posts: 48 Location: Sg
|
|
Posted: Thu Oct 07, 2004 12:15 am |
|
|
I tested my sniffer circuit using other 5 volt data bus. it is working. The waveform from the pin also clear, although mine is a analog one. I just thought it is sth related with the firmware. As when i modified the firmware here and there, such as the float_high, the working voltage range increases. But you do not see any mistake in the source code, is it?
Sigma |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Thu Oct 07, 2004 8:49 am |
|
|
Code: |
void cal_Oscillator(void)
{
#asm
call 0x3FF //**Call will return CAL value to W reg
movwf 0x90 //Move CAL value from W to OSCCAL reg
#endasm
}
|
This is not needed. The compiler makes this call. Look at the LST file for verification. The code should work. But if you do indeed have a scope, then all you have to do is look at the signals and measure the pluse widths to see if the timing is off. |
|
|
Sigma
Joined: 03 May 2004 Posts: 48 Location: Sg
|
|
Posted: Fri Oct 08, 2004 3:15 am |
|
|
I used the following code in the main program to test the pulse width, is it ok?
Code: |
output_high(PIN_A2);
delay_us(10);
output_low(PIN_A2);
delay_us(10);
|
Then i measured GP2 using my scope. It is exactly 10us in between. And makes no difference when i adjust the supply voltage.
Sigma |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Fri Oct 08, 2004 4:11 am |
|
|
Write a short bit of test code that sends continuous uppercase U characters (0x55). This will give you alternating ones and zeros in the data stream then measue the width of a bit of the middle of a character.
Something like:
Code: |
while (1)
{
delay_ms(1); // intercharacter gap for easy character detection
putc(0x55);
}
|
Measure the bit width. Also measure at the output of the max driver. How high the output goes above 0 volts and how low it goes below zero volts? Finally look at the rise and fall times of the bits. |
|
|
djpark
Joined: 02 Mar 2004 Posts: 49
|
|
Posted: Fri Oct 08, 2004 5:58 am |
|
|
Mark wrote: | Code: |
void cal_Oscillator(void)
{
#asm
call 0x3FF //**Call will return CAL value to W reg
movwf 0x90 //Move CAL value from W to OSCCAL reg
#endasm
}
|
This is not needed. The compiler makes this call. Look at the LST file for verification. The code should work. But if you do indeed have a scope, then all you have to do is look at the signals and measure the pluse widths to see if the timing is off. |
Mark is right. The first code CCS execute is to call this itself.
The factory calibration value in PIC12F629/675 is different from chip to chip, my stock include 0x63, 0x80, 0xa0, etc.. When this value is too far off from the factory calibration value stored in the flash, the osc frequency can go too far different to cause RS232 signal unreliable.
My experience shows that 0x63 is changed to 0x80, the slow speed of 1200 baud could not be established. Overiding this value with a fixed 0x90 is like asking for trouble.
Another thing to keep in mind is that some PIC programmers may not read the original calibration value from PIC and write back, but just program 0xff,0xff as in the hex file unless manually inserted. With this extreme calibration value, the PIC may not run at all and lead you to think it is spoiled.
-- dj |
|
|
Ttelmah Guest
|
|
Posted: Fri Oct 08, 2004 7:15 am |
|
|
djpark wrote: | Mark wrote: | Code: |
void cal_Oscillator(void)
{
#asm
call 0x3FF //**Call will return CAL value to W reg
movwf 0x90 //Move CAL value from W to OSCCAL reg
#endasm
}
|
This is not needed. The compiler makes this call. Look at the LST file for verification. The code should work. But if you do indeed have a scope, then all you have to do is look at the signals and measure the pluse widths to see if the timing is off. |
Mark is right. The first code CCS execute is to call this itself.
The factory calibration value in PIC12F629/675 is different from chip to chip, my stock include 0x63, 0x80, 0xa0, etc.. When this value is too far off from the factory calibration value stored in the flash, the osc frequency can go too far different to cause RS232 signal unreliable.
My experience shows that 0x63 is changed to 0x80, the slow speed of 1200 baud could not be established. Overiding this value with a fixed 0x90 is like asking for trouble.
Another thing to keep in mind is that some PIC programmers may not read the original calibration value from PIC and write back, but just program 0xff,0xff as in the hex file unless manually inserted. With this extreme calibration value, the PIC may not run at all and lead you to think it is spoiled.
-- dj |
One comment.
He is not overriding the value with a fixed value of 0x90. He is moving the value retuned by the call, _to_ the register at address 0x90. The code he posts, is OK, but unecessary.
On the timing test posted, I'd try again, and use an interrupt, generating a pulse on each interrupt. The problems with just using the 'delay' functions, are that these are not allways reliable (depends on the compiler version), and there is also the time involved in setting the bit and/or looping. For example, the code:
Code: |
while (true) {
output_high(PIN_A2);
delay_us(10);
output_low(PIN_A2);
delay_us(10);
}
|
Should _not_ produce an accurate 10uSec pulse. The loop itself takes time, as does the operation of setting/resetting the bit. The high pulse, should be one instruction time longer than 10uSec, or there is a timing problem in the oscillator.
Best Wishes |
|
|
|
|
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
|