PDA

View Full Version : Strange Behavior 12F1822



nobner
- 30th January 2012, 22:59
Hello together,
i'm using the 12F1822 for the first time.
My programm does software-pwm, lighting 5 LED's up and down.
When i'm using 16MHz internal frequency (OSCCON = 01111000) everthing works fine.
When i'm using 32MHz internal frequency (OSCCON = 01110000) port RA4 and RA5 are working fine,
on ports RA0,1,2 i get short (200ns) high to low spikes in the high-time of my pwm-signal.
The spikes have a frequency of 50KHz.
I looked in the datasheet an tried to disable comparator, ADC, an so on.
Nothing helped.
Does anybody has an idea?
Thanks in advance!
Norbert



REM Prozessordefinitionen und Register setzen
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _CLKOUTEN_OFF & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON
__config _CONFIG2, _PLLEN_ON
#ENDCONFIG

OSCCON = 110000

TRISA = 001000
ANSELA = 0
CM1CON0 = 0

disable

LED1 var PORTA.0
LED2 var PORTA.1
LED3 var PORTA.2
LED4 var PORTA.4
LED5 var PORTA.5

WERT_01 var byte
WERT_01 = 10
REM Wert auf 10 setzen, damit LED nicht ganz aus geht

WERT_02 var byte
WERT_02 = 10
REM Wert auf 10 setzen, damit LED nicht ganz aus geht

BASIS_01 VAR byte
BASIS_01 = 0

BASIS_02 VAR byte
BASIS_02 = 0

ZAEHL_101 var BYTE
ZAEHL_101=0
ZAEHL_102 var byte
ZAEHL_102=0

ZAEHL_201 var BYTE
ZAEHL_201=0
ZAEHL_202 var byte
ZAEHL_202=0

AUF_01 VAR BIT
AUF_01=0

AUF_02 VAR BIT
AUF_02=0

START:

rem LED1
IF AUF_01 = 0 THEN
IF WERT_01 < BASIS_01 then
led1=0
LED2=0
LED4=1
ENDIF
IF WERT_01 > BASIS_01 THEN
LED1=1
LED2=1
LED4=0
ENDIF
BASIS_01 = BASIS_01 + 1
IF BASIS_01 = 250 then LET BASIS_01 = 0
ZAEHL_101 = ZAEHL_101 + 1
IF ZAEHL_101 = 250 THEN
ZAEHL_102 = ZAEHL_102 + 1
ZAEHL_101 = 0
ENDIF
IF ZAEHL_102 = 5 THEN
WERT_01 = WERT_01 + 1
ZAEHL_102 = 0
ENDIF
IF WERT_01 = 240 AND BASIS_01 = 0 THEN
AUF_01 = 1
WERT_01 = 10
BASIS_01 = 10
ENDIF
endif

IF AUF_01 = 1 THEN
IF WERT_01 < BASIS_01 THEN
LED1=1
LED2=1
LED4=0
ENDIF
IF WERT_01 > BASIS_01 then
led1=0
LED2=0
LED4=1
ENDIF

BASIS_01 = BASIS_01 + 1
IF BASIS_01 = 250 then LET BASIS_01 = 0
ZAEHL_101 = ZAEHL_101 + 1
IF ZAEHL_101 = 250 THEN
ZAEHL_102 = ZAEHL_102 + 1
ZAEHL_101 = 0
ENDIF
IF ZAEHL_102 = 5 THEN
WERT_01 = WERT_01 + 1
ZAEHL_102 = 0
ENDIF
IF WERT_01 = 240 And basis_01 = 0 THEN
AUF_01 = 0
WERT_01 = 10
BASIS_01 = 10
ENDIF
REM Wert auf 240 und 10 setzen, damit LED nicht ganz aus geht
endif

REM LED2
IF AUF_02 = 0 THEN
IF WERT_02 < BASIS_02 then
led3=0
LED5=0
ENDIF
IF WERT_02 > BASIS_02 THEN
LED3=1
LED5=1
ENDIF
BASIS_02 = BASIS_02 + 1
IF BASIS_02 = 250 then LET BASIS_02 = 0
ZAEHL_201 = ZAEHL_201 + 1
IF ZAEHL_201 = 250 THEN
ZAEHL_202 = ZAEHL_202 + 1
ZAEHL_201 = 0
ENDIF
IF ZAEHL_202 = 3 THEN
WERT_02 = WERT_02 + 1
ZAEHL_202 = 0
ENDIF
IF WERT_02 = 240 AND BASIS_02 = 0 THEN
AUF_02 = 1
WERT_02 = 10
BASIS_02 = 10
ENDIF
endif

IF AUF_02 = 1 THEN
IF WERT_02 < BASIS_02 THEN
LED3=1
LED5=1
ENDIF
IF WERT_02 > BASIS_02 then
led3=0
LED5=0
ENDIF
BASIS_02 = BASIS_02 + 1
IF BASIS_02 = 250 then LET BASIS_02 = 0
ZAEHL_201 = ZAEHL_201 + 1
IF ZAEHL_201 = 250 THEN
ZAEHL_202 = ZAEHL_202 + 1
ZAEHL_201 = 0
ENDIF
IF ZAEHL_202 = 3 THEN
WERT_02 = WERT_02 + 1
ZAEHL_202 = 0
ENDIF
IF WERT_02 = 240 AND BASIS_02 = 0 THEN
AUF_02 = 0
WERT_02 = 10
BASIS_02 = 10
ENDIF
REM Wert auf 240 und 10 setzen, damit LED nicht ganz aus geht
endif

GOTO START

end

sayzer
- 31st January 2012, 06:43
"When i'm using 16MHz internal frequency (OSCCON = 01111000) everthing works fine."

You thought everything worked fine.

I see no DEFINE OSC 16 or 32.

"My programm does software-pwm, lighting 5 LED's up and down."

May I suggest that you use DT's MIBAM for these 5-LEDS ?
With 32Mhz, you can get high refresh rate with MIBAM.

Dave
- 31st January 2012, 11:38
nobner, that is in this line of code?
OSCCON = 110000

Apparently when copying text It did not allow the correct sequence to be copied. Look at the embeded code sequence at the line where you are setting OSCCON.

sayzer
- 31st January 2012, 13:14
nobner, that is in this line of code?
OSCCON = 110000

Apparently when copying text It did not allow the correct sequence to be copied. Look at the embeded code sequence at the line where you are setting OSCCON.

It is something with the system here. Sometimes percent sign, %, disappears in code block.

Norbert has it correct in code block.

I guess it will be fixed soon.

HenrikOlsson
- 31st January 2012, 15:45
Hi,

This sounds like the classic RMW issue.
Instead of aliasing your LEDn variables to the PORTA register, try alias them to the LATA register and see what happens.
Do a search for read modify write if you don't know what RMW means.

/Henrik.

nobner
- 31st January 2012, 21:11
Hello,
did a wrong measurement yesterday.
Only Ports RA0 and RA2 have the spikes.
All other ports are working correct at 16MHz and 32MHz.
I added DEFINE OSC 32 - nothing changed.
I replaced the aliases for the LED with direct ports in the programm (PORTA.0=1) - nothing changed.
Now i'll search for RMW as recommended.

HenrikOlsson
- 31st January 2012, 21:16
Hi,
Replacing the alias with direct port adress doesn't make any difference. What I suggested was to write to the LAT register instead of the PORT register, ie:
LATA.0=1 instead of PORTA.0=1
or created the alias pointing on the LAT register instead of the PORT regsiter:
LED1 VAR LATA.0 instead of LED1 VAR PORTA.0

nobner
- 31st January 2012, 21:56
Hi Henrik,
thank you for your great help, writing the LAT register did the job. Signals are perfect now.
I also found now a second solution for the problem - using the "high porta.0" and "low porta.0" works also.
Thank you very much,
best regards
Norbert

HenrikOlsson
- 31st January 2012, 22:10
Hi,
HIGH PORTB.0 works because it takes longer to execute than PORTB.0=1. This is because it also sets the TRIS register each time they executes.
In this case the extra delay introduced by the inherit write to TRIS was enough to allow the voltage on the pin to rise above the threshold within time to avoid the RMW issue. But there's no guarantee it'll work the next time as it depends on the oscillator speed (as you've noticed), load on the pin, PCB trace capacitance and so on. For devices which have both a PORT and a LAT register you really should write to LAT to avoid these kind of RMW issues.

Good luck!
/Henrik

sayzer
- 1st February 2012, 06:56
Hi Henrik,
thank you for your great help, writing the LAT register did the job. Signals are perfect now.
I also found now a second solution for the problem - using the "high porta.0" and "low porta.0" works also.
Thank you very much,
best regards
Norbert


Norbert,

So, your code is working as expected without having DEFINE OSC X in your code block?


If you are using 32MHz or 16 MHz or 8Mhz you need to tell the compiler at what speed it is running.
Otherwise, it will compile for 4Mhz.

For High and Low commands, it may not reflect the difference;
But, if you are using PWM commands especially something like MIBAM, there will be serious difference.

For example, if you set your OSCCON register to 8Mhz and enable PLL (that gives 32Mhz), as you did, but do not have DEFINE OSC 32 , the chip will run at 32Mhz, but the compiler will compile your code for 4Mhz as default.

If I am wrong with anything with my sayings here, someone please correct me.

nobner
- 3rd February 2012, 08:11
Hi Sayzer,
i tried with DEFINE OSC 32 and without DEFINE OSC 32, it made no visible difference in my application,
PWM-frequency is the same.
Finally I put DEFINE OSC 32 in my code, everything works fine.
Thanks to all for your support.