No reverse command for 28X1 - any workrounds?

matherp

Senior Member
Hi all

I've been programming PICs using the BoostC compiler for some time but have just started using Picaxe as it seemed as though it would simplify some coding although I'm no longer sure!!

I'm writing some code to use the SHT11 temperature and humidity sensor. This needs a pin to be frequently switched between being an input and an output. I've got it all working using "let dirsc" to set the port direction but this changes the whole TRISC register on the PIC. I also want to use I2C devices which also connect to PORTC and also use a port bi-directionally. The manual warns not to address the TRISC register direct as picaxe frequently changes it itself, which I assume means that I can't peek the register modify the local copy and then write it back as it might have changed in the mean time. The reverse command appears to do what I want but isn't available on the 28X1.

Any ideas appreciated. Once I've solved this I'll post the SHT11 code if anyone is interested.

Thanks

Peter
 

Dippy

Moderator
I don't know of a slick answer, but..

" peek the register modify the local copy and then write it back "

... is exactly what I'd try and see what happens. I guess you may have to do it regulalry after some other command has un-TRISed you.

It won't explode and you may be waiting ages for a 'proper' answer.
 

matherp

Senior Member
Thanks for the comments. I've gone with the idea of peeking the hardware tris register but then using the PICAXE trisc variable to write the value back. All seems to work, although I haven't tried it with an I2C device also in circuit yet. The code is attached below. As this is my first attempt at PICAXE coding I'd appreciate any constructive criticism on my coding style

Best regards

Peter

Code:
#picaxe 28x1
setfreq m8

TABLE 0,(0,55,0,83,0,110,0,138,0,165,0,193,0,221,0,249,1,21,1,49)
TABLE 20,(1,77,1,105,1,133,1,161,1,189,1,218,1,246,2,19,2,47,2,76)
TABLE 40,(2,105,2,134,2,163,2,192,2,221,2,250,3,23,3,52,3,82,3,111)
TABLE 60,(3,141,3,170,3,200,3,230,4,4,4,34,4,64,4,94,4,124,4,154)
TABLE 80,(4,185,4,215,4,246,5,21,5,51,5,82,5,113,5,144,5,175,5,207)
TABLE 100,(5,238,6,13,6,45,6,77,6,108,6,140,6,172,6,204,6,236,7,13)
TABLE 120,(7,45,7,77,7,110,7,143,7,176,7,208,7,241,8,19,8,52,8,85)
TABLE 140,(8,119,8,152,8,186,8,220,8,254,9,32,9,67,9,101,9,135,9,170)
TABLE 160,(9,205,9,240,10,19,10,54,10,89,10,125,10,160,10,196,10,232,11,12)
TABLE 180,(11,48,11,85,11,121,11,158,11,195,11,232,12,13,12,50,12,88,12,125)
TABLE 200,(12,163)
symbol SCK = %11111101
symbol SCK_PIN = 1
symbol DAT = %11111011
symbol DAT_PIN = 2
symbol NDAT = %00000100
symbol t_in = 3
symbol h_in = 5
symbol my_trisc = 0x87
symbol heartbeat = 3
symbol halfclock = 10
symbol fullclock = 20
symbol zero=4010

main:
	hsersetup B9600_8,1 ' 9600 baud background receive
	hserout 0,("Temp/Humidity Logger V1.0")
	high heartbeat
	gosub setup
	gosub connectionreset
	
cycle:
	gosub measuretemp
	gosub measurehumi
	debug
	wait 5
	goto cycle
	end
'
'
'	
setup:
	peek my_trisc ,b27
	b27 = b27 & SCK ' set the SCK as output
	b27 = b27 | NDAT ' set DAT as input
	trisc=b27 'clock under my control
	low portc SCK_PIN ' force clock low, data is externally controlled

return

datout:
	peek my_trisc ,b27
	b27 = b27 & DAT ' set the DAT as output
	b27 = b27 & SCK ' set the SCK as output
	trisc=b27 ' use the external pullup to set data high, clock under my control

return

datin:
	peek my_trisc ,b27
	b27 = b27 | NDAT ' set the DAT as input
	b27 = b27 & SCK ' set the SCK as output
	trisc=b27 ' use the external pullup to set data high, clock under my control
return

connectionreset:        ' routine to reset the chip
	gosub datin
	for b27 = 1 to 10
		high portc SCK
		pauseus fullclock
		low portc SCK
		pauseus fullclock
	next b27
	gosub transstart
return

transstart: ' routine to start a transaction
	low portc SCK_PIN: high portc DAT_PIN' clock low and data high
	pauseus halfclock
	gosub datout ' set the clock and data as outputs
	high portc SCK_PIN ' clock high and data high
	pauseus halfclock
	low portc DAT_PIN ' clock stays high, data low
	pauseus halfclock
	low portc SCK_PIN' clock goes low, data stays low
	pauseus fullclock
	high portc SCK_PIN ' clock high, data stays low
	pauseus halfclock
	high portc DAT_PIN ' clock stays high data high
	pauseus halfclock
	gosub datin
return

readbit: ' generate a clock pulse to read a bit into b1
	pauseus halfclock
	high portc SCK_PIN  ' set clock high, data stays high
	pauseus halfclock
	b1=pins & NDAT	
	pauseus halfclock
	low portc SCK_PIN' set clock low, data stays high
	pauseus halfclock
return	

writebyte: 'outputs the byte in b0
	low portc SCK_PIN: high portc DAT_PIN ' data high and clock low
	gosub datout ' set the clock and data as .outputs
	if bit7=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit6=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit5=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit4=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit3=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit2=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit1=0 then: gosub clocklow :else gosub clockhigh: endif
	if bit0=0 then: gosub clocklow :else gosub clockhigh: endif
	gosub datin ' sets data back to an input
	gosub readbit
return



readbyte: 'inputs a byte to b0, send ack if b1 = 1
	gosub datin
	b0=0
	gosub readbit:if b1!=0 then:  bit7 = 1:endif
	gosub readbit:if b1!=0 then:  bit6 = 1:endif
	gosub readbit:if b1!=0 then:  bit5 = 1:endif
	gosub readbit:if b1!=0 then:  bit4 = 1:endif
	gosub readbit:if b1!=0 then:  bit3 = 1:endif
	gosub readbit:if b1!=0 then:  bit2 = 1:endif
	gosub readbit:if b1!=0 then:  bit1 = 1:endif
	gosub readbit:if b1!=0 then:  bit0 = 1:endif
	pauseus halfclock
	if b5 = 1 then ' send an ack
	    low portc DAT_PIN
	    gosub datout
	    gosub clocklow
	    gosub datin
	else ' send transfer complete
	    gosub clockhigh
	endif
	

return


clocklow:
	low portc SCK_PIN: low portc DAT_PIN ' set data low
	pauseus halfclock
	high portc SCK_PIN ' set clock high, data stays low
	pauseus fullclock
	low portc SCK_PIN: low portc DAT_PIN 'set clock low, data stays low
	pauseus halfclock
return

clockhigh:
	low portc SCK_PIN: high portc DAT_PIN ' set data high
	pauseus halfclock
	high portc SCK_PIN ' set clock high, data stays high
	pauseus fullclock
	low portc SCK_PIN: high portc DAT_PIN ' set clock low, data stays high
	pauseus halfclock
return

waitcomplete: 'put timeout code in here if required
	low heartbeat
	pause 20
	b3=pins & NDAT
	if b3 !=0 then goto waitcomplete
	high heartbeat
return

measuretemp: ' read raw temperature data into w5
	gosub transstart
	b0 = t_in ' set measure temp command
	gosub writebyte
	gosub waitcomplete
	b5 = 1
	gosub readbyte
	b11 = b0
	gosub readbyte
	b10 = b0
	b5 = 0
	gosub readbyte
	if w5> zero then
		w5=w5-zero
		w1=w5//100
		w1=w1/10
		w5=w5/100
		hserout 0,("Temp=",#w5,".",#w1,"°C,")
	else
		w5=zero-w5
		w1=w5//100
		w1=w1/10
		w5=w5/100
		b0 = "-"
		hserout 0,("Temp=",b0,#w5,".",#w1,"°C,")
	endif
return

measurehumi:'read raw humidity data into w6
	gosub transstart
	b0 = h_in
	gosub writebyte
	gosub waitcomplete
	b5 = 1
	gosub readbyte
	b13 = b0
	gosub readbyte
	b12 = b0
	b5 = 0
	gosub readbyte
	for b2=0 to 200 step 2 'lookup the raw humidity value in the table
		readtable b2,b1
		b3=b2+1
		readtable b3,b0
		if w0>=w6 then: exit: endif	
	next b2
	b0=b2/2
	hserout 0,("RH=",#b0,"%",13,10)
return
 

matherp

Senior Member
There is certainly no need to keep refreshing the tris registers on modern chips as far as I am aware - certainly nothing in the microchip datasheets, but technicals comments suggest that the picaxe internal code keeps a local copy of them and will overwrite/refresh them which will change them if you poke direct. That's why I peeked the hardware register but then wrote the data back using "let trisc" which is standard picaxe syntax (same as dirsc but inverted)

best regards

Peter
 
Top