Code removed away due optimization [Solved]

Hello,
am trying to do bit access to IO pins on arduino pro mini 16MHz, 5V (atmega328p)
It looks like Arduino IDE ignores the second half of code and removes it away due optimization.
No signal is measured on pins EN, RS by oscilloscope. I am able to find the arduiono output .elf file and run it in simulator in Microchip studio to be able to see the actual disassembly code.
Aim: I try this bit access because of am trying a someone else's C code to drive 1x16 LCD OLED display (raystar REC001601BYPP5N00100)

#include <inttypes.h>
#include "Arduino.h"

// program for testing LCD display

// PB0 LCD_RS
// PB1 LCD_RW
// PB2 LCD_EN
// PD0 LCD_D0
// PD1 LCD_D1
// PD2 LCD_D2
// PD3 LCD_D3
// PD4 LCD_D4
// PD5 LCD_D5
// PD6 LCD_D6
// PD7 LCD_D7

inline void sendByte(uint8_t c)
{
	PORTD = c;
}

inline void lcd_rs_hi( void)
{
	PORTB |= _BV(PB0);
}

inline void lcd_rs_low( void)
{
	PORTB &= ~_BV(PB0);
}

inline void lcd_rw_hi( void)
{
	PORTB |= _BV(PB1);
}

inline void lcd_rw_low( void)
{
	PORTB &= ~_BV(PB1);
}

inline void lcd_en_hi( void)
{
	PORTB |= _BV(PB2);
}

inline void lcd_en_low( void)
{
	PORTB &= ~_BV(PB2);
}

inline void lcd_init_ports( void)
{
	PORTD = 0;
	PORTB &= ~(0x07);
	
	DDRD |= 0xFF; // 0b1111'1111
	DDRB |= 0x07; // 0b0000'0111
}

/* local function to generate some delay */
void delay_short(uint8_t cnt) {
  uint8_t i;
  for (i = 0; i < cnt; i++) {
    asm volatile("nop\n");
    asm volatile("nop\n");
    asm volatile("nop\n");
    asm volatile("nop\n");
    asm volatile("nop\n");
  }
}

/* local function to generate ms delay */
void delay_long(uint8_t cnt) {
  uint8_t i, j;
  for (j = 0; j < cnt; j++) {
    for (i = 0; i < 2000; i++) {
      asm volatile("nop\n");
      asm volatile("nop\n");
      asm volatile("nop\n");
      asm volatile("nop\n");
      asm volatile("nop\n");
    }
  }
}


/* Function to send the command to LCD */
void Lcd_CmdWrite(char cmd) {
  sendByte(cmd);                        //Send the Command
  lcd_rs_low();  // Send LOW pulse on RS pin for selecting Command register
  lcd_rw_low();  // Send LOW pulse on RW pin for Write operation
  lcd_en_hi();   // Generate a High-to-low pulse on EN pin
  delay_long(1); // 1ms
  lcd_en_low(); 
  delay_long(10);  // 10ms
}

/* Function to send the data to LCD */
void Lcd_DataWrite(char dat) {
  sendByte(dat);                        //Send the data
  lcd_rs_hi();  // Send LOW pulse on RS pin for selecting Command register
  lcd_rw_low();  // Send LOW pulse on RW pin for Write operation
  lcd_en_hi();   // Generate a High-to-low pulse on EN pin
  delay_long(1); // 1ms
  lcd_en_low(); 
  delay_long(10);  // 10ms
}


void setup() {
  // config
  lcd_init_ports();
  delay_long(500);  // 500ms

  while (1) {
    Lcd_CmdWrite(0x38);  // Function set, N=1, F=0, FT1=0, FT2=0
    delay_long(500);     // 500ms

    Lcd_CmdWrite(0x0E);  // Display ON/OFF, D=1, C=1, B=0
    delay_long(500);     // 500ms

    Lcd_CmdWrite(0x01);  // Display Clear
    delay_long(500);     // 500ms

    Lcd_CmdWrite(0x02);  // Display Return Home
    delay_long(500);     // 500ms

    Lcd_CmdWrite(0x04);  // Entry mode set I/D=0, SH=0
    delay_long(500);     // 500ms

    Lcd_DataWrite('H');
    Lcd_DataWrite('e');
    Lcd_DataWrite('l');
    Lcd_DataWrite('l');
    Lcd_DataWrite('o');
    Lcd_DataWrite(' ');
    Lcd_DataWrite('w');
    Lcd_DataWrite('o');
    Lcd_DataWrite('r');
    Lcd_DataWrite('l');
    Lcd_DataWrite('d');

    delay_long(5000);  // 5000ms
  }
}

void loop() {
}

your i variable cannot count to 2000 so you have an infinite loop when you call delay_long
in the same way, j won't count to 5000

try

void delay_long(uint32_t cnt) {
  uint32_t i, j;
  for (j = 0; j < cnt; j++) {
    for (i = 0; i < 2000; i++) {
      asm volatile("nop\n");
      asm volatile("nop\n");
      asm volatile("nop\n");
      asm volatile("nop\n");
      asm volatile("nop\n");
    }
  }
}

(or don't reinvent the wheel and use delay() )

1 Like

Problem Solved. I changed uint8_t to uint16_t. Now the pulses EN, RS are present. Thank you for help.

if you turn all the warnings on during compile time, I'd bet the compile would have told you about the limited range. it's good at catching those when using constants

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.