вопрос по применению progmem в gcc

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 45
Зарегистрирован: Вс янв 22, 2012 21:57:43

Сообщение malex66 »

доброго времени.
есть код:
Спойлер

Код: Выделить всё

/*
 * t_flash.c
 *
 *  Created on: 02.07.2016
 *      Author: alex
 */
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>


#define LCD_COMMAND                     0
#define LCD_DATA                        1

#define LCDDATAPORT                     PORTD
#define LCDDATADDR                      DDRD
#define LCDDATAPIN                      PIND
#define LCD_D4                          0
#define LCD_D5                          1
#define LCD_D6                          2
#define LCD_D7                          3

#define LCDCONTROLPORT          PORTD
#define LCDCONTROLDDR           DDRD
#define LCD_RS                          5
#define LCD_RW                          4
#define LCD_E                           6

#define LCD_CONTROL_MASK ((1 << LCD_RS) | (1 << LCD_RW) | (1 << LCD_E))
#define LCD_DATA_MASK ((1 << LCD_D4) | (1 << LCD_D5) | (1 << LCD_D6) | (1 << LCD_D7))
#define LCD_STROBEDELAY_US      5

#define LCD_ROW1_OFFSET         0x00
#define LCD_ROW2_OFFSET         0x40
#define LCD_ROW3_OFFSET         0x10
#define LCD_ROW4_OFFSET         0x50




char lcdGetNibble (char state)
{
        char temp = 0;
        LCDCONTROLDDR |= LCD_CONTROL_MASK;
        LCDCONTROLPORT |= (1<<LCD_RW);

        if (state)
                LCDCONTROLPORT |= (1<<LCD_RS);
        else
                LCDCONTROLPORT &= ~(1<<LCD_RS);

        LCDCONTROLPORT |=       (1<<LCD_E);

        LCDDATADDR &= ~LCD_DATA_MASK;
        LCDDATAPORT |= LCD_DATA_MASK;

        _delay_us (LCD_STROBEDELAY_US);

        LCDCONTROLPORT &= ~(1<<LCD_E);

        if (LCDDATAPIN & (1<<LCD_D7)) temp |= (1<<3);
        if (LCDDATAPIN & (1<<LCD_D6)) temp |= (1<<2);
        if (LCDDATAPIN & (1<<LCD_D5)) temp |= (1<<1);
        if (LCDDATAPIN & (1<<LCD_D4)) temp |= (1<<0);

        return temp;
}


char lcdRawGetByte (char state)
{
        char temp = 0;

        temp |= lcdGetNibble (state);
        temp = temp << 4;
        temp |= lcdGetNibble (state);

        return temp;
}

char lcdIsBusy (void)
{
        if (lcdRawGetByte(LCD_COMMAND) & (1<<7))
                return 0xff;
        else
                return 0x00;
}

void lcdSendNibble (char byte, char state)
{
        LCDCONTROLDDR |= LCD_CONTROL_MASK;
        LCDDATADDR |= LCD_DATA_MASK;

        LCDCONTROLPORT &= ~(1<<LCD_RW);

        if (state)
                LCDCONTROLPORT |= (1<<LCD_RS);
        else
                LCDCONTROLPORT &= ~(1<<LCD_RS);

        LCDCONTROLPORT |= (1<<LCD_E);

        LCDDATAPORT &= ~LCD_DATA_MASK;

        if (byte & (1<<3)) LCDDATAPORT |= (1<<LCD_D7);
        if (byte & (1<<2)) LCDDATAPORT |= (1<<LCD_D6);
        if (byte & (1<<1)) LCDDATAPORT |= (1<<LCD_D5);
        if (byte & (1<<0)) LCDDATAPORT |= (1<<LCD_D4);

        _delay_us (LCD_STROBEDELAY_US);

        LCDCONTROLPORT &= ~(1<<LCD_E);
}


void lcdRawSendByte (char byte, char state)
{
        #ifdef lcdEnableRussian
                if (state) byte = toRussian (byte);
        #endif

        lcdSendNibble ((byte>>4), state);
        lcdSendNibble (byte, state);
}

void lcdPutsFromFlash (char *str)
{
        while (pgm_read_byte (str))
        {
                while (lcdIsBusy());
                lcdRawSendByte (pgm_read_byte(str++), LCD_DATA);
        }
}

void lcdGotoXY (char str, char col)
{
        char offset [4];
        offset [0] = LCD_ROW1_OFFSET;
        offset [1] = LCD_ROW2_OFFSET;
        offset [2] = LCD_ROW3_OFFSET;
        offset [3] = LCD_ROW4_OFFSET;

        while (lcdIsBusy())     ;
        lcdRawSendByte ((0b10000000 | (offset [(unsigned char) str] + col)), LCD_COMMAND);
}

const static char strMessage0 [] PROGMEM = "Здесь:  12345678";

int main()
{
   lcdGotoXY (1, 0);
   lcdPutsFromFlash (strMessage0);
}

компиляция (eclips + avr плагин + avr-gcc 4.8.1) проходит успешно - но есть варнинг:
passing argument 1 of ‘lcdPutsFromFlash’ discards ‘const’ qualifier from pointer target type [enabled by default]

чем это может грозить? кто знает - подскажите пожалуйста.
а то сколько вызовов функции lcdPutsFromFlash - столько и варнингов....
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3497
Зарегистрирован: Вт окт 22, 2013 04:37:23
Откуда: Казань

Сообщение smacorp »

malex66 писал(а):чем это может грозить? а то сколько вызовов функции lcdPutsFromFlash - столько и варнингов....
Чем может грозить - хз. Скорее всего ничем.

А чтобы избавиться, строку
  • void lcdPutsFromFlash (char *str)
замените на
  • void lcdPutsFromFlash (const char *str)
Функция не меняет данные, адресуемые указателем, а GCC строг.

Вообще, есть мнение, что прописывать типы в аргументах функций это правильно.
Платы для HLDI - установки лазерной засветки фоторезиста.
Фоторезист Ordyl Alpha 350
Жидкое олово для лужения плат (видео) - самое лучшее и только у меня.
Паяльные маски XV501T-4 и KSM-S6189 (5 цветов).
Заказ печатных плат - pcbsmac@gmail.com
Реклама
Открыл глаза
Сообщения: 45
Зарегистрирован: Вс янв 22, 2012 21:57:43

Сообщение malex66 »

А чтобы избавиться, строку...
спасибо smacorp, как раз сам разобрался - просто это кусок проекта еще на четвертой студии... а там проходило вообще без const, что в определении, что в функции. вот приспичило его поднять из небытия...
Ответить

Вернуться в «AVR»