Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/320: Рейтинг темы: голосов - 320, средняя оценка - 4.86
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
1

FLASH память (внешняя)

13.06.2019, 17:48. Показов 61527. Ответов 19

Author24 — интернет-сервис помощи студентам
Товарищи! Подскажите пожалуйста..

Хочу приконнектить внешнюю память winbond w25q16 к микроконтроллеру stm32f103c8t6 используя HAL

если отправляю команды для получения ID устройства, то он мне все присылает, то есть (0xef и 0x14) как указано в даташите..

когда работаю с данными сначала всегда снимаю защиту с микросхемы
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void Flash_write_status()
    { 
        uint8_t Write_Enable = 0x06;
    uint8_t Sector_Erase = 0x01;        
        Address0 = 0;
    Address1 = 0;
        
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);     // CS to low        
    HAL_SPI_Transmit(&hspi1,&Write_Enable,1,1); // Write Enable Command     
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high
        
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);    // CS to low         
    HAL_SPI_Transmit(&hspi1,&Sector_Erase,1,0);// Page Program Command
        HAL_SPI_Transmit(&hspi1,&Address1,1,0); 
        HAL_SPI_Transmit(&hspi1,&Address0,1,0);     
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high       
      HAL_Delay (250);      
    }
потом включаю очистку всего чипа данной функцией
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void Flash_Erase_Chip(void)
{
    uint8_t Write_Enable = 0x06;
    uint8_t Erase_Chip = 0xC7;
 
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);     // CS to low
    
    HAL_SPI_Transmit(&hspi1,&Write_Enable,1,1); // Write Enable Command
    
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high
  
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);     // CS to low
 
    HAL_SPI_Transmit(&hspi1,&Erase_Chip,1,1);   // Erase Chip Command
 
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high
      HAL_Delay (50000); 
 
}
после этого все данные равны 0xFF(так и должно быть).
но когда пытаюсь записать данные то ничего в буфере не меняется...
C
1
2
3
4
5
6
7
8
9
10
11
   Flash_Erase_Chip();
   Flash_write_status();
    
       
      txData[0] = 0x01; 
 
  while (1)
  {    
   Flash_Write_Data(1,1,txData);
  Flash_Read_Data (1,1,rxData); 
   }
функции записи и чтения такие
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void Flash_Write_Data(unsigned int address, unsigned int count, unsigned char * buffer)
{
    uint8_t Write_Enable = 0x06;
    uint8_t Page_Program = 0x02;      
    
    Address0 = (uint8_t)(address & 0x000000ff);
  Address1 = (uint8_t) ((address & 0x0000ff00) >> 8);
  Address2 = (uint8_t) ((address & 0x00ff0000) >> 16);    
    
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);     // CS to low    
    HAL_SPI_Transmit(&hspi1,&Write_Enable,1,0); // Write Enable Command
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high 
    
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);    // CS to low 
 
    HAL_SPI_Transmit(&hspi1,&Page_Program,1,0);// Page Program Command
    
    HAL_SPI_Transmit(&hspi1,&Address2,1,0);     // Write Address 
        HAL_SPI_Transmit(&hspi1,&Address1,1,0); 
        HAL_SPI_Transmit(&hspi1,&Address0,1,0);
        
     for (unsigned int i=0; i<count; i++){
    HAL_SPI_Transmit(&hspi1,&buffer[i],1,1);      
     }
     
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high   
   
}
чтение:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
void Flash_Read_Data (unsigned int address, unsigned int count, unsigned char * buffer)
{      
     uint8_t Read_Data = 0x03;    
    
    Address0 = (uint8_t)(address & 0x000000ff);
  Address1 = (uint8_t) ((address & 0x0000ff00) >> 8);
  Address2 = (uint8_t) ((address & 0x00ff0000) >> 16);
    
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_RESET);   // CS low
    
    HAL_SPI_Transmit(&hspi1,&Read_Data,1,0);  // Read Command
        
      HAL_SPI_Transmit(&hspi1,&Address2,1,0);     // Write Address 
        HAL_SPI_Transmit(&hspi1,&Address1,1,0);
        HAL_SPI_Transmit(&hspi1,&Address0,1,0);
    
      for (unsigned int i=0; i<count; i++){
    HAL_SPI_Receive(&hspi1,&buffer[i],1,1);      //     
      }
        
        HAL_GPIO_WritePin(GPIOA,GPIO_PIN_1,GPIO_PIN_SET);       // CS to high   
      
}
не знаю что не так
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.06.2019, 17:48
Ответы с готовыми решениями:

stm32+ внешняя память(flash, fram, eeprom)
День добрый. Понадобилось хранить достаточно большой объем данных, порядка 128 кбайт. Необходимо их...

Внешняя память на 256 мб для STM32
Хотелось бы подключить к МК внешнюю память для хранения данных, желаемый размер 256 мегабайт и...

Flash память контроллера
Взбрендили мне в голову такую мысль: прошивка контроллера заливается во внутренную флэш память, где...

Как разделить FLASH и RAM память
Собственно это и есть вопрос. Т.е. как разделить FLASH и RAM память что бы МК можно было прошивать...

19
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
14.06.2019, 00:09 2
Лучший ответ Сообщение было отмечено northcitizen как решение

Решение

После любой записи или очистки нужно вычитывать статусный регистр (команда 0x5) и проверять нулевой бит (busy). Если этот бит равен 1, то надо проверять снова... и так до тех пор, пока он не упадёт в ноль. Использовать фиксированную задержку ненадёжно. Судя по даташиту, chip erase может исполняться до 1 секунды. А в функции Flash_Write_Data() у вас даже задержки нет.
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
14.06.2019, 11:24  [ТС] 3
Humanoid, Спасибо, Вам! Работает! Я счастлив!
0
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
16.06.2019, 18:10  [ТС] 4
Humanoid, подскажите, пожалуйста, как сделать запись логов на флешку. Думаю, что неправильный подход у меня.. Смотрите, вот, например, я хочу записать какие то параметры(данные) во флеш память. С помощью кода выше я записываю данные в формате hex. А, потом когда надо будет, просто вытаскиваю и из hex преобразовываю в txt. Это типа парсер еще нужен, чтобы разделить все красиво?
0
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
16.06.2019, 20:43 5
Hex - это всего лишь способ представления числа. Например, латинская "а", шестнадцатеричное 0x61 или десятичное 97 - это всё одно и тоже число. И почему сразу не записывать текст?
Если я неправильно вас понял, то покажите, как именно вы записываете лог и в каком формате.
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
16.06.2019, 21:19  [ТС] 6
Humanoid, Спасибо за ответ! Только я еще ничего не записал... Зато я знаю, что буду записывать. Я планирую взять данные от GPS приемника, и записать во внешний флеш(только координаты). Данные приходят и я через UART их принимаю. Выделяю в принятых сообщениях координаты и тут должен отправить их во флеш. С Вашего ответа, я понял, что можно отправить данные, например, используя printf()(данные мне то приходят в текстовом виде с приемника согласно протоколу NMEA). В конечном итоге мне нужен файл, который будет содержать данные координат в текстовом виде.
0
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
17.06.2019, 23:35 7
Лучший ответ Сообщение было отмечено northcitizen как решение

Решение

Тоже задумываю похожий проект. Хочу сделать трекер для велосипеда, что бы сохранять маршрут, по которому ездил. А потом дома по USB прочитаю этот список сохранённых координат и подзаряжу аккумулятор.
Скорее всего, буду записывать так:
1. Объявлю структуру, в которой будет хранится координата. Скорее всего, это будет метка времени типа uint32_t и пара координат типа double. Возможно, пересмотрю, что бы размер был степенью двойки (например, 32 байта). Например, можно добавить качество сигнала и т.п.
2. Переменная будет представлять собой массив таких структур.
3. Координаты буду накапливать в памяти, пока не наберётся данных на 256 байт (это размер страницы для W25Q64, которую я использую).
4. Как только накопилось 256 байт, то сохраняю их во флешку и отправляю процессор в спячку до того, как придут следующие координаты.

Например, так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
struct coord {
    double lon;
    double lat;
    uint32_t ts;
    uint32_t sig;
    uint64_t reserved;
};
 
static struct coord coords[8];  // 8 элементов по 32 байта каждый = 256 байт
static int coords_idx;  // текущий индекс массива, куда добавлять новую координату
 
void add_coord(........)  // парсер вызывает эту функцию, что бы добавить координату
{
    coords[coords_idx].lon = ....  // заполняем элемент массива
    ........
    coords_idx++;  // выбираем следующий элемент как текущий
    if (++coords_idx > 8) {  // если это был последний элемент, то сохраняем в SPI и дальше заполняем сначала
        coords_idx = 0;
        spiflash_append((uint8_t *)coords, sizeof(coords));
    }
}
Но проблема в том, что при выключении последние координаты (до 8 точек) будут потеряны. Зависит от того, с какой периодичностью сохранять координаты... если каждую секунды, то потеря последних 8 секунд не критична.
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
21.06.2019, 15:26  [ТС] 8
Humanoid, Кстати, есть еще одна флешка 25Q64FV. Решил завести ее на Миландр 1986BE94T. Завелась(по крайней мере получил ID производителя и микросхемы). Так, что обращайтесь, если нужно

Добавлено через 1 час 18 минут
В принципе допилил. Данные записываются. Читаются. Отличие 25Q64FV от 25Q16, то что в 25Q16 не использовал ResetEnable = 0x66 и сам Reset = 0x99.
0
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
29.06.2019, 20:25  [ТС] 9
Цитата Сообщение от Humanoid Посмотреть сообщение
4. Как только накопилось 256 байт, то сохраняю их во флешку и отправляю процессор в спячку до того, как придут следующие координаты.
Получается, вы записываете по странице? а как мне сделать если у меня функция записи такая
C
1
uint8_t w25q16_page_programm(const uint8_t * data, uint32_t addres, uint8_t lenght)
То есть когда я записал 256 байт(страничку), то мне нужно адрес увеличить на 1, правильно понял?
И я этот адрес могу увеличивать до размеров флеш памяти?
0
Эксперт .NET
10574 / 6498 / 1506
Регистрация: 25.05.2015
Сообщений: 19,685
Записей в блоге: 14
29.06.2019, 22:15 10
Цитата Сообщение от Humanoid Посмотреть сообщение
Но проблема в том, что при выключении последние координаты (до 8 точек) будут потеряны. Зависит от того, с какой периодичностью сохранять координаты... если каждую секунды, то потеря последних 8 секунд не критична.
Если это действительно проблема, то можно организовать выключение программно и перед ним сбрасывать буфер во флеш.
0
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
30.06.2019, 01:46 11
Цитата Сообщение от northcitizen Посмотреть сообщение
То есть когда я записал 256 байт(страничку), то мне нужно адрес увеличить на 1, правильно понял?
Нет, на 256. Адрес указывается в байтах.

И у вас аргумент length (который с опечаткой - все последние буквы перепутаны местами) имеет тип uint8_t... число 256 этой функции передать не получится.

Цитата Сообщение от Rius Посмотреть сообщение
Если это действительно проблема, то можно организовать выключение программно и перед ним сбрасывать буфер во флеш.
Тоже думал на счёт программной кнопки включения/выключения, но решил не заморачиваться. Потерять 8 секунд - это не проблема. Плату уже развёл для механического выключателя и переделывать теперь лень
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
01.07.2019, 10:09  [ТС] 12
Humanoid,
Цитата Сообщение от Humanoid Посмотреть сообщение
отправляю процессор в спячку
А, как вы переводите процессор в режим сна? Если мы не переведем его в сон, то можем записать незаполненный буфер?
0
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
01.07.2019, 11:10 13
Лучший ответ Сообщение было отмечено northcitizen как решение

Решение

Цитата Сообщение от northcitizen Посмотреть сообщение
А, как вы переводите процессор в режим сна?
Самое простое - это ARM-инструкция WFI, которая отключает процессор до тех пор, пока не придёт какое-нибудь прерывание. При этом энергопотребление значительно снижается. В качестве прерывания для пробуждения можно использовать сигнал от навигационного модуля, который раз в секунду даёт импульс. Такой сигнал есть у многих навигационных модулей. Но инструкция WFI отправляет в спячку только процессор, а остальная периферия продолжает работать. Но у STM32L151 (я их буду использовать) есть ещё более экономичные режимы сна, когда весь микроконтроллер почти ничего не потребляет. А вообще спячка нужна, что бы уменьшить энергопотребление и продлить время работы от батарейки.

Цитата Сообщение от northcitizen Посмотреть сообщение
Если мы не переведем его в сон, то можем записать незаполненный буфер?
Нет. Просто устройство не знает о том, что мы вот-вот щёлкнем выключатель и выключим питание. Такая проблема всегда есть при использовании кеширования. Например, если вы работаете с компьютером, а потом вдруг выдернули вилку из розетки и компьютер выключился. В этом случае вы так же потеряете последние данные, которые операционная система держала в оперативной памяти и ещё не успела сохранить на диск.
Варианта два:
1. Не накапливать данные в буфере, а сразу сохранять их на флешку по мере поступления. Я не хочу этого делать, так как планирую держать флешку в выключенном состоянии как можно дольше для экономии заряда аккумулятора.
2. Использовать программную кнопку выключения (как предлагал Rius). В этом случае когда мы нажимаем на кнопку выключения, то подаём сигнал на микроконтроллер, а тот уже сохраняет все данные на флешку и подаёт сигнал на транзистор, что бы выключить питание самому себе. По такому же принципу работают современные компьютеры.
3. Смириться с тем, что несколько последних записей во время выключения питания будут потеряны. Я для себя выбрал этот вариант.
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
05.07.2019, 16:33  [ТС] 14
Humanoid, Подскажите, пожалуйста, что делаю не так..

Пишу функцию записи данных во флеш память так(как вы показали):
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef __packed struct {        // структура координат 
    char ts[sizeof("hhmmss")];;        // время
      char lon[sizeof("XXXXX.XXX")];       // долготоа
    char Lat[sizeof("XXXX.XXX")];       // широта
 
 
}coord;
 
static coord coords;  
 
 
void add_coord(void)  // парсер вызывает эту функцию, что бы добавить координату
{
    uint8_t i,TS = 7;
    
    /*подготавливаем данные для записи во флеш память*/
    for(i=0; i < TS; i++ )
    {
    coords.ts[i] = GPSFixData.UTC[i];  // заполняем элемент массивa (Только время UTC)
    }
 
     /*записываем данные во влеш память*/
   w25q16_page_programm(&coords.ts[p], Address+p, 1);
    p++;
 
    
}
Функцию записи
C
1
 void add_coord(void)
вызываю в прерывании по UART.(пока не переделал парсер под таймер, чтобы через таймаут структуру заполянть).
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
void USART2_IRQHandler(void)
{
 volatile char UsartTemp = 0;
 
 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
 {
 UsartTemp = USART_ReceiveData(USART2);
 GPSBuf[GPSBufWrPoint] = UsartTemp;
 
 if ((GPSBufWrPoint > 1) && (GPSBufWrPoint < GPSBUFLENGTH)) // Проверка нахождения внутри буфера, чтобы при дальнейшем преобразовании не выскочить за границу
 {
 if ((GPSBuf[GPSBufWrPoint-1] == ',') && (GPSBuf[GPSBufWrPoint] == ','))
 { // Принятая последовательность байт вида ",," превращается в ",0,", тем самым превращая неопределенный параметр в четкий 0
 GPSBuf[GPSBufWrPoint]   = '0';
 GPSBuf[GPSBufWrPoint+1] = ',';
 GPSBufWrPoint++;
 }
 if ((GPSBuf[GPSBufWrPoint-1] == ',') && (GPSBuf[GPSBufWrPoint] == '*'))
 { // Принятая последовательность байт вида ",*" превращается в ",0*", тем самым превращая неопределенный параметр в четкий 0
 GPSBuf[GPSBufWrPoint]   = '0';
 GPSBuf[GPSBufWrPoint+1] = '*';
 GPSBufWrPoint++;
 }
 }
    
 if (GPSBufWrPoint < GPSBUFLENGTH)
 GPSBufWrPoint++; // Продолжаем заполнять буфер
     else
     { // Если буфер заполнился, начинаем искать и декодировать NMEA сентенции
__disable_irq();
           NMEA_Parser_RMC();
             NMEA_Parser_GLL();///1
           NMEA_Parser_GGA();//2
    //  add_coord();
             GPSBufWrPoint = 0;
__enable_irq();
     }
         
    }
}
Но проблема! Данные то пишутся, но другой вопрос какие! Я отпраляю на запись только UTC, а у меня пишутся и координаты и UTC и даже нераспарсенные части пакета пролетают..
Хотя структуру сделал __packed

Добавлено через 56 минут
структуру GPSFixData тоже сделал __packed.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 __packed struct  GPGGA_Struct // Структура с данными GPS-модуля
{
 char Time [sizeof("hhmmss")+RESERVE]; // Время
 char Latitude [sizeof("XXXX.XXX")+RESERVE]; // Широта
     char NS; // Север-Юг
 char Longitude[sizeof("XXXXX.XXX")+RESERVE]; // Долгот
 char EW; // Запад-Восток
 char UTC [sizeof("nncccc")+RESERVE]; // Количество спутников в решении
 char Latitude_GGA[sizeof("XXXX.XXX")+RESERVE]; // Месяц
 char Longitude_GGA[sizeof("XXXXX.XXX")+RESERVE]; // Число
 char UTC_GGA [sizeof("nncccc")+RESERVE]; // Поправка на местное время, часы
 char UTC_RMC [sizeof("nncccc")+RESERVE]; // Поправка на местное время, часы
 char Latitude_RMC[sizeof("XXXX.XXX")+RESERVE]; // Месяц
 char Longitude_RMC[sizeof("XXXXX.XXX")+RESERVE]; // Число
};
Добавлено через 6 минут
пишу по байту

Добавлено через 38 минут
_SayHello, Не посмотрите, если найдется несколько минут..?
0
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
05.07.2019, 19:04 15
Цитата Сообщение от northcitizen Посмотреть сообщение
/*записываем данные во влеш память*/
w25q16_page_programm(&coords.ts[p], Address+p, 1);
p++;
Кажется, вы тут цикл забыли сделать. Сейчас вы только один байт записываете. А переменную p увеличиваете неограниченно. Скорее всего, поэтому она и пишет всю память подряд, так как не ограничена размером массива ts. Вообще, что такое p? Наверное, нужно:
C
1
2
3
4
for (i = 0; i < sizeof(coords.ts); i++) {
    w25q16_page_programm(&coords.ts[p], Address+p, 1);
    p++;
}
Или даже за один раз:
C
1
2
w25q16_page_programm(coords.ts, Address+p, sizeof(coords.ts));
p += sizeof(coords.ts);
Цитата Сообщение от northcitizen Посмотреть сообщение
if (GPSBufWrPoint < GPSBUFLENGTH)
GPSBufWrPoint++; // Продолжаем заполнять буфер
else
{ // Если буфер заполнился, начинаем искать и декодировать NMEA сентенции
Не понял. Вы же принимаете текстовые данные. Они могут быть произвольной длины. Нужно ждать символ перевода строки и тогда уже считать, что строка полностью принята.
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
05.07.2019, 19:30  [ТС] 16
Цитата Сообщение от Humanoid Посмотреть сообщение
Вообще, что такое p?
С помощью p я иду по адресу флеш памяти. Это сделано для тестовго режима. В конечном итоге, я сделаю, чтобы переменная p ограничивалась размером флеш памяти
Спасибо вам! Я исправил! теперь данные обновляются каждую секунду(но почему, то иногда быстрее...)
C
1
2
3
4
5
6
7
8
9
10
11
12
 if (GPSBuf[GPSBufWrPoint]!= '\n')
 GPSBufWrPoint++; // Продолжаем заполнять буфер
     else
     { // Если буфер заполнился, начинаем искать и декодировать NMEA сентенции
__disable_irq();
           NMEA_Parser_RMC();
             NMEA_Parser_GLL();///1
           NMEA_Parser_GGA();//2
    //add_coord();
             GPSBufWrPoint = 0;
__enable_irq();
     }
0
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
13.07.2019, 16:40  [ТС] 17
Humanoid, Из за чего может быть, такое, что при записи структуры через
C
1
f_write(&fil, &GPSFixData.Latitude, sizeof(&GPSFixData.Latitude), &bw);
во флешку microSD пишется только 4 символа, а там 8+ '\0' ?? Всегда только 4.
Структура так выглядит:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 __packed struct  GPGGA_Struct // Структура с данными GPS-модуля
{
 char Time [sizeof("hhmmss")+RESERVE]; // Время
 char Latitude [sizeof("XXXX.XXX")+RESERVE]; // Широта
     char NS; // Север-Юг
 char Longitude[sizeof("XXXXX.XXX")+RESERVE]; // Долгот
 char EW; // Запад-Восток
 char UTC [sizeof("nncccc")+RESERVE]; // Количество спутников в решении
 char Latitude_GGA[sizeof("XXXX.XXX")+RESERVE]; // Месяц
 char Longitude_GGA[sizeof("XXXXX.XXX")+RESERVE]; // Число
 char UTC_GGA [sizeof("nncccc")+RESERVE]; // Поправка на местное время, часы
 char UTC_RMC [sizeof("nncccc")+RESERVE]; // Поправка на местное время, часы
 char Latitude_RMC[sizeof("XXXX.XXX")+RESERVE]; // Месяц
 char Longitude_RMC[sizeof("XXXXX.XXX")+RESERVE]; // Число
};
0
Почетный модератор
11525 / 4320 / 448
Регистрация: 12.06.2008
Сообщений: 12,412
13.07.2019, 17:09 18
Цитата Сообщение от northcitizen Посмотреть сообщение
sizeof(&GPSFixData.Latitude)
Замените на sizeof(GPSFixData.Latitude). Потому что вы указываете размер указателя, который в 32-битной системе всегда равен 4.
1
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
13.07.2019, 18:29  [ТС] 19
Цитата Сообщение от Humanoid Посмотреть сообщение
Замените на sizeof(GPSFixData.Latitude). Потому что вы указываете размер указателя, который в 32-битной системе всегда равен 4.
Спасибо вам!!!!!

Добавлено через 49 минут
Humanoid, А, если у нас координата вида FPSFixData.Latitude = 03259.498, чтобы ее привести к виду 32.991633 (59.498/60= 0.991633..)
я должен взять из переменной FPSFixData.Latitude элементы с третего по последний преобразовать в int и /60?? Или это не адекватно?
0
38 / 31 / 9
Регистрация: 29.03.2019
Сообщений: 345
14.07.2019, 19:40  [ТС] 20
вот так можно преобразовать из nmea в градусы. У меня получилось.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
 
    char buf[10];
    int Angle;
    float Min;
       memset(buf,0,10);
    
    strncpy(buf,GPSFixData.Latitude,2);
     Angle = atoi(buf);
    strncpy(buf,GPSFixData.Latitude+2,7);
     Min = atof(buf);
    GPSFixData.lat  = Angle + (Min/60.0f);
 
    memset(buf,0,10);
    
    strncpy(buf,GPSFixData.Longitude,3);
    Angle = atoi(buf);
    strncpy(buf,GPSFixData.Longitude+3,7);
    Min = atof(buf);
    GPSFixData.lon = Angle + (Min/60.0f);
только в структуре тремя постами выше добавил
C
1
2
 float lat;
    float lon;
В общем работает. Теперь координаты в градусах.

Humanoid, но возникла проблема. Теперь float не записать адекватно в
C
1
f_write(&fil, &GPSFixData.lat, sizeof(GPSFixData.lat), &bw);
в логах , что то вроде того..
160618 ШлoB F”тA

с этим пока не знаю, что делать...

Добавлено через 10 минут
надо, как то побайтно, что ли передавать
0
14.07.2019, 19:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.07.2019, 19:40
Помогаю со студенческими работами здесь

Внешняя память PIC: как нарастить внутреннюю память данных?
Я только начал разбираться с ПИКами и пока не все понимаю. Мне нужно организовать систему сбора и...

Внешняя память программ
Скажите кто нибудь цеплял внешнюю память программ к АТ89С51/52? Расскажите как это сделать, в гугле...

Внешняя память данных.
Требуется работать с внешней памятью (ROM). Не могу найти внятного описания карты внешней памяти....

Внешняя оперативная память
Народ кто цеплял? У меня 8515, хочу подсоеденить 64 кб. В даташитах рекомендуют использовать...

Внешняя память для AVR?
Всем привет! Посоветуйте способ организации внешней памяти, примерно 1-2 Мб, точно еще не...

Flash память
Здравствуйте, хотел бы задать вопрос по флешь памяти. Мне дана задача в зависимости от того на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru