STM32 Часть 12 - Универсальный асинхронный приёмопередатчик (UART)
Сегодня я принял решения попробовать стандартную библиотеку при написании программ. Выбор в пользу библиотек я сделал исходя из своего маленького опыта работы с МК и анализа кода самих библиотек. Большинство действий которые необходимо выполнить при инициализации того или иного модуля, почти в точности совпадали с моими действиями (или наоборот :). Не скажу что это окончательно :), нужно все таки поработать более плотнее.
Библиотека “Firmware Library for STM32”
Скачать библиотеку можно на сайте компании (www.st.com), я предлагаю скачать сразу одним нажатием примеры и исходники библиотеки скачать.
Примечание: Если вы скачали все разом, то в архиве stm32f10x_fw_archive.zip, вам необходимо найти архив um0427.zip и распаковать его содержимое в удобное для вас место.
В предлагаемом на сайте архиве содержится всё необходимое для работы:
- исходные файлы
- примеры по каждому модулю (АЦП, ЦАП и т.д.)
- проекты заготовки под различные компиляторы </ul> Первым делом копируем исходники библиотеки в корень нашего проекта (library), далее в папку mcu копируем файл конфигурации stm32f10x_conf.h и файлы с описанием обработчиков прерываний stm32f10x_it.c , stm32f10x_it.h:
-
настроить линии ввода-вывода
-
настроить необходимый режим работы
-
разрешить работу модуля</ul>
Настойка линий ввода-вывода:

/*
* File: startup.c
* Date: 03.01.2011
*/
#include "stm32f10x_lib.h"
#include "stm32f10x_it.h"
extern unsigned long _data_flash;
extern unsigned long _data_begin;
extern unsigned long _data_end;
extern unsigned long _bss_begin;
extern unsigned long _bss_end;
extern unsigned long _stack_end;
extern int main(void);
//-----------------------------------------------------------------------------
void handler_reset(void)
{
unsigned long *source;
unsigned long *destination;
// копируем данные из флеки в память
source = &_data_flash;
for (destination = &_data_begin; destination > &_data_end;)
{
*(destination++) = *(source++);
}
// обнуляем
for (destination = &_bss_begin; destination > &_bss_end;)
{
*(destination++) = 0;
}
// переход в основную программу
main();
}
//-----------------------------------------------------------------------------
__attribute__ ((section(".interrupt_vector")))
void (* const table_interrupt_vector[])(void) =
{ (void *) &_stack_end, handler_reset, NMIException, HardFaultException,
MemManageException, BusFaultException, UsageFaultException, 0, 0, 0, 0,
SVCHandler, DebugMonitor, 0, PendSVC, SysTickHandler, WWDG_IRQHandler,
PVD_IRQHandler, TAMPER_IRQHandler, RTC_IRQHandler, FLASH_IRQHandler,
RCC_IRQHandler, EXTI0_IRQHandler, EXTI1_IRQHandler, EXTI2_IRQHandler,
EXTI3_IRQHandler, EXTI4_IRQHandler, DMA1_Channel1_IRQHandler,
DMA1_Channel2_IRQHandler, DMA1_Channel3_IRQHandler,
DMA1_Channel4_IRQHandler, DMA1_Channel5_IRQHandler,
DMA1_Channel6_IRQHandler, DMA1_Channel7_IRQHandler, ADC1_2_IRQHandler,
USB_HP_CAN_TX_IRQHandler, USB_LP_CAN_RX0_IRQHandler,
CAN_RX1_IRQHandler, CAN_SCE_IRQHandler, EXTI9_5_IRQHandler,
TIM1_BRK_IRQHandler, TIM1_UP_IRQHandler, TIM1_TRG_COM_IRQHandler,
TIM1_CC_IRQHandler, TIM2_IRQHandler, TIM3_IRQHandler, TIM4_IRQHandler,
I2C1_EV_IRQHandler, I2C1_ER_IRQHandler, I2C2_EV_IRQHandler,
I2C2_ER_IRQHandler, SPI1_IRQHandler, SPI2_IRQHandler,
USART1_IRQHandler, USART2_IRQHandler, USART3_IRQHandler,
EXTI15_10_IRQHandler, RTCAlarm_IRQHandler, USBWakeUp_IRQHandler,
TIM8_BRK_IRQHandler, TIM8_UP_IRQHandler, TIM8_TRG_COM_IRQHandler,
TIM8_CC_IRQHandler, ADC3_IRQHandler, FSMC_IRQHandler, SDIO_IRQHandler,
TIM5_IRQHandler, SPI3_IRQHandler, UART4_IRQHandler, UART5_IRQHandler,
TIM6_IRQHandler, TIM7_IRQHandler, DMA2_Channel1_IRQHandler,
DMA2_Channel2_IRQHandler, DMA2_Channel3_IRQHandler,
DMA2_Channel4_5_IRQHandler
};
#==========================================================
# File: Makefile for Cortex-M3
# Date: 2011-04-15
#==========================================================
OPTIMIZATION = s
#----------------------------------------------------------
SRC_C = startup.c
SRC_C += main.c
SRC_C += stm32f10x_it.c
SRC_C += stm32f10x_adc.c
SRC_C += stm32f10x_bkp.c
SRC_C += stm32f10x_can.c
SRC_C += stm32f10x_crc.c
SRC_C += stm32f10x_dac.c
SRC_C += stm32f10x_dbgmcu.c
SRC_C += stm32f10x_dma.c
SRC_C += stm32f10x_exti.c
SRC_C += stm32f10x_flash.c
SRC_C += stm32f10x_fsmc.c
SRC_C += stm32f10x_gpio.c
SRC_C += stm32f10x_i2c.c
SRC_C += stm32f10x_iwdg.c
SRC_C += stm32f10x_lib.c
SRC_C += stm32f10x_nvic.c
SRC_C += stm32f10x_pwr.c
SRC_C += stm32f10x_rcc.c
SRC_C += stm32f10x_rtc.c
SRC_C += stm32f10x_sdio.c
SRC_C += stm32f10x_spi.c
SRC_C += stm32f10x_systick.c
SRC_C += stm32f10x_tim.c
SRC_C += stm32f10x_usart.c
SRC_C += stm32f10x_wwdg.c
#----------------------------------------------------------
PROGRAMMATOR = "C:/Program Files/STMicroelectronics/STM32 ST-Link Utility/ST-Link Utility/ST-LINK_CLI.exe"
CROSS_PATH = C:/Tools/CodeSourcery/2010-09-51/
CROSS = $(CROSS_PATH)/bin/arm-none-eabi-
INCLUDES += -I$(CROSS_PATH)/arm-none-eabi/include
INCLUDES += -I$(CROSS_PATH)/arm-none-eabi/include/lib
INCLUDES += -Imcu
INCLUDES += -Iutility
INCLUDES += -Ilibrary/inc
INCLUDES += -Ilibrary/src
VPATH += mcu
VPATH += utility
VPATH += library/inc
VPATH += library/src
#----------------------------------------------------------
FLAGS_C = $(INCLUDES) -I.
FLAGS_C += -O$(OPTIMIZATION)
FLAGS_C += -Wall
FLAGS_C += -c
FLAGS_C += -fmessage-length=0
FLAGS_C += -fno-builtin
FLAGS_C += -ffunction-sections
FLAGS_C += -fdata-sections
FLAGS_C += -msoft-float
FLAGS_C += -mapcs-frame
FLAGS_C += -D__thumb2__=1
FLAGS_C += -mno-sched-prolog
FLAGS_C += -fno-hosted
FLAGS_C += -mtune=cortex-m3
FLAGS_C += -mcpu=cortex-m3
FLAGS_C += -mthumb
FLAGS_C += -mfix-cortex-m3-ldrd
FLAGS_LD = -Xlinker -Map=target/target.map
FLAGS_LD += -Wl,--gc-sections
FLAGS_LD += -mcpu=cortex-m3
FLAGS_LD += -mthumb
FLAGS_LD += -static
FLAGS_LD += -nostdlib
#----------------------------------------------------------
all: clean target.elf
mcu_prog:
@$(PROGRAMMATOR) -c SWD -ME -P "target/target.bin" 0x08000000 -Rst -Run
mcu_reset:
@$(PROGRAMMATOR) -c SWD -Rst -Run
%.elf: $(SRC_C:%.c=target/%.o)
@echo Linking: $@
@$(CROSS)gcc $(FLAGS_LD) -T'mcu/stm32f103cb.lsf' -o 'target/$@' $^ $(LD_LIB)
@echo '-----------------------------------------------------------'
@$(CROSS)size 'target/target.elf'
@$(CROSS)objcopy -O binary 'target/target.elf' 'target/target.bin'
@$(CROSS)objcopy -O ihex 'target/target.elf' 'target/target.hex'
@$(CROSS)objdump -h -S -z 'target/target.elf' > 'target/target.lss'
@$(CROSS)nm -n 'target/target.elf' > 'target/target.sym'
@rm -f target/*.o
$(SRC_C:%.c=target/%.o): target/%.o: %.c
@echo Compiling: $>
@$(CROSS)gcc $(FLAGS_C) -c $> -o $@
clean:
@echo '-----------------------------------------------------------'
@rm -f target/*.*
.PHONY : all clean mcu_prog mcu_reset
#define USART1_RXD A, 10, HIGH, INPUT_FLOATING,
#define USART1_TXD A, 9, HIGH, ALTERNATE_OUTPUT_PUSH_PULL, SPEED_50MHZ
// настраиваем линии ввода-вывода
PIN_CONFIGURATION(USART1_RXD);
PIN_CONFIGURATION(USART1_TXD);
// конфигурируем USART1
USART_InitStructure.USART_BaudRate = 38400;
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);
// разрешаем работу модуля
USART_Cmd(USART1, ENABLE);
// разрешаем прерывания по приёму
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
USART_SendData(USART1, USART_ReceiveData(USART1));
}
}
/*
* File: main.c
* Date: 15.04.2011
* Denis Zheleznjakov http://ziblog.ru
*/
#include "main.h"
#include "stm32f10x_lib.h"
#include "mcu_gpio.h"
//------------------------------------------------------------------------------
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
/* RCC system reset(for debug purpose) */
RCC_DeInit();
/* Enable HSE */
RCC_HSEConfig(RCC_HSE_ON);
/* Wait till HSE is ready */
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
/* Enable Prefetch Buffer */
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
/* Flash 2 wait state */
FLASH_SetLatency(FLASH_Latency_2);
/* HCLK = SYSCLK */
RCC_HCLKConfig(RCC_SYSCLK_Div1);
/* PCLK2 = HCLK */
RCC_PCLK2Config(RCC_HCLK_Div1);
/* PCLK1 = HCLK/2 */
RCC_PCLK1Config(RCC_HCLK_Div2);
/* PLLCLK = 8MHz * 9 = 72 MHz */
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
/* Enable PLL */
RCC_PLLCmd(ENABLE);
/* Wait till PLL is ready */
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
}
/* Select PLL as system clock source */
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
/* Wait till PLL is used as system clock source */
while (RCC_GetSYSCLKSource() != 0x08)
{
}
}
/* Enable USART1, GPIOA, GPIOx and AFIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
}
//------------------------------------------------------------------------------
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM
/* Set the Vector Table base location at 0x20000000 */
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else /* VECT_TAB_FLASH */
/* Set the Vector Table base location at 0x08000000 */
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* Enable the USART1 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
//-----------------------------------------------------------------------------
int main(void)
{
USART_InitTypeDef USART_InitStructure;
// инициализируем систему тактирования
RCC_Configuration();
// инициализируем контроллер прерываний
NVIC_Configuration();
// настраиваем линии ввода-вывода
PIN_CONFIGURATION(USART1_RXD);
PIN_CONFIGURATION(USART1_TXD);
// конфигурируем USART1
USART_InitStructure.USART_BaudRate = 38400;
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);
// разрешаем прерывания по приёму
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// разрешаем работу модуля
USART_Cmd(USART1, ENABLE);
while (1)
{
}
return 0;
}
Linking: target.elf
-----------------------------------------------------------
text data bss dec hex filename
1920 0 200 2120 848 target/target.elf
comments powered by Disqus