Форум РадиоКот https://radiokot.ru/forum/ |
|
Помогите начинающему армовводу :) Пара вопросов опытным https://radiokot.ru/forum/viewtopic.php?f=59&t=148614 |
Страница 1 из 2 |
Автор: | clawham [ Пн сен 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 *) █ // if (ptr == NULL) // { // goto error; // } // visnet tut memset(ptr, SD_DUMMY_BYTE, sizeof(uint8_t) * BlockSize); */ ptr = (uint8_t *) █ //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 вот такая микруха но в ней внутри батарейка и она типа не забывает содержимое при отключении но батарейка подключается при первой подаче питания и это неоратимо - тоесть по сути попробовав я её убью т.к. она мне пока не нужна в том виде что она есть. а батарейку внутреннюю не поменяеш ведь. |
Автор: | Reflector [ Вт сен 26, 2017 09:18:00 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
подключил я на макетке проводками микруху статической памяти из кеша 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 в названии - это в килобитах. |
Автор: | clawham [ Вт сен 26, 2017 10:46:31 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
в том то и дело что ног нормально ![]() уточнение - не от 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 мегагерц? но всеравно мне кажется будет глючить. |
Автор: | Reflector [ Вт сен 26, 2017 10:56:11 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
в том то и дело что ног нормально ![]() У меня есть W24512A, из кеша 486, 32 ноги, 64КБ, 1-2 ноги неподключены, а на 30-й висит второй CS2(у bq4015 там A17). |
Автор: | clawham [ Вт сен 26, 2017 11:00:28 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
ОППА! А вот это инфа! Спасибо! попробую. очень похоже что у меня 17-я нога - просто чип селект бо пока там нуль - на выходе рамы просто мусор! спасибо большое!! вечером попробую ! впринципе мне и 64 кила хватит но конечно хочется побольше чтоб не грузить следующий кадр из флеши каждый раз а только один раз при включении прошил рамку и потом уже только с неё плюешся на выход. |
Автор: | Reflector [ Вт сен 26, 2017 11:37:26 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
тоесть чисто в теории в земляную ногу каждой микрухи может прилететь в районе пол ампера. и это на дикой частоте и любыми возможными гармониками. или стоит сбавить скорости и оставить спи на 14 мегагерц? но всеравно мне кажется будет глючить. В теме про осциллограф на STM32 разгоняли SPI на F103 до 64MHz и по нему экран работал, правда на 3V, но 28MHz должно тянуть в любом случае. |
Автор: | clawham [ Вт сен 26, 2017 13:26:45 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
экран находится в 5 мм от пинов проца и экран сразу расчитан на 3 вольта и экран впринципе не высоконагруженное током устройство. вдумайтесь в задачу! Три длинных узких линейки по 6 TLC впаралель! все на одной земле и тянут каждая по 16 светиков 10 милиампер НА ЗЕМЛЮ а земля у неё один единственный пин! на пузе нет земли!! конечно я землю сделаю огромной ширины и пропаяю/пролужу. конечно я и постараюсь трассировать плату так чтоб небыло разных расстояний от земли до сигнальных линий. но 6 TLC впаралель. а до платы - обязательно шлейфик 3-4 см длиною и таких плат спаралель - 3!!! а у меня уже на 5 см шлейфике до единственной TLC нагруженной 6-ю светиками всего и уже появляются иногда глюки! вот и вопрос - а что я делаю не так? А может надо задуматься над выходами с открытым колектором а на +5 тянуть внешними резюками? просто порог у TLC 2.6 вольт и когда проц питался от 3.2 и проводок был длиннее 4 см - постоянно лампочки дрыгали яркостью хотя я в них слал одну и ту же яркость. когда же поднял до 3.6 вольт питание и укоротил проводок - глюки пропали! вот и вопрос - эт я неправильно SPI модуль настроил или всетаки изза высокой частоты таки будут проблемы? |
Автор: | pashok675 [ Ср сен 27, 2017 13:45:35 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
Здравствуйте, уважаемые! ![]() Спойлер#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;//сброс флага прерывание } } |
Автор: | dosikus [ Ср сен 27, 2017 14:50:42 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
pashok675, покажите в чем сделан проект и расширение у файла main . Подключен ли стартап? |
Автор: | clawham [ Ср сен 27, 2017 14:59:01 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
По вопросу с внешней оперативкой - вопрос решен ! Спасибо большое 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 - никакой разницы. |
Автор: | dosikus [ Ср сен 27, 2017 15:04:34 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
clawham, един в двух лицах?????????? |
Автор: | clawham [ Ср сен 27, 2017 15:34:49 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
упс...видать чтото не так понял..не видел что Вы отписывались другому человеку ![]() pashok675 уж сорри...но даже я новичек не люблю магических цыфар. если уж вам надо установить 8-й бит в регистре то так и напишите 1<<8 а не 0х374689 |
Автор: | oleg110592 [ Ср сен 27, 2017 15:58:50 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
для 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 } |
Автор: | clawham [ Чт сен 28, 2017 07:33:46 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
И снова у меня затык. причем уже на финишной прямой. Вчера поднял таймеры для замера периода полного оборота и для генерации промежуточных точек(частота об/с * 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 и запустить дальше то второй вайл проходит. но если оно туда попадет то уже не выходит ![]() Как это так-то? уже написал так Код: while(LineTimerUpdEn == 0) { __nop(); __nop(); __nop(); __nop(); __nop(); } и в отладчике он всеравно постоянно гуляет по этому нопу хотя в переменной LineTimerUpdEn уже натюкало за 100 ! Как так то? В прерывания оно попадает. переменные инкрементирует а выйходить из цикла ожидания не выходит! ЧЯДНТ?!?! это ж простейшая фигня! |
Автор: | Reflector [ Чт сен 28, 2017 07:42:31 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
Код: volatile char LineTimerUpdEn = 0;
|
Автор: | clawham [ Чт сен 28, 2017 14:02:31 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
Reflector Спасибо! Почитал осмыслил ошибку понял . Сразу видно что человек с атмеги пересел - там нет никаких кеширований оптимизаций и регистров - память доступна сразу в один такт В общем и целом - работает! успевает отрабатывать до 30 герц перерисовки! это очень много и очень круто..теперь соберу макет с одной линейкой и посмотрю как по стабильности - говорят надо не один холл на оборот а больше чтоб стабильнее было |
Автор: | Reflector [ Чт сен 28, 2017 14:22:23 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
Сразу видно что человек с атмеги пересел - там нет никаких кеширований оптимизаций и регистров - память доступна сразу в один такт Мега и кеширования тут не при чем, компилятор видит, что переменная в цикле не модифицируется потому выполняет простейшую оптимизацию, грузит в регистр ее значение из памяти один раз, а не при каждой итерации. На AVR, если абстрагироваться от всего разнообразия компиляторов и их настроек, было бы то же самое, если, конечно, данная переменная не будет всегда храниться в регистре. |
Автор: | clawham [ Чт сен 28, 2017 17:45:27 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
у меня порядка 280-ти проектов под атмеги тиньки и просее. все на сях. есть пара на freertos / писал на том же кейле для авр. ниразу никаких приколов подобных небыло! так же в самом начале пару проектов делал на иаре - аналогично работало все прекрасно и уж тем более такие тупленияы во флаг.в кодевижн авр вообще все много проще - там есть тип переменной бит - который 100% в регистре и 100% проверяется в один такт. На большом компьютере я пишу на C# и там аналогично такого нет но правда я там семафорами пользуюсь - на большом компьютере ресурсы для атмеговода - неограничены ![]() ![]() Сейчас попробовал пустую прошивку сгенерить только моргать таймером через такой флаг. - стек ноль куча ноль переменная одна единственная - работает без volatile ![]() |
Автор: | Reflector [ Чт сен 28, 2017 18:48:36 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
Не знаю что там у тебя за проекты, но зайди в любую достаточно большую тему связанную с программированием на AVR и найдешь там ошибки связанные с отсутствием volatile. Вот, например. И в C# volatile же не просто так присутствует, просто многие там с ним никогда не сталкиваются, т.к. для этого нужно писать достаточно специфичные многопоточные приложения. |
Автор: | clawham [ Чт сен 28, 2017 20:33:21 ] |
Заголовок сообщения: | Re: Помогите начинающему армовводу :) Пара вопросов опытным |
там авр студио и GCC - я его один раз попробовал не понравилось и ушел на иар а потом и на кеил. проектов много и на прерываниях и на флагах но да - взял за привычку юзать битовые операции SBI CBI а при обьявлении битового массива - писать её в регистры - потому скорее всего и небыло проблем. хотя сейчас вот открыл проект на 90% атмеги 128 + 65 кб рам - вконце обьявил переменную чар без волатила - она записалась во внешней памяти! и ничо - с прерывания обновляется и из цикла выходит ![]() ![]() |
Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |