News:

;) This forum is the property of Proton software developers

Main Menu

Bits affected by SHOUT

Started by Frizie, Jul 17, 2022, 02:50 PM

Previous topic - Next topic

Frizie

In the program below to control a MCP4921 12-bits DAC, should the following happen:
If BIT-value 'GoUp' is TRUE, then WORD 'DAC_Value' counts up till value 4095.
Then 'GoUp' becomes FALSE, then WORD 'DAC_Value' counts down till value 0.
Then 'GoUp' becomes TRUE and everything starts all over again  :)

But in practice the value jumps from 0 right back to 4095 because bit 'GoUp' does not become TRUE.
It does this for 16 loops (after each PIC reset), after that it works fine    :o
If I take a portpin instead of BIT variable 'GoUp' (to check the status of the 'GoUp' bit with a LED), it works immediately well after startup  :o
I myself have the suspicion that this is caused by the bit argument in SHOUT: DAC_Value\12.
DAC_Value is a WORD, but I'm only using 12 bits.
The other 4 bits of the WORD declare that after 16x it will work.

Question is, where goes it wrong?  ???
The bit-argument from the WORD used in the SHOUT command, should not affect the main program...

DEVICE = 18F45K22
CONFIG_START
  FOSC    = HSHP 'HSMP ' (Medium Power) 4-16MHz) HSHP 'INTIO67           ;High Speed High Power (>16MHz) 'Internal oscillator block
  PLLCFG  = OFF               ;Oscillator used directly
' PLLCFG  = ON                ;Oscillator multiplied by 4
  PRICLKEN = OFF 'ON          ;Primary clock enabled
  FCMEN   = OFF               ;Fail-Safe Clock Monitor disabled
  IESO    = OFF               ;Oscillator Switchover mode disabled
  PWRTEN  = ON                ;Power up timer enabled
  BOREN   = SBORDIS           ;Brown-out Reset enabled in hardware only (SBOREN is disabled)
  BORV    = 190               ;VBOR set to 1.90 V nominal
  WDTEN   = ON                ;Watch dog timer is always enabled. SWDTEN has no effect.
  WDTPS   = 2048              ; 1:1024 is te kort wanneer 'ExterneEEPROMinstellen()' geactiveert wordt (dit gebeurt in geval het programma een lege externe 24C512 EEPROM aantreft)
  CCP2MX  = PORTC1            ;CCP2 input/output is multiplexed with RC1
  PBADEN  = OFF               ;PORTB<5:0> pins are configured as digital I/O on Reset
  CCP3MX  = PORTB5            ;P3A/CCP3 input/output is multiplexed with RB5
  HFOFST  = off 'ON                ;HFINTOSC output and ready status are not delayed by the oscillator stable status
  T3CMX   = PORTB5            ;T3CKI is on RB5
  P2BMX   = PORTD2            ;P2B is on RD2
  MCLRE   = INTMCLR 'EXTMCLR 'INTMCLR           ;RE3 input pin enabled; MCLR disabled                       
  STVREN  = ON                ;Stack full/underflow will cause Reset
  LVP     = OFF               ;Single-Supply ICSP disabled                                                             
  XINST   = OFF               ;Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
  DEBUG   = OFF               ;Disabled
  CP0     = OFF               ;Block 0 (000800-003FFFh) not code-protected
  CP1     = OFF               ;Block 1 (004000-007FFFh) not code-protected                                                                                                                                                                                         
  CP2     = OFF               ;Block 2 (008000-00BFFFh) not code-protected                                                                                                                                                                                           
  CP3     = OFF               ;Block 3 (00C000-00FFFFh) not code-protected
  CPB     = OFF               ;Boot block (000000-0007FFh) not code-protected
  CPD     = OFF               ;Data EEPROM not code-protected 
  WRT0    = OFF               ;Block 0 (000800-003FFFh) not write-protected
  WRT1    = OFF               ;Block 1 (004000-007FFFh) not write-protected
  WRT2    = OFF               ;Block 2 (008000-00BFFFh) not write-protected
  WRT3    = OFF               ;Block 3 (00C000-00FFFFh) not write-protected
  WRTC    = OFF               ;Configuration registers (300000-3000FFh) not write-protected
  WRTB    = OFF               ;Boot Block (000000-0007FFh) not write-protected
  WRTD    = OFF               ;Data EEPROM not write-protected
  EBTR0   = OFF               ;Block 0 (000800-003FFFh) not protected from table reads executed in other blocks
  EBTR1   = OFF               ;Block 1 (004000-007FFFh) not protected from table reads executed in other blocks
  EBTR2   = OFF               ;Block 2 (008000-00BFFFh) not protected from table reads executed in other blocks
  EBTR3   = OFF               ;Block 3 (00C000-00FFFFh) not protected from table reads executed in other blocks
  EBTRB   = OFF               ;Boot Block (000000-0007FFh) not protected from table reads executed in other blocks
CONFIG_END

DECLARE OPTIMISER_LEVEL = 0                             

DECLARE XTAL           = 22   ;Kristal 22.1184 MHz
DECLARE ALL_DIGITAL    = TRUE

DELAYMS 500

SYMBOL MCP4921_CS   = PORTD.0 ;Q: Chip Select (signal LOW is active)
SYMBOL MCP4921_SCO  = PORTD.1 ;Q: Serial Clock Output (for SPI)
SYMBOL MCP4921_SDO  = PORTD.2 ;Q: Serial Data Output (for SPI)

DIM DAC_Value       AS WORD   ;Value for the output voltage of the DAC
DIM GoUp            AS BIT    ;If 'GoUp' is TRUE (1) then 'DAC_Value' counts up, if this bit is FALSE then 'DAC_Value' counts down

OUTPUT MCP4921_CS             ;Make Chip Select pin an output
CLEAR

GOTO Main


PROC DAC_Out()
  MCP4921_CS = 0  ;Chip Select MCP4921
 'DELAYCS 1       ;Optional
  SHOUT MCP4921_SDO, MCP4921_SCO, MSBFIRST, [0b0111\4, DAC_Value\12]
 'DELAYCS 1       ;Optional
  MCP4921_CS = 1  ;Deselect
ENDPROC


Main:
DO
  CLRWDT
  DAC_Out()
  DELAYMS 1
  IF GoUp = 1 THEN
    INC DAC_Value
    IF DAC_Value = 4095 THEN GoUp = 0
  ELSE
    DEC DAC_Value
    IF DAC_Value =    0 THEN GoUp = 1
  ENDIF
LOOP
Ohm sweet Ohm | www.picbasic.nl

trastikata

#1
After reset, the initial value of GoUp and DAC_Value is 0.

Thus in your loop, the first condition that comes true is "ELSE" because GoUp = 0 and DAC_Value will roll over to 65535 because the first line after the "ELSE" is DEC DAC_Value and the loop will not update GoUp to 1 until another 65535 iterations occur.

Frizie

I know that.
But the question was and is, how is it possible that a complete other bit (used in the mainprogram) is affected?

If I give 'DAC_Value' a startvalue of, let's say 2000, the problem still exists  :o

Frizie.
Ohm sweet Ohm | www.picbasic.nl

tumbleweed

Try setting GoUp = 1 as the first line after main (before the loop)

Frizie

#4
If I do GoUp = 1 then it works directly.

But... thát is not the question!

Who guarantees me else that it will continue to work for 65520 times and after that it not does work again 16 times.
Where's that mysterious counter that counts down 16x?

Another test confirms my suspicion that the bit argument from SHOUT has influence.
Cause if I do:
SHOUT MCP4921_SDO, MCP4921_SCO, MSBFIRST, [0b01110\5, DAC_Value\11]
then it is not after 16 times, but after 32 times.
(with ofcourse: IF DAC_Value = 2047 THEN GoUp = 0 instead of 4095)

And why does it work right from the start, if I take a portpin as bit variable?
Ohm sweet Ohm | www.picbasic.nl

tumbleweed

#5
QuoteWhere's that mysterious counter that counts down 16x?
If you think about what trastikata said, when you start with GoUp = 0 you'll go through the else condition 65535 times until DAC_value gets decremented back to 0 again. 65535 = 0xFFFF. Note the MS four bits, which is 0xF (15). You'll ramp the DAC using the lower 12-bits (4095-0) 16 times until the entire DAC value = 0.

When you use 'DAC-Value\11' you still go through the loop 65535 times, but now you'll see twice as many ramps (32x).

QuoteAnd why does it work right from the start, if I take a portpin as bit variable?
Probably because the port pin is seen as a '1' instead of the bit variable GoUp which starts set = 0.

You could always add some sort of sanity check to the whole loop like
if DAC_Value > 4095 then
  DAC_Value = 4095
  GoUp = 0
endif

Start the program with DAC_Value = 0 and GoUp = 1. Problem solved.


Frizie

Tested again today as a result of your response and now the incident no longer occurs.
Yesterday I must have put the line DAC_Value = 2000 with my sleepy head either right below the GOTO Main or this line above the CLEAR, otherwise I can't explain it.

Very sorry that I bothered you people for this, I must have been blind  :-[
Ohm sweet Ohm | www.picbasic.nl

top204

#7
QuoteVery sorry that I bothered you people for this, I must have been blind

There is absolutely no need to be sorry Frizie. That is exactly why I have the forum in place, so that users can help other users, and we have such a lovely bunch of people on this forum, we are always happy to help each other.

In life, sometimes the obvious is not seen until another person points out something else, that makes one look somewhere else. I think the common term is "Cannot see the Wood for the Trees". I've been down that road many, many, many times, and it is something that never goes away, even after 30 years of programming. :-)

In your original code, there is no need to reduce the optimiser down to 0. For 18F and enhanced 14-bit core devices, the compiler's default optimiser setting is 100% trustworthy, and it makes the assembler code smaller and run faster and easier to understand and follow. Also, set or clear the "GoUp" bit before the main program starts, because if the DAC variable does not reach a value of 4095 or down to a value of 0, it is unknown what state it will be in. It is always better to err on the side of caution when coding, because the "real world" is a very random place and things that were "never" expected to happen, often happen!!! LOL

Frizie

Thank you for your good words Les  ;D

I usually do the things you (and others hereabove) say here.
But I had for the first time a MCP4921 (DAC) attached to my testcircuit.
You know how it goes: Quickly put together a test program (up/down of the voltage) to see if I can communicate with it.
That went pretty quickly, but noticed the "error", which was not an error but a typo from me.

The MCP4921 will soon work together in a much larger circuit to drive a machine.

Thanks again for everyone's help.
Ohm sweet Ohm | www.picbasic.nl