PDA

View Full Version : Delta-Sigma-ADC in Assembler embedded in PBP, increasing resolution



selbstdual
- 10th September 2006, 14:42
Good evening. I want to increase the code's resolution from 16bit to something deliberate. How do I have to change this code ?



...some code...
ASM
;************************************************* ********************
;* Filename: DeltaSig.asm
;************************************************* ********************
;* Author: Dan Butler
;* Company: Microchip Technology Inc.
;* Revision: 1.00
;* Date: 02 December 1998
;* Assembled using MPASM V2.20
;************************************************* ********************
;* Include Files:
;* p16C622.inc V1.01
;************************************************* ********************
;* Provides two functions implementing the Delta Sigma A2D.
;* InitDeltaSigA2D sets up the voltage reference and comparator
;* in the "idle" state.
;* DeltaSigA2D runs the actual conversion. Results provided in
;* result_l and result_h.
;* See An700 figure 2 for external circuitry required.
;************************************************* ********************
;* What's changed
;*
;* Date Description of change
;*
;************************************************* ********************
#include <p16C622.inc>
cblock
result_l
result_h
counter:2
endc
;
;
;
InitDeltaSigA2D
bsf STATUS,RP0
movlw 0xEC
movwf VRCON
bcf PORTA,3 ;set comparator pin to output
bcf STATUS,RP0
movlw 0x06 ;set up for 2 analog comparators with common reference
movwf CMCON
return
;
; Delta Sigma A2D
; The code below contains a lot of nops and goto next instruction. These
; are necessary to ensure that each pass through the loop takes the same
; amount of time, no matter the path through the code.
;
DeltaSigA2D
clrf counter
clrf counter+1
clrf result_l
clrf result_h
movlw 0x03 ; set up for 2 analog comparators with common reference
movwf CMCON
loop
btfsc CMCON,C1OUT ; Is comparator high or low?
goto complow ; Go the low route
comphigh
nop ; necessary to keep timing even
bcf PORTA,3 ; PORTA.3 = 0
incfsz result_l,f ; bump counter
goto eat2cycles ;
incf result_h,f ;
goto endloop ;
complow
bsf PORTA,3 ; Comparator is low
nop ; necessary to keep timing even
goto eat2cycles ; same here
eat2cycles
goto endloop ; eat 2 more cycles
endloop
incfsz counter,f ; Count this lap through the loop.
goto eat5cycles ;
incf counter+1,f ;
movf counter+1,w ;
andlw 0x04 ; Are we done? (We're done when bit2 of
btfsc STATUS,Z ; the high order byte overflows to 1).
goto loop ;
goto exit
eat5cycles
goto $+1 ; more wasted time to keep the loops even
nop ;
goto loop ;
exit
movlw 0x06 ; set up for 2 analog comparators with common reference
movwf CMCON
return
end
ENDASM

blainecf
- 13th September 2006, 16:01
By deliberate do you mean 8bits, 12 bits, 19bits??? Are you just wanting to know what was implicitly set (by default) that makes this 16 bit? What is your ultimate goal?

bcf

selbstdual
- 14th September 2006, 12:49
Thank you for your question.

Exactly, I want to know how it subdivides in 1024 steps. Then it should be easy to change it to the desired value.

mister_e
- 14th September 2006, 13:51
well i certainely miss something here but, 1024 steps it's 10Bit. you said you want Increase your actual 16Bit resolution.. euh... i'm i wrong or what.

By the way, why using the comparator when a real ADC give you already 10Bit resolution without headache, need few lines of code and no big additional hardware?

Ingvar
- 14th September 2006, 15:12
These lines checks for 1024 passes through the loop and stops if reached.

andlw 0x04 ; Are we done? (We're done when bit2 of
btfsc STATUS,Z ; the high order byte overflows to 1).

All you need to do is change ....

andlw 0x04

..... to .......

andlw 0x02 for 512(9 bits)
andlw 0x08 for 2048(11 bits)
andlw 0x10 for 4096(12 bits)
andlw 0x20 for 8192(13 bits)
andlw 0x40 for 16384(14 bits)
andlw 0x80 for 32768(15 bits)

If you need better resolution it can be done, but needs more changing in the code.

/Ingvar

selbstdual
- 15th September 2006, 01:14
Thank you so far.

In my current application, I need around 750 steps. Surely I could use 1024 steps right now.

I want to change it to the number of steps wanted, but I have not understood the relation yet.

Please explain the math behind your examples.

Ingvar
- 15th September 2006, 08:31
The code checks if bit 2 of the high byte of the wordsized variable "counter" is set. If it is, the program has looped around 1024 times, if not it keeps looping.

There is really no math involved, 1024dec = 0400hex = 0000010000000000bin.

You don't want to check for anything more complicated than if a single bit is being set or cleared. That would slow the ADconversion down, not something you want to do. I'm not saying it can't be done, just that it wouldn't be very easy. Especially if you don't know assembler and i get the impression that you don't.

My advice is that you stick with 10 bits(1024) and when the conversion is complete you scale the result to your desired value. That can be done in various ways. Here's a few..... all will scale to 752.

Dummy = ADresult * 752
ScaledResult DIV32 1024

ScaledResult = ADresult */ 188 '752/1024*256=188

ScaledResult = ADresult ** 48128 '752/1024*65536=48128

/Ingvar

selbstdual
- 15th September 2006, 20:39
What about using


andlw 0x2F0 ; Are we done? (We're done when bit2 of
btfsc STATUS,Z ; the high order byte overflows to 1).

Ingvar
- 19th September 2006, 10:28
No, you can only check one byte(8bits) in one go. You're also trying to check several bits at the same time, only one is "allowed". If you really MUST check for something more complicated you'll need to rewrite the code yourself. Certanly possible but nothing i will help you with.

Good luck.
/Ingvar

PS. Is there a perticular reason why you can't use 10 bits and scale the result as i showed you in my last post? DS.

selbstdual
- 30th September 2006, 15:44
Where is the result stored - in result_l or result_h or are they the same ?

At U = Umax there should be a value of 1024.

Ingvar
- 2nd October 2006, 10:51
Result_h is the high byte(8bits) of the wordsized(16bits) result. Result_l holds the lower 8 bits.

selbstdual
- 2nd October 2006, 20:25
I don't understand this. How do you combine these two to get a Dez-number between 0 and 1023 ?

Ingvar
- 3rd October 2006, 09:07
Ok, time for somebody else to step in. I don't have the patience, time and/or languageskills to explain how hex, binary and decimal correlates. I recommend that you buy a book that expalins the basics of "microcontrolling". Can't give you any advice on good books since i haven't needed one for 20 years.

Good luck
/Ingvar

HenrikOlsson
- 3rd October 2006, 09:39
Hi,
Haven't followed this from the beginning but I'll jump in here real quick.

A word is 16bits. A byte is 8bits. A word consists of 2bytes a high and a low. To combine 2 bytes into a word you can do:


MyWordResult var WORD

MyWordResult = Result_h * 256 + Result_l
HSEROUT [#MyWordResult,10]


If Result_h is 100 in decimal and Result_l is 25 in decimal. Your result would be 25625 in decimal. Or if you like in binary.



H I G H L O W
B Y T E B Y T E
MSB---> 01100100 00011001 <----LSB

See? The high byte is 100 and the low byte is 25.

Since the most significant bit in the low byte equals to 128 the least significant bit in the high byte equals to 256. That is why you multiply the highbyte by 256.

Or seeing it as 16bit word:

LSB MSB
1+0+0+8+16+0+0+0+0+0+1024+0+0+8192+16384+0 = 25625

/Henrik Olsson.

selbstdual
- 4th October 2006, 05:45
MyWordResult = Result_h * 256 + Result_l
This is what I was looking for. Plain and simple. Thank you.