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

Здравствуйте, уважаемые форумчане!

 

Существует плата с неким функционалом для работы с пк через usb. Используемый мк был msp430, а теперь решили перейти на stm. И при первоначальных тестах у меня возникли 2 проблемы. Первая проблема - это отправка данных с платы через уарт на пк. На прием все работало хорошо. Открыл список регистров, выяснилось что в регистр USART1->DR не записываются данные. Решил проверить, запишется ли значение в usart2->dr. Добавил код настройки 2го уарта, запустил... и обнаружил, что в оба уарта теперь вообще ничего не записывается, ни в один регистр. Попытался убрать код, проблема осталась. Собственно, это 2 проблема. Используемый код

#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
int i;

char* trans_dist;
int trans_n, trans_cur;
char flag_1 = 0;
char text_1[]={'h','e','l','l','o'};

void Transmit_data(char* source, int n)
{
int i=0;
for(;i<n;i++)
{
	//volatile char temp;
	USART1->SR &= ~USART_SR_TC;
	while(!(USART1->SR & USART_SR_TXE));
	USART1->DR = *source;
	//temp = USART1->DR;
	++source;
	if (i==(n-1))
		flag_1 = 0;
}
}



int main(void)
{
RCC->CR|=RCC_CR_HSION; 
while (!(RCC->CR & RCC_CR_HSIRDY));
RCC->CFGR &=~RCC_CFGR_SW; 
RCC->CFGR |= RCC_CFGR_SW_HSI; 

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
GPIOA->CRL |= GPIO_CRL_CNF1_0 | GPIO_CRL_CNF2_1 | GPIO_CRL_MODE2_1 | GPIO_CRL_CNF4_1 | GPIO_CRL_MODE4_1 | 
	GPIO_CRL_CNF5_0 | GPIO_CRL_CNF6_0 | GPIO_CRL_CNF7_0;
GPIOA->CRL &= ~(GPIO_CRL_CNF2_0 | GPIO_CRL_CNF4_0);
GPIOA->CRH |= GPIO_CRH_CNF9_1 | GPIO_CRH_MODE9_1 | GPIO_CRH_CNF10_0 | GPIO_CRH_CNF12_1 | GPIO_CRH_MODE12_1;
GPIOA->CRH &= ~(GPIO_CRH_CNF9_0 | GPIO_CRH_CNF12_0);
GPIOB->CRL |= GPIO_CRL_MODE0_1 | GPIO_CRL_MODE1_1 | GPIO_CRL_MODE2_1;
GPIOB->CRH |= GPIO_CRH_MODE10_1 | GPIO_CRH_MODE12_1 | GPIO_CRH_CNF13_0;
GPIOC->CRH |= GPIO_CRH_CNF13_0;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);
USART1->BRR = (8000000+19200/2)/19200;
USART1->CR1 |= USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
USART1->CR1 |= USART_CR1_UE;
//USART2->BRR = (8000000+19200/2)/19200;
//USART2->CR1 |= USART_CR1_RXNEIE | USART_CR1_TE | USART_CR1_RE;
//USART2->CR1 |= USART_CR1_UE;
NVIC_EnableIRQ(USART1_IRQn);

while(1)
{
	if (flag_1)
		Transmit_data(text_1, 5);
	//USART1->DR |= 49;
}
}
void USART1_IRQHandler(void)
{
//char t;
if(USART1->SR & USART_SR_RXNE)
{
	flag_1 = 1;
	USART1->SR &= ~USART_SR_RXNE;
	//t = USART1->DR;
}
if(USART1->SR & USART_SR_TXE)
{
	//USART1->SR &= ~USART_SR_TXE;
}
}

PA2 и PA3 - выход и вход для usart2, PA9 и PA10 - выход и вход для usart1

Среда: CooCox CoIDE 1.6.2, мк: stm32f100c4

Интересно ваше мнение по поводу обеих проблем.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У вас вроде бы GPIO настроены не верно.

Все альтернативные порты USART должны быть настроены как alternative push pull (и RX и TX линии).

И в функции передатчика вы делаете сброс битов не рекомендованным способом, из чего вывод - лучше используйте библиотеки ST, особенно в настройке GPIO это актуально - код нечитаем, оттого и ошибки. Тем более, библиотеки у вас подключены уже как видно из команд подачи тактирования на USART.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в регистр USART1->DR не записываются данные.

Почему вы решили что не записываются? Записали, потом считали и сравнили с тем что записывали?

Но USARTx->DR - это на самом деле 2 независимых регистра. При записи это регистр данных передатчика, при чтении - регистр данных приёмника. В общем случае прочтённое из этого регистра не равно тому что только что в него было записано.

Отмечу что отладчик не имеет магического способа доступа к регистрам, он их пишет и читает так же как и программа процессорного ядра. Просмотр USARTx->DR в отладчике приводит к потере принятых данных, так как при этом флаг наличия данных сбрасывается.

Все альтернативные порты USART должны быть настроены как alternative push pull (и RX и TX линии).

Нет, RX должна быть настроена как вход или вход с подтяжкой.

TX - да, alternative push pull (но при необходимости можно и alternative open drain).

Изменено пользователем maksimp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

kan35, maksimp спасибо что откликнулись

И в функции передатчика вы делаете сброс битов не рекомендованным способом, из чего вывод - лучше используйте библиотеки ST, особенно в настройке GPIO это актуально - код нечитаем, оттого и ошибки. Тем более, библиотеки у вас подключены уже как видно из команд подачи тактирования на USART.

Настройка GPIO сделана вручную из-за того, что есть некоторые выводы должны быть настроены как "push-pull", другие как "input floating". Недавно сел за CooCox, необходимой функции настройки не нашел, а GPIO_Init не подходит.

По поводу сброса битов - это да, спасибо.

Но USARTx->DR - это на самом деле 2 независимых регистра. При записи это регистр данных передатчика, при чтении - регистр данных приёмника. В общем случае прочтённое из этого регистра не равно тому что только что в него было записано.

Отмечу что отладчик не имеет магического способа доступа к регистрам, он их пишет и читает так же как и программа процессорного ядра. Просмотр USARTx->DR в отладчике приводит к потере принятых данных, так как при этом флаг наличия данных сбрасывается.

По поводу регистра DR - каюсь, видимо плохо читал документацию, буду перечитывать, может и ещё что найду. А вот по поводу отладчика сам бы нескоро догадался, спасибо.

И все-таки, чем могла быть вызвана вторая проблема и можно ли ее как то исправить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте! Я тоже недавно начал разбираться с STM32, так что подсказать мало чем смогу, но мою настройку рабочего USART с радостью предоставлю, может поможет...

#define USART_DBG_GPIO			  GPIOA
#define USART_DBG_GPIO_CLK		  RCC_APB2Periph_GPIOA
#define USART_DBG_RxPin			 GPIO_Pin_10
#define USART_DBG_TxPin			 GPIO_Pin_9

void USART_Configure(unsigned int baudrate) 
{
 GPIO_InitTypeDef  GPIO_InitStructure;
 USART_InitTypeDef USART_InitStructure;

 /* Enable GPIO and USART_DBG clock */
 RCC_APB2PeriphClockCmd(USART_DBG_GPIO_CLK | USART_DBG_CLK | RCC_APB2Periph_AFIO, ENABLE);

 /* Configure USART_DBG Tx  */
 GPIO_InitStructure.GPIO_Pin = USART_DBG_TxPin;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   // Скорость обновления пина
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	  //	Режим - альтернативный Push-Pull
 GPIO_Init(USART_DBG_GPIO, &GPIO_InitStructure);	 

 /* Configure USART_DBG Rx */
 GPIO_InitStructure.GPIO_Pin = USART_DBG_RxPin;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; // Режим - Открытый вход
 GPIO_Init(USART_DBG_GPIO, &GPIO_InitStructure);

 /* Caonfigure USART parameters*/
 USART_InitStructure.USART_BaudRate = baudrate;
 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
 USART_InitStructure.USART_StopBits = USART_StopBits_1;
 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(USART_DBG, &USART_InitStructure);	 
 USART_Cmd(USART_DBG, ENABLE);
 USART_SendData(USART_DBG,'A');					// Отправляем символ А в порт
}

 

Еще один # define забыл ))

 

Необходимо добавить

 

#define USART_DBG_CLK RCC_APB2Periph_USART1

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Elcarnado

спасибо за пример, но я уже пробовал настраивать уарт через USART_Init, не помогло.

Ещё вопрос, по конкретнее, существует ли биты блокировки настройки USART'а? Я правда таких не нашел, но думаю стоит спросить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

существует ли биты блокировки настройки USART'а?
Это биты, отключающие его тактирование. Без тактирования ни один из регистров писаться не будет, читаться будут нули. Других нету.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

существует ли биты блокировки настройки USART'а?

Ещё есть регистры сброса периферии RCC_APB1RSTR и RCC_APB2RSTR (п. 7.3.4, 7.3.5 в reference manual). Если выставить в них бит в то работа соответствующего модуля блокируется.

 

Добавил код настройки 2го уарта, запустил... и обнаружил, что в оба уарта теперь вообще ничего не записывается, ни в один регистр.

Вы разрешили прерывания от USART2, но обработчик прерывания не написали.

Прерывание происходит, флаг прерывания не сбрасывается, прерывание снова тут же проиходит и т.д. Программа перестаёт выполняться.

 

Изменено пользователем maksimp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Всем спасибо, кто ответил, извиняюсь, что так долго не писал.

Вобщем 2 проблема решилась загрузкой другой прошивки, написанной, собственно, по примеру Elcarnado. Потом была залита предыдущая прошивка, настройка уарта работает.

В чем была причина так и не разобрались. Второй уарт также был проверен (косвенно), похоже что ситуация такая же, как и с первым.

maksimp

Как я писал, настройка 2 уарта делается, по крайней мере, причина была не в прерываниях.

Изменено пользователем THI

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте друзья.

Инициализировал USART1 (МК STM32F100C4T6) при помощи стандартной библиотеки STDLib

	GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStructure;


#if !defined REMAP_USART1
// Включаем тактирование порта А и USART1
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// Настраиваем ногу TxD (PA9) как выход push-pull c альтернативной функцией
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);

#else
/** USART1 GPIO Configuration	
	 PB6	 ------> USART1_TX
	 PB7	 ------> USART1_RX
*/

/*Enable or disable APB2 peripheral clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);

/*Configure GPIO pin */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure GPIO pin */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStruct);

/*Configure peripheral I/O remapping */
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
#endif	
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 9600*2;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);

/* Enable the USART1 */
USART_Cmd(USART1, ENABLE);

/* Enable USART1 Receive and send interrupts */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	 
USART_ITConfig(USART1, USART_IT_TC, ENABLE);

NVIC_EnableIRQ(USART1_IRQn); 			// Разрешение прерывания USART1

 

Но вот символьная скорость вместо 9600 бод как заказывал, в 2 раза меньше. В чем может быть причина?

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Открыл исходник (stm32f10x_usart.c) там в функции USART_Init(...) обнаружен такие строчки :

/* USART OverSampling-8 Mask */
#define CR1_OVER8_Set             ((u16)0x8000)  /* USART OVER8 mode Enable Mask */
#define CR1_OVER8_Reset           ((u16)0x7FFF)  /* USART OVER8 mode Disable Mask */


if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
  {
    /* Integer part computing in case Oversampling mode is 8 Samples */
    integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));    
  }
  else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
  {
    /* Integer part computing in case Oversampling mode is 16 Samples */
    integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));    
  }

 

Кто объяснит, где в регистре USART_CR1 бит (CR1_OVER8) ???

 

 

Разобрался, для корректной работы с SPL нужно определить HSE_VALUE (частоту внешнего кварца), если это значение не определено, то из файла STM32f10x.h подставляется дефолтное:

#if !defined  HSE_VALUE
#ifdef STM32F10X_CL   
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#else 
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* STM32F10X_CL */
#endif /* HSE_VALUE */

Изменено пользователем Rimsky

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Кто объяснит, где в регистре USART_CR1 бит (CR1_OVER8) ???

Reference manual только и объяснит. Читали?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Reference manual только и объяснит. Читали?

 

Читал, только в МК STM32F100C4T6 такого бита в регистре USART_CR1 нет.

 

В прочем с этим я разобрался. :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В прочем с этим я разобрался. :)

И какое же правильный ответ?

Определить HSE_VALUE?

 

1. По поводу OVER8.

В других МК он есть на месте 15 бита. В F100 он жестко обнулен, что соответствует 16 выборкам.

Позицию бита можно было узнать из RM на дригие МК или по маске из библиотеки.

В RM на ваш МК можно найти фразу, что начиная с 14 бита по 31 в регистре CR1 железные нули.

 

2. По поводу HSE_VALUE.

Я не фанат стандартной библиотеки, но когда только она появилась и долгое время после имел

некоторые проблемы как раз с HSE_VALUE. Дело в том, что для внешнего кварца у STM приняты

стандартные значения в 8 или 25 МГц, а я (уж так сложилось исторически) применяю кварцы на

12 МГц. Делители библиотека рассчитывает исходя из заданного HSE_VALUE и стандартного для

указанного семейства кварца. Я правил код библиотеки под себы, но это великое зло.

Интересно, это до сих пор так? (вопрос разобравшемуся человеку :))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

 

1. По поводу OVER8.

В других МК он есть на месте 15 бита. В F100 он жестко обнулен, что соответствует 16 выборкам.

Позицию бита можно было узнать из RM на дригие МК или по маске из библиотеки.

В RM на ваш МК можно найти фразу, что начиная с 14 бита по 31 в регистре CR1 железные нули.

В общем так я и поступил. Смутило то, что SPL взято с stm32gui_lib в котором идет явная привязка к МК STM32F10x....

 

2. По поводу HSE_VALUE.

Я не фанат стандартной библиотеки, но когда только она появилась и долгое время после имел

некоторые проблемы как раз с HSE_VALUE. Дело в том, что для внешнего кварца у STM приняты

стандартные значения в 8 или 25 МГц, а я (уж так сложилось исторически) применяю кварцы на

12 МГц. Делители библиотека рассчитывает исходя из заданного HSE_VALUE и стандартного для

указанного семейства кварца. Я правил код библиотеки под себы, но это великое зло.

Интересно, это до сих пор так? (вопрос разобравшемуся человеку :))

В расчете baud rate для USARTA есть вызов процедуры RCC_GetClocksFreq(&RCC_ClocksStatus); Которая инициализирует значения структуры RCC_ClocksStatus элементы которой участвуют в расчете. В этой процедуре и фигурирует определение HSE_VALUE. Если оно не соответствует Вашему кварцу, то и расчет будет не верным. У меня кварц на 4096000, что отличается от дефолтного в 2 раза, вот тут то и были грабли.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...