Just a bit behind on the newsletter! 8^(
But I will catch up! Here is Aprils issue:
SX based 15 MHz frequency
counter.
( by Alberto Geraci of BTX Sistemas Argentina )
This is a simple frequency counter project based in a SX28 microcontroller from Ubicom. It doesn't try to be an exact instrument measurement, only try to demonstrate, with a very low cost and low quantity of materials, ( only two ICs ) how much we could get from an SX28 plus the RS232 serial port in a PC.
Let me to leave to the people who read this article to experiment with it, make some changes, or apply new ideas. If you like you could write to me at btxsistemas~NOSPAM~ at ciudad.com.ar .
In this article,
you have the complete schematic diagram
for the frequency counter, the Windows software and installer, a
picture
with the software in action, and all source code, including the
SX
assembly code and the PC Visual Foxpro 6.0 code. {ed: available on
request}
The project is in a basis of two parts, one is the SX code which implement all frequency count, and the RS232 serial communication.
The second part is the PC software that only reads the data sent by the SX and shows it in a window of a simulated standard frequency counter.
This lets the PC software to be not responsible about the maximum wave frequency to be tested, and leave to the SX code all the quickly job, taking advantage of the 50 MIPS.
I think that using a different external counter in this project, you could get much more than 15 MHz wide of band for the frequency counter.
About SX code:
The original idea to measure the external input frequency as quickly as possible with the SX28 in this project is the following:
The signal to be measured need to be an square wave ( you could do this with any schmitt trigger gate ) and it will be the clock for an external counter, that count how many input pulses receive during a exactly elapsed time.
This time, is the called "time base" of the frequency counter and its given by the SX software, like this instrument is totally auto-range, the SX software will take more than one measure to know exactly the value of the input frequency, giving in only 12 bits of resolution ( 12 bits external counter ) a complete result in 8 decimal digits in the display. ( PC software display ).
How to do this ?, Ok we will take first a 0.5 seconds ( time base ) value of the counter, and after that a 1/4096 seconds value, this two measures will give us, four byte of data to be send to the PC software.
And that is all we need, then the PC soft will make some calculation to get the decimal frequency value.
{ed: Here is the main part of the code. The rest is mostly delay routines and setup.}
begin setb rescount ; clr the counter call res_delay ; delay for the counter reset clrb rescount ; finish clr the counter. call half_sec ; let's the input freq to run the counter for 1/2 sec. mov data1p,rc ; mov to data1p variable, the content of rb register. mov data1s,ra ; mov to data1s variable, the content of ra register. setb rescount ; clr the counter call res_delay ; delay for the counter reset clrb rescount ; finish clr the counter. call short_time ; let's the input freq to run the counter for 1/4096 sec. mov data2p,rc ; mov to data2p variable, the content of rb register. mov data2s,ra ; mov to data2s variable, the content of ra register. ; at this point we finished to measure the input frequency. Now we'll send it to serial port. mov !option,#%10011111 ; for RS232 enable mov w,data1p call send_byte call send_delay and data1s,#%00001111 ; to avoid the undesired data at high niblle of port RA. mov w,data1s call send_byte call send_delay mov w,data2p call send_byte call send_delay and data2s,#%00001111 ; to avoid the undesired data at high niblle of port RA. mov w,data2s call send_byte call send_delay mov !option,#%11011111 ; for RS232 disable ; finished to sent the data to serial port, all begins again. mov data1p,#0 ; mov data1s,#0 ; mov data2p,#0 ; mov data2s,#0 ; jmp begin
OK at this point we have a lot of different possibilities to change or to add, I think the first and most important to get more speed, for measure higher frequencies, is the change of the external counter, in this project to demonstrate the work, I was using the 74HC4040 which have a 12 bits of resolution, so think about a 16 bits counter to get a 4.29 GHz (theoretical) or real= the maximum input clock frequency. of the counter.
You must use (change in SX soft) the entire rb and rc port to read all this 16 bits and let the ra.x bit to implement the serial communication.
About the PC software:
The PC software was entire programmed in Visual Fox 6.0, the idea was to create an small window into a dialog based application, which shows you the frequency. measured with the hardware.
You can install the software by clicking only in the setup icon, be carefully to get installed and registered the Microsoft MSCOMM 6.0 control in your windows version, This software is only for windows application, you cant use it with another operating system. {ed: the installer is in Spanish, but most options are standard and easy to figure out. There is a point where there appears to only be buttons for changeing the install directory and canceling the install, but there is, in fact, another, larger, button above and to the left with a picture of a computer on it. Click on that to continue.)
When you start the software, you can see an rectangle window with a pict simulating the frequency counter, it has only two buttons to control it, one is the power button to close the software and the another is the COMX select button to choose which COM port to use.
Here are the graphics used in the program:
COM1
COM2
Like we said before, the frequency counter is full auto range and you dont need to make changes in the time base of it, this software will receive four bytes of data every 0.6 seconds ( approximately ) and it will convert it in a big decimal display to be read for you, in the case the hardware is not connected the software will show the display as off; NO error is advised.
The software language is only in English version to get Spanish version write to btxsistemas please.
OK Thats all folks, and I hope, that you enjoy it
Alberto Geraci
BTX Sistemas.
NOTE: YOU CAN USE THIS PROJECT ONLY FREE, FOR NON COMMERCIAL PURPOSES WITHOUT MY AUTHORIZATION.
Given two registers named "Port" and "Pin". "Port" contains the low byte of the address to one of the IO ports. "Pin" contains a value of 0 to 7 representing a bit of the port register.
Use these two registers to point to an actual IO pin and set it high or low. The Port and Pin numbers can not be hard coded. They must be set dynamically...
Scott Datallo posted this solution to the piclist, and after some complaint about how his "obvious" code is totally impossible to understand by anyone else, he even added comments.
; setbit(unsigned char PORT, unsigned char PIN) ; ; inputs: ; PORT = lower byte of the address of LATA,B,C,D, or E ; PIN = 0..7 is the bit in the port we wish to set ; ; code works like this: ; ; unsigned char *pPort; ; ; pPort = PORT; ; *pPort |= (1<< (PIN&7)); ; ; movff PORT, FSR0L ;PORT holds the lower byte of the address ;of the I/O Port latch ; ; compute 1 << PIN ; mov W, #$04 ;Assume bit 1 of PIN is set; W = 1<<2 sb PIN.$1 ;But check to make sure. mov W, #$01 ;oops, W = 1<<0 snb PIN.$0 ;If bit 0 is set rlncf WREG,F ; then W <<= 1 ( W is now 2 or 8). snb PIN.$2 ;If bit 2 is set swap WREG ; then shift left 4 ; now W = 1<<PIN, and FSR0H:L point to the port latch or INDF0, W ; Set the bit:
CRC-32 is useful for tcp/ip implementations. Scott Dattalo says:
If you go here:http://www.repairfaq.org/filipg/LINK/F_crc_v35.html#CRCV_001
You'll find the specs for the CRC-32 to be:
Name : "CRC-32" Width : 32 Poly : 04C11DB7 Init : FFFFFFFF RefIn : True RefOut : True XorOut : FFFFFFFF Check : CBF43926If you go here:
http://rcswww.urz.tu-dresden.de/~sr21/crc.html
and grab the C-Code:
http://rcswww.urz.tu-dresden.de/~sr21/crctester.c
You'll find an algorithm that implements CRC-32. In fact, it implements crc-32 in 4 different ways, slow and fast bit by bit and slow and fast table reads.
I've added a new one that uses nibble indexing (think PIC) and smaller tables:
unsigned long crcSmalltablefast (unsigned char* p, unsigned long len) { // fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip. // only usable with polynom orders of 8, 16, 24 or 32. unsigned long crc = crcinit_direct; unsigned long i; if (refin) crc = reflect(crc, order); if (!refin) while (len--) { i = ((crc >> (order-8)) & 0xff) ^ *p++; crc = (crc << 8) ^ crcrow0[i&0x0f] ^ crccol0[i>>4]; } else while (len--) { i = (crc & 0xff) ^ *p++; crc = (crc >> 8) ^ crcrow0[i&0x0f] ^ crccol0[i>>4]; } if (refout^refin) crc = reflect(crc, order); crc^= crcxor; crc&= crcmask; return(crc); }The two small tables are 16-element arrays obtained straight from the 256-element table:
if(i<16) crcrow0[i] = crctab[i]; if((i & 0x0f) == 0) crccol0[i>>4] = crctab[i];Or if you want, here they are
row col ----------------------- 00000000 00000000 77073096 1db71064 ee0e612c 3b6e20c8 990951ba 26d930ac 076dc419 76dc4190 706af48f 6b6b51f4 e963a535 4db26158 9e6495a3 5005713c 0edb8832 edb88320 79dcb8a4 f00f9344 e0d5e91e d6d6a3e8 97d2d988 cb61b38c 09b64c2b 9b64c2b0 7eb17cbd 86d3d2d4 e7b82d07 a00ae278 90bf1d91 bdbdf21cIf you look closely at these numbers, all sorts of amazing patterns jump out. I've only just now started looking at them and haven't unraveled the underlying symmetry (yet).
The brute force implementation to which Tony and I elude, requires building these two arrays bit-by-bit based on the index into the array. For example, the far left column of nibbles is 0,7,e,9,... If you examine the most significant bit of this you'll see 0,0,1,1,.... This bit is the same as the second lsb of the index. In other words, if the index is a nibble, its bits can be labeled i3,i2,i1,i0. The most significant bit of the row array, r31, is simply i1.
If you label the nibbles of the row and column array, R7R6... and C7C6..., then you can express the nibble R7 by:
R7 = (i1, i1^i0, i1^i0, i0)
Where (a,b,c,d) form the four bits of the nibble.
Now it's a grind. Meticuously derive the remaining 15 boolean expression, drink a couple of pots of coffee, and a magic pattern will appear before your eyes!
;============================================================= ; ; CRC-32 for 18fxxx PIC's {ed: translated for SX by James Newton} ; ; 25JUL03 T. Scott Dattalo ; ; References ; 1) http://www.repairfaq.org/filipg/LINK/F_crc_v3.html ; 2) http://rcswww.urz.tu-dresden.de/~sr21/crc.html ; ; crc-32 ; ; This is an implementation of the 32-bit CRC algorithm based ; on the polynomial 04c11db7. According to reference (1), this ; CRC is used in Ethernet and PKZIP. Reference (2) implements ; this algorithm several different ways in C - crctester.c. The ; algorithm(s) in this PIC implementation extend those in reference (2). ; ; The first extension involves two lookup tables each 16 words long. ; It starts by examining the 256-element table created by the function ; generate_crc_table. If you write the 256-element as a 16 by 16 ; table, then the first row and column are: ; ; row 0 col 0 ; 00000000 00000000 ; 77073096 1db71064 ; ee0e612c 3b6e20c8 ; 990951ba 26d930ac ; 076dc419 76dc4190 ; 706af48f 6b6b51f4 ; e963a535 4db26158 ; 9e6495a3 5005713c ; 0edb8832 edb88320 ; 79dcb8a4 f00f9344 ; e0d5e91e d6d6a3e8 ; 97d2d988 cb61b38c ; 09b64c2b 9b64c2b0 ; 7eb17cbd 86d3d2d4 ; e7b82d07 a00ae278 ; 90bf1d91 bdbdf21c ; ; Here's C-function that implements the CRC-32 algorithm with these ; two arrays: ; ; unsigned long crcSmalltablefast (unsigned char* p, unsigned long len) ; { ; ; // fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip. ; // only usable with polynom orders of 8, 16, 24 or 32. ; ; unsigned long crc = crcinit_direct; ; unsigned long i; ; ; if (refin) ; crc = reflect(crc, order); ; ; if (!refin) ; while (len--) { ; i = ((crc >> (order-8)) & 0xff) ^ *p++; ; crc = (crc << 8) ^ crcrow0[i&0x0f] ^ crccol0[i>>4]; ; } ; else ; while (len--) { ; i = (crc & 0xff) ^ *p++; ; crc = (crc >> 8) ^ crcrow0[i&0x0f] ^ crccol0[i>>4]; ; } ; ; if (refout^refin) ; crc = reflect(crc, order); ; ; crc^= crcxor; ; crc&= crcmask; ; ; return(crc); ; } ; ; ; The next optimization is obtain by examining the patterns that ; exist in the 16-element arrays. Notice for example, that: ; crccol0[3] = crccol0[2] ^ crccol0[1]. ; In general, if the index into the array is written as a bit ; pattern: i = (abcd) then: ; crccol0[i] = crccol0[abcd] ; = crccol0[a000] ^ crccol0[0b00] ^ crccol0[00c0] ^ crccol0[000d] ; ; The same is true for crcrow0. Since it's possible to build the 16 elements ; from just 4 elements, then the two arrays can be reduced from 32 elemetns ; to just 8. Re-write this as a single array: ; ; 77073096 ; ee0e612c ; 076dc419 ; 0edb8832 ; 1db71064 ; 3b6e20c8 ; 76dc4190 ; edb88320 ; ; And then the CRC-32 can be computed like so: ; ; ; unsigned long crcbitbybit_2(unsigned char* p, unsigned long len) ; { ; ; unsigned long i; ; unsigned long crc = crcinit_direct; ; unsigned long u,v; ; ; if (refin) ; crc = reflect(crc, order); ; ; ; if(!refin) { ; ; ; } else ; while (len--) { ; i = (crc & 0xff) ^ *p++; ; crc >>= 8; ; ; if(i & 0x01) ; crc ^= 0x77073096; ; ; if(i & 0x02) ; crc ^= 0xee0e612c; ; ; if(i & 0x04) ; crc ^= 0x076dc419; ; ; if(i & 0x08) ; crc ^= 0x0edb8832; ; ; if(i & 0x10) ; crc ^= 0x1db71064; ; ; if(i & 0x20) ; crc ^= 0x3b6e20c8; ; ; if(i & 0x40) ; crc ^= 0x76dc4190; ; ; if(i & 0x80) ; crc ^= 0xedb88320; ; ; } ; ; crc^= crcxor; ; crc&= crcmask; ; ; return(crc); ; } ; ; ; enter with W=new data byte and current crc in crc:0-3 ; exit with new crc ; ; 76 instructions, 76 cycles. crc32_ver2: xor W, crc_lo mov temp, W ; low byte mov W, crc_ml snb temp.0 xor W, #$96 snb temp.1 xor W, #$2c snb temp.2 xor W, #$19 snb temp.3 xor W, #$32 snb temp.4 xor W, #$64 snb temp.5 xor W, #$cb snb temp.6 xor W, #$90 snb temp.7 xor W, #$20 mov crc_lo, W ; mid-low byte mov W, crc_mh snb temp.0 xor W, #$30 snb temp.1 xor W, #$61 snb temp.2 xor W, #$c4 snb temp.3 xor W, #$88 snb temp.4 xor W, #$10 snb temp.5 xor W, #$20 snb temp.6 xor W, #$41 snb temp.7 xor W, #$83 mov crc_ml, W ; mid-high byte mov W, crc_hi snb temp.0 xor W, #$07 snb temp.1 xor W, #$0e snb temp.2 xor W, #$6d snb temp.3 xor W, #$db snb temp.4 xor W, #$b7 snb temp.5 xor W, #$6e snb temp.6 xor W, #$dc snb temp.7 xor W, #$b8 mov crc_mh, W ; hi byte clr W snb temp.0 xor W, #$77 snb temp.1 xor W, #$ee snb temp.2 xor W, #$07 snb temp.3 xor W, #$0e snb temp.4 xor W, #$1d snb temp.5 xor W, #$3b snb temp.6 xor W, #$76 snb temp.7 xor W, #$ed mov crc_hi, W ret crc_init mov W, #$ff mov crc_lo, W mov crc_ml, W mov crc_mh, W mov crc_hi, W ret crc_invert not crc_lo not crc_ml not crc_mh not crc_hi ret
file: /Techref/new/letter/news0304.htm, 18KB, , updated: 2006/3/3 13:03, local time: 2024/8/21 20:05,
3.144.8.168:LOG IN
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://piclist.com/tecHREF/new/letter/news0304.htm"> Massmind news letter, April 2003 </A> |
Did you find what you needed? |
![]() o List host: MIT, Site host massmind.org, Top posters @none found - Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr. |
Welcome to piclist.com! |
.