2025-09-09 7:45 AM
I am officially confused.
I'm trying to use an ADC without the HAL layer, and for some reason I just don't get it to work. With HAL, it works fine.
I have tried comparing register contents, and I've now run into a wall. There must be something the HAL function is doing that I am missing or misunderstanding.
In this test, I am trying to sample ADC2, channel 16, just once, without DMA or anything. With my own code, ADCSTART never goes low after I've started the ADC.
When I check what the HAL code does differently, I simply don't get it.
The HAL setup code (which works):
ADC2Handle->Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
ADC2Handle->Init.ContinuousConvMode = DISABLE;
ADC2Handle->Init.DMAContinuousRequests = DISABLE;
ADC2Handle->Init.DataAlign = ADC_DATAALIGN_RIGHT;
ADC2Handle->Init.DiscontinuousConvMode = DISABLE;
ADC2Handle->Init.EOCSelection = ADC_EOC_SINGLE_CONV;
ADC2Handle->Init.ExternalTrigConv = ADC_SOFTWARE_START;
ADC2Handle->Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
ADC2Handle->Init.LowPowerAutoWait = DISABLE;
ADC2Handle->Init.NbrOfConversion = 1;
ADC2Handle->Init.NbrOfDiscConversion = 0;
ADC2Handle->Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
ADC2Handle->Init.OversamplingMode = DISABLE;
ADC2Handle->Init.Resolution = ADC_RESOLUTION_12B;
ADC2Handle->Init.ScanConvMode = ADC_SCAN_ENABLE;
HAL_ADC_Init(ADC2Handle);
ChannelCfg.Channel = 16;
ChannelCfg.Offset = 0;
ChannelCfg.OffsetNumber = ADC_OFFSET_NONE;
ChannelCfg.Rank = ADC_REGULAR_RANK_1;
ChannelCfg.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
ChannelCfg.SingleDiff = ADC_SINGLE_ENDED;
HAL_ADC_ConfigChannel(ADC2Handle, &ChannelCfg);
HAL_ADC_Start(ADC2Handle);
In short, I just want to sample channel 16 once, with 12 bit resolution and 640.5 cycles.
The main registers I have checked are these:
CR = 0x10000005 (ADC regulator on; regular conversion started; ADC enabled)
CFGR = 0x80001000 (Injected queue disabled; overrun mode)
CFGR2 = 0 (Makes sense, as I don't use oversampling)
SMPR1 = 0x00000007 (This confuses me a lot. Doesn't this just set channel 0 sampling time to 640.5 cycles?
SMPR2 = 0 (... and why is this 0? Shouldn't it have been used for setting the channel 16 sampling time?)
SQR1 = 0 (Even more confusing. Surely, this should be pointing at channel 16 as the one and only channel in the sequence. Instead, it points at channel 0.)
I have also checked that the DMA channel if off, as I don't use DMA for this single sample:
DMA2->CCR4 = 0x00000580 (The main thing here is that the DMA channel is off. Which it should be.)
I would have expected SMPR2 to be (at least) 0x001C0000, to set the channel 16 sampling time to 640.5 cycles. Also, I expected SQR1 to be 0x00000400, to indicate channel 16 for the first and only conversion. Instead, both registers read 0, which I simply don't understand.
Have I completely misunderstood how the ADC works? When I read the manual, the SMPRx registers contain the sample times for each channel (regardless of sequence), and the SQRx registers are used for specifying the sample sequence and the number of conversions.
Can anytone shed some light on this?
2025-09-16 12:41 AM
Well, the architecture still exists, and improved successor silicon is still sold.
Besides of price-sensitive hobbyists, there are retro fans still rebuilding old systems, and companies reusing "old" software. One of my former employers had based a whole (stat-of-the-art) device platform on an ASIC containing a 8051 as main controller.
But regardless, almost any "old" CPU is a good entry to learn and understand the basic concepts. Which is IMHO the preferred way over memorizing "click-and-drag" software (which includes Cube !) that only forces you to learn something when it doesn't work ...
And by the way, the proprietary core of the STM8 very much resembles the Z80, both in registers and instruction set.
2025-09-16 1:15 AM
@Ozone wrote:But regardless, almost any "old" CPU is a good entry to learn and understand the basic concepts. Which is IMHO the preferred way over memorizing "click-and-drag" software (which includes Cube !) that only forces you to learn something when it doesn't work ...
I fully agree!