STM32F4Discovery UART

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Аватара пользователя
ave101
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Пт янв 02, 2015 14:45:31

STM32F4Discovery UART

Сообщение ave101 »

STM32F4Discovery UART

Рабочий код. Проверено в железе. Под CooCox.

Прием осуществляется в прерывании.
Этот код шпаргалка для разных случаев.

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

#define PLL_M 8 // 149 cтр. cmsis_boot/system_stm32f4xx.c
#define HSE_VALUE ((uint32_t)8000000) // 92 стр. cmsis_boot/stm32f4xx.h

Код: Выделить всё

// STM32F4 UART
// Автор: vk.com/zz555 (11.08.2015)

// USART1 - TX=PA9(PB6), RX=PA10(PB7)
// USART2 - TX=PA2(PD5), RX=PA3(PD6)
// USART3 - TX=PB10(PD8), RX=PB11(PC11)
// UART4  - TX=PA0(PC10), RX=PA1(P11)
// UART5  - TX=PC12, RX=PD2
// USART6 - TX=PC7, RX=PC7

// При создании нового проекта в CooCox в Viev/Repository/Pepipherals поставить только 2 галочки:
// M4 CMSIS core
// CMSIS BOOT

// Нужно изменить 2 значения в системных файлах для настройки частоты от внешнего кварца 8 MHz
// #define PLL_M 		8								// 149 cтр. cmsis_boot/system_stm32f4xx.c
// #define HSE_VALUE    	((uint32_t)8000000)					// 92 стр.  cmsis_boot/stm32f4xx.h

#include "stm32f4xx.h"

// У Stm32f4Discovery есть 4 светодиода на выводах: PD12 (green), PD13 (orange), PD14 (red), PD15 (blue)
#define LED_ON            GPIOD->BSRRL = GPIO_BSRR_BS_15            // PD15 LED ON (пишем в младшие 16 бит, чтобы включить)
#define LED_OFF           GPIOD->BSRRH = GPIO_BSRR_BS_15            // PD15 LED OFF (пишем в старшие 16 бит, чтобы выключить)

uint32_t 	tim_delay;
uint8_t		rx_status;
uint8_t		rx_data;
uint8_t		rx_bit;
uint8_t		rx_buf[64];

// Обработчик прерывания системного таймера, прерывания каждую 1 ms
void SysTick_Handler(void) {
	if (tim_delay != 0) tim_delay--;
}

// Функция временной задержки в милисекундах
void Delay_ms(uint32_t delay) {
	tim_delay = delay;
	while (tim_delay != 0) {
		if (rx_status == 1) return;
	}
}

// Прерывание по приему данных по USART
void USART1_IRQHandler(void) {
	if ((USART1->SR & USART_SR_RXNE) != 0) {						// Если пришло что-то от USART
		rx_data = USART1->DR;										// Считываем то что пришло в переменную
		rx_buf[rx_bit]=rx_data; 									// Помещаем принятый байт в буфер
		if (rx_bit != 64) rx_bit++; else rx_bit=0;					// Наращиваем счётчик байтов буфера
		if (rx_data == 0x0D) rx_status=1;							// Если пришел конец посылки <CR><LF> 0x0D,0x0A (13,10)
	}
}

// Функция отправляет байт в USART
void send_uart(uint_fast8_t data) {
	while (!(USART1->SR & USART_SR_TC));							// Ждем пока бит TC в регистре SR станет 1
	USART1->DR=data;												// Отсылаем байт через UART
}

// Функция отправляет строку в USART
void send_str(char * string) {
	uint8_t i=0;
	while (string[i]) {
		send_uart(string[i]);
		i++;
	}
	send_uart('\r');
	send_uart('\n');
}

// Инициализация stm
void stm_init(void) {
	SystemInit();
	SysTick_Config(168000);											// Запуск прерываний на системном счетчике при частоте 168 MHz - 1ms

	// Инициализация USART1
	RCC->APB2ENR  |= RCC_APB2ENR_USART1EN;
	RCC->AHB1ENR  |= RCC_AHB1ENR_GPIOBEN;
	RCC->AHB1ENR  |= RCC_AHB1ENR_GPIODEN;
	GPIOD->MODER  |= GPIO_MODER_MODER15_0;							// LED (pin out)
	GPIOB->MODER  |= (GPIO_MODER_MODER6_1 | GPIO_MODER_MODER7_1);	// USART1 (TX=PB6, RX=PB7)
	GPIOB->AFR[0] |= 0x77000000;
	USART1->BRR    = 0x222E; 										// 9600
	USART1->CR1   |= USART_CR1_TE; 									// Разрешить передатчик
	USART1->CR1   |= USART_CR1_RE; 									// Разрешить приёмник
	USART1->CR1   |= USART_CR1_UE; 									// Разрешить USART
	USART1->CR1	  |= USART_CR1_RXNEIE;       						// Разрешить прерывание по приему данных
	NVIC_EnableIRQ (USART1_IRQn);           						// Разрешить прерывания от USART1
}

int main(void) {
	stm_init(); 													// Инициализация stm

	while (1) {
		LED_ON;
		Delay_ms(100);												// Задержка 0.1 с
		LED_OFF;
		
		send_str("STM32F4");

		rx_status=0;
		rx_bit=0;
		Delay_ms(1000);												// Задержка 1 с

		// Проверка принятой посылки по UART
		if (rx_status == 1) {
			if (rx_buf[0]=='5') {
				rx_status=0;
				rx_bit=0;
				rx_buf[0]=0;
				send_str("5 OK");									// Ответ "5 OK" при приеме цифры "5"
				Delay_ms(1000);										// Задержка 1 с
			}
		}
	}
}
Изображение
Последний раз редактировалось ave101 Вт авг 11, 2015 17:47:30, всего редактировалось 1 раз.
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: STM32F4Discovery UART

Сообщение dosikus »

ave101 писал(а): // Функция отправляет байт в USART

Код: Выделить всё

	while (!(USART1->SR & USART_SR_TC));							// Ждем пока бит TC в регистре SR станет 1

Bit 6 TC: Transmission complete
This bit is set by hardware if the transmission of a frame containing data is complete and if
TXE is set. An interrupt is generated if TCIE=1 in the USART_CR1 register. It is cleared by
a software sequence (a read from the USART_SR register followed by a write to the
USART_DR register). The TC bit can also be cleared by writing a '0' to it. This clearing
sequence is recommended only for multibuffer communication.
GPIOB->AFR[0] |= 0x77000000;
USART1->BRR = 0x222E; // 9600
С поста и далее http://kazus.ru/forums/showpost.php?p=6 ... stcount=37
Реклама
Ответить

Вернуться в «ARM»