tag:blogger.com,1999:blog-19417248795919356662024-02-20T02:51:02.090+00:00Dave's Z80 JourneySome people like to build cars from scratch, well I'm going to build a computer from scratch. I have no idea what I am doing (well I know what a computer is and what it is made up of, but my electronics experience is very limited). Here goes...Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.comBlogger42125tag:blogger.com,1999:blog-1941724879591935666.post-32099629479638329632014-02-11T22:16:00.001+00:002014-02-20T19:01:56.867+00:0042. Working with the 74193 - 4 bit binary up/down counter.The 74193 is quite a useful IC to have in your collection. It can count up or down in binary from 0000 to 1111. You can reset the value to zero, you can pre-set the start value (useful as a buffer when not used as a counter) and if you count above or below the four bits it can flag a carry or borrow condition. This last bit is quite important as it means you can daisy chain lots of 74193s together to count with 8, 12, 16 bits and so on.<br />
<br />
The pins are:<br />
<br />
<pre><span style="color: #666666; font-size: x-small;">16 Vcc Input Voltage
8 GND Ground
15 A IN Input Bit 0
1 B IN Input Bit 1
10 C IN Input Bit 2
9 D IN Input Bit 3
11 LOAD IN Load Inputs - Inactive state HIGH. Go LOW/HIGH to load inputs.
3 QA OUT Output Bit 0
2 QB OUT Output Bit 1
6 QC OUT Output Bit 2
7 QD OUT Output Bit 3
14 CLEAR IN Reset Outputs - Inactive State LOW. Go HIGH/LOW to reset.
4 DOWN IN Count Down - Inactive state HIGH. Go LOW/HIGH to count down.
5 UP IN Count Up - Inactive State HIGH. Go LOW/HIGH to count up.
13 BORROW OUT Count has gone below 0000. Connect this to DOWN of IC below.
12 CARRY OUT Count has gone above 1111. Connect this to UP of IC above.</span>
</pre>
<br />
In this example below I have daisy chained 3x Philips 74HC193Ns together to produce a 12 bit value:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpZI63nJhrH0U5yQ3pj9avfVujRtk2bQa3K2Bd1HXAWcQXZNFQMN3kA3-fCmkp10YAjgmhuRJlFqAkUiv2BHH6jZ0hww1wGqkcsoh-Mypg6NL7SCjSjnxcME5MU56IZ9FnjRzQdhYyhDA/s1600/20140211_211520.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpZI63nJhrH0U5yQ3pj9avfVujRtk2bQa3K2Bd1HXAWcQXZNFQMN3kA3-fCmkp10YAjgmhuRJlFqAkUiv2BHH6jZ0hww1wGqkcsoh-Mypg6NL7SCjSjnxcME5MU56IZ9FnjRzQdhYyhDA/s1600/20140211_211520.jpg" height="360" width="640" /></a></div>
<pre></pre>
<br />
The red jump wires are connected to the UP input. Initially from an Arduino UNO providing a simple pulse with a 100ms delay, then from the CARRY to the UP of the next IC.<br />
<br />
A/B/C/D and BORROW are not connected. LOAD and DOWN connected to +5V as I'm not going to load a value and I am not going to count down.<br />
<br />
Just to show how this works I connect the outputs to some red LEDs followed by some inline 1K resistors (which are hidden behind the LEDs in the picture).<br />
<br />
Using this method, these 3x 74193s create a 12 bit address line which could be used help program or read a 4K by 8 bit EEPROM. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/GP3P0EY9v5o?feature=player_embedded' frameborder='0'></iframe></div>
<br />
<br />
Here's the Arduino code to pulse the 74193:<br />
<pre><span style="color: #274e13;">/*
74193 Synchronous 4 bit binary up/down counter
*/
int RESET = 2; // Connect to Pin 14 on the IC
int COUNT_UP = 3; // Connect to Pin 5 on the IC
void setup() {
// Initialise Pins
pinMode(RESET,OUTPUT);
pinMode(COUNT_UP,OUTPUT);
// Set default pin states
digitalWrite(COUNT_UP,HIGH);
digitalWrite(RESET,LOW);
// Perform a reset. Clears outputs to low state i.e. 0000
digitalWrite(RESET,HIGH);
digitalWrite(RESET,LOW);
}
void loop() {
// Clock Up Pulse
digitalWrite(COUNT_UP,LOW);
digitalWrite(COUNT_UP,HIGH);
delay(100);
}</span></pre>
Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com3tag:blogger.com,1999:blog-1941724879591935666.post-83226362483435428852014-01-31T19:05:00.002+00:002014-01-31T19:05:44.313+00:0041. PS/2 Keyboard TestNow a computer is no good, unless you can type something into it. Although it is possible to read a USB keyboard you need additional hardware if you are just using an Arduino UNO. However there is an Arduino library for PS/2 Keyboards. I found it at <a href="http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html">http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html</a>. You'll need to add it to the Arduino IDE Libraries. Click on Sketch->Import Library->Add Library...<br />
<br />
All I needed now was a PS/2 Keyboard as all my keyboards are USB these days. Fortunately they can still be found in plentiful supply at your favourite online stores.<br />
<br />
Of course, with s PS/2 keyboard you need a PS/2 socket to plug it in. I had an old motherboard and a hot air gun soon melted the solder to free it from the main board. Now to make it breadboard friendly.<br />
<br />
You only need 4 pins. +5V, GND, Clock and Data. See <a href="http://en.wikipedia.org/wiki/PS/2_port">http://en.wikipedia.org/wiki/PS/2_port</a> for details of the pin outs. I used a continuity tester to check which pins underneath matched which ps/2 port inputs and soldered on four jump wires.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsTsZsAvyK-V5IhMp2JwO8dTNsU32CsIlH_HZUwar-_pwnASYubwzMVbwqJudmZHXdCsOY9GEaziTy3Q1XnSBMB9vIXuhWLeZ_I2GzHQ6XQR06zDL6q8nkhZJsdgsQXpU0Ns3IhyphenhyphenqjjY/s1600/20140131_183145.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpsTsZsAvyK-V5IhMp2JwO8dTNsU32CsIlH_HZUwar-_pwnASYubwzMVbwqJudmZHXdCsOY9GEaziTy3Q1XnSBMB9vIXuhWLeZ_I2GzHQ6XQR06zDL6q8nkhZJsdgsQXpU0Ns3IhyphenhyphenqjjY/s1600/20140131_183145.jpg" height="225" width="400" /></a></div>
<br />
<br />
Using just the LiquidCrystal library and the PS2Keyboard library, I was able to write all over my 20x4 LCD display.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP07SOWSAwyasnitX5w50CFgrDE_jQI23vFM3sliyO-H4mDQ2sPEX85yxacMc4zzZLbSfkN8fpPOZ1ExqdI-j3QJx60vDEHAcwIUFPE4ulSCh9poGiga2du3-1BGOKthDVaA_C-QsfaMo/s1600/20140131_183400.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjP07SOWSAwyasnitX5w50CFgrDE_jQI23vFM3sliyO-H4mDQ2sPEX85yxacMc4zzZLbSfkN8fpPOZ1ExqdI-j3QJx60vDEHAcwIUFPE4ulSCh9poGiga2du3-1BGOKthDVaA_C-QsfaMo/s1600/20140131_183400.jpg" height="400" width="225" /></a></div>
<br />
The PS2Keyboard library defaults to US layout doesnt have the UK layout defined so I might tweak that later.<br />
<br />
Heres the code:<br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">#include <LiquidCrystal.h></span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">#include <PS2Keyboard.h></span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">LiquidCrystal lcd(10,9,8,7,6,5,4);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">PS2Keyboard keyboard;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">const int DataPin = 3;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">const int IRQpin = 2;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">int row=1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">int col=0;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">void setup() {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> // put your setup code here, to run once:</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> delay(1000);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> keyboard.begin(DataPin, IRQpin);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.begin(20,4);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.print("Keyboard Test");</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> //lcd.cursor();</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.blink();</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.setCursor(col,row);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">}</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"><br /></span>
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">void loop() {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> // put your main code here, to run repeatedly: </span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> if (keyboard.available()) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> </span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> // read the next key</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> char c = keyboard.read();</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> </span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> // check for some of the special keys</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> if (c == PS2_ENTER) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=0;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> row=row+1;</span><br />
<span style="color: #274e13; font-family: 'Courier New', Courier, monospace; font-size: x-small;"> } else if (c == PS2_ESC) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.clear(); // clear screen if ESC is pressed.</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=0;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> row=0;</span><br />
<span style="color: #274e13; font-family: 'Courier New', Courier, monospace; font-size: x-small;"> } else if (c == PS2_LEFTARROW) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=col-1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> } else if (c == PS2_RIGHTARROW) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=col+1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> } else if (c == PS2_UPARROW) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> row=row-1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> } else if (c == PS2_DOWNARROW) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> row=row+1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> } else if (c == PS2_DELETE) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=col-1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.setCursor(col,row);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> c=32;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.print(c);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.setCursor(col,row);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> } else {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> </span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> // otherwise, just print all normal characters</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.print(c);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=col+1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> if (col>19) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=0;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> row=row+1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> if (col<0) {</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> col=19;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> row=row-1;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> if (row>3) row=0;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> if (row<0) row=3;</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> }</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;"> lcd.setCursor(col,row);</span><br />
<span style="color: #274e13; font-family: Courier New, Courier, monospace; font-size: x-small;">}</span>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-69599703928138499892014-01-20T20:03:00.001+00:002014-02-01T12:31:37.574+00:0040. A foray with I²CIt's been a while since I built something that didn't come in a kit.<br />
<br />
I've had a RTC (Real Time Clock) chip (PCF8563) in my collection for a while as I wanted to get to grips with I²C.<br />
<br />
I²C is a protocol for allowing ICs to communicate via a 2 wire interface. One wire is the clock (SCL) and the other is the data (SDA). This saves on the number of connections and also simplifies circuit design.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC5HZCr4fYTWWK-FQF5mijOoEjyxgxzPspQ36d_yFDb0kg5wy8qZ-cryrt-anyHDWJOou_fZ7m6BRocfwKNJGLsimTHa_WnID71kc-KKpRq3_I-mJrIaDv2tHz4kg-g1nAuUqUxNypGBo/s1600/20140119_220214.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC5HZCr4fYTWWK-FQF5mijOoEjyxgxzPspQ36d_yFDb0kg5wy8qZ-cryrt-anyHDWJOou_fZ7m6BRocfwKNJGLsimTHa_WnID71kc-KKpRq3_I-mJrIaDv2tHz4kg-g1nAuUqUxNypGBo/s1600/20140119_220214.jpg" height="400" width="225" /></a>My early experiments writing bit bashing code on a PIC to speak I²C ended up fruitless and I thought I had missed some vital information. Needless to say, it put me off for a bit. I got other people's code to work on the PIC but I wanted to understand it because I thought it might be cool to get the Z80 to talk to a RTC.<br />
<br />
However, the Arduino boards have a dedicated I²C interface and library code that makes it a piece of cake to get started. So I dug out the PCF8563 and started coding. Fortunately there was even code examples for Arduino using the PCF8563. Once you've seen how the code should be written its a lot easier to roll your own.<br />
<br />
So I got the RTC clock wired up, and added my 16x2 LCD and in no time had a clock working. It seemed a bit too easy, so I wondered what else I could connect to the I²C bus. I found the DS1631 temperature/thermostat IC.<br />
<br />
Each I²C device has a different address. I don't know how unique they are as there are only 128 addresses available. Bit 0 is used to signify read or write. Luckily the RTC and Temp IC are different.<br />
<br />
Needless to say it wasn't to hard to talk to the DS1631 as well using the <a href="http://arduino.cc/en/Reference/Wire">Wire</a> library and display the temperature.<br />
<br />
To spice things up a bit more I wanted to divorce the ATMega328P from my Arduino Uno and put it directly on the breadboard. This needed an additional 16MHz crystal and 2x 22pF capacitors.<br />
<br />
Lastly a battery backup for the RTC clock which is quite easy to connect by using diodes to make sure the current goes in the right direction.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1XQqMjLbJ-jjvR_xleinUU8c2i0HSdip0_kWcfjCd7D_c5JJOxoCH2UGg9BoKGH4A8Q8JdzaSt2TE1gK8Xw7Kf7Mv2tyhzsWSTZi_B4C8dg_V-4sG4tX8r2rliy94wYtYwY11pmONXwU/s1600/Tout+on+DS1631_schem.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1XQqMjLbJ-jjvR_xleinUU8c2i0HSdip0_kWcfjCd7D_c5JJOxoCH2UGg9BoKGH4A8Q8JdzaSt2TE1gK8Xw7Kf7Mv2tyhzsWSTZi_B4C8dg_V-4sG4tX8r2rliy94wYtYwY11pmONXwU/s1600/Tout+on+DS1631_schem.png" height="320" width="264" /></a></div>
The software allows you (via the 2 buttons) to set the date and time and set a thermostat temperature, which when reached lights the red LED via a 1K resistor at the bottom. In fact the DS1631 will operate on its own once configured to control a heating system.<br />
<br />
Update: somehow the 1K resistor was a 47 ohm. I noticed that when the thermostat temperature was reached and the LED lit up the temperature would go back up again. It seems without much resistance on the output it causes the IC to warm up due to the current flow. What I have done now it put a 10k resistor and fed that into a BC548B transistor to light the LED.<br />
<br />
<br />Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-45339811231968924912014-01-20T18:38:00.000+00:002014-01-20T18:48:06.659+00:0039. Time on my hands.I bought this watch kit from <a href="http://www.coolcomponents.co.uk/solder-time-watch-kit.html">Cool Components</a>. Easy to solder and assemble. I realised afterwards that I could customize the PIC chip as the source code is available. I prefer a 24 hour clock, and this is programmed just to display the 12 hour clock. But its still a great watch and wearing it about at work has become a conversation piece.<br />
<span id="goog_556695851"></span><span id="goog_556695852"></span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7QreqngIuEw9MMc2_pq2HjhSfHxAjSaU_HoyHlBRcxl2q2DqFm3VR5C1iBOTuYET-puapKE8VqQnb8BDLDcq6te_cN0J2mEJGYTHiB_6Mcv9gdnVHIoj6sazy0twDcEUVnJGST0ooUA8/s1600/20140101_193826.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7QreqngIuEw9MMc2_pq2HjhSfHxAjSaU_HoyHlBRcxl2q2DqFm3VR5C1iBOTuYET-puapKE8VqQnb8BDLDcq6te_cN0J2mEJGYTHiB_6Mcv9gdnVHIoj6sazy0twDcEUVnJGST0ooUA8/s1600/20140101_193826.jpg" height="180" width="320" /></a></div>
Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-19175351763820711362013-01-03T21:27:00.001+00:002013-01-03T21:30:35.506+00:0038. Nixie Clock with ZM1177 Tubes.For Christmas, my wife bought me a ZM1177 Nixie QTC Clock kit from <a href="http://www.pvelectronics.co.uk/">http://www.pvelectronics.co.uk</a><br />
<br />
It took me all Saturday afternoon to make, mostly soldering and snipping wires. There was a bit of a mess up with the plexiglass case as I was sent 2 base parts and no top part with holes for the tubes. However a quick email to the vendor and the correct part was mailed out straight away. Excellent Service!<br />
<br />
I also got the GPS option so the time is always right.<br />
<br />
And here it is.....<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicoWH8hR1WqhotqLnBGpwoTwJaq_ohWau8XtmNhqC7J7LQkcYgcfkwCRlkuHvq7QEZ3thvxnBPPgw9TodYU0OFfAF-tIxp0lfJYA0mHo6JCusyH3gFa_EwXDN8jucTxaHKTDmgZ1O3b8k/s1600/2013-01-03+17.13.43.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicoWH8hR1WqhotqLnBGpwoTwJaq_ohWau8XtmNhqC7J7LQkcYgcfkwCRlkuHvq7QEZ3thvxnBPPgw9TodYU0OFfAF-tIxp0lfJYA0mHo6JCusyH3gFa_EwXDN8jucTxaHKTDmgZ1O3b8k/s320/2013-01-03+17.13.43.jpg" width="320" /></a></div>
<br />Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-19796632267906277212012-08-07T11:49:00.001+01:002012-08-07T11:49:24.704+01:0037. Raspberry Pi Case.Just got this case for my Raspberry Pi. I got it from <a href="http://www.modmypi.com/">http://www.modmypi.com</a>. Its very good. Fit is perfect, it doesn't rattle around in the case and the quality is very good too. You can choose any colours you like and even mix and match top and bottom case colours. The case clips together very solidly and comes with some stick on clear rubber feet. Well worth the money.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3M4LJExDAPhve7XuG4xfG9DSG5dxttV92kv0kM1fmb7XdwNmtdfCddW6P6u5Og52I8j0-C-G9bzgqwZFlzLxIykVvI961P1lWEzVaykAq1gWu3U8ABMAe7GhMWL6mZ_e70RaCtQtvt14/s1600/2012-08-07+10.54.51.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="245" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3M4LJExDAPhve7XuG4xfG9DSG5dxttV92kv0kM1fmb7XdwNmtdfCddW6P6u5Og52I8j0-C-G9bzgqwZFlzLxIykVvI961P1lWEzVaykAq1gWu3U8ABMAe7GhMWL6mZ_e70RaCtQtvt14/s320/2012-08-07+10.54.51.jpg" width="320" /></a></div>
<br />Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-86490814687695610862012-08-03T22:47:00.000+01:002012-08-03T22:47:20.318+01:0036. Apple 1 - Hello World!It's been a while. I've been getting distracted by all things geeky. I thought I'd share this though.<br />
<br />
I became curious by the Apple-1, the original must have Apple product, the Ford Model T of computers if you like. All you got was a circuit board, but no keyboard or monitor (a bit like the raspberry Pi of its day). I decided to look for an emulator for it, and at this stage knew nothing of the Apple-1's underpinnings. It wasn't a Z80 but my old friend the 6502. I've not touched the 6502 since secondary school when I used to play with the Commodore PET/CBM in the early 80's.<br />
<br />
I got the Pom-1 emulator in Java flavor and downloaded the Apple-1 manual.<br />
<br />
I soon realised that to program the Apple-1 you just entered 6502 machine codes and ran the machine code programs. No BASIC interpreter (although there is a 6502 program for the Apple-1 that you can load in to get BASIC). So I set about relearning 6502 machine language and so far my efforts have resulted in my first "Hello World!" program.<br />
<br />
Here's a screenshot of the code and it running:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAYglGj3bIUMt2Q12K5Wyd1H2e_GmVmfMeQckVl_o80bh73iucGHFdLboTjCzZciDtWCC5uRnGCHP4BB6J0uSwsvJPl67tx9NjCrxKPJX4eb5CVZWsy0uGj3-GSV1o0Nfzn9RwRWhdQPg/s1600/apple1-hello_world.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAYglGj3bIUMt2Q12K5Wyd1H2e_GmVmfMeQckVl_o80bh73iucGHFdLboTjCzZciDtWCC5uRnGCHP4BB6J0uSwsvJPl67tx9NjCrxKPJX4eb5CVZWsy0uGj3-GSV1o0Nfzn9RwRWhdQPg/s1600/apple1-hello_world.png" /></a></div>
<br />
\ is the only screen indication that the Apple-1 is alive. 0.22 displays the first 23 bytes and R runs from address 0.<br />
<br />
Why is this relevant? Well this is something like what I want to build with the Z80Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com1tag:blogger.com,1999:blog-1941724879591935666.post-67378622435316563402012-05-20T12:38:00.001+01:002012-05-20T12:38:56.719+01:0035. Floppy Drive Music. Stage 1.Ok well, I need to find time to understand the radio stuff, so I'm gonna park that for now and move on to Floopy Drive Music. Ok yes, its been done before (as has most of the stuff I'm doing), but I haven't done it yet.<br />
<br />
So what is floppy drive music? Well by stepping the drive's motor at different speeds we can get different pitches from it. Combine the different pitches and you get music.<br />
<br />
I'm going to use the Arduino Uno to start with but I may program a PIC chip to do the same later.<br />
<br />
After a bit of reading on the web, it seems the Arduino will not have enough power from the +5V supply to power the floppy drive. Its recommended to use another power source.<br />
<br />
So I have an old PC power supply handy which should do the job. However, when its disconnected from its host PC's motherboard, its does nothing when plugged into the mains. Fortunately you can fake this by shorting the PS_ON# pin to it's adjacent COM (see <a href="http://www.smpspowersupply.com/connectors-pinouts.html">http://www.smpspowersupply.com/connectors-pinouts.html</a> for pin details).<br />
<br />
Of course using a PC PSU (Power Supply Unit) means it come with all the connectors to connect to the power pins of floppy drive, and andthing else you might want to plug in.<br />
<br />
Pins connected, plugged in and powered on. Fan on the PSU starts and floppy drive makes a short whirring noise.<br />
<br />
<br />Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-39884753691936282702012-04-12T21:31:00.001+01:002012-04-12T21:31:08.355+01:0034. Diversion into radio.The lack of any joy with the MSF signal has got me thinking about radio electronics.
I connect a wire to CH1 on my Xprotolabs Oscilloscope because I remember getting random signals once before.<br />
<br />
Here's watch I picked up.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP4t8HR448oWv9T3bM1HqKRU9KkM3Kjl0JoMBF94cBAueJ-UdsSfHDpQnu_50r4U9wWFo50fkSgChUQfv1Nl7bjVCBP2H2GIlp6m_skCs6syGMHNZCQNkOe0iH-v0Wx1Q2uVoYSl-iXHk/s1600/xprotlab-pic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="244" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP4t8HR448oWv9T3bM1HqKRU9KkM3Kjl0JoMBF94cBAueJ-UdsSfHDpQnu_50r4U9wWFo50fkSgChUQfv1Nl7bjVCBP2H2GIlp6m_skCs6syGMHNZCQNkOe0iH-v0Wx1Q2uVoYSl-iXHk/s400/xprotlab-pic.png" width="400" /></a></div>
Its very weak, the oscilloscope settings are at max resolution. Somewhere in there is probably the MSF signal.<br />
<br />
Now while this is a divergence from the Z80 theme, I think its well worth looking into so improve my electronics knowledge as this is part if the journey.<br />
<br />
So I learnt recently about transistors, and how they can amplify a signal. So lets amplify this and see what we can make of it...Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-80790831778952350612012-04-05T22:32:00.001+01:002012-04-05T22:39:55.907+01:0033. Radio Ga GaRather than set the time myself, I thought I might be able to get the time signal from the Rugby Transmitter in the UK. Well its not in Rugby anymore but the name still sticks. Its in Anthorn in Cumbria and is called the MSF Signal transmitting on 60KHz. The <a href="http://www.npl.co.uk/science-technology/time-frequency/time/products-and-services/msf-radio-time-signal">National Physics Laboratory</a> (NPL) give you all the details of how to decode the signal so all I need is a receiver.<br />
<br />
I bought one from <a href="http://www.pvelectronics.co.uk/index.php?main_page=product_info&products_id=2">PV Electronics</a>. It come with an antenna and a receiver module which sends a signal that you can simply connect to an IC and decode the message.<br />
<br />
Well I get a signal, but not very well. Its anything I can use. I should get a pulse of varying length every second, but all I get are random on/offs. I have no way to tell if either the antenna or the receiver are faulty. I am assuming that I am not getting very good reception. It does get better when I point the antenna directly towards Anthorn, but still nothing useful.<br />
<br />
Maybe I just need a bigger antenna, so I started reading about them so I could make one, and found that its not a simple subject. Check this out: <a href="http://www.antenna-theory.com/">http://www.antenna-theory.com/</a> My brain hurts!<br />
<br />
A glimmer of hope though, it turns out that MSF was turned off from 26/03/2012 until today. Alas no, still a random signal.Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-43884270337119087462012-03-03T11:44:00.000+00:002012-03-03T11:44:00.672+00:0032. PIC Clock - Tic 2I wanted to see how far I could push the clock idea by adding two more dual 7 segment displays to add seconds and information. This meant controlling 8 transistors, however with all pins on the PIC16F505 used up from the last version I had to come up with a way to control 8 digits from 4 pins. Well as it happens, using binary, 3 pins are enough to control 8 outputs. Binary 000 to 111 is 8 different values.<br />
<br />
Now as luck would have it, there is such a thing as an 8 bit decoder controlled by 3 inputs in the guise of a 74LS238. There are many manufacturers and I used an M<b>74</b>HC<b>238</b>B1 from ST Microelectronics. Its does exactly the same thing.<br />
<br />
Using 1 less pin to control the 8 digits means I have a pin left over. This gives me an extra button to control the functions of the clock. I have yet to program these in but the its all wired up ready. All you can do is increase the minutes as before. The day was hardcoded so it always says SA for Saturday.<br />
<br />
I programmed in the entire alphabet (well as best you can with a 7 segment display as M,W,K,Q and X are not ideal) and this means I can display the day (Mo, Tu, We etc.), mode (AL for alarm, Yr for year etc.) amongst other uses I have yet to conjour.<br />
<br />
Here is it displaying Saturday 10:39 and 41 seconds.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF1HljdALnIkBnCzYAzwGIavcJpOcfVAIUT0pgPWPotuquPTZY07ydcFsfbYhOb42ohp94YHc4AAmLYyuWR5V0QNORGtwDDdmGHDvqeJ5QR_6h3qFgKDc3BXKWBCFrQeVJg_3kpPF5smg/s1600/2012-03-03+10.41.14.jpg" imageanchor="1" style=""><img border="0" height="400" width="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF1HljdALnIkBnCzYAzwGIavcJpOcfVAIUT0pgPWPotuquPTZY07ydcFsfbYhOb42ohp94YHc4AAmLYyuWR5V0QNORGtwDDdmGHDvqeJ5QR_6h3qFgKDc3BXKWBCFrQeVJg_3kpPF5smg/s400/2012-03-03+10.41.14.jpg" /></a></div><br />
With the additional displays there is a noticeable flicker as each one is updated and this is because the delay between refreshing each digit has doubled from 4x4ms to 8x4ms. I've not addressed this as its not that bad. Using a faster external oscillator is one option but all pins on the PIC are used so the alternatives are to halve the prescaler for TMR0 or use a different PIC with a faster internal oscillator.Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-55786193826979966992012-02-18T13:17:00.002+00:002012-02-18T13:26:57.201+00:0031. PIC Controlled Digital Clock.Following on from my new found friend the transistor, I had the idea to use four of them to switch on four 7 segment LED displays. Using 7 outputs from the PIC16F505 to control the segments a,b,c,d,e,f & g, another 4 outputs would switch each digit on in sequence. As it would be very fast you would see all digits on.<br />
<br />
This I realised would make a good clock project.<br />
<br />
With the PIC16F505 there are 14 pins, one for VCC on for GND and 12 can be used for I/O, 4 for controlling each 7 segment display, 7 for the individual segments and 1 to act as a time adjustment input. One of the pins can only be an input but all the others are bi-directional if needed so the input only pin was assign for the clock adjustment.<br />
<br />
Something to bare in mind when writing code for a clock is that you must keep refreshing the display. Its no good writing the time out then waiting for a minute because all you will see is the last digit. You have to keep writing over and over to fool the eye into seeing a continuous display. In order to do this you must sync the time between displaying each digit. The internal clock runs at 4MHz and the internal timer (TMR0) is incremented on each instruction cycle which is made of 4 clock pulses. Effectively then the timer is 1/4 of the clock i.e 1MHz. By setting the PIC prescaler to 1:32 (dividing the timer by 32), you have time to run code to display one digit and wait for 125 tics at 1MHz/32/125 which makes 4ms. So the time between displaying each digit is 4ms. Keeping a count of the 4ms increments, when we reach 250 we have 1 second. Keep a count of the seconds and you then have your minutes.<br />
<br />
The prescaler effectively tells you how many instructions can be executed between TMR0 tics so at 1:32 it equates to 32 instructions. The whole of my PIC program is 163 instructions (163 12bit bytes). We wait for 125 lots of 32 instructions before we increment the 4ms counter and move onto the next digit. What I am trying to point out here is that TMR0 may have ticked over a few times before you reach the checking loop.<br />
<br />
One last timing issue is how to check for the clock-set button being pressed. This also needs to be done between each digit and allow the minutes to incremented reasonable quickly to set the time. This can be done by checking bit 5 of the 4ms counter, if set then check the input line and if that's set then increment the minutes.<br />
<br />
Here some of the timing code that sits between each digit being displayed to show you how I've done it:<br />
<br />
<pre style="color:green">; time synchronisation
wait movf TMR0,W ; get timer 4MHz/4cy/32 = 32us
xorlw .125 ; compare with 125 x 32us = 4ms
btfss STATUS,Z ; if not equal
goto wait ; then continue waiting
; If TMR0 register is written, the increment is inhibited for the
; following two cycles. The user can work around this by writing
; an adjusted value to the TMR0 register.
; increment 4ms counter
movlw 8 ; advance 8x32us to allow for TMR0 reset
movwf TMR0 ; reset TMR0 with adjusted value
incf CNT1 ; increment 4ms timer
; check for clock set
clkset btfss CNT1,5 ; check every time bit 5 goes hi
goto incsec ; if not set goto incsec
movf PORTB,W ; Get input from PORTB
andlw b'001000' ; Line high?
btfss STATUS,Z ; If not -- active low
goto incsec ; got incsec
incf MINUTE ; increment minute
clrf SECOND ; reset seconds to zero
clrf CNT1 ; clear 4ms counter
goto lomin ; go check the minutes
; increment seconds
incsec movf CNT1,W ; get 4ms counter
xorlw .250 ; compare with 250
btfss STATUS,Z ; if not equal
goto check ; goto check
incf SECOND ; else increment second
clrf CNT1 ; reset 8ms timer
; check time
check movf SECOND,W ; get seconds.
xorlw .60 ; compare with 60.
btfss STATUS,Z ; if not
goto lomin ; goto lomin,
incf MINUTE ; else increment minutes.
clrf SECOND ; clear seconds.
;work out new time
lomin
</pre><br />
The breadboard layout looks like this:<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYMYVdtnSrhYd8AKHOqq42hbRTZgWS65zJGs0NnGmZR15NBGwR_hQcQ1yh7PQsejE97eXTdk2SOAGPH6zmhyPMDsTh9VrP7aZvakpIHcmQWtoJ3L-Z_VCzJTwscWJtSNZ1C_dkYcxFtFQ/s1600/2012-02-18+10.53.58.jpg" imageanchor="1" style=""><img border="0" height="300" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYMYVdtnSrhYd8AKHOqq42hbRTZgWS65zJGs0NnGmZR15NBGwR_hQcQ1yh7PQsejE97eXTdk2SOAGPH6zmhyPMDsTh9VrP7aZvakpIHcmQWtoJ3L-Z_VCzJTwscWJtSNZ1C_dkYcxFtFQ/s400/2012-02-18+10.53.58.jpg" /></a></div>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-45243004841188697492012-02-11T19:43:00.000+00:002012-02-11T19:43:44.293+00:0030. Christmas Lights with TransistorsA component I haven't used yet: The Transistor.<br />
<br />
I had some battery operated Christmas lights. They were static, always on, with red, green, orange and blue LEDs.<br />
<br />
I wondered if I could make them flash. As it turns out they were wired into two groups, red/orange and green/blue. At one end they were connect all together at the positive terminal and at the other end they two groups each connected to a resistor and the negative terminal. As this was all wound up in plastic sheath I would probably have damaged it trying to separate all the wires, so I left it as it was and went with the two grouped colours.<br />
<br />
Now as the red/orange and green/blue were connect to the negative terminal via a resistor each, this meant they were outputs, that is +5---LED---Resistor---GND.<br />
<br />
In order to program a PIC chip to control them I needed an input. This was not going to work, so I figured I could use an NPN Transistor to act as a switch.<br />
<br />
I programmed a PIC12F508 to connect to pins to two transistors to switch the LEDs on and off. I also incorporated a 4-gang DIP switch to allow 16 flashing modes. I ended up just having Switch 1 as a fast/slow option, switches 2 & 3 to give 4 flashing modes and switch 4 enables the original static always on mode.<br />
<br />
Here's my breadboard layout before I soldered it all together and put it into battery compartment and put a USB cable to provide +5V power instead of 4.5V with batteries.<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKQUfxPGSnkITxTx18O4NLcCaUZd3wlQlGU6bUyM73It3fnOorr_mahqq0cy0kEVVgJ4GjmMBeM9XqvCJW_Bn8fjXZ9ipR8UE-bayt3bbmjkcayYnvWcaVAHPb001PlvlQh7KpeKuiWGo/s1600/2012-02-01+15.10.55.jpg" imageanchor="1" style=""><img border="0" height="300" width="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKQUfxPGSnkITxTx18O4NLcCaUZd3wlQlGU6bUyM73It3fnOorr_mahqq0cy0kEVVgJ4GjmMBeM9XqvCJW_Bn8fjXZ9ipR8UE-bayt3bbmjkcayYnvWcaVAHPb001PlvlQh7KpeKuiWGo/s400/2012-02-01+15.10.55.jpg" /></a></div>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com1tag:blogger.com,1999:blog-1941724879591935666.post-38416136722682473942011-10-23T10:39:00.003+01:002012-02-12T21:05:24.388+00:0029. Manual Up/Down CounterI modified the circuit in the previous post by removing the 555 timer clock input and adding two switches so I could manually increment or decrement the value. These sent a signal to a 556 Timer chip (dual 555s) setup in monostable fashion to send a distinct pulse to the "clock-up/down" signals of the 74193. I also wired the "borrow" output of the first 74193 to the "clock-down" input of the second 74193 so it could count backwards. As inactive inputs to the clock up/down should be high when not in use I sent the 556 outputs via a 7404 hex inverter.<br />
<br />
On the monostable circuits I used 8.2K resistors and a 10μF capacitors. I tried a 47μF capacitors but the pulse length was a little too long. With the 10μF capacitors I am getting the occasional double clock pulse, so it would sometimes skip 2 counts. I hooked up my oscilloscope and it looks like I have some noise on the output pulse when triggered. I'm not sure what's causing this so any ideas would be much appreciated.<br />
<br />
Update: the circuit noise I have read is due to the switch contacts bouncing and to fix this I need a <b>debouncing</b> circuit.Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-78695863481145119232011-10-20T22:50:00.001+01:002011-10-20T22:54:13.443+01:0028. Here are my 2 digitsGiving my PIC16F505s programmed as Hex-to-7-segment-display-drivers a work out by making a Hex Counter. I wanted to have 4 digits but the breadboard wasn't big enough. I might work on this later<br />
<br />
For now, check out my little video:<br />
<br />
<iframe width="425" height="349" src="http://www.youtube.com/embed/DJEzqJFkdkc?hl=en&fs=1" frameborder="0" allowfullscreen></iframe>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-15488589595112472572011-10-20T22:32:00.001+01:002011-10-21T20:57:15.584+01:0027. Traffic Lights with PIC12F508sI thought I'd have some fun with the PICs, so I made this 3 way traffic light system.<br />
<br />
Pins:<br />
1. +5V<br />
2. Transmit<br />
3. Receive<br />
4. Master/Slave<br />
5. Green<br />
6. Amber<br />
7. Red<br />
8. Ground<br />
<br />
PIC code can be found <a href="https://docs.google.com/document/d/1uAIvu2PqcDagKNs7GAlEf5kWLNqRzFNEHDbm68dth4o/edit?hl=en_US&pli=1">here</a>.<br />
<br />
<iframe width="425" height="349" src="http://www.youtube.com/embed/rwAc0gbGf5Y?hl=en&fs=1" frameborder="0" allowfullscreen></iframe>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-49728649918383171452011-10-07T19:02:00.002+01:002011-10-07T19:04:08.741+01:0026. No Logic In using PICsI considered using PIC chips for memory logic, so they could select whether an address was for RAM or ROM. Programmatically this is not a problem, the code can be written to do this quite easily. The problem is that they cant do it fast enough.<br />
<br />
Most Z80 instructions work over 4 clock cycles, T1, T2, T3 and T4. During T1, the address pins A0-A15 are set to the value of PC (Program Counter) and half a cycle later, MREQ (Memory Request) and RD (Read) pins go active. By the end of T2 the data is fetched from the data bus on D0-D7.<br />
<br />
If the Z80 is running at 1MHz then each cycle is 1μs (1 micro second), so fetching an instruction takes at most 2μs.<br />
<br />
Now consider a PIC microcontroller running at 4MHz. Again each instruction takes 4 cycles, so the instruction to read the pins on a PIC such as MOVF GPIO,W will take 1μs (4Mhz / 4 cycles), so at most we could only perform 2 instructions on the PIC while the Z80 is trying to fetch the next instruction or operand on the data bus. A branch instruction on the PIC takes 8 cycles, so we could not even fit a loop into the time frame.<br />
<br />
The only it could work with a PIC is if the Z80 was running at a much slower clock rate. However this Z80 can go at 2.5MHz and the Z80B can go at 4MHz, and it'd be a shame not to run at full speed.<br />
<br />
You can clock some of the PICs with an external crystal to 20MHz and the more expensive PICS to 60MHz and this would allow 5 or 15 instructions in 1μs respectively, but probably still not fast enough at higher Z80 speeds.<br />
<br />
Time to bring out the classic TTL chips.Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-21047661371536908562011-10-01T13:50:00.002+01:002011-10-12T22:01:12.950+01:0025. Need a clock? Take your PIC!Having discovered PIC microcontrollers, I think I will use them quite a lot on this project. One use is as a clock. The smaller PICs have 4MHZ internal oscillators and the larger ones I think are 8MHz. One of the pins can be configured to be a CLKOUTand will send a signal 1/4 of the clock speed. This is effectively 1 pulse for every instruction. Using the internal oscillator of 4MHz this should give a 1MHz clock signal.<br />
<br />
I'm using one my PIC16F505s for this, although a PIC12F508 would be (a) cheaper and (b) has less pins [update: and it doesn't externalize its clock]. We only need to connect up +5V and ground, plus the clock pin. On the PIC16F505 its pin 3 (RB4/OSC2/CLKOUT).<br />
<br />
The code would look like this:<br />
<pre style="color:green">include "p16f505.inc" ;
__config _IntRC_OSC_CLKOUTEN
org 000
loop nop
goto loop
end
</pre><br />
I tried it on the Z80. I think it works. I measured it on my small oscilloscope but I don't think its fast enough to keep up with the signal change. Instead I measured the signal on the A15 pin. I did get a signal but there was a lot of noise when the pin went low. Its 4.705Hz, so multiply this by 65536 (the Z80 is executing NOP and the PC will loop every 65536 instructions) and then by 4 (number of clock signals to execute NOP) should give the clock speed. It gives 1,233,387.52, just slightly over 1MHz. Peak voltage is 2.040V, low is 0.480V. At this resolution I am not sure these voltages are accurate. I checked the MREQ pin and this looks like its working but the voltage delta is 800mV. Is this enough to give a true high/low difference? I'm not sure at this stage.<br />
<br />
There was a wierd effect after a few mins where the higher address pins such as A15 seemed to be static rather than blinking. I put a decoupling capacitor (don't ask me why I just guessed), on the PIC chip and that seems to have solved the issue. Its been running for over an hour now and seems to be ok.<br />
<br />
Time to see what else these babies can do...Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-237915447309746302011-09-28T23:09:00.002+01:002020-08-29T13:46:54.339+01:0024. Homebrew Hex to 7 segment display drivers working.Yes I did it. I wrote PIC machine code to program the PIC16F505 Microcontrollers to perform the function of Hex to 7 segment Display Drivers.<br />
<br />
I started writing the code before I even had the PIC Programmer or PIC chips. On the first run, I found I had an issue with the inputs not being grounded with pull-down resistors, causing the inputs to fluctuate randomly, but some 10K resistors on the inputs connected to ground sorted that. If you have a switch, when its on its fine, a voltage goes to set the pin high or 1. When the switch is off the pull-down resistors connect the pin to ground giving a low or 0 input.<br />
<br />
I did initially opt to use one pin on the PIC16F505 as a latch, so it would only display the input when a button was pressed. I decided it wasn't necessary and the program loops around reading the inputs and setting the outputs to light up the LEDs.<br />
<br />
Hers's a pic of the setup with annotation. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTSni2B1A05qt0rXh6T5bL4WOqgjVWGc6Ker-con9PR-RhnBsRMdNfhcKeMO_LrzG_GxHMrk9_76oz4QpCAQZgA4QIXjNC1xtpoP-079Kaqs0hDqDpxezIqHE2HGCl8E2ikmYGKQUoabA/s1600/dual-7-seg-displays.jpg" imageanchor="1"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTSni2B1A05qt0rXh6T5bL4WOqgjVWGc6Ker-con9PR-RhnBsRMdNfhcKeMO_LrzG_GxHMrk9_76oz4QpCAQZgA4QIXjNC1xtpoP-079Kaqs0hDqDpxezIqHE2HGCl8E2ikmYGKQUoabA/s320/dual-7-seg-displays.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
The PIC assembly code is here:
<br />
<br />
<pre style="color: green;font-family:consolas;">; include file with config bit definitions
include "p16f505.inc" ;
; config - enable internal OSC and allow use of RB4
; - disable MCLRE and allow use of RB3 (input only)
; - disable Watchdog Timer, we don't use it.
__config _IntRC_OSC_RB4EN & _MCLRE_OFF & _WDT_OFF
; local regsiters
INB equ 0x08
INC equ 0x09</pre>
<pre style="color: green;">INPUT equ 0x0A</pre>
<pre style="color: green;">OUTB equ 0x0B
OUTC equ 0x0C
PWRSTS equ 0x0D</pre>
<pre style="color: green;">SEGDATA equ 0x10
SEG0 equ 0x10
SEG1 equ 0x11
SEG2 equ 0x12
SEG3 equ 0x13
SEG4 equ 0x14
SEG5 equ 0x15
SEG6 equ 0x16
SEG7 equ 0x17
SEG8 equ 0x18
SEG9 equ 0x19
SEGA equ 0x1A
SEGB equ 0x1B
SEGC equ 0x1C
SEGD equ 0x1D
SEGE equ 0x1E
SEGF equ 0x1F
; start here
org 000
movf STATUS,PWRSTS ; Save Power on status
; Port configuration
; a
; +-----+ ---
; VCC [| |] GND f| g |b
; D3 --> RB5 [| |] RB0 --> a ---
; D2 --> RB4 [| PIC |] RB1 --> b e| |c
; D1 --> RB3 [| 16F |] RB2 --> c ---
; D0 --> RC5 [| 505 |] RC0 --> d d
; NC RC4 [| |] RC1 --> e
; g <-- RC3 [| |] RC2 --> f
; +-----+
;
; RRRRRR
; BBBBBB
; 543210
init movlw b'111000' ; Set PORTB Pins
tris PORTB
; RRRRRR
; CCCCCC
; 543210
movlw b'100000' ; Set PORTC Pins
tris PORTC
; Load Segment values into memory.
;Digit gfedcba abcdefg a b c d e f g
;0 0x3F 0x7E on on on on on on off
;1 0x06 0x30 off on on off off off off
;2 0x5B 0x6D on on off on on off on
;3 0x4F 0x79 on on on on off off on
;4 0x66 0x33 off on on off off on on
;5 0x6D 0x5B on off on on off on on
;6 0x7D 0x5F on off on on on on on
;7 0x07 0x70 on on on off off off off
;8 0x7F 0x7F on on on on on on on
;9 0x6F 0x7B on on on on off on on
;A 0x77 0x77 on on on off on on on
;b 0x7C 0x1F off off on on on on on
;C 0x39 0x4E on off off on on on off
;d 0x5E 0x3D off on on on on off on
;E 0x79 0x4F on off off on on on on
;F 0x71 0x47 on off off off on on on
movlw 0x3F
movwf SEG0
movlw 0x06
movwf SEG1
movlw 0x5B
movwf SEG2
movlw 0x4F
movwf SEG3
movlw 0x66
movwf SEG4
movlw 0x6D
movwf SEG5
movlw 0x7D
movwf SEG6
movlw 0x07
movwf SEG7
movlw 0x7F
movwf SEG8
movlw 0x6F
movwf SEG9
movlw 0x77
movwf SEGA
movlw 0x7C
movwf SEGB
movlw 0x39
movwf SEGC
movlw 0x5E
movwf SEGD
movlw 0x79
movwf SEGE
movlw 0x71
movwf SEGF
; End of initialisation
; To here 37 Instructions @ 4MHz = 37uS
; Main Program Starts here.
poweron clrf OUTB ; Clear output Register B
clrf OUTC ; Clear output Register C
btfss PWRSTS,RBWUF; Check Power-On Status
goto display ; blank if power on
; Reset output values and indexes
loop clrf OUTB ; Clear output Register B
clrf OUTC ; Clear output Register C
movlw SEGDATA ; Load W with SEG DATA base
movwf FSR ; Save to FSR
; read value from PORTs
movf PORTB,W ; Read PORTB</pre>
<pre style="color: green;"> movwf INB ; Save PORTB</pre>
<pre style="color: green;"> movf PORTC,W ; Read PORTC
movwf INC ; Save PORTC
; combine port reads into a nibble in W register
clrf INPUT ; Clear INPUT register
btfsc INB,RB5 ; Test RB5 (D3)
bsf INPUT,3 ; Set D0</pre>
<pre style="color: green;"> btfsc INB,RB4 ; Test RB4 (D2)
bsf INPUT,2 ; Set D1
btfsc INB,RB3 ; Test RB3 (D1)
bsf INPUT,1 ; Set D2
btfsc INC,RC5 ; Test RC5 (D0)
bsf INPUT,0 ; Set D3
movf INPUT,W ; Move value to W
; add value to index register and fetch segment value
addwf FSR,F ; Add index to FSR pointer
; prepare register output bits
btfsc INDF,0 ; Test for 'a' segment
bsf OUTB,RB0 ; Set 'a' segment
btfsc INDF,1 ; Test for 'b' segment
bsf OUTB,RB1 ; Set 'b' segment
btfsc INDF,2 ; Test for 'c' segment
bsf OUTB,RB2 ; Set 'c' segment
btfsc INDF,3 ; Test for 'd' segment
bsf OUTC,RC0 ; Set 'd' segment
btfsc INDF,4 ; Test for 'e' segment
bsf OUTC,RB1 ; Set 'e' segment
btfsc INDF,5 ; Test for 'f' segment
bsf OUTC,RB2 ; Set 'f' segment
btfsc INDF,6 ; Test for 'g' segment
bsf OUTC,RB3 ; Set 'g' segment
; move output to ports
display movf OUTB,W ; Get values to send to PORTB
movwf PORTB ; Send to PORTB
movf OUTC,W ; Get values to send to PORTC
movwf PORTC ; Send to PORTC
; around again
goto loop ; go back to loop - 50uS loop
end
<!------><!------></pre>
Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com4tag:blogger.com,1999:blog-1941724879591935666.post-46683410549281179242011-09-23T22:54:00.000+01:002011-09-23T22:54:46.781+01:0023. Put out by the output.I had this idea, that I would connect up some 7 segment displays to show what all the registers where set to if I stepped through a Z80 program. Its a little bit ambitious at this stage of my journey, so I thought I would start by creating something to input Z80 commands directly onto the data bus. I bought some in-line 8 bit switches, however the data pins on the Z80 are split into two group by the fact that the +5V Vcc input sit between them. Not only that, they are not in order like the address pins. So I put some jump wires in to put them into the right order. Now it'd be great to have a hex display of the data that I am trying to put in, so I thought I could use two 7 segment displays. Easy right?<br />
<br />
For each nibble (thats what 4 bits of a byte are called) I need a 7 segment display. One for the upper values of 0123456789ABCDEF and one for the lower. The displays have 8 inputs 7 for the segments and one for the decimal point. So I read that to convert 4 bits to 7 I needed a hex to 7 segment display driver. Cool, so I go surfing the web to find one. All I can can find are BCD to 7 segment display drivers (BCD is Binary Coded Decimal and basically allows the values 0123456789) such as the 7447. I eventually find some, the DM9368 and the MC14495. They don't make them any more, but if you hunt around you can find them for like £30 each.<br />
<br />
Going back to my original idea of displaying the registers, I worked out I'd need 52. Ouch!<br />
<br />
As I desperately try to find alternatives, one blogger mentions using a PIC microprocessor instead, and programming it to perform the same function. Hmm, could this work?<br />
<br />
So I get diverted into looking at what these PIC things are. I soon discover that they're kind of like the ATMega that powers the Arduino, but can come in very small sizes, I mean some are only 8 pins. This diversion opens up a whole new world. New software, new machine code language, new software to program them and new programmers to, well, program them.<br />
<br />
Needless to say, I have been reading numerous .pdf documents on how all this stuff works. I'm not even sure if it will work yet. I've initially plumbed for the PIC16F505. I was going to go with the PIC16C505 from Maplin for £1.89, but its a bit outdated, but the PIC16F505 is 79p from RS Components. Now it used to be that RS were only open to Businesses, but I believe they have now opened up their doors to the general public.<br />
<br />
I found this <a href="http://proto-pic.co.uk/mplab-compatible-mini-usb-pic-programmer/">USB PIC Programmer</a> too for £35. So I am going to bite the bullet and give it a go because 79p x 52 is a lot easier to swallow. Of course I'll just try with 1 for now.<br />
<br />
The software is free from <a href="http://www.microchip.com/">Microchip</a> and I've started writing some simple code so I can get the hang of it. At least its compiling ok.<br />
<br />
So here I am programming a completely new and alien (to me) microprocessor so I can get some output (and input) from (to) a Z80 using some 7 segment displays. Kind of ironic really.<br />
<br />
I may be a while....Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-65479627090970629212011-09-07T13:23:00.002+01:002011-09-07T13:36:39.797+01:0022. Building An EEPROM Programmer (Part 3).Ok So does it actually work. YES!<br />
<br />
On linux you can check the data in the zx81.rom file by typing:<br />
<pre style="color:green;font-family:courier">od -Ax -t x1 zx81.rom</pre><br />
Running the EERPROM Reader in Part 1, I can visually see that they look the same. As a final check I got the ERRPROM Reader to add all the bytes together (OK not the best way to check sum a file but I am not here to write a proper CRC checksum routine for the Arduino just now), and also wrote a C program to do the same on Linux called sum.c:<br />
<br />
<pre style="color:green;font-family:courier">#include <stdio.h>
main()
{
int c,sum;
sum=0;
while ((c=getchar()) != EOF) {
sum=sum+c;
}
printf("Checksum: %d\n",sum);
}
</pre><br />
The final value came back as 855105 for both.<br />
<br />
Result!<br />
<br />
As a final check, I unplugged the Arduino removing power from the EEPROM in the process. Left it for a few minutes and then plugged that Arduino again restoring power to the EEPROM and reran the EEPROM Reader program. All data preserved and sum still the same.Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-68733149724718101532011-09-07T13:06:00.002+01:002011-09-07T13:34:36.927+01:0021. Building An EEPROM Programmer (Part 2).The Arduino can receive data via the Serial interface. This is how I want to send the Z80 programs to the EEPROM. The problem is the Arduino is not reading fast enough and so what gets sent is lost. Its fine for sending the odd few bytes now and then, but (using my zx81.rom as a test) sending 8K of data is a bit much for it to handle in one go.<br />
<br />
The Serial buffer on the Arduino is 128 bytes, so all I was getting to start with was the first 128 bytes of the 8K successfully, after that it was a random sets of 128 bytes from the Serial port that it grabbed hold of before the stream of data ended.<br />
<br />
To compensate for this, I decided to send 64 bytes at a time with 1 second interval. Now this is fairly easy to do in Linux with a script:<br />
<br />
<b>eeprom_send.sh</b><br />
<pre style="color:green;font-family:courier">#!/bin/bash
split -C 64 ${1} ${1}.part.
for part in `ls ${1}.part.*`
do
cat ${part} >> ${2}
sleep 1
done
rm -f ${1}.part.*
</pre><br />
To use it type:<br />
<pre style="color:green;font-family:courier">./eeprom_send.sh zx81.rom /dev/ttyACM0
</pre><br />
But first you just need to program the Arduino and then open the serial monitor window (dont ask me why).<br />
<br />
Here is the Arduino program:<br />
<pre style="color:green;font-family:courier">/*
EEPROM Programmer
*/
#define memsize 8192
int STS = 13; // Status Indicator
int AP[16] = {22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52};
int AD[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int DP[8] = {23,25,27,29,31,33,35,37};
int DD[8] = {0,0,0,0,0,0,0,0};
int CE = 4;
int OE = 3;
int WE = 2;
int i;
int A;
int D;
int wait;
void setup() {
Serial.begin(115200);
Serial.flush();
pinMode(STS, OUTPUT);
// Setup Address Pins
for (i=0;i<16;i++) {
pinMode(AP[i],OUTPUT);
}
// Setup Data Pins
for (i=0;i<8;i++) {
pinMode(DP[i],OUTPUT);
}
// Setup Control Pins
pinMode(CE, OUTPUT);
pinMode(WE, OUTPUT);
pinMode(OE, OUTPUT);
// Setup Chip
digitalWrite(CE, LOW);
digitalWrite(WE, LOW);
digitalWrite(OE, HIGH);
Serial.println("Waiting for Data...");
while(Serial.available()==0) {
digitalWrite(STS,LOW);
delay(100);
digitalWrite(STS,HIGH);
delay(100);
}
for (A=0;A<memsize;A++) {
D=Serial.read();
digitalWrite(STS,HIGH); //Signal that we're writing.
// Setup Address Pins
for (i=0;i<16;i++) {
if((A&bit(i))>0) {
AD[i]=HIGH;
} else {
AD[i]=LOW;
}
digitalWrite(AP[i],AD[i]);
}
delay(1);
digitalWrite(OE,LOW); // Reads Disabled
delay(1);
digitalWrite(CE,HIGH); // Chip Enable
delay(1);
digitalWrite(WE,HIGH); // Write Enabled
delay(1);
// Setup Data Pins
for (i=0;i<8;i++) {
if((D&bit(i))>0) {
DD[i]=HIGH;
} else {
DD[i]=LOW;
}
digitalWrite(DP[i],DD[i]);
}
delay(1);
digitalWrite(WE,LOW); // Write Disabled
delay(1);
digitalWrite(CE,LOW); // Chip Disabled
delay(1);
digitalWrite(OE,HIGH); // Reads Enabled
delay(1);
digitalWrite(STS,LOW); // Signal that we're waiting
wait=0;
while(Serial.available()==0) {
delay(1);
if (wait>2000) {
A=memsize;
break;
}
wait++;
}
}
}
void loop() {
digitalWrite(STS, HIGH); // set the LED on
delay(1000); // wait for a second
digitalWrite(STS, LOW); // set the LED off
delay(1000); // wait for a second
}
</pre>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com13tag:blogger.com,1999:blog-1941724879591935666.post-24508580689237773072011-09-06T17:50:00.012+01:002021-04-23T17:15:40.158+01:0020. Building An EEPROM Programmer (Part 1).<p style="font-weight:bold;">Please note that I have disabled comments on this post purely due to a persistent spammer - Dave 23/04/2021.</p>
Its all very well having an EEPROM chip to store our program for the Z80, but somehow we need to get the code onto it. Enter, the EEPROM programmer. So far I have wired up the EEPROM to the Arduino Mega and I can read from it successfully. Writing to it is easy enough, but just now I can't bulk load a file to it. When I do, go find Part 2 :)<br />
<br />
Here's a diagram I made using this great tool called <a href="http://fritzing.org/">Fritizing</a>: <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcDXvI0H3Vp2ilqE8JBeSR_CC8xVsSuc1d9W_n3f6c56dZMU0S23atcELMztFIR-h3QB8ulx9msWld0V5_YLBZj1VITcgImyqQs1mq8R4vOOwwcKH4WddKNXSYpNisxnKD6LqNkeL04M4/s1600/eeprom_programmer_bb.png" imageanchor="1"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcDXvI0H3Vp2ilqE8JBeSR_CC8xVsSuc1d9W_n3f6c56dZMU0S23atcELMztFIR-h3QB8ulx9msWld0V5_YLBZj1VITcgImyqQs1mq8R4vOOwwcKH4WddKNXSYpNisxnKD6LqNkeL04M4/s320/eeprom_programmer_bb.png" width="320" /></a></div>As you can see I've used a 74LS04 Hex Inverter to make sure the 3 control lines are HIGH by default as the pins on the Arduino are LOW by default and as the control pins are 'Active Low' we don't want data overwritten accidentally. It also means that setting the pin to HIGH in the Arduino code means the pin is Active.<br />
<br />
Here's the EEPROM Reader code for the Arduino Mega: <br />
<pre style="color:green;font-family:courier">/*
EEPROM Chip Reader
*/
#define memsize 8192
int STS = 13; // Status Indicator
int AP[16] = {22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52};
int AD[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int DP[8] = {23,25,27,29,31,33,35,37};
int DD[8] = {0,0,0,0,0,0,0,0};
int CE = 4;
int OE = 3;
int WE = 2;
int i;
int j;
int D;
int A;
void setup() {
// Setup Control Pins
pinMode(CE, OUTPUT);
pinMode(WE, OUTPUT);
pinMode(OE, OUTPUT);
// Disable Chip, and disable read and write.
digitalWrite(CE, LOW);
digitalWrite(WE, LOW);
digitalWrite(OE, LOW);
Serial.begin(115200);
Serial.println("Reading EEPROM...");
pinMode(STS, OUTPUT);
digitalWrite(STS,HIGH);
// Setup Address Pins
for (i=0;i<16;i++) {
pinMode(AP[i],OUTPUT);
}
// Setup Data Pins
for (i=0;i<8;i++) {
pinMode(DP[i],INPUT);
}
delay(1000);
for (A=0;A<memsize;) {
if (A<4096) Serial.print("0");
if (A<256) Serial.print("0");
if (A<16) Serial.print("0");
Serial.print(A,HEX);
Serial.print(" ");
for (j=0;j<16;j++) {
// Setup Address Pins
for (i=0;i<16;i++) {
if((A&bit(i))>0) {
AD[i]=HIGH;
} else {
AD[i]=LOW;
}
digitalWrite(AP[i],AD[i]);
}
digitalWrite(CE,HIGH); // Chip Enabled
digitalWrite(OE,HIGH); // Read Enabled
// Read Data Pins
D=0;
for (i=0;i<8;i++) {
DD[i]=digitalRead(DP[i]);
D=D+bit(i)*DD[i];
}
digitalWrite(OE,LOW); // Read Disabled
digitalWrite(CE,LOW); // Chip Disabled
if (D<16) Serial.print("0");
Serial.print(D,HEX);
Serial.print(" ");
A++;
}
Serial.println();
}
}
void loop() {
digitalWrite(STS, HIGH); // set the LED on
delay(500); // wait for a second
digitalWrite(STS, LOW); // set the LED off
delay(500); // wait for a second
}
</pre>Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com19tag:blogger.com,1999:blog-1941724879591935666.post-75442235699284403672011-08-31T20:24:00.004+01:002011-08-31T20:37:23.771+01:0019. The Ups and Downs of an Astable 555 Timer (How fast will it go?)Well not that fast really. OK its faster than the refresh rate on your TV, but in the grand scheme of the computer world, its not that fast at all. Now I did get it to clock up 250KHz but the problem is that the peak voltage was not high enough and the low voltage not low enough. Its seems the faster I tried to get it to go the smaller the voltage difference.<br />
<br />
Measuring the signal with the Xprotolab Oscilloscope is not easy either. It has a minimum resolution of 500 nano seconds per pixel, which if you do the sum 1/0.0000005 = 2MHz, means a 250KHz signal is 8 pixels wide. At higher frequencies the signal starts to become a blur on the screen.<br />
<br />
Another aspect of the <a href="http://en.wikipedia.org/wiki/555_timer_IC#Astable">astable 555 timer</a> is the Duty Cycle. Ideally, you probably want the time the voltage is high to be the same as when it is low, e.g. 50% each. The main external components used are 2 resistors (R1 & R2) and a capacitor (C1). Using 2 identical resistors gives you a Duty Cycle of 66%. To achive a Duty Cycle of 50% R2 needs to be roughly 10x that of R1. So with 2x 1K resistors and a 1nF capacitor we get about 250KHz with a 66% Duty Cycle, but changing R2 for a 10K resistor gets a 52% Duty Cycle and a much reduced clock speed of 57KHz. However, the low volatge is 0.000V and the peak is 4.480V using a 5V supply, much more usable. The Z80 Datasheet says that the input voltage for CLK should be Vcc-0.6 minimum, which with a 5V supply is 4.4V, so 4.480V should be OK to drive the clock signal.<br />
<br />
Here are a few screenshots to show what I am talking about:<br />
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZQDIrhl00MYqlwf4Rg8Z-KXjKPCUMQdAfX3XRgseoXkcli7iOomNA_rrNfJtw6zdsCSow8d4MwEgDXq_PD52KSc_0siun7gB3j6WameyrVMJIi43mNsfQlA-cTkIS3gSqoeR2cZH9GI8/s1600/1k1k1nF.bmp" imageanchor="1" style=""><img border="0" height="64" width="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZQDIrhl00MYqlwf4Rg8Z-KXjKPCUMQdAfX3XRgseoXkcli7iOomNA_rrNfJtw6zdsCSow8d4MwEgDXq_PD52KSc_0siun7gB3j6WameyrVMJIi43mNsfQlA-cTkIS3gSqoeR2cZH9GI8/s320/1k1k1nF.bmp" /></a></div>R1=1K R2=1K C1=1nF ~ Vmax=4.160V Vmin=1.600V Freq=250KHz Duty=66%<br />
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZrWLjgx9eb_zSm9rLOKsVIDgbDmn8PH9XUks1sD3jec2Gnu46QMmU04WjSslik7O8bBpGv2oSCbAb3t91MimjjjFdWxJ0pUQ5rE3dZQymHdGTN9pD8C-91pWvKSNt67ZovFi4W6ZdhOQ/s1600/1k1k10nF.bmp" imageanchor="1" style=""><img border="0" height="64" width="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZrWLjgx9eb_zSm9rLOKsVIDgbDmn8PH9XUks1sD3jec2Gnu46QMmU04WjSslik7O8bBpGv2oSCbAb3t91MimjjjFdWxJ0pUQ5rE3dZQymHdGTN9pD8C-91pWvKSNt67ZovFi4W6ZdhOQ/s320/1k1k10nF.bmp" /></a></div>R1=1K R2=1K C1=10nF ~ Vmax=4.480V Vmin=0.000V Freq=42.55KHz Duty=66%<br />
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr2kUBgjsQbto1ee5YJ0hY8jggbYcsnyBLvlBwj9MVuwZ_rqMb3O8U6A1oyD2ghPCihQ-BhDWr-C98k5KVDebWTWgwx4GVomqPSPITTAUobkroXHklxBGYf3XwfWTi4FynivaeLELOjfk/s1600/1k10k1nF.bmp" imageanchor="1" style=""><img border="0" height="64" width="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr2kUBgjsQbto1ee5YJ0hY8jggbYcsnyBLvlBwj9MVuwZ_rqMb3O8U6A1oyD2ghPCihQ-BhDWr-C98k5KVDebWTWgwx4GVomqPSPITTAUobkroXHklxBGYf3XwfWTi4FynivaeLELOjfk/s320/1k10k1nF.bmp" /></a></div>R1=1K R2=10K C1=1nF ~ Vmax=4.480V Vmin=0.000V Freq=58.82KHz Duty=52%<br />
<br />
If I want to run this faster I am going to have to buy a quartz crystal. For this standard Z80 it needs to be 2.5MHz. (The Z80A will go at 4MHz).Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0tag:blogger.com,1999:blog-1941724879591935666.post-54057025535002856612011-08-31T17:42:00.002+01:002011-09-02T11:21:47.552+01:0018. Pinups! Oops! I mean Pinouts :)I was trying to visualise the connections between the main ICs for my little project. Specifically the address bus pins(A0 to A15) and the data bus (D0 to D7). Looking at 3 .pdf datasheets did not help and what I really wanted was a side by side picture. So I started up Microsoft Paint and started making some of my own images, and here they are:<br />
<div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwcbY1m3R6eur_y9kYzNzasdbQSJNdYZuAu5xn35vGHa2AUELMGYIbtszWDMTzSwgyCm-o0Im-3AmI32KeCx2QqAQL9LmvY9RIRon9sw0pkD4tc1sF4wPRbxXoDKAmYPTDX0UWEtaBohA/s1600/z80.bmp" imageanchor="1" style=""><img border="0" height="208" width="119" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwcbY1m3R6eur_y9kYzNzasdbQSJNdYZuAu5xn35vGHa2AUELMGYIbtszWDMTzSwgyCm-o0Im-3AmI32KeCx2QqAQL9LmvY9RIRon9sw0pkD4tc1sF4wPRbxXoDKAmYPTDX0UWEtaBohA/s320/z80.bmp" /></a> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGf7I30IOQhxj6OHo1D400DW4w9ZUxGbSKybbzl8SHq0K26PlqTouNaTTiO0QebiMlGqAy9xEnm3-AXG2QNub67j-SXIpYDyWF6NJD5MToxpdILnbXdCRUmw7ai3SKDrh15btDL-WFNEE/s1600/sram.bmp" imageanchor="1" style=""><img border="0" height="167" width="101" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGf7I30IOQhxj6OHo1D400DW4w9ZUxGbSKybbzl8SHq0K26PlqTouNaTTiO0QebiMlGqAy9xEnm3-AXG2QNub67j-SXIpYDyWF6NJD5MToxpdILnbXdCRUmw7ai3SKDrh15btDL-WFNEE/s320/sram.bmp" /></a> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjmajpOhvA2rQeq-fuZGbdVD9_Nkmm8iqGZ6gdSCXBmYF8Y8-53PO_tBjh2IVuITJijpP_j9eGyHTEWTshNEgVuthYOO-jRGKXgPFl-cX55q1Ojj1aZT5TJwvrbRzTdW5ATMGwXpu0noA/s1600/eeprom.bmp" imageanchor="1" style=""><img border="0" height="145" width="101" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjmajpOhvA2rQeq-fuZGbdVD9_Nkmm8iqGZ6gdSCXBmYF8Y8-53PO_tBjh2IVuITJijpP_j9eGyHTEWTshNEgVuthYOO-jRGKXgPFl-cX55q1Ojj1aZT5TJwvrbRzTdW5ATMGwXpu0noA/s320/eeprom.bmp" /></a></div>The Z80, the 128k SRAM and the 8K EEPROM.Davehttp://www.blogger.com/profile/17357814190097545183noreply@blogger.com0