All good answers so far. I would like to amplify that the key practical difference between a macro and a function is that a macro can control when and if its arguments are evaluated, and a function cannot. Among other implications, this allows you to write new control constructs in the language, which you can't do with functions.
For example, take a look at the if-not macro from Clojure core. This is exactly like the standard "if" but inverted: if the condition is false, it runs the first bit of code; if the condition is true, it runs the second.
If you write something similar as a function, it won't work. The function version will run both the "then" and the "else" code immediately when the function is called, regardless of whether the condition is true or false. The macro version, on the other hand, can choose whether (and when) to run the code it's given as arguments.
A less trivial example is abstracting out the typical "try ... catch ... finally" control construct ubiquitous in Java and common in other languages into a "with-whatever" macro. If you're holding a finite resource such as a file handle or a network socket that must be released, even in case of error, you need a "finally" block to do that, but your application code has to be spliced unevaluated into the interior of the "try" block, to be run within that context.
You wind up copying essentially the same unaltered boilerplate try...catch...finally block around everywhere in your program and pasting a small locally applicable section into the "try" part. (Look at any non-trivial Java source code.) This boilerplate can't be abstracted into a function, because a function would evaluate the local code immediately when it's called, in the caller's context, and then give the result of that code to the "with-whatever" function.
A macro, on the other hand, can delay evaluation until specifically called for by the macro's code, allowing it to splice your arbitrary local code into the interior of the "try" construct unevaluated. The entire result (the entire try/catch/finally, including your unevaluated app-specific code within the try) is then returned to the caller and spliced into the caller's context, complete, to be executed there.
You can thus write a program that writes programs.