Hi, do you have experience with black pill (STM32F411CeU6)? I need to know if it is able to sample digital signal with frequency up to 300 kHz. This MCU should run with 100 MHz. I know from the experience that 16 Mhz arduino is too slow for the job :). ISR will contain reading digital value and also one sum char and integer. Is black pill fast enough? Thank you for answers.
I know from the experience that 16 Mhz arduino is too slow for the job
Well you can sample digital signals at 300KHz with a Uno so I don’t understand why you say that. You must be doing something else. Maybe you are using the digitalRead function which is slow, you should be using direct port addressing.
but yes that chip will be a lot faster.
Well it is failing to maintain constant pulse width.
This is the code:
ISR(TIMER1_COMPA_vect) {
cli();
static boolean var = HIGH;
if (var) {
PORTD = 255;
} else {
PORTD = 0;
}
var = var ^ 1;
sei();
}
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(7, OUTPUT);
// TIMER 1 for interrupt frequency 301886.7924528302 Hz:
cli(); // stop interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 301886.7924528302 Hz increments
OCR1A = 52; // = 16000000 / (1 * 301886.7924528302) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 1 prescaler
TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
}
// the loop function runs over and over again forever
void loop() {
while(1);
}
and this is what I get:
Tough to guess. The arm is faster, but it also has greater minimum interrupt overhead (in cycles.)
Your failure with the avr is probably due to another interrupt delaying service to your timer.
The arm has multiple interrupt priorities that might help with that.
It also has dma, which might be worth looking into.
ISR(TIMER1_COMPA_vect) {
cli();
static boolean var = HIGH;
if (var) {
PORTD = 255;
} else {
PORTD = 0;
}
var = var ^ 1;
sei();
}
You have no need to use cil() and sei() in an ISR, that happens automatically.
Those spaces are probably caused by the millis() timer going on timer 0. It is that you need to disable because if your timer 1 goes off while the Arduino is servicing the timer 0' ISR then your ISR will have to wait until it is finished before being called. There is only one level of interrupts on the Arduino and once one is being serviced all others are locked out until it is finished.
The only reason you would use cil() and sei() in an ISR, is the other way round to let your ISR yield to other interrupts.
Sure enough, I turned timer 0 off and it is stable at 300 kHz, so it is possible to at last sample my high frequency serial data signal with uno. Will see how long will be my redundancy check, hopefully will fit in time window. Thank you for your help!