We ended-up splitting the division code over multiple loops of the core system so that it would not exceed the allotted time when the engine was running at maximum RPM. It meant that the value that required division would only update at something like 1/6th of the data acquisition speed of all other values, but hey, it worked.
Maybe I still have the source code on some floppy disk somewhere...
Edit: I remembered wrong, it was a GMC truck: https://www.sae.org/publications/technical-papers/content/92...
Edit #2: found a picture of our truck: https://live.staticflickr.com/8487/8186513796_bd60fd3fd2_b.j...
Like any programming job, but without formal experience you'll need more (and interesting) informal experience, ie side projects.
Start with something simple, like an STM32Discovery board. Blink the LEDs. Respond to the button.
Get a logic analyzer, like a Saleae ($400 for the Logic8) or Digilent Digital Discovery ($200, worse software IMO) or something similar. Get a bench power supply. Get an oscilloscope (Rigol DS1054Z is cheap ($400 or so) and hackable. Don't get a PC-based one, get one with a UI similar to what you'll use in professional work.) Get a couple of cheap USB-UART adapters, maybe a BusPirate, an ST-Link, and a hand full of STM32BluePill boards.
Get an SPI flash memory dev board, and write code to read/write that external flash. Use the STM32's built-in SPI peripheral. Use the logic analyzer to decode the signals & for debugging.
Get an I2C sensor dev board, and write code to read the sensor value. Use the STM32's built-in I2C peripheral.
Get FreeRTOS running on your Discovery board. Make tasks for your sensor reads, LED control, maybe log data to the SPI chip. Show that it's all hard real-time.
From there, maybe add more inputs & outputs. Making a 3D printer or CNC router from scratch would be impressive. Or an RC car, or some sort of robot, or a drone. Maybe go to a more capable SoC, like a BeagleBone Black board or Raspberry Pi. The product I work on (an eletronic logging device for the trucking industry) was initially prototyped using a BeagleBone Black. (This post is my own opinion, and should not be taken as official statements of my employer.)
Or go to a less capable chip, like a PIC16F18345 ($12 dev boards) and see what you can do with <=1024 bytes of RAM.
Definitely learn to build your code without using the vendor IDE. It'll save you a lot of pain. Makefiles (or CMake, or whatever build system you prefer) + writing linker scripts + pointing your preferred IDE (or editor) at that is a much better way.
Espressif's ESP32 and ESP8266, Nordics NRF52 parts, and some others have built-in networking (BlE, WiFi, Cell, etc). Those can be good for all sorts of projects.
There's some industry bias against Arduino, it's seen as overly abstract and not something "real" programmers use. If you get an Arduino, it can be a great starting place, but also get an ICSP (In Circuit Serial Programmer) and learn to use the ATMEGA328p chip without the Arduino bootloader+libraries. It's a fine chip and a fine platform, but not necessarily great for resume building.
Basically look on Adafruit and Sparkfun and the like, figure out what sorts of sensors & outputs look interesting, and start making things to use them. The product lines I mentioned happen to be popular among hobbyists, which means less chance of getting stuck without community help available.
You can implement this as a fixed point multiply by the constant 1.8.
You are already using base 10 fixed point, so it simply becomes a multiply by 18, which can be simplified to a few shifts and adds:
(Celsius << 4) + Celsius + Celsius
Don't forget to add 32 and the algorithm requires a 16bit shift and three 16 bit adds.
Yep, for the nand2tetris course, we had division, but it was in the OS, and a really expensive operation. I wrote a program that needed to know which third of a line a point was on. (i.e. identify 4 on a 15-length line as being in the first third).
I naively wanted to do something like "if x < L / 3", but rearranged it to "if x * 3 < L". (Of course, the language only supported integers and not fractions or floating point, so I needed to do that anyway.)
If there’s no memory for that, do multiplication by 9/5 the way it’s done in Bresenham’s line algorithm (https://en.wikipedia.org/wiki/Bresenham's_line_algorithm). If you start at zero Celsius = 32 Fahrenheit, that’s 50 steps, at most. Might not be (much) smaller than a lookup table, though.
Precomputing the steps for each degree Celsius difference and storing each in a single bit (a one degree change in Celsius will increase degrees Fahrenheit by either 1 or 2) might be the most memory-efficient approach. For a 100 degree Celsius range that’s a 50 bits table (starting at the center of the range). Edit: even that may be too large. That table will repeat every 9 bits, so one byte almost is enough. It might be a struggle to make that a net gain, given the more complex conversion code, though.
Am I wrong? Looking for DS18B10 data sheet always gives me the DS18S20. Hmm, dunno.
Anyway, assuming a sign + 7 bits integer + 4 bits fractional format, you can calculate inside 16 bit signed without overflow with a 3-bit shifted 9/5 constant without overflowing, up to beyond 100°C. With a bit of shifting, the following is quite accurate:
int16_t celsius2fahrenheit(int16_t c)
{
int16_t f = 0;
f += c << 4;
f -= c;
f -= c >> 1;
f -= c >> 3;
f += c >> 5;
f += 32 << 7;
f >>= 3;
return f;
}
Accuracy: C=0 (int: 0), F=32 (exact: 32, int: 512)
C=15.3 (int: 244), F=59.4375 (exact: 59.54, int: 951)
C=37 (int: 592), F=98.625 (exact: 98.6, int: 1578)
C=100 (int: 1600), F=212.062 (exact: 212, int: 3393)Also worth considering that I originally had no interest in fahrenheit (I live in the UK). This was done as an extra later on. Didn't want to poo the original implementation taking fahrenheit straight off the sensors.
int16_t celsius2fahrenheit10(int16_t c)
{
int16_t f = 0;
f += c << 4;
f -= c;
f -= c >> 1;
f -= c >> 3;
f += c >> 5;
f += 320 * 8;
f >>= 3;
return f;
}
This is really accurate: C=0 (int 0) F=32 (int: 320, exact: 32)
C=15.3 (int 153) F=59.5 (int: 595, exact: 59.54)
C=37 (int 370) F=98.6 (int: 986, exact: 98.6)
C=100 (int 1000) F=212 (int: 2120, exact: 212)You probably have the official User's Manual already, but there's a link to it there if you don't. I found it essential in addition to the assembly code manual.
I haven't found much '48 stuff out there so I'm looking forward to reading all your stuff on this!
With this example, say 100C. Convert to deciC and offset, say, 25 degrees to make it unsigned. 1250. Multiply by 9. 11250. Divide by 5 takes 2250 iterations. I am unfamiliar with the MCS-48, but Google says it can be clocked at 11Mhz. It would take maybe 40ms to do the divide?