A new beginning

04/30/10 | by anthony [mail] | Categories: Code

Recently I've had the wonderful opportunity to TA ESE 123 at Stony Brook University with Professor David Westerfeld. Over the past semester I've been working in the student lab, helping with their assignments and lab tasks. For the second half of the class however, the students were to build a digital clock combined with a USB charger. The project took advantage of AVR mirocontrollers for the digital clock part of the design. Being a freshman level class, it would be a daunting task to teach not only basic electric theory, but combine that with basic microcontroller theory combined with learning assembly. I decided it would be best to write a handout that went over all the basics of computation theory, microcontrollers as well as completely outline the hardware and software aspects of the digital clock. The resulting document is about 30 pages of insight, knowledge and experience all dedicated to the project this semester of ESE 123. The audience of this document is the beginner and expert alike, I hope that anyone who reads it learns something new.

Attached to this post is the full handout, it introduces a new line of hardware for this blog, the AVR series of microcontrollers. The specific chip used in the project was the ATtiny48 microcontroller. I am also attaching the full commented code.

Get the full writeup here: Write Up
Grab the code here: Code

*Note, the code was written by Professor Westerfeld and cannot be used without his consent.

Introducing the PIC18

12/22/09 | by anthony [mail] | Categories: Informative, General

I figured it'd be a good time to move to a more capable microcontroller as the projects on the blog seems to be getting more and more complicated and lets face it, keeping up with our PIC16 and their limitations can get a little annoying when you're moving lots of important data. We need more pins, we need more features on the chip and we need better instructions.

Enter the PIC18 series from microchip.

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2696&param=en537796

The PIC18 is the most high end 8-bit microcontroller that microchip offers. It has many advantages over the lower end PIC16s the biggest being a new and improved instruction-set and memory management system.

I suggest you take a look at a datasheet for a PIC, everything in this article will reference:

http://ww1.microchip.com/downloads/en/DeviceDoc/39605F.pdf

A new memory system:

The coolest thing with the PIC18s is an Access Bank system. In this system the MCUs RAM is divided up into 16 banks (0-15)> Each bank has however many memory addresses(Depending on PIC, for example the PIC18F1220 has 256 byte banks) and you select which bank you want with the BSR (Bank Select Register). This sounds awfully similar to ram-pages of the PIC16F however its the access bank delimiter in the opcode that makes life so much easier. The access bank is the first 128 Bytes of bank 0 (Our General purpose registers) and the last 128 of bank 15 (Our Special Function registers) by default all operations are done in the access bank (a=0)This allows us to access a good amount of GPR and all of our SFR without ever changing what bank were working in. No more STATUS,RPx calls. However if we want to access ram outside the access bank we have to set the access bank delimiter call in the instruction to 1 and then by default you will be working in whatever bank happens to be set in the BSR.

Software accessible Stack:

I'm not too familiar with this feature, but the PIC18 allows you to control the stack from software, you also have complete control over the stack pointer, this is extremely powerful and not offered on the PIC16

New and improved modules:

The PIC18 series features an 8-bit hardware multiplier. Microchip provides sample code for doing all sorts of fun arithmetic. This is good if you want to crunch numbers but don't want to go into a full DSP. Also some PIC18s feature on chip USB and other goodies.

Priority interrupts:

This is another really cool feature. The PIC18 features two interrupt vectors, one high priority and one low priority. This allows you to have a really complex interrupt scheme allowing really sophisticated user interaction. For every interrupt you can choose what priority it is. An example of this is having a sample system for a sensor have highest priority while the user interface is low priority, that way even if the user is interacting the device to cause an interrupt, you don't interrupt the sample of the sensor if it is time sensitive.

NEW INSTRUCTIONS!:

This feature is going to take me the longest to get used to, but the PIC18 features a plethora of new instructions to make our lives easier. One nice and needed one is a MOVFF instruction (move from one register to another) These instructions are meant to speed up your code and make execution much faster. All new instructions follow a similar style to the traditional ones, they just do more for the clock. You can take a look at them on page 193 of the datasheet.

Free C compiler:

Microchip offers a free c-compiler for the PIC18 series for MPLAB, i haven't used it but its free and its a c compiler.

Tons of other stuff i still have to figure out:
I'm working on it :P

The PIC18 series is a really powerful line and there isn't much that they cant do. The first project i will be posting with them is a Digitial Audio Processor, we'll be taking advantage of the priority interrupts to make really fast and efficient code.

Hope to see you soon, happy programming!

The Fundamentals of Digital Audio

12/08/09 | by anthony [mail] | Categories: Informative, General

Digital audio is a very powerful thing, we listen to our iPods every day, we stream music from websites using our computers and we work with many algorithms derived from techniques in digital audio. Digital audio has its roots in wave mechanics and is a very fundamental process for modern computation. We will be discussing sound as a wave, some basic properties of waves and how to convert a wave into something which you can store in memory, and techniques to play that wave back. We’ll start with an introduction to sound and how to represent sound as a wave, and a mathematical function.

An introduction to sound:

Sound is a wave, and like all waves it transfers energy through a medium, in this case it is usually air. Whenever something emits a “sound” it compresses air molecules, these compressed air molecules exert a force on uncompressed ones, this starts a chain reaction and sound propagates; this is the essence of a sound wave. For sound to exist you need a medium, be it air, a solid, liquid or plasma. The sound wave will travel through that medium until it dissipates completely and is undetectable. Sound is usually the result of a force or stress on an object, you hit a tuning fork on a table, and it will vibrate at a particular frequency. To better visualize a sound wave mathematically, we will look at strign vibrations.

String Vibrations:

Like a turning fork, a string when plucked vibrates a particular frequency. The frequency at which a string vibrates at is due to its mass, length and tension on that string. The frequency which is most prevalent is called the fundamental frequency, when you play middle c on an instrument the fundamental frequency is 261 Hz. Now if middle c is a set frequency, why does middle c sound different on different instruments? The answer is because the sound from an instrument inst pure, each instrument has a unique harmonic structure which delivers a unique sound. To understand this more let’s look at the math of a wave.

Mathematical representation of a sound wave:

The nice thing about waves, is we can represent them mathematically, the simplest being that of a sine wave. Sine is a natural function which oscillates between crest to crest at a particular frequency. We can represent a pure oscillating sound by the following function.

Where A is the amplitude (sine is a function which oscillates between 1 and -1, multiplying it by A will result in A as the amplitude). The Greek letter omega is the angular frequency which is denoted in radians/second and the Greek letter phi denotes the angular offset (for all cases in this article we can consider it zeros). A “Pure” sound is that which is sinusoidal, we here these all the time on cheap synthesizers, when a sound is sinusoidal, it can be represented by the above formula alone. If a synthesizer were to play middle c, it would produce a sine wave of frequency 261Hz (omega = 640) and what you would notice is that it sounds like the right pitch, but no natural instrument sounds like a pure tone. When an instrument makes a tone, it is usually comprised of its fundamental frequency and higher order oscillations called harmonics. Harmonics are usually either ½(Strings) or ¾(Closed tube) integer multiples of the fundamental frequency of a lesser amplitude. Because of this we can consider and natural tone a superposition of fundamental sine waves and harmonic sine waves. Most tones in nature are comprised of a superposition of sine waves. We can use this fact to break down any complex sound into a series of many simple ones governed by the very simple formula above.

Synthesizer theorem:

Breaking a complex sound into a series of sine waves can be done using a Fourier series. A Fourier series simply is a mathematical series which can break apart any repeating oscillations into a series of simpler sine waves. We use a Fourier transform to translate an arbitrary function into a series of sine functions. For the purpose of this article we’ll use a Fourier series as a concept and we won’t be exploring the math behind it (Maybe one day).

To give a quick example of this we can consult Wikipedia. We all know and love our humble saw tooth wave; If we find the Fourier series of a saw tooth wave we get the following series as a result.

If we take n=1 we get the fundamental frequency of the series:

If we take the first 5 terms we get:

As we take n to infinity, we get a better and better approximation of our function. This is the fundamental way in which analog synthesizers would generate more complicated sounds, they would take several sine wave oscillators which they would combine in ways to reproduce a wave, and they wouldn’t need many because after a while the approximation was good enough to replicate the sound. This is fine and dandy, but in digital circuits we do not use sine waves as our building blocks, instead we use impulses.

The Impulse wave:

An impulse wave is completely different from a sine wave, instead of taking a wave as an infinite series of sine waves; we take the function and evaluate its value at a specific time t. We break the function up into many steps and by taking the value at every step we can reconstruct the wave. In this scenario as step size goes to infinity, we get a better reconstruction of the wave.

In this graph we have 5 impulses (red) that make up the waveform (green). Each impulse exists at time t and has a definite height to it. We break up a wave into specific impulses with definite height, we do this every sample. If the red waveform were 10KHz and we had 5 impulses per period, our sample frequency would be 50KHz. Each sample all we do is record the height of the waveform at that time.

If we were to reconstruct the wave using our impulses we would get the following:

As you can see, its not a pretty picture, but if you were to filter the signal, you would get a pretty good reconstruction of the original. To increase reconstruction we increase the sample rate and get more samples of the waveform per period. A wave with 100 samples/wave looks much more accurate than one with 10 samples/wave.

One golden rule is that your sampling frequency should always be above that of your highest recorded sound (Or at least the ones you would like to capture)

Digital Audio:

The heart of digital audio is taking an analog sound signal in the form of voltage over time and doing periodic analog to digital conversions and then storing these results in memory for later use.

Lets go back to our graph with the impulses. Lets say the vertical axis is voltage and the horizontal is time. Every impulse we sample a wave:

IMPULSE # -- VOLTAGE -- A2D(Int)(VDD=5V) -- T(uS)(@50KHz/Sample)
1         --  .1     --  5               -- 20
2         --  .2     --  10              -- 40
3         --  .3     --  15              -- 60
4         --  .4     --  21              -- 80
5         --  .5     --  26              -- 100
6         --  .1     --  5               -- 120
7         --  .2     --  10              -- 140
8         --  .3     --  15              -- 160
9         --  .4     --  21              -- 180
10        --  .5     --  26              -- 200
etc...

In all digital audio systems there are two things which determine your bandwidth.
The first is bit-rate which is how many bits you use to convert the signal. A bit-rate of 8-bits can break a signal up into 256 parts, thus a 5V signal has an ideal resolution of (5/256) 19mV(not bad!).

The second is sampling-rate, this is how often you sample a waveform, typical MP3 sample rates are about 44.1KHZ or one sample every 22uS.

The bandwidth of a signal is simply the sample-rate times the bit-rate.

The advantage of a digital system is that 22uS is rather slow, we can do a lot of work between sampling and storing a waveform, and with some good code we can produce high-quality powerful audio systems which are easy and cheap to make.

What now?
So now that we have an introduction to basic properties of sound, what can we do now? In upcoming posts i will be discussing the PIC18 series of micro-controllers, and some sample code to do audio pass-through and eventually storing and playing back a waveform.

Weak Pull up Resistors.

09/21/09 | by anthony [mail] | Categories: Informative, General

I haven't posted in a while so i figured i'd get back into the swing of things by posting a short post on the pic's internal weak pull up resistors.

What are pull up resistors?

A pull up resistor is a fairly high resistance (usually 1K for TTL and 10K for CMOS) resistor to pull a pin to a high logic level. This is very useful as this prevents your logic levels from floating between 1 and 0. This also lets to prime a pin to a certain logic level and have an event (such as a button press) be used to then pull your pin to another logic level.

You can also pull pins down to ground if you desire using the same method (except hooking the resistor between the pin and ground instead of the pin and vdd)

For the pic16f690 you can enable WPA by clearing bit 7 of OPTION_REG (cleared by default) and setting the appropriate bits in the WPUA(bank 1) and WPUB(bank 2) registers.

This feature is extremely useful in keeping more hardware inside the pic and using as little external hardware as possible.

Often you will pull up a pin to vdd and have a button press short the pin to ground (making the pin a 0) instead of having an external resistor you can just use the on-chip WPA resistors.

So, just a short write up for now, but i have plenty of stuff coming in the next coming weeks.

I would like to introduce the PIC18 line of microcontrollers and begin posing some more sophisticated tutorials.

I will also be updating the circuit blog to include some soldering advice.

Most importantly, i need suggestions and comments, if there is a guide you would like to see, please don't hesitate to ask!

I'm looking forward to the next year to bring even more exciting content to my blog!

PIC Memory Organization & EEPROM Control

04/01/09 | by anthony [mail] | Categories: Informative, General

One of the most key features of any electronic system is how memory is organized. This includes how much Ram and Rom, how they are subdivided and how to access the memory. Every series of PIC is different and every PIC has different amounts of memory. It is your job to understand how memory is mapped in your system and to use if efficiently.

A memory system defines a system, it is the one thing that makes it unique and when you master it, you master a system. This has two effects, it makes a system hard to master, and it makes other systems easier to use. Every system from X86 to PowerPC to our PICs are essentially the same thing, ROM to store program data, RAM to store variables and running code and a processor to crunch data. No matter what, a processor might have different instructions, but it still is a beast that doesn’t change too much. ROM and RAM define a system; every system is going to use it differently. The logic rarely changes system to system however the code can do a complete 360 depending on what system you use just because of how memory is mapped.

First let’s define a few things:

RAM (Random Access Memory): This is the place where your variables reside (General Purpose Registers), and how you access special function registers. When you setup a Cblock or set a variable to an address, this is where it’s going. RAM is super fast but very limited, and everything is stored temporarily. RAM is merely to hold values that are important to current operation.

ROM (Read-Only Memory): ROM is like your hard disk, its where all permanent data is stored, like your program. This is marginally slower but not too slow. Unlike your hard disk, this ROM is super fast since it’s on die. When you program your code onto a PIC this is where it goes.

Since a lot of this blog focuses on the PIC16F690 I am going to be going over the memory architecture of it.

Everything on memory organization can be found in the section 2.0 Memory Organization:
http://ww1.microchip.com/downloads/en/DeviceDoc/41262E.pdf

The first section goes over a few things you should know:

The RAM is partitioned into 4 banks (0-3). Depending on the data you’re addressing depends on which bank you need to access. In each bank you’ll find a mirage of General Purpose Registers, used for storing program variables, and Special Function Registers, used for controlling the microcontroller. The next few tables’ show where these SFR reside and what banks they’re located in. The rest is just trivial stuff we’ve gone over before.

Likewise how the RAM is partitioned so is the ROM. The ROM is compromised by Program Memory and Data Memory. Program memory is reserved for your program (however on PIC18’s and above you can write to it and use it for data). Data memory is used exclusively for storing data. On the PIC16F690 it is 256 Bytes. Writing and controlling this DATA ROM is not as straight forward as controlling a GPR.

The PIC has a built in EEPROM control module which you use to read and write to EEPROM.

The EEPROM Control Module:

This module is fairly simple and allows you to store program variables in hard data for later use. 256 Bytes doesn’t sound like much but it does come in handy.

The Registers:

EECON1: Control register.
EECON2: Non implemented register used in writing data (see below)
EEDAT: This is the register that holds the data to be written or has been read.
EEDATH: Some memory is larger than 8 bits so this is the High portion of the register that contains the MSB of a non 8-bit number.
EEADR: This is the register that holds the memory address of the a data to be read or written
EEADRH: The high register for EEADR for non 8-bit addresses.

The Sequence:

Write (Data memory only):
Configure EEPROM for write
Set the address to be written to EEADR and EEADRH
Set the data in the data registers
Initiate a write sequence and wait.

Read (Data and program memory):
Configure EEPROM for read
Set the address to be read to EEADR and EEADRH
Initiate a read sequence and wait.
Data will be in the data register.

The sequence is pretty straightforward, the only tough part is the control so lets go over EECON1.

EECON1: EEPROM control register
Bit 7: EEPGD – 1: Access Program Memory 0: Acess Data memory
Bit 6-4: Unimplemented
Bit 3: WRERR – 1: There was a write error 0: Write operation completed
Bit 2: WREN – 1: Allows write to EEPROM 0: Write is not allowed
Bit 1: WR – 1: Initiates a write 0: Write is complete
Bit 0: RD – 1: Initiates a Read 0: Read is complete.

As you can see, this module is pretty simple a sample read code will be something of the sort:

clrf  EECON1 ;Read Data memory, do not allow writes
movlw 0x00
movwf EEADR
movwf EEADRH   ;Clear address location start at 00
bsf   EECON1,0  ;Initiate read
btfsc EECON1,0  ;Wait till clear
goto  $-1
movfw EEDAT     ;Move read data to where-ever
movwf DAT

Reading from EEPROM will be very similar to the above routine just make sure you're in the right banks for each register (EECON1 and EEDAT/EEADR aren't in the same bank)

Writing to the EEPROM isn't exactly as intuitive as reading but is still pretty easy:

Just like above, you set up the EECON1 register for whatever you're doing and move the data you want to write into EEDAT and the address you want to in EEADR and EEADRH. After you do that, you initiate a write sequence such as the following:

WRITE:
	bsf      STATUS,RP0
	movlw    0x55      
	movwf    EECON2
	movlw    0xAA
	movwf    EECON2
	bsf      EECON1,WR   
	btfsc    EECON1,WR
	goto     $-1
	bcf      STATUS,RP0
	return

Now, to write to data EEPROM you must write 0x55 then 0xAA to EECON2 (one after another) and then set the WR bit on EECON1.

This sequence is what is required by Microchip in their data sheet.

Other thank that, EEPROM control is fairly straight forward and is very powerful.

Good luck and any questions/concerns please feel free to send me an EMAIL.

Pages: 1 2 3 4 5 >>

July 2010
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Ads by Google

This blog is dedicated to working with digital circuitry and the use of microcontrollers, small compact computers on a chip. I will be encompassing many techniques to develop projects, tools to use to write and assemble code and i will be sharing any projects i am currently working on. User feedback is a must! I do not know it all, hell im not even that experienced, but without a general place to get all the info needed i find it very hard to get into the world of microcontrollers without pursing a CE degree. So come one come all and enter the world of mystery and creativity!

Search

XML Feeds

multiblog engine