Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Soft-RS232 on 12F675 ~ Not syncning?

Status
Not open for further replies.

johankj

New Member
Hello all. This is my first post, althought I've been reading this forum quite a bit. Excellent stuff! Anyways, I hope there is someone out there that can help me with my little PIC-Chip. :eek:

I'm a novice with PICs, but I have a good project which require RS232. I have managed to to it with a 16F627, but I need ADC on a small footsprint, so I went for the 12F675.

After I rewrote the code to fit the 12F675, I just couldn't get it working. :( I was banging my head against the wall for weeks, but I just couldn't figure out why. :mad:

My suspicion is that I overwrote the OSCCAL values. I'm not sure if I can read the location of that value, since the programmer I'm using (Velleman) is not that good. If I jump to that address, as part of the recommended calibrarion routine, the PIC hangs. I'm pretty sure it's lost, is this what you would expect from an overwritten OSCCAL value? 3F3F, I'm not even sure what that transelates to in Opcode. I've ordered a proper programmer, which should arrive next week :D

BTW: Two good links to pages regarding OSCCAL:
**broken link removed**
**broken link removed**

I'll post my code below for anyone to check. Sorry for the mess, couldn't get the table thing to work. I've written it as simple as possible, with no trixi parts. Is my code ok? Does it do what I want it to do? (Which is to output an ASCII letter every now and then :p )


list p=12F675 ; list directive to define processor
#include <p12f675.inc> ; processor specific variable definitions

__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_oFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

;***Set up the Constants
COUNT1 equ 20h ; First counter for our delay loops
COUNT2 equ 21h ; Second counter for our delay loops
RS232TX equ 23h ; Variable byte to send on RS232
RS232LC equ 24h ; RS232 Delay Loop counter
RS232BC equ 25h ; RS232 Bit counter (0 to 7)

;***Set up the port & Initialise
bcf STATUS, RP0 ; Bank 0
clrf GPIO ; Init GPIO
movlw 0x7 ; Set GP<2:0> to digital IO? (07h not 0x7)
movwf CMCON ; Disable comparator
bsf STATUS, RP0 ; Bank 1
clrf ANSEL ; Digital IO, disables ADC
; call 0x3ff ; Get Calibation value
; movwf OSCCAL ; Calibrate
movlw B'00100000' ; Set GPIO
movwf TRISIO ; All pins outputs, except GPIO5

bcf STATUS, RP0 ; Bank 0

MOVLW b'01010101' ; Byte to be sent. Not implemented.
MOVWF RS232TX ;

bcf GPIO,2 ; Clear GPIO2, initialization for RS232

;*** Start of main loop
Effect1
movlw b'00000100' ; Start bit
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

;*** Start LSB
movlw b'00000100' ; LSB (0)
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000000' ; 1
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000100' ; 2
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000000' ; 3
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000100' ; 4
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000000' ; 5
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000000' ; 6
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

movlw b'00000100' ; MSB (7)
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS
;*** End MSB

movlw b'00000000' ; Stop bit
movwf GPIO ;
call RS232BitDelay ; Wait for 104uS

call Delay ; The long wait
call Delay ;

goto Effect1 ;

;*** Bit Delay for RS232
RS232BitDelay ; This loop loops for exactly one bit to be
MOVLW 0x18 ; Pushed on an RS232 line 9600,1,N
MOVWF RS232LC
RS232Loop
nop
DECFSZ RS232LC,1
goto RS232Loop
return

;*** Longer wait
Delay
Loop1 decfsz COUNT1,1 ; This second loop keeps the LED
goto Loop1 ; turned off long enough for us to
decfsz COUNT2,1 ; see it turned off
goto Loop1 ;
return

end

;****End of the program****

I'm gonna order a few more of those 12F675, and see if I can't get it working. Any advice on the above would be most appreciated, to recap: Is my code OK, and have I overwritten OSCCAL?

Does anyone know the aproximate frequency-range for the internal oscilator?

Oh, and the project I'm doing with this particular PIC is a circut that samples temperature and moisture, and sends it down RS232. I will actually use this on work. I'll post the whole project when it's done, if anyones interested. ;)

All replies are most welcome. And thanks again everyone for an excellent forum.
 
Your code is too horrible to look at! :D

Check the datasheet for the BCF and BSF instructions, you DON'T access individual pins in that crude fashion on a PIC, only on inferior antique processors!. You also use a loop to send 8 bits!.

You should also check my tutorials, although for the 16F628 they only require very slight changes for the 12F675, and include nice reliable RS232 routines!.
 
Yeah, sorry for the bad code. I was using BCF and BSF, together with a incremental barrell function (To print the whole ASCII-table). but I thought this was easier to debug (at least for me :) ), because I think it is a timing error.

(Thanks for the quick reply BTW - And I loop to send 10 bits :p :D )
 
Last edited:
johankj said:
My suspicion is that I overwrote the OSCCAL values. I'm not sure if I can read the location of that value, since the programmer I'm using (Velleman) is not that good. If I jump to that address, as part of the recommended calibrarion routine, the PIC hangs. I'm pretty sure it's lost, is this what you would expect from an overwritten OSCCAL value? 3F3F, I'm not even sure what that transelates to in Opcode. I've ordered a proper programmer, which should arrive next week :D

Your suspicioun is correct. If the callibration value is lost, probably you won't have precise timing for any serial routine.
The calibration value is in the last location and is read/written as any other location by the (hardware) programmer. The software can take care of it or you have to write the known value manually, after transferring the code.
Second problem: you can't use the calibration routine when the last location contains 0x3F3F. You need a RETLW (0x34) instruction (with a random calibration value). 0x20 selects the center frequency for example. You may try some values or use a crystal (if you have enough I/O pins).

EDIT: 0x20 = b100000 (only 6 bits are used in the OSCCAL register and they are left justified.
 
Last edited:
h20=b100000=d32 :) I see.

So I guess I could just move that into OSCCAL, and see if I get lucky. ;)

The data-sheet doesn't say, does anyone know how much a 1 inreases/decreases the frequency? I remember reading somewhere that it was tested to ~0.78% But does Microchip say anything about it.

I just thought of something. I have a Fluke 110 multimeter, which can measure frequencies up to 50kHz = 20uS period. I'll just use it to measure the 104uS period, and then I'll see if it caribrated. I'll just modify the code to go 0101010101... Hopefully the fact that it's a square-wave matter.

4.230 Khz +-0.1% + 231.5 +-0.1% uS on min values (000000xx)
5.730 Khz +-0.1% = 174.5 +-0.1% uS On reset values (100000xx)
7.610 Khz +-0.1% = 131.4 +-0.1% uS On Max values (1111111xx)

Well, I could detect a change, but not as detailed as I hoped. Those values are off. :(

Neither of them worked, sadly. Well, time to hit the sack. I'll try again tomorrow, maybe lower the frequency or something. I'll guesse I'll be ordering a few more of these, and then learn from my mistake...
 
johankj said:
h20=b100000=d32 :) I see.
Yes, only 6 bits of the OSCCAL register are used. 0 selects the minimum frequency and 63 the maximum frequency. The 6 bits are left justified in the register, as you wrote (I've added a note to my previous post).


I usually place a delay routine after the calibration... I don't remember if it's necessary, but I think that the oscillator takes some time to become stable.
 
Last edited:
First, build RS232 softcode on a known good stable PIC set to same internal RC frequency as the 12F675. Once working good, copy over to 12F675.

For all my 12F675 projects, I include a power-up configurator for the oscillator. If a push a button or just pull an i/o line high during power-up, PIC will go into config mode. I use a scope to monitor another i/o line which when calibrated should be a solid 4 MHZ wave. This was done because I had crap PIC programmers and had no choice but to reconfigure the PIC oscillator value after each flash.

Basically, the current frequency is show on scope, and if you wish to adjust, just hold down or tap the button till desired frequency is met. Each button tap saves the oscillator into eeprom. What is not seen is that on power up the PIC automatically loads the oscillator value from eeprom and sends it to OSCCAL.
 

Attachments

  • oscillator-config.txt
    702 bytes · Views: 279
Last edited:
hi,
I bought a bunch of 12F629's a while ago, before i did any programming i read every chip and noted the oscal value for each chip. This saved me alot of hassle later on, i suggest you do the same.:)
 
eng1 said:
EDIT: 0x20 = b100000 (only 6 bits are used in the OSCCAL register and they are left justified.

But its the most significant 6 bits, right? Yeah, left justefied, I saw the it in your other post now.

My next question would be if there is any harm, or a minimum grace period in repeatedly writing to the OSCCAL register. I guesse not. :)

Basically, the current frequency is show on scope, and if you wish to adjust, just hold down or tap the button till desired frequency is met. Each button tap saves the oscillator into eeprom. What is not seen is that on power up the PIC automatically loads the oscillator value from eeprom and sends it to OSCCAL.

That is a good idea. I'm gonna use i variation on that, since I don't have a scope (yet), a reliable frequency counter, or another factory calibrated 12F675 (yet). I'll do a frequency sweep to see when the RS232 syncs, and then just use that frequency.

I bought a bunch of 12F629's a while ago, before i did any programming i read every chip and noted the oscal value for each chip. This saved me alot of hassle later on, i suggest you do the same.

Yeah, like I said, I've learnt my lesson. :eek:

I'm gonna write a small program that does what I said tonight, I'll post the results.
 
Success!!!

I wrote a program that is a vertion of donnidj's idea, but simpler. It starts OSCCAL at zero on reset, then writes an 'A' on RS232. It then adds 'one' to the OSCCAL value, pauses, and returns to the loop.

Here's what it looks like in the terminal, copied and pasted to Notepad to easier see where OSCCAL 'loops':

longaaas-jpg.11290


Interestingly, the rs232 seems quite robust, syncing for OSCCAL values about 14 values apart. I went for the middle one, of course.

Now where did I write down that OSCCAL value? :p

Thanks everyone for suggestions and help. :D
 

Attachments

  • LongAAAs.jpg
    LongAAAs.jpg
    26.3 KB · Views: 964
I needed near perfect 1 microsecon instruction cycles because I was measuring high velocity projectiles in my chronograph. Now the RS232 is robust because it has a high tolerance, both the PIC and the PC. Alot of PC's and devices's rs232 clocks are far from being at center frequency of their baudrates. Get a good Digital scope and take a look at a sweep of baud rates transmitted out of your PC. You will wonder how two devices even communicate with the level or error in timing it produces. RS232 has gotten away with this large tolerance because the baud rates are multiples of each other as oppossed to being small increases next to each other like 9.6K, 9.7K, 9.8K...

Please make this lesson's check out to "donniedj". Thank you :)
 
Last edited:
johankj said:
Now where did I write down that OSCCAL value? :p

You won't be able to find the value when you need it, unless....

You inscribed it on the underside of the chip using a sharp pin.

This is the first thing I do when I got the new chip.
 
johankj said:
Interestingly, the rs232 seems quite robust, syncing for OSCCAL values about 14 values apart. I went for the middle one, of course.

If you think about how RS232 receive works then it is reasonable to assume that it should tolerate ±5% timing error. When a start bit is received the hardware (or software) waits 1½ bit times until sampling for the next bit and then 1 bit time between subsequent samples. For the receiver to read the last bit incorrectly the time has to have moved by a ½ bit after 8 (or 9) bits. Thats 1 in 16 or about 6%.

It makes you realise that the 1% internal clock is easily accurate enough for RS232 at any speed the hardware supports.

BTW, well done on finding an elegant and simple method to recalculate the OSCAL value.

Mike.
 
Pommie said:
When a start bit is received the hardware (or software) waits 1½ bit times until sampling for the next bit and then 1 bit time between subsequent samples.

Actually not, you wait half a bit time, and confirm you're still in the start bit, then wait one bit time and read the first bit. This helps to prevent false triggering.

Obviously for the timing question though it makes no difference at all.
 
I just discovered the 12F683 chip some time ago. It can operate up to 8MHz and does not use an OSCAL value. It is somehow self calibrating. I'm using it now instead of the 12F675. Check it out.

Jess
 
That's my favorite 8-pin PIC. I should have mentioned it to you before.

It's fast enough to support a full-duplex 9600 baud bit-banged serial I/O package with circular buffers using 3x bit-rate interrupts.

Regards, Mike
 
I have alot of samples of both 675 and 683 (683 collecting dust in bin) but was unaware that 683 default calibration value '0' means factory calibration. All this time I thought all 8-pin PICs must be calibrated once erased just because the 675 must be.

These 8-pin and 8-bit wonders just keep getting better. Only if the other Micro company could follow in Microchips footsteps, only if...
 
The calibration values are stored in fuses in a special register, beyond the user program memory and they're not erased when programming the PIC12F683.
I like this PIC because it has TIMER2 module too.
 
It's also the only 8-pin part with a CCP module.

Please check out this zero jitter 8-channel Servo Controller concept (below).

Regards, Mike
 

Attachments

  • Crazy-8 Servo Controller v3 (12F283).JPG
    Crazy-8 Servo Controller v3 (12F283).JPG
    55.1 KB · Views: 727
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top