current control via microcontroller
I suggest you use an OpAmp to do the regulation part for you. This not only increases the bandwidth (speed) of your regulation loop, but takes some "stupid" work off of your microcontroller's todo list -- possibly permitting a weaker/cheaper/smaller microcontroller if that's all it needs to do. Of course it also saves you from implementing a PID loop in software (there's a keyword for you if you still want to go down that path.)

Here's the basic voltage controlled constant current source:







simulate this circuit &ndash; Schematic created using CircuitLab

You can ignore C1, R1 and R2, as they are practical improvements not necessary for understanding the circuit's concept.

The OpAmp is used in negative feedback mode. That means some circuitry that depends on the output of the OpAmp returns a positive feedback (output up -> feedback up) to the negative input (-) of the OpAmp, resulting in overall negative feedback. Then, the OpAmp outputs whatever is necessary to make (+) and (-) equal. In this case, the feedback signal is the voltage drop over the reference resistor Rref of 100 Ohm. This gives a direct measure of the current via $$I_{\text{Rref}} = \frac{U_{\text{Rref}}}{100\,\Omega}$$
So if you input 2V at (+), the OpAmp will drive the gate of the MOSFET in such a way that the drain-source passes a current that's just right to make Rref drop 2V. Because then (+) and (-) is both 2V. The current through the reference resistor and thus through the load will be 20mA in that situation. Similarly 1V input will yield 10mA current, and so on.

Of course, you could replace the reference resistor with anything else that gives you some preferably linear voltage signal depending on the current, such as your hall current sensor. The translation from input voltage to output current won't be so simple as with a power-of-ten resistor though, and more difficult with a non-linear relationship. If your hall sensor has a linear relationship the datasheet will tell you a current-to-voltage factor, like 123 mV/A. You can use that to translate desired output currents to the necessary input voltage. The method of using a reference resistor is simple, cheap and common also in professional precision devices, so think about whether you really need a hall sensor here.

C1, R1 and R2 are to protect the OpAmp from the rather large gate capacitance of the (power-)MOSFET and the resulting instability/oscillation. That's an amplifier theory thing (keywords phase margin, open-loop gain). Essentially, the capacitance alters the phase (think "delay") of the feedback signal with respect to the output. If that effect is strong enough, it leads to overall positive feedback (for some frequency component) even though we've plugged the feedback into the negative input of the OpAmp. Positive feedback in a circuit that's supposed to regulate something of course isn't good, it leads to violent oscillation at the system's eigenfrequency.

Now to the input signal.
You see that I've used an analog source, and I recommend you do this, too. For example, use a 12-bit DAC IC into which your µC shifts the voltage bits via SPI. That's easier implemented as it sounds, in case you have no experience with external DACs.

If you stick with PWM, you will need to strongly lowpass filter the signal with a series resistor and parallel capacitor to get an almost-DC signal. There will always be some ripple left which necessarily feeds into your then-not-so-constant current source. And the better you suppress the ripple by increasing the resistance and capacitance of your lowpass filter, the slower your current source will react to changes of the PWM duty cycle setting in the program.

Note that I've chosen OA1 and M1 almost randomly. You will have to match these components according to your requirements. You'll probably want an OpAmp that can swing to the lower rail at 0V and can also handle 0V at the inputs. Those are commonly called "Single-Supply" OpAmps. The MOSFET should be able to handle the voltage and currents present in your current path, should be able to dissipate the maximally occuring power, and should have a gate threshold voltage that is well within the OpAmps capabilities of creating. For the latter take into account the positive supply of the OpAmp minus some voltage margin (see output swing in the datasheet). Only "rail-to-rail" OpAmps can actually deliver voltage very close to the positive supply.
Finally, you should of course get an idea what order of magnitude of currents you want and by that choose the Rref reasonably, such that the voltage drop is in the range your input signal source can generate with sufficient precision.