PDA

View Full Version : RS232 communications issue



DiverBob
- 7th December 2009, 15:53
I have been a lurker on this forum for quite a while and the old threads and answers have served to answer all my questions until now.

I am using a 12F683 processor, 3 pins are configured as ADC inputs, GPIO.2 is for serial communications and GPIO.5 is a digital output. GPIO.5 is taken high at the start of the program and remains hi unless the serial line sends an 'A' followed by a 1. Then GPIO.5 is taken low.

GPIO.5 controls the enable line on a voltage regulator (Microchip 1802T - 5V LDO regulator). When the shutdown line is high the regulator is on and pulling the line low disables the voltage regulator thus turning off the circuit. This is to provide a software means of shutting down a battery-powered circuit to maximize battery life.

The problem I have been experiencing is that the program sits at the SERIN2 command and never seems to recognize the 'A' so it never takes GPIO.5 low. I have cut the program down to its bare essentials but can't seem to figure out why it's not working. I have verified the serial input line is correctly sending the right sequence.


@ DEVICE PIC12F683, MCLR_OFF, INTRC_OSC_NOCLKOUT, WDT_ON, BOD_OFF
@ DEVICE PWRT_ON, FCMEN_OFF, IESO_OFF, PROTECT_OFF

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 200
DEFINE OSC 8

ANSEL = %00111011
ADCON0 = %10000001
TRISIO = %0001111
OSCCON = %01100000
CMCON0 = %00000111
INTCON.7 = 0
INTCON.3 = 1

RESULT VAR word[3]
value var word
holding var word
i var byte

MAIN:
output GPIO.5
GPIO.5 = 1
Goto Main1

Main1:
SERIN2 GPIO.2, 396, [WAIT("A"), value]
if value = 1 then
GPIO.5 = 0
else
if value = 2 then
gosub GETADC
gosub display1
endif
endif
goto Main1
end

display1:
serout2 GPIO.2, 396, 10, [dec result[0], 13]
serout2 GPIO.2, 396, 10, [dec result[1], 13]
serout2 GPIO.2, 396, 10, [dec result[2], 13]
return
end

GETADC:
'average ADC over 10 cycles
holding = 0
for i = 1 to 10
adcin 0, result[2]
holding = holding + result[2]
pause 10
next i
holding = holding/10
result[2] = holding

holding = 0
for i = 1 to 10
adcin 1, result[1]
holding = holding + result[1]
pause 10
next i
holding = holding/10
result[1] = holding

holding = 0
for i = 1 to 10
adcin 3, result[0]
holding = holding + result[0]
pause 10
next i
holding = holding/10
result[0] = holding
return
end
end

Hopefully someone else can see where I am going wrong!

mackrackit
- 7th December 2009, 17:04
Have you tried
DEC value

aratti
- 7th December 2009, 17:33
The problem I have been experiencing is that the program sits at the SERIN2 command and never seems to recognize the 'A' so it never takes GPIO.5 low.

You must change your code:

SERIN2 GPIO.2, 396, [WAIT("A"), value]

in

SERIN2 GPIO.2, 396, [WAIT("A"), value.byte0,value.byte1]

Since serin2 will accept only byte (value is a word) serin2 recognize 'A' but cannot fill the word so it doesn't proceed. Remember you have to transmit your word in two bytes LSB first MSB after.

Naturally if you don't need a word (variable Value) then turn it into a byte variable and use your original code.

Al.

Bruce
- 7th December 2009, 18:10
One major problem is you have OSCCON = %01100000 with DEFINE OSC 8.

OSCCON = %01110000 would use the internal 8MHz osc.

Darrel Taylor
- 7th December 2009, 18:15
GPIO.5 is still in Analog mode.

ANSEL = %00111011

And you have both SERIN2 and SEROUT2 on the same Pin GPIO.2.
<br>

DiverBob
- 7th December 2009, 18:52
GPIO.5 is still in Analog mode.

ANSEL = %00111011

And you have both SERIN2 and SEROUT2 on the same Pin GPIO.2.
<br>

Actually that is on purpose, there is another processor sending the request and then the 12F683 answers the request either by turning off the voltage regulator or sending the ADC results back. I only had a limited number of ports available on the other processor and it is located remotely from the 12F683.

DiverBob
- 7th December 2009, 18:58
Thanks for the ideas! I'll be sure to try them out tonight and get back with the results later.

DiverBob
- 8th December 2009, 02:07
Thank you very much! Just wanted to let everyone know that the solutions presented work great. I did find another issue with the processor that was putting out the RS232 to the 12F683 (incorrect clock freq which threw the timing out the door). The real key to the problem I was having was declaring the VAR value as a WORD and not BYTE - goes to show that you shouldn't take for granted even the little simple things.

I thought I'd post the final version of the code incase someone else needs help with something like this:

@ DEVICE PIC12F683, MCLR_OFF, INTRC_OSC_NOCLKOUT, WDT_ON, BOD_OFF
@ DEVICE PWRT_ON, FCMEN_OFF, IESO_OFF, PROTECT_OFF

DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 200

ANSEL = %00111011
ADCON0 = %10000001
TRISIO = %0001111
OSCCON = %01100000
CMCON0 = %00000111
INTCON.7 = 0
INTCON.3 = 1

RESULT VAR word[3]
value var byte
holding var word
i var byte

MAIN:
output GPIO.5
GPIO.5 = 1
Goto Main1

Main1:
SERIN2 GPIO.2, 396, [WAIT("A"), value]
if value = 1 then
GPIO.5 = 0
else
if value = 2 then
gosub GETADC
gosub display1
endif
endif
goto Main1
end

display1:
serout2 GPIO.2, 396, 10, [dec result[0], 13]
serout2 GPIO.2, 396, 10, [dec result[1], 13]
serout2 GPIO.2, 396, 10, [dec result[2], 13]
return
end

GETADC:
'average ADC over 10 cycles
holding = 0
for i = 1 to 10
adcin 0, result[2]
holding = holding + result[2]
pause 10
next i
holding = holding/10
result[2] = holding

holding = 0
for i = 1 to 10
adcin 1, result[1]
holding = holding + result[1]
pause 10
next i
holding = holding/10
result[1] = holding

holding = 0
for i = 1 to 10
adcin 3, result[0]
holding = holding + result[0]
pause 10
next i
holding = holding/10
result[0] = holding
return
end
end

Next job is to figure out the settings to place the processor in sleep with a wake-up on interrupt from GPIO.2 when a serial input is recieved. I need to do some reading in the datasheet and search previous posts first. Its nice to know that there are some knowledgeable people out there if I run into problems!

Bob