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.

16F88 UART question && A/D interrupt and bootloader

Status
Not open for further replies.

Turkish

New Member
Hi,

I've been playing around with a 16F88 for the past week or so, and have had quite a lot of sucess with it. I intend to use this uC in a piece of test equipment, and so far I have learnt a lot about this chip.

I am communicating with a PC via serial and interfacing it with a program I am writing in C#. This is also coming along nicely.


Ok the problem I am having is with the sending and recieving of data. I need to transmit the logic (on/off) status of switches, but transmitting the port 'byte' (i don't know how else to call it - the binary string that represents the PORT register) which contains the bit status (set or unset) appears at my PC as a character (letter/symbol). Presumably the PC is converting the packet, but I would like the 'raw' data (hex string or whatever) so I can convert to binary and determine which switches are being pressed.

If that still makes sense (sorry for the waffle!), I have tried to convert the characters the PIC is sending back to binary, but the resulting unicode for the character does not tie up with the byte I KNOW is being sent.


So far I have been getting around this problem by individually checking the switch status of the port, and transmitting 1 or 0 characters instead... because this is done sequentially in a specific order (and loop), I know the first digit is switch one, second is two, etc:

Code:
movlw	'0'
btfsc 	PORTA, 0	;check if switch 1 is being pressed
movlw	'1'
call	send

the 'call send' part just refers to a macro that moves the w to TXREG and implements a wait cycle while the packet is sent.

However I am at the point where I am trying to optimise the code, and 8 parts of code like this in a loop is pretty messy. I'm hoping someone knows a more efficient way to do this (how to send a complete byte of them all), where I don't have to try and convert dodgy characters (or at least suggest a better way to covnert them in C#!!!) :)



The second question/problem I am having is somewhat similar to above. It relates to send A/D data via the same serial connection. I am having to transmit the BITS of the ADRESH and ADRESL registers seperate and re-compile them into a number at the PC. I am hoping the method for problem 1 will solve this one.

The other issue is that due to switching noise the ADC data is very innaccurate, and I am told (by the data sheet and others) that I should put the uC into SLEEP mode while the conversion takes place and then wake up with the A/D interrupt.

However I am unsure how to proceed, as I have not messed around with interrupts that much (at least not in this program) and in addition I am using a bootloader - which means the 0x04 memory space is already taken up by a 'goto main program' word, rather than an interrupt service routine.

Having the program 'fall' through the interrupt serivce routine into the main program on startup doesn't really cure the issue. I was hoping that someone had an idea how to proceed with using a bootloader and maintaining interrupt support - so I had an idea what the ACTUAL problem is (rather than "what is wrong? the ISR, the init, the ADC, the SLEEP?")... I'd like to start eliminating the posibilities.


I am writing my PIC's program in assembler, it seems easier than trying to learn PIC C or something else, and I have tried for the past few days to search for similar issues/sample code.

I'm not expecting anyone to do it for me, but a few pointers or at least some reassurance I am going about things the right way would really be helpful...

I've attached the ASM source code I am working with... some of it is commented out, some is probably wrong at this point, I can't quite remember (and I can't test it because I blew up my 16F88's ICSP data port and didn't realise until I wiped it this morning xD - waiting for RS to deliver another...)

Thank you very much for reading if you spent the time to sift through the waffle in this post! Haha...


Turkish.
 

Attachments

  • hello.asm
    3.9 KB · Views: 203
Last edited:
For your first problem, you can send a hexadecimal string to the PC by doing,
Code:
SendHex		movwf	HexTemp		;store for later
		swapf	HexTemp,W	;get high nibble
		call	SendLoNibble	;send it
		movfw	HexTemp		;get low nibble and fall through
SendLoNibble	andlw	0fh		;keep lower 4 bits
		addlw	0x100-d'10'	;if a-f then carry set
		btfsc	STATUS,C	;was it > 9
		addlw	7		;yes, add 7
		addlw	"0"+d'10'	;convert to ascii
		goto	SendByte	;and send it

You just load W with the value and call SendHex. You could send "&h" before it to make conversion easier at the PC end.

As for the ADC being inacurate, I haven't found this to be a problem.

Mike.
 
I agree with Pommie, no problems with ADC accuracy on PIC's - you might also try checking my PIC tutorials, which do what you require - with Tutorial 11.4 having both decimal and hexadecimal outouts, to both (or either) RS232 and LCD. I've also written binary ASCII versions as well, I'm not sure now if they are in one of the tutorials or not?.
 
Wow, thanks for the fast replies, and the wealth of information!

In response to:
As for the ADC being inacurate, I haven't found this to be a problem.

I should mention at this point that I am using the internal RC oscillator for the uC 8Mhz clock frequency... a situation for which the data sheet specifically states a adc start-sleep-interrupt subroutine is required in order to maintain it's accuracy.

The main problem I am noticing in this aspect is the first and second bits of the ADC output 'oscillating' incredibly quickly... even when the ADC input is connected to a laboratory power supply and a huge delay is added in. The only explaination I have for this is the uC noise associated with looping and checking the 'GO/DONE' bit before continuing - while the ADC is in progress.


It could of course be directly attributed to the fact it is still on breadboard, I was kinda *hoping* I could achieve something close to production performance in this situation :(



Again thank you for the replies :), you have been most helpful.


Turkish
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top