Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Помогите начинающему армовводу :) Пара вопросов опытным

Пн сен 25, 2017 22:28:23

Здравствуйте!
Сюда я пришел из соседней ветки viewtopic.php?f=57&t=148469

В общем аврка никак не справлялась и я решил попробовать STM32А100RBT6 на отладочной плате STM VL Discovery

Итак - проц от встроенного гены умножитель 6. разгона пока не касаемся.
использую CubeMX для инициализации и HAL для работы с периферией. удалось подключить 44780 spi sdcard TLC5940. все работает и летает. Файлы читаются спи шуршит через ДМА, экранчик пляшет

Но есть несколько проблем:
1) очень долго искал драйвер spi dscard под fatfs - нашел какой-то шилд адафрут и к нему исходник.
В общем в процедуре
Код:
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)

идет обращение к флешке через вот такой кусок кода
Спойлер
Код:
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
{
    HAL_StatusTypeDef status = HAL_OK;

    /* Check the communication status */
    status = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*) DataIn, DataOut, DataLegnth, SpixTimeout);
   if (status != HAL_OK)
   {
      /* Execute user timeout callback */
      SPIx_Error();
   }   
}


логично предположить что читать 512 байтные буферы и писать их же - будет быстрее через дма? ок не вопрос - настраиваю кубом так же как на spi2 делал - DMA только там был один канал на передачу а тут поднял оба канала на прием и передачу, сгенерил под них прерывания и обработчики прерывания а процедуру обмена переписал вот так

Спойлер
Код:
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
{
    HAL_StatusTypeDef status = HAL_OK;
   if(DataLegnth<65)
   {
      status = HAL_SPI_TransmitReceive(&hspi1, (uint8_t*) DataIn, DataOut, DataLegnth, SpixTimeout);
             if (status != HAL_OK)
      {
         /* Execute user timeout callback */
         SPIx_Error();
      }
   }
   else
   {
      status = HAL_SPI_TransmitReceive_DMA(&hspi1, (uint8_t*) DataIn, DataOut, DataLegnth);
      if (status != HAL_OK)
      {
         /* Execute user timeout callback */
         SPIx_Error();
      }
      while(HAL_DMA_GetState(&hdma_spi1_tx) != HAL_DMA_STATE_READY);
   }   
}


Тоесть сделал сначала только на дма. потом понял что 1-3-5 байт кидать через дма некомильфо - сделал вот таким образом то так то сяк. В общем оно-то работает но 29 мегабайт читаются без дма за 19 секунд а с дма - 110 секунд. минимум что добивался - 90 секунд!!! как так-то? при этом больше ничем проц не занимался! что я делал тут не так?

Дальше второй вопрос - библиотека адафрутовая иногда в непонятных местах зависала на чтении файлов. просто ни с того ни с сего то на 512 байте считанном тормозило то ещё где. жутко долго искал где и что но в итоге нашел команду:

файл adafruit_sd
Спойлер
Код:
/**
 * @brief  Reads block(s) from a specified address in the SD card, in polling mode.
 * @param  pData: Pointer to the buffer that will contain the data to transmit
 * @param  ReadAddr: Address from where data is to be read
 * @param  BlockSize: SD card data block size, that should be 512
 * @param  NumOfBlocks: Number of SD blocks to read
 * @retval SD status
 */
uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
{
    uint32_t offset = 0;
    uint8_t retr = BSP_SD_ERROR;
    uint8_t *ptr = NULL;
    SD_CmdAnswer_typedef response;
    uint8_t block[BlockSize];

      
   
    /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and
     Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */
    response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED);
    SD_IO_CSState(1);
    SD_IO_WriteByte(SD_DUMMY_BYTE);
    if (response.r1 != SD_R1_NO_ERROR)
    {
        goto error;
    }
      
/* это я закоментил      

    //ptr = malloc(sizeof(uint8_t) * BlockSize);
    ptr = (uint8_t *) &block;
//    if (ptr == NULL)
//    {
//        goto error;
//    }

      // visnet tut
   
    memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t) * BlockSize);
   
*/
   
   ptr = (uint8_t *) &block;
   //memset(ptr, SD_DUMMY_BYTE,  BlockSize);

      
      
    /* Data transfer */
    while (NumberOfBlocks--)
    {
        /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */
        /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
        response = SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, (ReadAddr + offset) / (flag_SDHC == 1 ? BlockSize : 1), 0xFF,
                SD_ANSWER_R1_EXPECTED);
        if (response.r1 != SD_R1_NO_ERROR)
        {
            goto error;
        }

        /* Now look for the data token to signify the start of the data */
        if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK)
        {
            /* Read the SD block data : read NumByteToRead data */
            SD_IO_WriteReadData(ptr, (uint8_t*) pData + offset, BlockSize);

            /* Set next read address*/
            offset += BlockSize;
            /* get CRC bytes (not really needed by us, but required by SD) */
            SD_IO_WriteByte(SD_DUMMY_BYTE);
            SD_IO_WriteByte(SD_DUMMY_BYTE);
        }
        else
        {
            goto error;
        }

        /* End the command data read cycle */
        SD_IO_CSState(1);
        SD_IO_WriteByte(SD_DUMMY_BYTE);
    }

//    if (ptr != NULL)
//        free(ptr);
    retr = BSP_SD_OK;

    error:
    /* Send dummy byte: 8 Clock pulses of delay */
    SD_IO_CSState(1);
    SD_IO_WriteByte(SD_DUMMY_BYTE);
      
//    if (ptr != NULL)
//        free(ptr);

    /* Return the reponse */
    return retr;
}


в этой процедурке зависало на строке
Код:
memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t) * BlockSize);


заремил её и вроде как все полетело и без проблем! а что не так с этит мемсетом? это ж просто очистка буффера!? что тут я сделал не так?


Дальше ещё интереснее. Ок разобрался с флешкой и спи - как-то работает.

подключил я на макетке проводками микруху статической памяти из кеша 386-го компьютера(или 486 - не уверен)
Микруха называется MAGIC MG12512-15K/ Никакого внятного шита на неё я не нашел потому просто расключил как обычную срам 512 киловую.
D0-D7 - на порт А0-А7 проца один-в-один
ну а адреса младшие 16 - на PORTC0-15 16 17 и 18 бит адреса завел на PORTD.0 PORTD.1 и PORTB.6 - естественно ноги на выход макс скорость и т.д.

ну и написал процедурку установки собственно адреса
Спойлер
Код:
void Ram_SetAddr(uint32_t addr)
{
   GPIOC->ODR = addr&0xFFFF;
   
   if(addr&(1<<16))
   {
      HAL_GPIO_WritePin(RamA16_GPIO_Port, RamA16_Pin, GPIO_PIN_SET);
      
   }
   else
   {
      HAL_GPIO_WritePin(RamA16_GPIO_Port, RamA16_Pin, GPIO_PIN_RESET);
      
   }
   
   if(addr&(1<<17))
   {
      HAL_GPIO_WritePin(RamA17_GPIO_Port, RamA17_Pin, GPIO_PIN_SET);
      
   }
   else
   {
      HAL_GPIO_WritePin(RamA17_GPIO_Port, RamA17_Pin, GPIO_PIN_RESET);
      
   }
   
   if(addr&(1<<18))
   {
      HAL_GPIO_WritePin(RamA18_GPIO_Port, RamA18_Pin, GPIO_PIN_SET);
      
   }
   else
   {
      HAL_GPIO_WritePin(RamA18_GPIO_Port, RamA18_Pin, GPIO_PIN_RESET);
      
   }
}


Она вроде как работает - если записать нуль - все ноги падают в ноль. мерял тестером на микрухе. если записать 524287 - все ноги поднимаются на +
Да микруху питал и 3.3 вольтами и 5-ю. вроде арм мой толерантен?

Так вот. Дальше написал процедурку чтения и записи в эту память

Спойлер
Код:
void RamDelay()
{
   uint16_t a=0;
   for(a=0;a<20;a++)
   {
      
   }
}

void Ram_Write(char* buf, uint32_t addr, uint32_t length)
{
   uint32_t EndAddr = addr + length;
   char data=0;
   uint32_t ClrA = 0xFF << 16;
   GPIO_InitTypeDef GPIO_InitStruct;
   
   //HAL_GPIO_WritePin(RamCE_GPIO_Port, RamCE_Pin, GPIO_PIN_SET);
   Ram_CE_1
   Ram_OE_1
   
   /*
   
   GPIO_InitStruct.Pin = RamA14_Pin|RamA15_Pin|RamA16_Pin|RamA0_Pin
                          |RamA1_Pin|RamA2_Pin|RamA3_Pin|RamA4_Pin
                          |RamA5_Pin|RamA6_Pin|RamA7_Pin|RamA8_Pin
                          |RamA9_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
   
   
   */
   
   
   GPIO_InitStruct.Pin = RamD0_Pin|RamD1_Pin|RamD2_Pin|RamD3_Pin
                   |RamD4_Pin|RamD5_Pin|RamD6_Pin|RamD7_Pin;
                  
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
   GPIOA->BSRR = ClrA;
   
   do
   {
      Ram_CE_1
      Ram_SetAddr(addr);
      
      data = *buf;
      
      GPIOA->BSRR = data&0xFF;
      
      RamDelay();
      
      Ram_CE_0
      
      Ram_WE_0
      
      RamDelay();
      
      Ram_WE_1
      
      buf++;
      
      GPIOA->BSRR = ClrA;
      
      addr++;
   }while(addr<EndAddr);
   
   GPIOA->BSRR = ClrA;
   GPIOC->BSRR = (uint32_t)(0xFFFF)<<16;   
}


void Ram_Read(char* buf, uint32_t addr, uint32_t length)
{
   uint32_t EndAddr = addr + length;
   uint32_t ClrA = 0xFF;
   uint32_t ClrC = 0xFFFF;
   
   GPIO_InitTypeDef GPIO_InitStruct;
   
   ClrA = ClrA<<16;
   ClrC = ClrC<<16;
   
   //HAL_GPIO_WritePin(RamCE_GPIO_Port, RamCE_Pin, GPIO_PIN_SET);
   Ram_CE_1
   Ram_OE_1
      
   GPIO_InitStruct.Pin = RamD0_Pin|RamD1_Pin|RamD2_Pin|RamD3_Pin
                   |RamD4_Pin|RamD5_Pin|RamD6_Pin|RamD7_Pin;
                  
   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
   //GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
   GPIO_InitStruct.Pull = GPIO_NOPULL;
   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
   
   GPIOA->BSRR = ClrA;
   
   do
   {
       Ram_CE_1
      
      Ram_SetAddr(addr);
      
      //GPIOA->BSRR = data&0xFF;
      
      Ram_CE_0
      
      Ram_OE_0
      
      RamDelay();
      
      *buf = GPIOA->IDR&0xFF;
      
      Ram_CE_1
      
      Ram_OE_1      
      
      buf++;
      addr++;
      
   }while(addr<EndAddr);
   *buf = 0;
   
   GPIOA->BSRR = ClrA;
   GPIOC->BSRR = ClrC;   
}


Намудрил конечно много но то уже в попытках выискать глюка. короче оно вроде как работает но не так как хотелось. сначала я подключил её по адресам абы-как и по данным абы-как - для оперативки то разницы нет - что и куда запишем то оттуда потом и прочитаем! Но получились странные глюки
https://www.dropbox.com/sh/85fzdvaxd7eq ... Hty0a?dl=0 ramin - то что я читал с флешки(я его и на экран выводил так что там читалось красиво и в отладчике на шине данных осцилом и логанализером байты смотрел - все как и положено).

а вот то что записывалось на карту в качестве считываемых данных с памяти - полный швах! сказать что там чтото не так? ну вроде ниногда куски текста проскакивают. но иногда какие-то крякозяблы причем таким образом как вроде там нет атких адресов.

Ок психанул и переконектил макетку один-в-один PORTA.0 на А0 рамы и атк далее - один-в-один битик к битику..макетка стала конечно ёжиком но картина кряков изменилась!
стало вот так
https://www.dropbox.com/sh/71p745dutnai ... JCJxa?dl=0

нуок думаю мож дохлая рама? пошел наковырял ещё одну.

картина немного поменялась но кардинально не улучшилось!

https://www.dropbox.com/sh/ihx5vlfk6kn6 ... 8McTa?dl=0


Какие могут у кого быть идеи что я делаю не так?

Весь исходник под CubeMX и Keil uVision тут https://www.dropbox.com/s/vzl5drljh0so1dw/2.rar?dl=0

С этой пролемой долюлюсь второй день - ничего на ум не приходит. рамы где-то взять ну хз где именно срамки взять да ещё на такой обьем. Есть в наличии всего одна https://media.digikey.com/pdf/Data%20Sh ... Q4015(Y,LY)_Rev_Apr_2014.pdf вот такая микруха но в ней внутри батарейка и она типа не забывает содержимое при отключении но батарейка подключается при первой подаче питания и это неоратимо - тоесть по сути попробовав я её убью т.к. она мне пока не нужна в том виде что она есть. а батарейку внутреннюю не поменяеш ведь.
Последний раз редактировалось clawham Вт сен 26, 2017 10:48:05, всего редактировалось 2 раз(а).

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Вт сен 26, 2017 09:18:00

подключил я на макетке проводками микруху статической памяти из кеша 386-го компьютера(или 486 - не уверен)
Микруха называется MAGIC MS12512-15K/ Никакого внятного шита на неё я не нашел потому просто расключил как обычную срам 512 киловую.
D0-D7 - на порт А0-А7 проца один-в-один
ну а адреса младшие 16 - на PORTC0-15 16 17 и 18 бит адреса завел на PORTD.0 PORTD.1 и PORTB.6 - естественно ноги на выход макс скорость и т.д.

Сколько ног у этой MS12512-15K? Если это память с кеша 386/486, то она наверняка на 64КБ, а 512 в названии - это в килобитах.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Вт сен 26, 2017 10:46:31

в том то и дело что ног нормально :) у MAGIC MG12512-15K - ровно 32 ноги! точно так же как и у bq4015

уточнение - не от 486 а от амд к6 233 их там 4 штуки были.


Ещё попутно возник вопрос схемотехнического характера!

У меня STM32F100RBT6 - он 3.3 вольта имеет питание. я поднял до 3.6. но TLC5940 - она 5-тивольтовая чтоб на GSCLK выдерживать 56 мегагерц! а мне надо очень большая частота шима. Так вот вопрос - плата контроллера будет одна и вынесена в небольшую отдельную герметичную коробочку а три платы лучей - будут шлейфиком подключаться к ней. Проблема в том что даже на расстояниях в макетной плате иногда появляются артефакты во внутреннем регистре при передаче данных. частота проца 56 мегагерц, делитель спи 2. я вот побаиваюсь - а сможет ли проц вытянуть столько микросхем впаралель? все 6 микрух на каждой линии да *3 линии это 18 микросхем у которых много запаралеленных ног:
1) GSCLK 56 мегагерц,
2)XLAT (одиночный импульс 100 us 2-8 килогерц)
3) BLANK - перезапуск счетного регистра 14 килогерц 100 микросекунд импульс
4) SCK - клок для сдвигового регистра - 28 мегагерц квадрат.

потянет ли это безобразие выходы моего арма? может какие-то шинные буфферы надо поставить? или вообще скоростных фетов на выход проца поставить чтоб линии эти на землю тянули а шину около каждой TLCшки 10-20 омами на +5 подтягивать?

Как подобные задачи вообще решаются? ток светиков у меня будет настроенный 12 миллиампер но синему и зеленому шим заполнение никогда не будет выше 1/4 чтоб уровнять яркость - красный светик мало выдает люмен.
тоесть чисто в теории в земляную ногу каждой микрухи может прилететь в районе пол ампера. и это на дикой частоте и любыми возможными гармониками. или стоит сбавить скорости и оставить спи на 14 мегагерц? но всеравно мне кажется будет глючить.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Вт сен 26, 2017 10:56:11

в том то и дело что ног нормально :) у MAGIC MG12512-15K - ровно 32 ноги! точно так же как и у bq4015

У меня есть W24512A, из кеша 486, 32 ноги, 64КБ, 1-2 ноги неподключены, а на 30-й висит второй CS2(у bq4015 там A17).

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Вт сен 26, 2017 11:00:28

ОППА! А вот это инфа! Спасибо! попробую. очень похоже что у меня 17-я нога - просто чип селект бо пока там нуль - на выходе рамы просто мусор! спасибо большое!! вечером попробую ! впринципе мне и 64 кила хватит но конечно хочется побольше чтоб не грузить следующий кадр из флеши каждый раз а только один раз при включении прошил рамку и потом уже только с неё плюешся на выход.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Вт сен 26, 2017 11:37:26

тоесть чисто в теории в земляную ногу каждой микрухи может прилететь в районе пол ампера. и это на дикой частоте и любыми возможными гармониками. или стоит сбавить скорости и оставить спи на 14 мегагерц? но всеравно мне кажется будет глючить.

В теме про осциллограф на STM32 разгоняли SPI на F103 до 64MHz и по нему экран работал, правда на 3V, но 28MHz должно тянуть в любом случае.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Вт сен 26, 2017 13:26:45

экран находится в 5 мм от пинов проца и экран сразу расчитан на 3 вольта и экран впринципе не высоконагруженное током устройство. вдумайтесь в задачу!
Три длинных узких линейки по 6 TLC впаралель! все на одной земле и тянут каждая по 16 светиков 10 милиампер НА ЗЕМЛЮ а земля у неё один единственный пин! на пузе нет земли!! конечно я землю сделаю огромной ширины и пропаяю/пролужу. конечно я и постараюсь трассировать плату так чтоб небыло разных расстояний от земли до сигнальных линий. но 6 TLC впаралель. а до платы - обязательно шлейфик 3-4 см длиною и таких плат спаралель - 3!!! а у меня уже на 5 см шлейфике до единственной TLC нагруженной 6-ю светиками всего и уже появляются иногда глюки! вот и вопрос - а что я делаю не так? А может надо задуматься над выходами с открытым колектором а на +5 тянуть внешними резюками? просто порог у TLC 2.6 вольт и когда проц питался от 3.2 и проводок был длиннее 4 см - постоянно лампочки дрыгали яркостью хотя я в них слал одну и ту же яркость. когда же поднял до 3.6 вольт питание и укоротил проводок - глюки пропали! вот и вопрос - эт я неправильно SPI модуль настроил или всетаки изза высокой частоты таки будут проблемы?

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Ср сен 27, 2017 13:45:35

Здравствуйте, уважаемые! :) Пытаюсь изучать микроконтроллеры stm32 и писать код в качестве практики с использованием CMSIS. Для изучения взял stm32f103c8t6. Для начала попробовал задать свои настройки тактирования и помигать светодиодом в прерывании по переполнению таймера TIM4. В качестве источника тактирования выбрал HSE кварц 8 МГц, задал частоту системной шины 72 МГц, частоту периферии 18 МГц. Инициализировал таймер, пины. При отладке обнаружил первый косяк, программа не входит в прерывание таймера, хотя флаг устанавливается. Далее попытался помигать светодиодом по флагу прерывания в бесконечном цикле и заметил вторую проблему, мигание происходит не с той частотой. Что я делаю не так?

Спойлер#include "stm32f10x.h"

uint32_t time;

void TIM4_IRQHandler(void)//обработчик прерывания переполнения 4 таймера
{
GPIOC->ODR ^=0x2000;
TIM4->SR &=~0x1;//сброс флага прерывание
}

int main(void)
{

RCC->CR |=0x10000; //включение HSE, HSEON
while((RCC->CR&0x20000)==0)//ожидание готовности HSE, HSERDY
{}
RCC->CFGR &=~0x20000; //очистка бита PLLXTPRE
RCC->CFGR |=0x10000;// HSE без делителя, PLL_SRC
RCC->CFGR &=~0x3;//очистка битов SW
RCC->CFGR |=0x1; //установка источника для sysclk HSE, SW
RCC->CR &=~0x1000000; //выключение PLL, PLLON
RCC->CFGR &=~(0x3C0000); //очистка PLLMUL, PLLMUL
RCC->CFGR |=0x1C0000; //установка умножителя частоты 9, PLLMUL
RCC->CR |=0x1000000;//включение PLL, PLLON
while((RCC->CR&0x2000000)!=0x2000000)//чтение бита готовности PLL, PLLRDY
{}
RCC->CFGR ^=0x3; // установка источника тактирования SYSCLK от PLL, SW
while((RCC->CFGR&0x8)!=0x8)//ожидание готовности ,SWS
{}
RCC->CR ^=0x1;//выключение HSI, HSION
RCC->CR &=0xFFFFFF07;//выключение калибровки HSI, HSITRIM
RCC->CFGR |=0x500;//включение делителя на 4, PPRE1
RCC->APB2ENR |=0x30;
RCC->APB2ENR |=0x4;
RCC->APB1ENR |=0x4; //включение тактирования 4 таймера
TIM4->DIER |=0x1; //включение прерывания по переполнению
TIM4->PSC |=35999; //установка предделителя на 36000
TIM4->ARR =999; //установка значения автоматической перезагрузки на 1000
GPIOC->CRH =0x200000;
NVIC_EnableIRQ (TIM4_IRQn);//включение прерываний от таймера 4
TIM4->CR1 |=0x1; //запуск таймера
TIM4->SR &=0x0;// сброс флага прерывания обновления таймера 4
__enable_irq ();





while(1)
{
if((TIM4->SR &0x1)==0x1)
{
GPIOC->ODR ^=0x2000;
TIM4->SR =0x0;//сброс флага прерывание
}
}

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Ср сен 27, 2017 14:50:42

pashok675, покажите в чем сделан проект и расширение у файла main .
Подключен ли стартап?

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Ср сен 27, 2017 14:59:01

По вопросу с внешней оперативкой - вопрос решен ! Спасибо большое Reflector ! действительно 512 килобит. ну а те два пина что у Вашей микры НЦ у моей - вызывают какую-то кашу если они не в нуле! короче добился скорости 4 мегабайта в секунду чтения и 1850 килобайт в секунду записи. Запись особо не оптимизировал так как скорость записи вообще не принципиальна а вот над чтением поколдовал.

dosikus , проект простой - открыл STM32CubeMX, выбрал свой проц, натыкал пинаут и модулей, сконфигурировал как надо, в опциях выставил Кеил и сгенерил результат.
дальше уже кейл открыл свой проект сгенеренный и собственно так я его и развиваю.
файл main так и называется main.c
стартам на ассемблере есть - отображается в кейле. кейл просто скачал с офсайта последнюю версию и при открытии проекта кубового - он сам накачал библиотек.

https://www.dropbox.com/s/oje7imsx84ryrpz/2_1.rar?dl=0 обновленный проект

Возникла новая проблема с флешкой..ну тоесть это кагбэ не проблема - просто глюк или фича - иногда запись из оперативки на флешку происходит как и чтение с флешки в оперативку - 200 милисекунд но иногда запись тормозится до скорост 7 секунд н 65 килобайт файл. флешки перепробовал 5 разных с разными фроматами и размерами кластеров. примерное соотношение - каждый 5-й раз записывается быстро а остальные медленно - не то что мне это мешает - скорость записи на флешку никак у меня не лимитированны просто непонятно почему так медленно? и почему иногда - быстро? Естественно я пробовал дма не дма и разгон не разгон и разные частоты SPI - никакой разницы.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Ср сен 27, 2017 15:04:34

clawham, един в двух лицах??????????

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Ср сен 27, 2017 15:34:49

упс...видать чтото не так понял..не видел что Вы отписывались другому человеку :) Гы сори.

pashok675 уж сорри...но даже я новичек не люблю магических цыфар. если уж вам надо установить 8-й бит в регистре то так и напишите 1<<8 а не 0х374689

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Ср сен 27, 2017 15:58:50

для pashok675
давно с F1 экспериментировал - нашел у себя такую настройку тактирования, не помню работало ли
Спойлер
Код:
void InitClk()
{
    unsigned long int TimeOut = 10000;
    //Запустить HSE
    RCC->CR   |=  RCC_CR_HSEON;            //Включить генератор HSE
    while((RCC->CR & RCC_CR_HSERDY)==0)    //Ожидание готовности HSE
        if(TimeOut) TimeOut--;
    if(TimeOut==0) return;               //Ошибка!!! Генератор HSE не запустился
    RCC->CR   |=  RCC_CR_CSSON;            //Разрешить работу системы защиты сбоя HSE
    RCC->CFGR &= ~RCC_CFGR_PLLXTPRE;       //Не использовать делитель HSE
    //Частота  SystemCoreClock выше 24 MHz - разрешить буфер предварительной выборки FLASH
    FLASH->ACR|=  FLASH_ACR_PRFTBE;        //Включить буфер предварительной выборки
    FLASH->ACR&= ~FLASH_ACR_LATENCY;       //Очистить FLASH_ACR_LATENCY
    FLASH->ACR |= FLASH_ACR_LATENCY_2;     //Пропускать 2 такта
    //Настройка PLL
    RCC->CFGR  |= RCC_CFGR_PLLSRC;         //Источником сигнала для PLL выбран HSE
    RCC->CR   &= ~RCC_CR_PLLON;            //Отключить генератор PLL
    RCC->CFGR &= ~RCC_CFGR_PLLMULL;        //Очистить PLLMULL
    RCC->CFGR |=  RCC_CFGR_PLLMULL9;       //Коефициент умножения = 9
    RCC->CR   |=  RCC_CR_PLLON;            //Включить генератор PLL
    while((RCC->CR & RCC_CR_PLLRDY)==0) {} //Ожидание готовности PLL
    //Переключиться на тактирование от PLL
    RCC->CFGR &= ~RCC_CFGR_SW;             //Очистка битов выбора источника тактового сигнала
    RCC->CFGR |=  RCC_CFGR_SW_PLL;         //Выбрать источником тактового сигнала PLL
    while((RCC->CFGR&RCC_CFGR_SWS)!=0x08) {} //Ожидание переключения на PLL
    //Настроить делитель для шины APB1
    RCC->CFGR &= ~RCC_CFGR_PPRE1;          //Очистка битов предделителя "APB1 Prescaler"
    RCC->CFGR |=  RCC_CFGR_PPRE1_DIV4;     //Установить "APB1 Prescaler" равным 4
    //Настроить делитель для шины APB2
    RCC->CFGR &= ~RCC_CFGR_PPRE2;          //Очистка битов предделителя "APB2 Prescaler"
    RCC->CFGR |=  RCC_CFGR_PPRE2_DIV4;     //Установить "APB2 Prescaler" равным 4
}

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 07:33:46

И снова у меня затык. причем уже на финишной прямой. Вчера поднял таймеры для замера периода полного оборота и для генерации промежуточных точек(частота об/с * 128). Свел все модули в одну картину и все завертелось.
таймер два настроен как захват ноги + на отрицательный перепад - сброс самого же себя в ноль - нереально удобно - в атмегах этого очень не хватало.
В регистре сразу получаю период вращения в делителе второго таймера. только первый делит такт процессора на 1536 а второй делит такт процессора на 12. Ну и естественно включены прерывания по ICR и обновлению таймера.
В случае прихода импульса - срабатывает сначала прерывание захвата а потом прерывание обновления(что таймер в нуль стал)
так я флагами ловлю - был импульс входной или таймер просто переполнился.

во втором таймере просто глобальную переменную char инкрементирую.
В начале main.c написал
Код:
char LineTimerUpdEn = 0;


потом в меине ж прописал обработчик прерывания
Код:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) 
{
  if(htim->Instance == TIM3)
  {
     LineTimerUpdEn++;
    
     if(GPIOA->ODR & GPIO_PIN_12)
     {
        GPIOA->BSRR = GPIO_PIN_12<<16;       
     }
     else
     {
        GPIOA->BSRR = GPIO_PIN_12;       
     }
  }
}


воот ну и в основном цикле в конче передачи пакета из оперативки - просто жду
Код:
while(HAL_DMA_GetState(&hdma_spi2_tx) != HAL_DMA_STATE_READY);

while(LineTimerUpdEn == 0);
LineTimerUpdEn=0;


Так вот вчера весь вечер чпокался с этим последним ожиданием флага!
Неужели так делать нельзя? он все время крутится в этом вайле! но в отладчике если прогу тормознуть на предыдущем ожидании dma и запустить дальше то второй вайл проходит.
но если оно туда попадет то уже не выходит :) при этом светик на ноге a12 моргает 64 герцами как положено, в отладчике переменная увеличивается. а оно сидит в вайле!
Как это так-то?
уже написал так
Код:
while(LineTimerUpdEn == 0)
{
__nop();
__nop();
__nop();
__nop();
__nop();
}


и в отладчике он всеравно постоянно гуляет по этому нопу хотя в переменной LineTimerUpdEn уже натюкало за 100 ! Как так то? В прерывания оно попадает. переменные инкрементирует а выйходить из цикла ожидания не выходит! ЧЯДНТ?!?! это ж простейшая фигня!

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 07:42:31

Код:
volatile char LineTimerUpdEn = 0;

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 14:02:31

Reflector Спасибо!
Почитал осмыслил ошибку понял . Сразу видно что человек с атмеги пересел - там нет никаких кеширований оптимизаций и регистров - память доступна сразу в один такт

В общем и целом - работает! успевает отрабатывать до 30 герц перерисовки! это очень много и очень круто..теперь соберу макет с одной линейкой и посмотрю как по стабильности - говорят надо не один холл на оборот а больше чтоб стабильнее было

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 14:22:23

Сразу видно что человек с атмеги пересел - там нет никаких кеширований оптимизаций и регистров - память доступна сразу в один такт

Мега и кеширования тут не при чем, компилятор видит, что переменная в цикле не модифицируется потому выполняет простейшую оптимизацию, грузит в регистр ее значение из памяти один раз, а не при каждой итерации. На AVR, если абстрагироваться от всего разнообразия компиляторов и их настроек, было бы то же самое, если, конечно, данная переменная не будет всегда храниться в регистре.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 17:45:27

у меня порядка 280-ти проектов под атмеги тиньки и просее. все на сях. есть пара на freertos / писал на том же кейле для авр. ниразу никаких приколов подобных небыло! так же в самом начале пару проектов делал на иаре - аналогично работало все прекрасно и уж тем более такие тупленияы во флаг.в кодевижн авр вообще все много проще - там есть тип переменной бит - который 100% в регистре и 100% проверяется в один такт. На большом компьютере я пишу на C# и там аналогично такого нет но правда я там семафорами пользуюсь - на большом компьютере ресурсы для атмеговода - неограничены :) Также писал немного под КПК и андроид - аналогично - подобные циклы проходили на ура :)

Сейчас попробовал пустую прошивку сгенерить только моргать таймером через такой флаг. - стек ноль куча ноль переменная одна единственная - работает без volatile :) видимо всетаки оптимизации + много использовнаной памяти (7.2 кб на текущий момент):)

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 18:48:36

Не знаю что там у тебя за проекты, но зайди в любую достаточно большую тему связанную с программированием на AVR и найдешь там ошибки связанные с отсутствием volatile. Вот, например. И в C# volatile же не просто так присутствует, просто многие там с ним никогда не сталкиваются, т.к. для этого нужно писать достаточно специфичные многопоточные приложения.

Re: Помогите начинающему армовводу :) Пара вопросов опытным

Чт сен 28, 2017 20:33:21

там авр студио и GCC - я его один раз попробовал не понравилось и ушел на иар а потом и на кеил.

проектов много и на прерываниях и на флагах но да - взял за привычку юзать битовые операции SBI CBI а при обьявлении битового массива - писать её в регистры - потому скорее всего и небыло проблем. хотя сейчас вот открыл проект на 90% атмеги 128 + 65 кб рам - вконце обьявил переменную чар без волатила - она записалась во внешней памяти! и ничо - с прерывания обновляется и из цикла выходит :) яхз что я делаю не так там :) но теперь то уж буду знать что volatile просто обязателен для переменных с множественным доступом из нескольких потоков
Ответить