Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Create an i2c device from a PIC MCU
Author | Message | ||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
Hi all, As seen in a couple of my posts, I have "grown" my own i2c slave devices. I wonder, is anyone interested in following up or maybe someone has done it already differently using MCUs other than F88 and F819? I/ve also done F88 and F819 i2c masters where number crunching speed was required in the master and a picaxe was too slow. (e.g. my 125KHz cattle ear tag reader) David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
Hi MOBI, I'm (slowly) working on a 125KHz animal tag reader project using the Mini Maximite as the controller and the reader is a slave module made by Priority One here in Melbourne (Model RFIDRW-E-232 - Atmel Mega 168PA based). Communication uses RS232. I'd be interested in your cattle reader project as a more embedded option than the RFIDRW-E-232 module. Where can I find information on the project? Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
I originally did it on the Ozelectronic forum but I'm happy to do it here again stage by stage if you like. I had always intended to Atmel it (currently runs picf88 as master/number cruncher) as well I would like to "blue tooth" it so no download cable is needed - currently dumps into a usb-serial cable. The prototype is a bit rough - works on 6 to 8 half flat AA cells with a read range of about 180 to 200mm. Good enough for yard work - works in a pen of cattle if you fit unit to a bamboo pole or the like and scan over the animal's heads. Unit will not record duplicate tags, and will hold up to 600+ tags with group separators (blank tag) for multiple herds. David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
My need is pretty simple - your cattle reader is doing a lot! I'm reading a passive FDX-B implanted cat tag with a very short read range - like 20mm or so, at the entrance to a cat door! The RFIDRW-E-232 module continuously scans for a tag and transmits the reading as ASCII text when it finds one. It's a nice module, 35X65mm and $40 or so, and can accept about a dozen plain text commands but it's overkill for what I need. The Mini-Maximite controller will be quite close to the reader (about 300mm or so) and has to have other power/control wire circuitry, so serial via wire is easiest for me. I'll check out your Ozelectronics project. At this stage I'm pretty well set up with what I have and the programming is underway in MMBasic but it would be nice to be able to put a few components on the Main board rather than piggy-back the module. Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
[quote=greg]I'm reading a passive FDX-B implanted cat tag [/quote] He Greg, My rfid device is HDX not FDX. Mind you I am interested in any data you have on hardware/protocol etc to read and decode FDX. In any case, this topic is starting to wander from 'home grown i2c'. Might have to start a topic for rfid in case there is anyone else interested. David M. |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
My rfid device is HDX not FDX. Mind you I am interested in any data you have on hardware/protocol etc to read and decode FDX. In any case, this topic is starting to wander from 'home grown i2c'. Might have to start a topic for rfid in case there is anyone else interested. Hi MOBI, The module I'm using also does HDX and several others. Check out this site: Priority One Design The module I'm using is their Product 10/24: "FDX-B/HDX RFID Reader Writer with external antenna & RS232 port". There's a lot of protocol information in the datasheet they have available for it on that module's page. Don't worry about a new thread from my point of view, I haven't heard of much interest from others on TheBackShed re RFID. Greg |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
It has been a while since I posted here on this topic and besides, it was getting a bit OT. For anyone interested, I have put a PIC16F88 firmware for an i2c slave device in the attached zip file. I think it is a bit big to include in a code block directly but if it is easier to discuss, then I will. It is just a template, i.e. it has no practical function other than to be able to write to or read from up to 8 device registers. The user must develop and insert the code in the "main_loop" section to provide the i2c function required. e.g. I took the digital output from a simple frequency counter and sent it to the master via i2c. This meant that I didn't have to do any data processing, just send to the i2c LCD on the same bus. Simple and easy. It is pretty self explanatory but questions are welcome. 2013-02-22_110953_i2c_master_latest.zip David M. |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
I'll put the firmware in assembly code in three sections (posts). The first is the variable block and configuration word. ; programme to use pic 16f88 as i2c slave
#include p16f88.inc list p=p16f88 ; ; uSec10 equ h'20' ;delay variables - always included just in case ms1 equ h'21' sec1 equ h'22' ms10 equ h'23' delay_byte equ h'24' ;not used in this example databyte equ h'25' ;register for data to o/p or i/p buff_size equ 8 ;number of internal addresses offset equ h'26' ;internal address pointer addr0 equ h'27' ;internal memory locations addr1 equ h'28' ;more or less as required or ram permits addr2 equ h'29' addr3 equ h'2a' ;eight should be plenty addr4 equ h'2b' addr5 equ h'2c' addr6 equ h'2d' addr7 equ h'2e' ;//// put slave variables here tempw equ h'70' ;interrupt "stack" status_temp equ h'71' ;independent of banks fsr_temp equ h'72' address equ b'00001000' ;i2c device base address /// change to suit your needs sda equ 1 ;i2c pins scl equ 4 __config config1, _lvp_off & _boden_off & _mclr_off & _wdt_off & _intrc_io ;& _cp_all David M. |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
This bit of the firmware sets up the PIC i/o and register configuration to act as a i2c slave (interrupt driven) org 0 goto start org 4 goto interrupt org 6 start: clrf porta ;get rid of any leftover data clrf portb bcf status,irp bcf status,rp1 bsf status,rp0 ;bank 1 clrf ansel movlw b'11110000' movwf trisa ;port a inputs and outputs movlw b'11111111' movwf trisb ;port b inputs (PB1,PB2,PB3, and PB4) MUST be inputs bsf trisb,1 ;scl and sda as inputs for i2c bsf trisb,4 movlw b'01100000' ;set int rc osc to 4MHz movwf osccon clrf sspstat ;clear ssp status register bcf status,rp0 ;select bank 0 movf portb,w ;read address select (1 of 4) bits PB2 and PB3 andlw b'00001100' ;mask for address bits movwf tempw ;save bits in temp register bcf status,c ;clear carry bit rrf tempw,w ;sh*t bits to pos 1 and 2 iorlw address ;combine with base address bsf status,rp0 ;bank 1 movwf sspadd ;set slave address bsf pie1,sspie ;enable interrupts bcf status,rp0 ;bank 0 bcf pir1,sspif movlw b'00110110' ;set up for slave read no interrupt movwf sspcon ;enable interrupts as required bsf intcon,peie bsf sspcon,sspen bsf intcon,gie ;switch on global interrupt enable ;=========================================================== ======== ; end of pic setup routine ; beginning of main-loop initialisation ;=========================================================== ======== David M. |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
I was going to split it into 3 sections but think 4 might be better. This section includes delay routines which always come in handy and a generic i2c to main_loop hand shaking routine - this my change depending on slave device requirements. ;=========================================================== ======== ; ; main slave function programme starts here ; ;=========================================================== ======== ;=========================================================== ======== clrf addr0 ;depending on the slave type, you may need to clear other addr registers clrf addr1 clrf offset ;set up indirect address for slave regs main_loop: movf addr1,f btfss status,z ;i.e addr1 = 0 goto main_loop ;this is part of the i2c - main_loop hand shaking clrf addr0 ;it might be different for a different slave device clrf addr1 ;//// main part of slave gets written here////// goto main_loop ;=========================================================== ======== ; start of main_loop routines etc. ;=========================================================== ======== ;=========================================================== ======== ;delay routines - set for 4MHz clock speed ;=========================================================== ======== delay10: ;10uSec per loop movwf usec10 ;come in with uSx10 count in w reg delay10a: nop ;pad out to 10uSecs nop nop nop nop nop decfsz usec10,f goto delay10a ;loop count 10uSec loops return delayms: movwf ms1 ;come in with mSec count in W reg delaymsa: movlw 100 ;set up for 100 x 10uSec = 1 mSec call delay10 decfsz ms1,f goto delaymsa return delayms10: ;come in with mSx10 count in W reg movwf ms10 delayms10a: movlw 10 call delayms decfsz ms10,f goto delayms10a return delaysec: movwf sec1 ;come in with seconds count in W reg delayseca: movlw 100 ;1000 mSec call delayms10 decfsz sec1,f goto delayseca return ;=========================================================== ============= ; End of Main Loop Routines etc. ; Beginning of interrupt routines David M. |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
This is the last and most important part as it includes the interrupt handling and i2c functions. This firmware can be installed in a PIC as it is but will only allow you to treat the device as an 8 byte i2c RAM. You need to put a main_loop function in to do anything worth while. I'll dig up a simple example and include somewhere after this post. If I get any interest or not. ;=========================================================== ============= ; this is the data i/o section - i2c slave main routine ;=========================================================== ============= ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++ interrupt: movwf tempw ;save contents of w reg swapf status,w movwf status_temp ;save contents of status reg movf fsr,w movwf fsr_temp ;save fsr register clrf status ;bank 0 bcf pir1,sspif movf sspbuf,w ;clear data buffer movwf databyte ;save in databyte bsf status,rp0 ;bank 1 btfsc sspstat,d_a ;check if data or address goto data_mode ;=========================================================== ============= ; get and process mode byte ;=========================================================== ============= btfsc sspstat,r_w ;check if we need a mode byte goto send call inbyte ;read mode byte movlw buff_size ;get number of internal addresses subwf databyte,w ;check if valid address btfsc status,c ;valid if carry is 0 clrf databyte ;if bad address, assume address 0 movf databyte,w ;good address, so put it in <offset> movwf offset goto int_end data_mode: btfss sspstat,r_w ;check if read or write goto receive ;input data send: bcf status,rp0 ;bank 0 movlw addr0 ;physical location of address block addwf offset,w ;point to required address movwf fsr ;put address in indirect address mode movf indf,w ;get data to be output btfsc sspcon,ckp ;check if another byte goto int_end ;no so finish movwf sspbuf ;send data to master nop ;delay needed to correct timing nop nop nop nop bsf sspcon,ckp bcf pir1,sspif incf offset,f movlw buff_size subwf offset,w btfsc status,z clrf offset goto int_end receive: bcf status,rp0 ;bank 0 movlw addr0 ;physical location of address block addwf offset,w ;point to required address movwf fsr ;put address in indirect address mode movf databyte,w movwf indf ;put data in appropriate address incf offset,f ;automatic increment of address movlw buff_size subwf offset,w ;check if exceeded address limit btfsc status,z clrf offset ;back to start of addresses goto int_end ;=========================================================== ============= int_end: bcf status,rp0 ;bank 0 movf fsr_temp,w movwf fsr bcf pir1,sspif ;clear the interrupt flag swapf status_temp,w ;restore temps movwf status swapf tempw,f swapf tempw,w retfie inbyte: bcf status,rp0 ;bank 0 btfss pir1,sspif ;wait for databyte in goto inbyte movf sspbuf,w ;read data buffer and put in databyte reg movwf databyte bcf pir1,sspif ;clear interrupt flag return end ;mandatory instruction David M. |
||||
Print this page |