a stack. The core automatically saves several registers on the stack when an interrupt fires. Initial stack pointer value is read from address 0x0 the first thing when the core starts up. That value should normally equal to the end of RAM + 1.
correct vector table offset in the SCB->VTOR register. By default it‘s 0, which (again by default) is the start of flash. If your startup code / linker script combination sets up the vector table correctly, great.
a handler. you have that.
address of that handler + 1 needs to be in the correct position in the vector table. The way you‘re assigning a value to a location in the (assumed) vector table isn‘t going to work by default, since it‘s in flash.
the interrupt needs to be enabled in the NVIC and its priority set. This uses NVIC->ISER[x] and NVIC->IPR[x] registers.
finally, the peripheral needs to be configured to generate actual interrupt requests.