реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> STN32F107 SYSCLK = 72 MHz, частота USART1
smk
сообщение Nov 15 2013, 18:52
Сообщение #1


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Пытаюсь запустить отладку по USART. Как ни считаю USART1->BRR а все никак не могу получить нормальную передачу. Принимается совсем не то, передается. Раньне как-то на stm32f207 такой проблемы небыло. Что не так? Спасибо.
Код
void USART1_Init (void)
{
    unsigned int integerdivider, tmpreg, fractionaldivider;


    RCC->APB2ENR |= (1u<<2);
  /* Configure PA9 as alternate function push-pull */
    GPIOA->CRH &= ~(1u<<6);
    GPIOA->CRH |=(1u<<4)|(1u<<5)|(1u<<7);        
  /* Configure PA10 as input */
    GPIOA->CRL &= ~((1u<<8)|(1u<<9)|(1u<<11));
    GPIOA->CRL |=(1u<<10);        

  /* Determine the integer part */
  integerdivider = ((0x19 * fclk) / (0x04 * (115200)));
  tmpreg = (integerdivider / 0x64) << 0x04;
  /* Determine the fractional part */
  fractionaldivider = integerdivider - (0x64 * (tmpreg >> 0x04));
  tmpreg |= ((((fractionaldivider * 0x10) + 0x32) / 0x64)) & ((uint8_t)0x0F);
  /* Write to USART BRR */
// USARTx->BRR = (unsigned short)tmpreg;
    
    RCC->APB2ENR |= (1u<<14);
    USART1->BRR = (unsigned short)tmpreg;//313UL; //115200
    USART1->CR1 |= (1UL<<2)|(1UL<<3)|(1UL<<13);
}

void BYTE_Transmit_USART1 (unsigned char data)
{
    USART1->DR = data;
    while (!(USART1->SR & (1UL << 6)));
    USART1->SR &= ~(1UL << 6);    
}

//это передача.
for(i=0; i<10; i++)
{
BYTE_Transmit_USART1(0xAA);
}


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Nov 15 2013, 19:36
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



У меня (для stm32f1xx) вот так считается:

Код
    /* для устройств на шине APB2 (up to 72 MHz) */
    static uint_fast32_t
    calcdivround_apb2(
        int_fast32_t freq        /* требуемая частота на выходе делителя, в герцах. */
        )
    {
        return (APB2_FREQ + freq / 2) / freq;
    }

....

Код
    USART1->BRR = calcdivround_apb2(baudrate);        // младшие 4 бита - это дробная часть.

инициализация:

Код
    RCC->APB2ENR |= RCC_APB2ENR_USART1EN; // Включение тактирования USART1.


    USART1->CR1 |= (USART_CR1_RE | USART_CR1_TE); // Transmitter Enable & Receiver Enables


    RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;     //включить тактирование альтернативных функций

    arm_hardware_pioa_periphout_altfn2(GPIO_ODR_ODR9, 255);    // TX DATA line (2 MHz)
    arm_hardware_pioa_inputs(GPIO_ODR_ODR10);        // RX data line

    NVIC_EnableIRQ(USART1_IRQn);        // enable USART1_IRQHandler();

    USART1->CR1 |= USART_CR1_UE; // Включение USART1.
т.е., 4 дробных бита в делителе позволяют не учитывать oversampling на 16 в аппаратуре контроллера при расчёте скорости, а просто записатть результат деления тактовой частоты периферии на baud rate. Естественно, программирвоание делителя делать после включения этого периферийного устройства.

зы: BYTE_Transmit_USART1 сами придумали? Жестоко... Вы что, микропроцессор впервые в жизни увидели? Всегда делается просто - проверяется готовность, выводим байт. Бит готовности в этом регистре сбрасываается сам...

Да, мне ещё недавно встретился компилятор для ARM, который unsigned short считал 8-битным. Искренне надеюсь, что у вас не это поделие.
Ну и до кучи, в том компиляторе размер Int переключался в опциях проекта на 2/4 байта.

Сообщение отредактировал Genadi Zawidowski - Nov 15 2013, 19:36
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 15 2013, 19:36
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Так я и делаю. Уже все перепробовал. Удивление необыкновенное. Должно работать но не работает. Т.е. работает, но baudrate какойто совсем не тот. А передача идет.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Aleksandr Barano...
сообщение Nov 15 2013, 20:22
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 169
Регистрация: 31-08-05
Из: New York
Пользователь №: 8 118



Может такое вставить и посмотреть, чему равна apbclock?

Код
RCC_GetClocksFreq(&RCC_ClocksStatus);
  if ((*(u32*)&USARTx) == USART1_BASE)
  {
    apbclock = RCC_ClocksStatus.PCLK2_Frequency;
  }
  else
  {
    apbclock = RCC_ClocksStatus.PCLK1_Frequency;
  }

  /* Determine the integer part */
  integerdivider = ((0x19 * apbclock) / (0x04 * (USART_InitStruct->USART_BaudRate)));
  tmpreg = (integerdivider / 0x64) << 0x04;

  /* Determine the fractional part */
  fractionaldivider = integerdivider - (0x64 * (tmpreg >> 0x04));
  tmpreg |= ((((fractionaldivider * 0x10) + 0x32) / 0x64)) & ((u8)0x0F);

  /* Write to USART BRR */
  USARTx->BRR = (u16)tmpreg;


--------------------
ASB
Go to the top of the page
 
+Quote Post
1113
сообщение Nov 15 2013, 20:28
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 604
Регистрация: 24-02-06
Из: Москва
Пользователь №: 14 658



Цитата(Aleksandr Baranov @ Nov 15 2013, 23:22) *
и посмотреть, чему равна apbclock?
может быть известная проблема - STM`мовские примеры рассчитаны на частоту кварца 25 МГц, а у вас какая?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 15 2013, 21:01
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (smk @ Nov 15 2013, 21:52) *
CODE
  /* Determine the integer part */
  integerdivider = ((0x19 * fclk) / (0x04 * (115200)));
  tmpreg = (integerdivider / 0x64) << 0x04;
  /* Determine the fractional part */
  fractionaldivider = integerdivider - (0x64 * (tmpreg >> 0x04));
  tmpreg |= ((((fractionaldivider * 0x10) + 0x32) / 0x64)) & ((uint8_t)0x0F);
  /* Write to USART BRR */
// USARTx->BRR = (unsigned short)tmpreg;
Серьезные расчеты.
CODE
    USART1->BRR = (PCLK1_FREQ + TERMINAL_BAUDRATE / 2) / TERMINAL_BAUDRATE;



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 16 2013, 08:18
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



У меня выходит будто USART1->DR = 0xAA;//data; не выполняется. Одни нули на выходе.

Цитата(Сергей Борщ @ Nov 15 2013, 23:01) *
Серьезные расчеты.
Код
    USART1->BRR = (PCLK1_FREQ + TERMINAL_BAUDRATE / 2) / TERMINAL_BAUDRATE;

USART1->BRR = (72000000 + 115200 / 2) / 115200;

Цитата(1113 @ Nov 15 2013, 22:28) *
может быть известная проблема - STM`мовские примеры рассчитаны на частоту кварца 25 МГц, а у вас какая?

25 мгц

После однократной прокрутки нижеприведенного имею в терминале 40 нулевых байт.
Код
            for(i=0; i<10; i++)
                {
                    BYTE_Transmit_USART1(0xAA);
                }

            for(i=0; i<1000000; i++)
                {

                }


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 16 2013, 11:58
Сообщение #8


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



У вас не включено тактирование альтернативных функций ног:
Код
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

(В примере от Genadi Zawidowski это есть)

ЗЫ. И ещё. Выкладывать в форуме код типа
Код
RCC->APB2ENR |= (1u<<14)

вместо
Код
RCC->APB2ENR |= RCC_APB2ENR_USART1EN

- это просто неуважение к участникам форума. Мало кто помнит наизусть, что такое 14й бит в APB2ENR. То есть, вы вынуждаете людей, которые хотят вам помочь, лезть в даташиты. Этим вы сильно снижаете вероятность того, что вам помогут.
(Да и вам потом самому свой код читать будет тяжело).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 16 2013, 13:14
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(AHTOXA @ Nov 16 2013, 13:58) *
У вас не включено тактирование альтернативных функций ног:
Код
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

(В примере от Genadi Zawidowski это есть)


Не помогло. А на счет даташитов, то куда без них?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Nov 16 2013, 13:55
Сообщение #10


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
Не помогло

Приведите изменённый код здесь. Судя по тому, что принимаете на терминале все "0", выход к порту не подключился.

Сообщение отредактировал Genadi Zawidowski - Nov 16 2013, 13:57
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 16 2013, 14:40
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(smk @ Nov 16 2013, 19:14) *
А на счет даташитов, то куда без них?

Неужели вы и правда не понимаете?
Когда я вижу строчку
RCC->APB2ENR |= (1u<<2);
, я без даташита не могу сказать, что включает эта строчка.
А если эта строчка будет выглядеть как
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
, то пойму сразу.
Вы же, когда постите сюда свой код, хотите, чтобы его проверили и поняли?
Думаете, многие полезли в даташит чтобы вам помочь?

Вот у вас ещё ошибка:
Код
  /* Configure PA10 as input */
    GPIOA->CRL &= ~((1u<<8)|(1u<<9)|(1u<<11));
    GPIOA->CRL |=(1u<<10);

биты для конфигурирования PA10 находятся в CRH.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 18 2013, 07:15
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(AHTOXA @ Nov 16 2013, 16:40) *
Неужели вы и правда не понимаете?

Вот у вас ещё ошибка:
Код
  /* Configure PA10 as input */
    GPIOA->CRL &= ~((1u<<8)|(1u<<9)|(1u<<11));
    GPIOA->CRL |=(1u<<10);

биты для конфигурирования PA10 находятся в CRH.

Спасибо, действительно CRH. Надеюсь заработает. А на счет замечания, конечно так читабельнее. Но я уже натыкался на ошибочные дефайны и времени на то, чтоб это обнаружить уходило немало. Так что доверие подорвано. Единственное, это самому проверять перед тем как в код вставлять. Но как по мне так это лишние хлопоты когда даташит уже перед глазами. Впрочем для взгляда со стороны конечно Ваше предложение удобнее.


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 18 2013, 15:23
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(AHTOXA @ Nov 16 2013, 16:40) *
Вот у вас ещё ошибка:
Код
  /* Configure PA10 as input */
    GPIOA->CRL &= ~((1u<<8)|(1u<<9)|(1u<<11));
    GPIOA->CRL |=(1u<<10);

биты для конфигурирования PA10 находятся в CRH.

Не помогло.

А вот это что такое?
Код
arm_hardware_pioa_periphout_altfn2(GPIO_ODR_ODR9, 255);    // TX DATA line (2 MHz)
    arm_hardware_pioa_inputs(GPIO_ODR_ODR10);        // RX data line



Вот код, имеющийся в сухом остатке. Кто подскажет что не так?

Код
    RCC->APB2ENR |= (1u<<0);//AFIOEN: Alternate function I/O clock enable
    RCC->APB2ENR |= (1u<<2);//IOPAEN: I/O port A clock enable
    RCC->APB2ENR |= (1u<<14);//USART1EN: USART1 clock enable

    USART1->BRR = (72000000UL + 115200UL / 2UL) / 115200UL;
    USART1->SR &= ~(1UL << 6);    
    USART1->CR1 |= (1UL<<13);
    USART1->CR1 |= (1UL<<2)|(1UL<<3);//    
    
  /* Configure PA9 as alternate function push-pull */
    GPIOA->CRH &= ~((1u<<4)|(1u<<6));
    GPIOA->CRH |=(1u<<5)|(1u<<7);        
  /* Configure PA10 as input */
    GPIOA->CRH &= ~((1u<<8)|(1u<<9)|(1u<<11));
    GPIOA->CRH |=(1u<<10);            
}

void BYTE_Transmit_USART1 (unsigned char data)
{
    USART1->DR = 0xAA;//data;
    while (!(USART1->SR & (1UL << 6)));
}


Уже все перебрал, проверил. Все прописывется как надо и куда надо. Даташит перечитал. Не работает, но по всем меркам должно. Что может быть не так?


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 18 2013, 17:38
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Сначала настраиваем ноги,
потом настраиваем UART,
и только в самом конце включаем его.
(Биты считать не стал, уж не обессудьте).


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
smk
сообщение Nov 18 2013, 18:17
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446



Цитата(AHTOXA @ Nov 18 2013, 19:38) *
Сначала настраиваем ноги,
потом настраиваем UART,
и только в самом конце включаем его.
(Биты считать не стал, уж не обессудьте).

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


--------------------
Живи днем так, чтобы ночью ты спал спокойно.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 08:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01458 секунд с 7
ELECTRONIX ©2004-2016