diff --git a/Marlin/Marlin.h b/Marlin/Marlin.h
index cfa57eb0f9a2836c827290b7c0e2a3026469d273..a0f996887a6505ce9c14dfeebf90a0f57dd258f5 100644
--- a/Marlin/Marlin.h
+++ b/Marlin/Marlin.h
@@ -384,9 +384,8 @@ extern uint8_t active_extruder;
 void calculate_volumetric_multipliers();
 
 // Buzzer
-#if HAS_BUZZER
+#if HAS_BUZZER && PIN_EXISTS(BEEPER)
   #include "buzzer.h"
-  extern Buzzer buzzer;
 #endif
 
 /**
diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 6993862574158c499bfbc1ce9ae3170546bc862e..201f67428d458125fe9b615194e93958522f72db 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -373,9 +373,14 @@ static millis_t stepper_inactive_time = (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL
   Stopwatch print_job_timer = Stopwatch();
 #endif
 
-// Buzzer
-#if HAS_BUZZER
-    Buzzer buzzer;
+// Buzzer - I2C on the LCD or a BEEPER_PIN
+#if ENABLED(LCD_USE_I2C_BUZZER)
+  #define BUZZ(d,f) lcd_buzz(d, f)
+#elif HAS_BUZZER
+  Buzzer buzzer;
+  #define BUZZ(d,f) buzzer.tone(d, f)
+#else
+  #define BUZZ(d,f) NOOP
 #endif
 
 static uint8_t target_extruder;
@@ -5657,7 +5662,7 @@ inline void gcode_M226() {
     // Limits the tone duration to 0-5 seconds.
     NOMORE(duration, 5000);
 
-    buzzer.tone(duration, frequency);
+    BUZZ(duration, frequency);
   }
 
 #endif // HAS_BUZZER
@@ -6129,9 +6134,7 @@ inline void gcode_M428() {
         SERIAL_ERROR_START;
         SERIAL_ERRORLNPGM(MSG_ERR_M428_TOO_FAR);
         LCD_ALERTMESSAGEPGM("Err: Too far!");
-        #if HAS_BUZZER
-          buzzer.tone(200, 40);
-        #endif
+        BUZZ(200, 40);
         err = true;
         break;
       }
@@ -6142,10 +6145,8 @@ inline void gcode_M428() {
     SYNC_PLAN_POSITION_KINEMATIC();
     report_current_position();
     LCD_MESSAGEPGM(MSG_HOME_OFFSETS_APPLIED);
-    #if HAS_BUZZER
-      buzzer.tone(200, 659);
-      buzzer.tone(200, 698);
-    #endif
+    BUZZ(200, 659);
+    BUZZ(200, 698);
   }
 }
 
@@ -6327,7 +6328,7 @@ inline void gcode_M503() {
       #if HAS_BUZZER
         millis_t ms = millis();
         if (ms >= next_tick) {
-          buzzer.tone(300, 2000);
+          BUZZ(300, 2000);
           next_tick = ms + 2500; // Beep every 2.5s while waiting
         }
       #endif
@@ -8470,7 +8471,7 @@ void idle(
     print_job_timer.tick();
   #endif
 
-  #if HAS_BUZZER
+  #if HAS_BUZZER && PIN_EXISTS(BEEPER)
     buzzer.tick();
   #endif
 }
diff --git a/Marlin/buzzer.h b/Marlin/buzzer.h
index a398269d71994d924a37bb19ccf8167e57a4f84b..4548acfaa3bd551b8a8e37ae42ae7d8b18764a19 100644
--- a/Marlin/buzzer.h
+++ b/Marlin/buzzer.h
@@ -27,6 +27,8 @@
 #include "circularqueue.h"
 #include "temperature.h"
 
+#include "MarlinConfig.h"
+
 #define TONE_QUEUE_LENGTH 4
 
 /**
@@ -135,4 +137,6 @@ class Buzzer {
     }
 };
 
+extern Buzzer buzzer;
+
 #endif
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index b08eaccd29dc062efb99ec8470c5ef7f3cfc4e73..d00937402f67bdb131a0d01e4faf87eb31a1f130 100755
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -1074,8 +1074,8 @@ void kill_screen(const char* lcd_msg) {
             lcd_return_to_status();
             //LCD_MESSAGEPGM(MSG_LEVEL_BED_DONE);
             #if HAS_BUZZER
-              buzzer.tone(200, 659);
-              buzzer.tone(200, 698);
+              lcd_buzz(200, 659);
+              lcd_buzz(200, 698);
             #endif
           }
           else {
@@ -2342,23 +2342,23 @@ void kill_screen(const char* lcd_msg) {
    * Audio feedback for controller clicks
    *
    */
-
-  #if ENABLED(LCD_USE_I2C_BUZZER)
-    void lcd_buzz(long duration, uint16_t freq) { // called from buzz() in Marlin_main.cpp where lcd is unknown
+  void lcd_buzz(long duration, uint16_t freq) {
+    #if ENABLED(LCD_USE_I2C_BUZZER)
       lcd.buzz(duration, freq);
-    }
-  #endif
+    #elif PIN_EXISTS(BEEPER)
+      buzzer.tone(duration, freq);
+    #endif
+  }
 
   void lcd_quick_feedback() {
     lcdDrawUpdate = LCDVIEW_CLEAR_CALL_REDRAW;
     next_button_update_ms = millis() + 500;
 
     // Buzz and wait. The delay is needed for buttons to settle!
+    lcd_buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
     #if ENABLED(LCD_USE_I2C_BUZZER)
-      lcd.buzz(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
       delay(10);
     #elif PIN_EXISTS(BEEPER)
-      buzzer.tone(LCD_FEEDBACK_FREQUENCY_DURATION_MS, LCD_FEEDBACK_FREQUENCY_HZ);
       for (int8_t i = 5; i--;) { buzzer.tick(); delay(2); }
     #endif
   }
diff --git a/Marlin/ultralcd.h b/Marlin/ultralcd.h
index b1d4300c04ebb91474558dbe13efdc8a4aa9720f..4cc8334ec91521b101aab0d6a640c34739541b0a 100644
--- a/Marlin/ultralcd.h
+++ b/Marlin/ultralcd.h
@@ -43,7 +43,7 @@
   void lcd_kill_screen();
   void kill_screen(const char* lcd_msg);
 
-  #if ENABLED(LCD_USE_I2C_BUZZER)
+  #if HAS_BUZZER
     void lcd_buzz(long duration, uint16_t freq);
   #endif