Перейти к содержанию

Delau

Members
  • Постов

    7
  • Зарегистрирован

  • Посещение

Электроника

  • Стаж в электронике
    1-2 года

Достижения Delau

Новичок

Новичок (1/14)

  • Неделя на форуме
  • Месяц на форуме
  • Год на форуме

Последние значки

0

Репутация

  1. Да, точно, спасибо за подсказку!
  2. Применил вот такой вариант: float x; uint8_t *p_x = (uint8_t *) &x; uint8_t a, b, c, d; uint32_t abcd; a = *p_x; b = *(p_x+1); c = *(p_x+2); d = *(p_x+3); abcd = (a)|(b<<8)|(c<<16)|(d<<24); и обратно a = (uint8_t) abcd; b = ((abcd & 0xFF00)>>8); c = ((abcd & 0xFF0000)>>16); d = ((abcd & 0xFF000000)>>24); *p_x = a; *(p_x+1) = b; *(p_x+2) = c; *(p_x+3) = d; В первой части программы объявлен указатель на переменную х. Затем переменным a, b, c, d присваиваются значения по указателю (адрес инкрементируется), потом, в abcd складываются все байты. Обратное преобразование аналогично. Проверил. Всё работает.
  3. Всем привет! Пытаюсь записать во flash числа float. Пишутся только положительные. Отрицательные записываются просто как четыре байта нулей. Применяю SPLовскую ф-цию FLASH_ProgramWord(uint32_t Address, uint32_t Data). Я прекрасно понимаю что аргумент передаваемый этой функции есть uint32_t, а я пытаюсь туда передать float. Поэтому и пишется ноль. Отсюда вопрос, как привести float к uint32? Или может ещё какой вариант записи есть?
  4. Т.е. фактически у меня всё правильно. Только через объявление структуры глобально. Спасибо за ответ.
  5. Всем привет! В рамках моей задачи есть необходимость изменять значение переменной в прерывании (да в прочем распространённое явление). Всё бы хорошо если бы проект не состоял из нескольких библиотек (file.c, file.h тоже распространённое явление ). Обычно библиотека создаётся с максимальным уровнем абстракции, что в свою очередь приводит к необходимости объявлять аргументы в функции в виде указателей. Всё хорошо - объявил, к примеру, структуру, и передал её адрес в функцию, обработал и забыл. НО, как быть если функция вызывается в обработчике прерывания?! У меня получилось только через объявление структуры глобально (extern), тогда понятно что она доступна в любом месте программы (в любом файле). И мне это ох как не нравиться. Не нравиться потому что появляется глобальная переменная. Начал я детально изучать STMовские библиотеки, ибо там я свободно вызываю функцию в обработчике прерывания без передачи аргументов. И вот что получилось, на примере TIM6. В файле stm32f10x.h объявлена структура: typedef struct { __IO uint16_t CR1; uint16_t RESERVED0; __IO uint16_t CR2; и т. д. } TIM_TypeDef; далее в нём же пошли такие дефайны: #define PERIPH_BASE ((uint32_t)0x40000000) #define APB1PERIPH_BASE PERIPH_BASE #define TIM6_BASE (APB1PERIPH_BASE + 0x1000) #define TIM6 ((TIM_TypeDef *) TIM6_BASE) Теперь файл stm32f10x_tim.h #include "stm32f10x.h" void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState); И наконец файл stm32f10x_tim.c #include "stm32f10x_tim.h" void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) { if (NewState != DISABLE) { /* Enable the TIM Counter */ TIMx->CR1 |= TIM_CR1_CEN; } else { /* Disable the TIM Counter */ TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN)); } } Теперь я могу в абсолютно любом месте программы сделать вызов, допустим так: TIM_Cmd(TIM6, ENABLE); Хоть в обработчике прерывания хоть где ещё. Я не объявляю глобальных структур! Давайте посмотрим на мою задачу. В h-файле объявлена структура: typedef struct { usart_status_TypeDef status; uint32_t baudrate; //9600 or 115200 uint8_t *p_tx_buf; и т. д. } usart_init_struct_TypeDef; в с-файле есть функция: void usart_it_handler(usart_init_struct_TypeDef *usart_struct) { if (USART_GetITStatus (USART1, USART_IT_TC)) { //здесь куча всяких вызовов и далее самое главное usart_struct->status = transmit_complete; //это одно из полей вышеобъявленной структуры }; }; Теперь обработчик прерывания. с-файл: void USART1_IRQHandler(void) { usart_it_handler(&usart_struct); }; И работает всё это только при условии что структура usart_struct будет глобальной т. е. я её объявляю в файле main и в файле с обработчиками прерываний (extern)/ Разница между моим и STMовским кодом заключается в том что у них есть привязка к физическим адресам периферии, а у меня нет. Как сделать код похожим на STMовский? Чтобы можно было вызывать функцию в любом месте программы без объявления глобальных структур.
  6. Я ещё раз просмотрел Reference manual. Вот информация касательно transmition complete: After writing the last data into the USART_DR register, wait until TC=1. This indicates that the transmission of the last frame is complete. This is required for instance when the USART is disabled or enters the Halt mode to avoid corrupting the last transmission Косвенно указывает на то, что прерывание срабатывает после записи (передачи) последнего байта. Я ничего не записываю. If a frame is transmitted (after the stop bit) and the TXE bit is set, the TC bit goes high. An interrupt is generated if the TCIE bit is set in the USART_CR1 register. After writing the last data into the USART_DR register, it is mandatory to wait for TC=1 before disabling the USART or causing the microcontroller to enter the low power mode (see Figure246: TC/TXE behavior when transmitting) TC устанавливается после передачи. Я ничего не передаю. Я просто включаю USART. У меня даже физические вывода не сконфигурированные. Есть ещё информация по сбросу флага. Это собственно всё. Проц у меня STM32F100
  7. Добрый день форумчане! После включения USART, через 1,25 mS приходит прерывание по завершению передачи. Помогите понять почему так происходит? Это нормально или нет? В код введены тестовые пины. По активности PC13 я и вижу вход в прерывание. Но, если я правильно понимаю, этого быть не должно. #include "stm32f10x.h" #include "stm32f10x_usart.h" GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStruct; void USART1_IRQHandler(void) { if (USART_GetITStatus (USART1, USART_IT_TC)) { GPIO_SetBits(GPIOC, GPIO_Pin_13); // test pin USART_ClearITPendingBit(USART1, USART_IT_TC); GPIO_ResetBits(GPIOC, GPIO_Pin_13); // test pin }; }; int main (void) { RCC_DeInit(); RCC_HSICmd(DISABLE); RCC_LSICmd(DISABLE); RCC_HSEConfig(RCC_HSE_ON); while (RCC_WaitForHSEStartUp()==ERROR); RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1); RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_3); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); RCC_PLLCmd(ENABLE); while (RCC_GetSYSCLKSource() != 0x08) {}; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOC, &GPIO_InitStruct); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_2; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); GPIO_SetBits(GPIOC, GPIO_Pin_0); // test_pin USART_Cmd(USART1, ENABLE); USART_ClearFlag(USART1, USART_FLAG_TC); USART_ClearITPendingBit(USART1, USART_IT_TC); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3; NVIC_Init(&NVIC_InitStruct); USART_ITConfig(USART1, USART_IT_TC, ENABLE); while (1) { }; }; К сожалению осцилограмма не прикрепляется
×
×
  • Создать...