There is mention in the datasheet that the MCU will enter the hard fault interrupt if you try to write more than a half word to a memory address, but I'm pretty sure that I am explicitly writing a half word in the code I have now...
As ataradov showed you, you were not. Well, at least you probably got confused by what "writing a half word" means. The right-hand value of the assignment was indeed 16-bit (half-word), but that doesn't matter here. What matters is that your write access was 32-bit due to dereferencing a pointer to a 32-bit integer. Maybe this is obvious to you and you just made a silly mistake (that happens to everybody!), but otherwise, I suggest learning a bit more about this if you're doing embedded programming.
As to the "volatile" qualifier, this is good practice to add it here, because such an access could get optimized out by the compiler. This is a common issue, and talked about in numerous other threads, so you can look it up. Note that from tests I made with recent versions of GCC, dereferencing a pointer converted from an absolute address (integer) such as here actually does NOT get optimized out even without the volatile qualifier, but there's no guarantee about this from a standard POV, so you should use it.