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.

pic16f870 a to d, d to a

Status
Not open for further replies.
I'm pretty new to this stuff but I'm building a program to shift the voltage from one value to another in varying degrees depending on the input voltage range.

.5v shift up to .6
.4v shift up to .45 etc...

I think I've got the code down for the a to d conversion and then I read the pic has no analog output. Oops!

I've tried looking for an IC to convert d to a but i don't really know what I'm looing for or how to interface it with the pic16f870 in software or hardware.
I've spent a lot of time just getting to here!
 
hotrodhed120 said:
I'm pretty new to this stuff but I'm building a program to shift the voltage from one value to another in varying degrees depending on the input voltage range.

.5v shift up to .6
.4v shift up to .45 etc...

I think I've got the code down for the a to d conversion and then I read the pic has no analog output. Oops!

I've tried looking for an IC to convert d to a but i don't really know what I'm looing for or how to interface it with the pic16f870 in software or hardware.
I've spent a lot of time just getting to here!
microchip makes a few DtoA converters
but this link shows how to do it with a controller,
https://www.electro-tech-online.com/custompdfs/2007/03/00655a.pdf
this is their d/a line
https://www.microchip.com/ParamChartSearch/chart.aspx?mid=11&lang=en&branchID=11028
 
hotrodhed120 said:
I'm pretty new to this stuff but I'm building a program to shift the voltage from one value to another in varying degrees depending on the input voltage range.

.5v shift up to .6
.4v shift up to .45 etc...

I think I've got the code down for the a to d conversion and then I read the pic has no analog output. Oops!

I've tried looking for an IC to convert d to a but i don't really know what I'm looing for or how to interface it with the pic16f870 in software or hardware.
I've spent a lot of time just getting to here!

A simple (and cheap) method is an 'R2R ladder', this just requires resistors and an opamp buffer to give a nice fast D2A output - no need for a special IC, and it's really fast as well. MicroChip have an application note about it at **broken link removed**
 
I was hoping to use code to add a value to an almost infinitly variable voltage between 0v-1v, if i read these app. notes right I'll only have a limited amount of step voltages, one for each output. I don't know if pwm will work, because the output analog signal will be monitored by a separate computer that I have no control over. I would like to use this application to modify the signal before the main computer even sees it. PWM is still a grey area for me in actual implementation.
 
hotrodhed120 said:
I was hoping to use code to add a value to an almost infinitly variable voltage between 0v-1v, if i read these app. notes right I'll only have a limited amount of step voltages, one for each output. I don't know if pwm will work, because the output analog signal will be monitored by a separate computer that I have no control over. I would like to use this application to modify the signal before the main computer even sees it. PWM is still a grey area for me in actual implementation.



Sorry, not infinite just 0-255 which would be great.
 
hotrodhed120 said:
Sorry, not infinite just 0-255 which would be great.

An R2R ladder would be great for 8 bit (0-255), although you can make it as high a resolution as you need - but 8 bit uses a single port, and the higher resolution you have, the smaller the tolerance of the resistors has to be.

R2R is dead easy to program, because you just stick the value out the port, and there's no filtering required as with PWM - with PWM the response time depends on the filtering, with fast PWM and higher frequency filters being required for a fast response time (check the MicroChip link I posted, which shows both R2R and PWM).
 
I gotcha, so portb would have output bits 0-7 set to 00110101 to equal 53 (in fig. 4)to get the desired output from the r2r? that would work great! thanks!
 
hotrodhed120 said:
The hard part seems to find one. I've got a P# 898-81-r10k from BI Tech but cannot find a supplier with one. Help!

It's just resistors, you only need to buy resistors - that's what makes it so easy - use at least 1% ones, preferably better.
 
Geez, you got the right chip for the job, so use it!

I made this program in Proton+ but I don’t think the lite version supports 16F870 - grab a 16F877 so you can develop code in the lite version. Pretty much the same, just that it has more pins..

anyhow, use the ADC feature to sample the input voltage, then use the PWM feature of the PIC to make an analogue output whos value will be the same as the input.

This is just an example of how to use the ADC and PWM features, its not a specific answer, but should save you alot of board space and components..

The input voltage can be anything from 0-5V and the output is a 255 Bit (0.019V steps) output

**broken link removed**

Heres the program;


Code:
Device = 16F870

XTAL = 4

Declare ADIN_RES 10 		' 10-bit result required 
Declare ADIN_TAD FRC 		' RC OSC chosen 
Declare ADIN_STIME 50 		' Allow 50us sample time 

Declare CCP1_PIN = PORTC.2

Dim Result as Float
Dim Total as Float
Dim X as Byte

ADCON1 = %10000000 			' Set analogue inputs, Vref is Vdd

Main:
	 Total = 0
	 X = 0
	 
	 Repeat 
	 		Result = ADIN 0
	 		Total = Total + Result
	 		Inc X
	 Until X = 10
	 
	 Result = Total / 10
	 
	 Result = Result / 1023 * 255
	 
	 X = Result
	 
	 If X = 255 Then X = 254
	 
	 HPWM 1, X, 32767

	 Goto Main

Just to explain a couple of things;

* I generally take multiple samples (this case 10) to get a more accurate result of the ADC, just divided the total by 10 to find the average

* I move Result into X because the HPWM function only supports 16bit math opperations (don't worry about thinking too far into this at the moment) and I check if X is >= 255 as the PWM output will be ambiguous.. (something you learn after playing with it after a while)

* PWM is not a hard concept to tackle, for the beginner it has limited uses, but this is an example of how to use it for DAC (Digital to analogue conversions). **broken link removed**

* Have a read in the Proton help file for more info on specific commands! And see what else you can do while your there!
 
Last edited:
Just on that, I have made the program more accurate.

The only step it cant reach is 255 (because the HPWM output become ambigous)

I modified this line

Code:
If X = 255 Then X = 254

To

Code:
If X >= 254 Then X = 253

Inc X
**broken link removed**

Hope this helps you/someone else out!
 
Last edited:
gramo said:
Just on that, I have made the program more accurate.

The only step it cant reach is 255 (because the HPWM output become ambigous)

I don't see your problem?, setting the PWM to 255 (for 8 bit PWM) sets the output at 5V (no pulses) just as you want, just as setting it to 0 outputs zero volts (no pulses). I also don't see how your modification makes it more accurate?, it makes it less accurate!.

The problem with PWM though is the response time, which to be any good needs more complicated filtering than your example - and will never approach the speed of an R2R ladder.
 
Nigel Goodwin said:
I don't see your problem?, setting the PWM to 255 (for 8 bit PWM) sets the output at 5V (no pulses) just as you want, just as setting it to 0 outputs zero volts (no pulses). I also don't see how your modification makes it more accurate?, it makes it less accurate!.

Did you watch the video's? Its fairly clear that the first program was one step out.


Nigel Goodwin said:
The problem with PWM though is the response time, which to be any good needs more complicated filtering than your example - and will never approach the speed of an R2R ladder.

Correct, but the response time in this situation is around 50-100ms (average guess) as the videos are the file being simmed at around 1/3rd real-time. Is that good enough for this app? Its great for many apps where uS updates arnt critical. the output can be buffered by an opamp quite easily aswell. You could even through in a bigger cap to slew the output more to give a longer response time if needed

I'm not sure as to why the PWM is ambiguous at 255, perhaps its my outdated version of Proton+ but watch this video of the following code

Code:
Device = 16F877
Declare XTAL = 4

Declare CCP1_PIN = PORTC.2

HPWM 1, 255, 32767

While 1=1 

Wend

32767 is the frequency, 1 is the channel, 255 is the setting for PWM duty cycle. Like you said - 255 should give a straight 5V - for some reason I can't get it to do that, the following video displays a couple of different PWM's 128 (50%), 192 (75%), 254 (99%), 255 (100%) each for a couple of seconds on a cro, but take a look at the 255, its anything but stable.. its anything but a steady 5V.. any ideas?

**broken link removed**
 
Last edited:
Just looking through the help file, it should def support 255;

Dutycycle is a variable, constant (0-255), or expression that specifies the on/off (high/low) ratio of the signal. It ranges from 0 to 255, where 0 is off (low all the time) and 255 is on (high) all the time. A value of 127 gives a 50% duty cycle (square wave).

Time to get down with the .asm
 
Hrmm, I'm lost for words, can you see a fault with it?

NOLIST

#include "D:\Projects\BASICE~1\HPWM-D~1\HPWM-D~1.PBP"

LIST
F1_SOF equ $ ; HPWM-D~1.BAS
F1_000007 equ $ ; in [HPWM-D~1.BAS] HPWM 1, 255, 32000
Movlw 255
Movwf GEN
Movlw 125
Movwf PP1H
Clrf PP1
Movlw 1
F@Call H@pwm
F1_000009 equ $ ; in [HPWM-D~1.BAS] While 1=1
bc@ll1
F1_000011 equ $ ; in [HPWM-D~1.BAS] Wend
F@Jump bc@ll1
bc@ll2
END

HPWM-D~1.PBP:

Code:
		LIST
;{
;FILE F1 = D:\Projects\BASICE~1\HPWM-D~1\HPWM-D~1.BAS
;}
;[Variable Listing]
;[End Listing]
	NOLIST

	LIST
	LIST  P = 16F877,f = INHX8M ,w = 2, x = on, r = DEC, mm = ON, n = 0, c = 255
	#include E:\PBCPRO~1\CROWNH~1\INC\P16F877.lpb
XTAL = 4
_CORE = 14
_MAXRAM = 368
_RAM_END = 0
_MAXMEM = 8192
_ADC = 8
_ADC_RES = 10
_EEPROM = 256
_PAGES = 4
_BANKS = 3
RAM_BANKS = 4
_USART = 1
_USB = 0
_FLASH = 1
BANK0_START = 32
BANK0_END = 127
BANK1_START = 160
BANK1_END = 239
BANK2_START = 272
BANK2_END = 367
BANK3_START = 400
BANK3_END = 495
_SYSTEM_VARIABLE_COUNT = 11
ram_bank = 0
f@call macro dest
	if (dest < 1)
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	else
	if (dest > $)
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	else
	if ((dest & 6144) == 0)
	clrf 10
	else
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	endif
	endif
	endif
	call dest
	endm
f@jump macro dest
	if (dest < 1)
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	else
	if (dest > $)
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	else
	if ((dest & 6144) == 0)
	clrf 10
	else
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	endif
	endif
	endif
	goto dest
	endm
set@page macro dest
	if ((dest & 2048) == 0)
	bcf 10,3
	else
	bsf 10,3
	endif
	if ((dest & 4096) == 0)
	bcf 10,4
	else
	bsf 10,4
	endif
	endm
s@b	macro varin
	if((varin & 384) == 0)
	if(ram_bank == 1)
	bcf 3,5
	endif
	if(ram_bank == 2)
	bcf 3,6
	endif
	if(ram_bank == 3)
	bcf 3,5
	bcf 3,6
	endif
ram_bank = 0
	endif
	if((varin & 384) == 128)
	if(ram_bank == 0)
	bsf 3,5
	endif
	if(ram_bank == 2)
	bsf 3,5
	bcf 3,6
	endif
	if(ram_bank == 3)
	bcf 3,6
	endif
ram_bank = 1
	endif
	if((varin & 384) == 256)
	if(ram_bank == 0)
	bsf 3,6
	endif
	if(ram_bank == 1)
	bcf 3,5
	bsf 3,6
	endif
	if(ram_bank == 3)
	bcf 3,5
	endif
ram_bank = 2
	endif
	if((varin & 384) == 384)
	if(ram_bank == 0)
	bsf 3,5
	bsf 3,6
	endif
	if(ram_bank == 1)
	bsf 3,6
	endif
	if(ram_bank == 2)
	bsf 3,5
	endif
ram_bank = 3
	endif
	endm
r@b	macro
	if((ram_bank & 1) != 0)
	bcf 3,5
	endif
	if((ram_bank & 2) != 0)
	bcf 3,6
	endif
ram_bank = 0
	endm
	#include E:\PBCPRO~1\CROWNH~1\INC\REG_LD14.INC
GEN = 32
PP0 = 33
PP0H = 34
PP1 = 35
PP1H = 36
PP2 = 37
PP2H = 38
PP3 = 39
PP3H = 40
PP4H = 41
PP6H = 42
	org 0
	nop
	movlw high Start@
	movwf 10
	goto Start@
	org 4
rsout@
h@pwm movwf 41
	movlw 66
	movwf 33
	movlw 15
	movwf 34
	call d@vd
	skpnz
	bcf 18,T2CKPS0
	skpz
	bsf	18,T2CKPS0
	addlw 252
	skpc
	bcf	18,T2CKPS1
	skpnc
	bsf	18,T2CKPS1
	movlw 64
	movwf 33
	movlw 66
	movwf 34
	movlw 15
	movwf 37
	clrf 38
	btfsc 18,T2CKPS0
	call hpw@2s
	btfsc 18,T2CKPS1
	call hpw@2s
	call d@vd2
	decf 33,w
	bsf 3,5
	movwf 146
	bcf	3,5
	movfw 33
	movwf 35
	movfw 34
	movwf 36
	movfw 32
	movwf 39
	movwf 40
	incfsz 32,w
	clrf 40
	call m@py
	movfw 38
	decfsz 41,f
	goto $ + 13
	movwf 21
	movlw 12
	movwf 23
	btfsc 37,7
	bsf 23,5
	btfsc 37,6
	bsf 23,4
	bsf 3,5
	bcf PORTC,2
	bcf 3,5
	bsf 18,TMR2ON
	goto i@nt
	movwf 27
	movlw 12
	movwf 29
	btfsc 37,7
	bsf 29,5
	btfsc 37,6
	bsf 29,4
	bsf 3,5
	bcf PORTC,1
	goto $ - 12
hpw@2s call hpw@2l
hpw@2l clrc
	rrf 37,f
	rrf 34,f
	rrf 33,f
	return
d@vd clrf 38
	clrf 37
d@vd2 movlw 16
	movwf 39
	rlf 34,w
	rlf 37,f
	rlf 38,f
	movfw 35
	subwf 37,f
	movfw 36
	skpc
	incfsz 36,w
	subwf 38,f
	skpnc
	goto $ + 8
	movfw 35
	addwf 37,f
	movfw 36
	skpnc
	incfsz 36,w
	addwf 38,f
	clrc
	rlf 33,f
	rlf 34,f
	decfsz 39,f
	goto $ - 21
	movfw 33
	goto i@nt
m@py movlw 16
	movwf 42
	clrf 34
	clrf 33
	rrf 40,f
	rrf 39,f
	skpc
	goto $ + 7
	movfw 35
	addwf 33,f
	movfw 36
	skpnc
	incfsz 36,w
	addwf 34,f
	rrf 34,f
	rrf 33,f
	rrf 38,f
	rrf 37,f
	decfsz 42,f
	goto $ - 15
	movfw 37
	goto i@nt
i@nt bcf 3,7
i@nt2 bcf 3,5
	bcf 3,6
	nop
	return
Start@
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top