This question often comes up, and while there is often a heated debate, these are my thoughts on the subject.
I typically use a timestamp when I need to record a fixed point in time. For example when a record was inserted into the database or when some useraction took place that resulted in a row being updated. The Timestamp data type has various features that allow it to automatically perform this function. The default value for the Timestamp data type results in it being set to the current_date when a new row is added. If you as the On Update syntax, this value will also be updated whenever the row is updated.
I use a datetime field when the date/time can be set and changed arbitrarily. For example when the field can be updated based on specific events or actions, besides a simple row Update. In addition, a TimeStamp field can only store dates since 1970, so if you need to store dates in the past, such as a birthday, you must use DateTime.
A couple other things to keep in mind, TimeStamp fields support the TimeZone setting on your server. For example, if I have a database in Europe, and take a dump of that database to syncronize/populate a database in America, then the timestamp would update to reflect the real time of the event in the new time zone, while datetime would still reflect the time of the event in the European timezone. By default, the current time zone for each connection is the server’s time, however the time zone can be set on a per-connection basis.
Lastly, TIMESTAMP stores its value in 4 bytes, while DATETIME uses 8 bytes. This is the main reason why TimeStamp has a lower limit of 1970.