|
STN32F107 SYSCLK = 72 MHz, частота USART1 |
|
|
|
Nov 15 2013, 19:36
|

Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
Nov 15 2013, 20:22
|
Частый гость
 
Группа: Участник
Сообщений: 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
|
|
|
|
|
Nov 15 2013, 21:01
|

Гуру
     
Группа: Модераторы
Сообщений: 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)
|
|
|
|
|
Nov 16 2013, 08:18
|
Гуру
     
Группа: Свой
Сообщений: 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++) {
}
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Nov 16 2013, 11:58
|

фанат дивана
     
Группа: Свой
Сообщений: 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. То есть, вы вынуждаете людей, которые хотят вам помочь, лезть в даташиты. Этим вы сильно снижаете вероятность того, что вам помогут. (Да и вам потом самому свой код читать будет тяжело).
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 16 2013, 13:14
|
Гуру
     
Группа: Свой
Сообщений: 2 246
Регистрация: 17-03-05
Из: Украина, Киев
Пользователь №: 3 446

|
Цитата(AHTOXA @ Nov 16 2013, 13:58)  У вас не включено тактирование альтернативных функций ног: Код RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; (В примере от Genadi Zawidowski это есть) Не помогло. А на счет даташитов, то куда без них?
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Nov 16 2013, 14:40
|

фанат дивана
     
Группа: Свой
Сообщений: 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.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Nov 18 2013, 07:15
|
Гуру
     
Группа: Свой
Сообщений: 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. Надеюсь заработает. А на счет замечания, конечно так читабельнее. Но я уже натыкался на ошибочные дефайны и времени на то, чтоб это обнаружить уходило немало. Так что доверие подорвано. Единственное, это самому проверять перед тем как в код вставлять. Но как по мне так это лишние хлопоты когда даташит уже перед глазами. Впрочем для взгляда со стороны конечно Ваше предложение удобнее.
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
|
Nov 18 2013, 15:23
|
Гуру
     
Группа: Свой
Сообщений: 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))); } Уже все перебрал, проверил. Все прописывется как надо и куда надо. Даташит перечитал. Не работает, но по всем меркам должно. Что может быть не так?
--------------------
Живи днем так, чтобы ночью ты спал спокойно.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|