MCUdude / MiniCore

Arduino hardware package for ATmega8, ATmega48, ATmega88, ATmega168, ATmega328 and ATmega328PB
Other
1k stars 246 forks source link

delay() not working ATMEGA328P-AU #312

Closed Georgew221 closed 3 months ago

Georgew221 commented 3 months ago

Using MiniCore 3.0.2 locks the MCU when getting to int delay() processes. The processes that are sub-int (0.9) continue the MCU programming as expected. delayMicroseconds() seems to work okay, but not suitable for longer delay times.

delay(1); //Will break code/MCU pauses at the delay() indefinitely
delay(0.1); //MCU will continue the program

This is using a ATMEGA328P-AU and a 16MHz external crystal.

MCUdude commented 3 months ago

Can you post a bare minimum sketch that will reproduce your issue? Ideally a blink sketch of some sort.

delay(0.1); //MCU will continue the program

the delay number has to be an integer, so this won't/shouldn't work.

Georgew221 commented 3 months ago

I've just bodged _delay_ms(1000); into working on it - I can use it as a workaround at the mo.

This is what I've got now;

#include <SoftwareSerial.h>
#include "util/delay.h" DELAY_BACKWARD_COMPATIBLE 

int ATReadyPin = A2;
const byte External_TX = 1;
const byte External_RX = 0;

//Serial Definitions
SoftwareSerial Ext_Comms(External_RX, External_TX);

void setup() {
  pinMode(ATReadyPin, OUTPUT);
  pinMode(External_TX, OUTPUT);
  pinMode(External_RX, INPUT);
  Ext_Comms.begin(19200);
  Ext_Comms.println("ATReady, enabling LIN controllers");
  digitalWrite(ATReadyPin, HIGH);
  _delay_ms(1000);
  digitalWrite(ATReadyPin, LOW);
}

void loop() {
  _delay_ms(1000);
  digitalWrite(ATReadyPin, HIGH);
  _delay_ms(1000);
  digitalWrite(ATReadyPin, LOW);
  Ext_Comms.println("Looped");
}

Changing any of the _delay_ms() to delay() will pause the MCU.

MCUdude commented 3 months ago

I'll give your code a try later today. Are you using a bootloader or an ISP programmer for uploading? And why would you use SoftwareSerial when hardware serial is available on the same pins?

Georgew221 commented 3 months ago

Arduino as ISP as the programmer if that matters, although I have burnt the bootloader just to make sure the 328 isn't using the internal oscillator. I was trying to debug a baud issue so was using SoftwareSerial to quickly change the pins is all.

MCUdude commented 3 months ago

If you compile and upload using the default "Arduino UNO" option (not MiniCore), does it still freeze?

Georgew221 commented 3 months ago

With bootloader burnt from Minicore, and compiling/uploading as if it were an Uno it still pauses at delay().

Georgew221 commented 3 months ago

Just tried it on another PCB of mine and it works fine with Minicore. Possible a bad 328 but confused as to why the old _delay_ms() is working with Minicore on it but the normal one isn't? Assuming they a check the cycle counts in the same way as the timings of _delay_ms() are correct?

MCUdude commented 3 months ago

It probably is a bad chip. delay() and _delay_ms() are completely different. _delay_ms() is just a bunch of instructions (mostly NOPs I think) and your program will grow every time you call _delay_ms(). delay() and delayMicroseconds() on the other hand uses timer0 as their timekeeping. So if there is something related to timer0 that doesn't work in the chip, you might see the same results as we're getting. Where did you get your chips from?

Georgew221 commented 3 months ago

They were assembled by JLCPCB so one would assume they're good. Marking as closed as most likely a fab issue 😊 Thanks for the quick reply!