赞
踩
最近玩了一阵arduino,转投STM32,不过发现网上大部分程序都涉及一些寄存器知识,新入门都总是云里雾里的,决定写个C语言,寄存器无关的Demo项目。
本项目基于GCC,使用stm32f103rbt6,本人在Mac上编译通过,代码适用于Linux。
下载 http://pan.baidu.com/share/link?shareid=605106&uk=4043729724
arm toolchain 使用 summon-arm-toolchain
//main.c
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/f1/flash.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/usart.h>
void USART1_Init();
void delay(void);
int main(void)
{
rcc_clock_setup_in_hse_8mhz_out_24mhz();//设置时钟
rcc_peripheral_enable_clock(&RCC_APB2ENR,RCC_APB2ENR_IOPBEN);//打开PB口时钟
gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_2_MHZ,
GPIO_CNF_OUTPUT_PUSHPULL, GPIO0);//PB0输出 灯接PB0
USART1_Init();
while(1)
{
gpio_clear(GPIOB,GPIO0);//关灯
delay();
usart_send(USART1,'a');//串口发送
gpio_set(GPIOB,GPIO0);//开灯
delay();
usart_send(USART1,'A');
}
}
void delay(void)
{
unsigned int i;
for( i = 0; i <0x3ffff; ++i)
asm("nop");
}
void USART1_Init(void)
{
rcc_peripheral_enable_clock(&RCC_APB2ENR,RCC_APB2ENR_USART1EN);//打开串口1时钟
usart_set_mode(USART1,USART_MODE_TX_RX);
usart_set_stopbits(USART1,USART_STOPBITS_1);
usart_set_flow_control(USART1,USART_FLOWCONTROL_NONE);
usart_set_baudrate(USART1,19200);
usart_enable(USART1);
}
//makefile
EPREFIX=/Users/apple/.gentoo
export PATH := $(EPREFIX)/usr/local/bin:$(PATH)
PREFIX = arm-none-eabi
STM32FLASH=stm32flash
CC = $(PREFIX)-gcc
LD = $(PREFIX)-ld -v
AR = $(PREFIX)-ar
AS = $(PREFIX)-as
CP = $(PREFIX)-objcopy
OD = $(PREFIX)-objdump
STM32LIB=${EPREFIX}/usr/local/arm-none-eabi/lib/libopencm3_stm32f1.a
#STM32LIB=${EPREFIX}/usr/local/arm-none-eabi/lib/libstm32.a
STM32LD=stm32.ld
TTY=/dev/tty.SLAB_USBtoUART
CFLAGS= -DSTM32F1 -I./ -c -fno-common -O0 -mcpu=cortex-m3 -mthumb
LFLAGS = -T$(STM32LD) -nostartfiles
ODFLAGS = -S
run:clean main
${STM32FLASH} -w main.bin -v -g 0x0 ${TTY}
main:main.o stm32.o
${LD} ${LFLAGS} -o main.elf *.o ${STM32LIB}
${CP} -Obinary main.elf main.bin
clean:
echo $(PATH)
rm -rf *.o main
//stm32.ld
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
}
SECTIONS
{
.text : {
*(.vectors) /* Vector table */
*(.text*) /* Program code */
. = ALIGN(4);
*(.rodata*) /* Read-only data */
. = ALIGN(4);
_sidata = .;
} >rom
/* C++ Static constructors/destructors, also used for __attribute__
* ((constructor)) and the likes */
.preinit_array : {
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
} >rom
.init_array : {
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} >rom
.fini_array : {
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
} >rom
/*
* Another section used by C++ stuff, appears when using newlib with
* 64bit (long long) printf support
*/
.ARM.extab : {
*(.ARM.extab*)
} >rom
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} >rom
. = ALIGN(4);
_etext = .;
.data : {
_sdata = .;
_data = .;
*(.data*) /* Read-write initialized data */
. = ALIGN(4);
_edata = .;
} >ram AT >rom
_data_loadaddr = LOADADDR(.data);
.bss : {
_sbss = .;
*(.bss*) /* Read-write zero initialized data */
*(COMMON)
. = ALIGN(4);
_ebss = .;
} >ram
/*
* The .eh_frame section appears to be used for C++ exception handling.
* You may need to fix this if you're using C++.
*/
/DISCARD/ : { *(.eh_frame) }
. = ALIGN(4);
end = .;
}
PROVIDE(_estack = ORIGIN(ram) + LENGTH(ram));
//stm32.c 启动代码 本文件从另一项目copy的,适用于些芯片所有项目
/**
******************************************************************************
* @file startup_stm32f10x_hd.c
* @author MCD Application Team
* @version V3.0.0
* @date 04/06/2009
* @brief STM32F10x High Density Devices vector table for RIDE7 toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address,
* - Configure external SRAM mounted on STM3210E-EVAL board
* to be used as data memory (optional, to be enabled by user)
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
*******************************************************************************
* @copy
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>© COPYRIGHT 2009 STMicroelectronics</center></h2>
*/
/* Includes ------------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define WEAK __attribute__ ((weak))
#define Initial_spTop 0x20000400
/* Private macro -------------------------------------------------------------*/
extern unsigned long _etext;
/* start address for the initialization values of the .data section.
defined in linker script */
extern unsigned long _sidata;
/* start address for the .data section. defined in linker script */
extern unsigned long _sdata;
/* end address for the .data section. defined in linker script */
extern unsigned long _edata;
/* start address for the .bss section. defined in linker script */
extern unsigned long _sbss;
/* end address for the .bss section. defined in linker script */
extern unsigned long _ebss;
/* init value for the stack pointer. defined in linker script */
extern void _estack;
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void Reset_Handler(void)__attribute__((__interrupt__));
extern int main(void);
void __Init_Data(void);
/******************************************************************************
*
* Forward declaration of the default fault handlers.
*
*******************************************************************************/
void WEAK Reset_Handler(void);
void WEAK NMI_Handler(void);
void WEAK HardFault_Handler(void);
void WEAK MemManage_Handler(void);
void WEAK BusFault_Handler(void);
void WEAK UsageFault_Handler(void);
void WEAK MemManage_Handler(void);
void WEAK SVC_Handler(void);
void WEAK DebugMon_Handler(void);
void WEAK PendSV_Handler(void);
void WEAK SysTick_Handler(void);
/* External Interrupts */
void WEAK WWDG_IRQHandler(void);
void WEAK PVD_IRQHandler(void);
void WEAK TAMPER_IRQHandler(void);
void WEAK RTC_IRQHandler(void);
void WEAK FLASH_IRQHandler(void);
void WEAK RCC_IRQHandler(void);
void WEAK EXTI0_IRQHandler(void);
void WEAK EXTI1_IRQHandler(void);
void WEAK EXTI2_IRQHandler(void);
void WEAK EXTI3_IRQHandler(void);
void WEAK EXTI4_IRQHandler(void);
void WEAK DMA1_Channel1_IRQHandler(void);
void WEAK DMA1_Channel2_IRQHandler(void);
void WEAK DMA1_Channel3_IRQHandler(void);
void WEAK DMA1_Channel4_IRQHandler(void);
void WEAK DMA1_Channel5_IRQHandler(void);
void WEAK DMA1_Channel6_IRQHandler(void);
void WEAK DMA1_Channel7_IRQHandler(void);
void WEAK ADC1_2_IRQHandler(void);
void WEAK USB_HP_CAN1_TX_IRQHandler(void);
void WEAK USB_LP_CAN1_RX0_IRQHandler(void);
void WEAK CAN1_RX1_IRQHandler(void);
void WEAK CAN1_SCE_IRQHandler(void);
void WEAK EXTI9_5_IRQHandler(void);
void WEAK TIM1_BRK_IRQHandler(void);
void WEAK TIM1_UP_IRQHandler(void);
void WEAK TIM1_TRG_COM_IRQHandler(void);
void WEAK TIM1_CC_IRQHandler(void);
void WEAK TIM2_IRQHandler(void);
void WEAK TIM3_IRQHandler(void);
void WEAK TIM4_IRQHandler(void);
void WEAK I2C1_EV_IRQHandler(void);
void WEAK I2C1_ER_IRQHandler(void);
void WEAK I2C2_EV_IRQHandler(void);
void WEAK I2C2_ER_IRQHandler(void);
void WEAK SPI1_IRQHandler(void);
void WEAK SPI2_IRQHandler(void);
void WEAK USART1_IRQHandler(void);
void WEAK USART2_IRQHandler(void);
void WEAK USART3_IRQHandler(void);
void WEAK EXTI15_10_IRQHandler(void);
void WEAK RTCAlarm_IRQHandler(void);
void WEAK USBWakeUp_IRQHandler(void);
void WEAK TIM8_BRK_IRQHandler(void);
void WEAK TIM8_UP_IRQHandler(void);
void WEAK TIM8_TRG_COM_IRQHandler(void);
void WEAK TIM8_CC_IRQHandler(void);
void WEAK ADC3_IRQHandler(void);
void WEAK FSMC_IRQHandler(void);
void WEAK SDIO_IRQHandler(void);
void WEAK TIM5_IRQHandler(void);
void WEAK SPI3_IRQHandler(void);
void WEAK UART4_IRQHandler(void);
void WEAK UART5_IRQHandler(void);
void WEAK TIM6_IRQHandler(void);
void WEAK TIM7_IRQHandler(void);
void WEAK DMA2_Channel1_IRQHandler(void);
void WEAK DMA2_Channel2_IRQHandler(void);
void WEAK DMA2_Channel3_IRQHandler(void);
void WEAK DMA2_Channel4_5_IRQHandler(void);
void WEAK SystemInit_ExtMemCtl(void);
/* Private functions ---------------------------------------------------------*/
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
__attribute__ ((section(".vectors")))
void (* const g_pfnVectors[])(void) =
{
(void *)Initial_spTop, /* The initial stack pointer */
Reset_Handler, /* Reset Handler */
NMI_Handler, /* NMI Handler */
HardFault_Handler, /* Hard Fault Handler */
MemManage_Handler, /* MPU Fault Handler */
BusFault_Handler, /* Bus Fault Handler */
UsageFault_Handler, /* Usage Fault Handler */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
0, /* Reserved */
SVC_Handler, /* SVCall Handler */
DebugMon_Handler, /* Debug Monitor Handler */
0, /* Reserved */
PendSV_Handler, /* PendSV Handler */
SysTick_Handler, /* SysTick Handler */
/* External Interrupts */
WWDG_IRQHandler, /* Window Watchdog */
PVD_IRQHandler, /* PVD through EXTI Line detect */
TAMPER_IRQHandler, /* Tamper */
RTC_IRQHandler, /* RTC */
FLASH_IRQHandler, /* Flash */
RCC_IRQHandler, /* RCC */
EXTI0_IRQHandler, /* EXTI Line 0 */
EXTI1_IRQHandler, /* EXTI Line 1 */
EXTI2_IRQHandler, /* EXTI Line 2 */
EXTI3_IRQHandler, /* EXTI Line 3 */
EXTI4_IRQHandler, /* EXTI Line 4 */
DMA1_Channel1_IRQHandler, /* DMA1 Channel 1 */
DMA1_Channel2_IRQHandler, /* DMA1 Channel 2 */
DMA1_Channel3_IRQHandler, /* DMA1 Channel 3 */
DMA1_Channel4_IRQHandler, /* DMA1 Channel 4 */
DMA1_Channel5_IRQHandler, /* DMA1 Channel 5 */
DMA1_Channel6_IRQHandler, /* DMA1 Channel 6 */
DMA1_Channel7_IRQHandler, /* DMA1 Channel 7 */
ADC1_2_IRQHandler, /* ADC1 & ADC2 */
USB_HP_CAN1_TX_IRQHandler, /* USB High Priority or CAN1 TX */
USB_LP_CAN1_RX0_IRQHandler, /* USB Low Priority or CAN1 RX0 */
CAN1_RX1_IRQHandler, /* CAN1 RX1 */
CAN1_SCE_IRQHandler, /* CAN1 SCE */
EXTI9_5_IRQHandler, /* EXTI Line 9..5 */
TIM1_BRK_IRQHandler, /* TIM1 Break */
TIM1_UP_IRQHandler, /* TIM1 Update */
TIM1_TRG_COM_IRQHandler, /* TIM1 Trigger and Commutation */
TIM1_CC_IRQHandler, /* TIM1 Capture Compare */
TIM2_IRQHandler, /* TIM2 */
TIM3_IRQHandler, /* TIM3 */
TIM4_IRQHandler, /* TIM4 */
I2C1_EV_IRQHandler, /* I2C1 Event */
I2C1_ER_IRQHandler, /* I2C1 Error */
I2C2_EV_IRQHandler, /* I2C2 Event */
I2C2_ER_IRQHandler, /* I2C2 Error */
SPI1_IRQHandler, /* SPI1 */
SPI2_IRQHandler, /* SPI2 */
USART1_IRQHandler, /* USART1 */
USART2_IRQHandler, /* USART2 */
USART3_IRQHandler, /* USART3 */
EXTI15_10_IRQHandler, /* EXTI Line 15..10 */
RTCAlarm_IRQHandler, /* RTC Alarm through EXTI Line */
USBWakeUp_IRQHandler, /* USB Wakeup from suspend */
TIM8_BRK_IRQHandler, /* TIM8 Break */
TIM8_UP_IRQHandler, /* TIM8 Update */
TIM8_TRG_COM_IRQHandler, /* TIM8 Trigger and Commutation */
TIM8_CC_IRQHandler, /* TIM8 Capture Compare */
ADC3_IRQHandler, /* ADC3 */
FSMC_IRQHandler, /* FSMC */
SDIO_IRQHandler, /* SDIO */
TIM5_IRQHandler, /* TIM5 */
SPI3_IRQHandler, /* SPI3 */
UART4_IRQHandler, /* UART4 */
UART5_IRQHandler, /* UART5 */
TIM6_IRQHandler, /* TIM6 */
TIM7_IRQHandler, /* TIM7 */
DMA2_Channel1_IRQHandler, /* DMA2 Channel 1 */
DMA2_Channel2_IRQHandler, /* DMA2 Channel 2 */
DMA2_Channel3_IRQHandler, /* DMA2 Channel 3 */
DMA2_Channel4_5_IRQHandler, /* DMA2 Channel 4 and Channel 5 */
0,0,0,0,0,0,0,0, /* @0x130 */
0,0,0,0,0,0,0,0, /* @0x150 */
0,0,0,0,0,0,0,0, /* @0x170 */
0,0,0,0,0,0,0,0, /* @0x190 */
0,0,0,0,0,0,0,0, /* @0x1B0 */
0,0,0,0, /* @0x1D0 */
(void *)0xF1E0F85F /* @0x1E0. This is for boot in RAM mode for
STM32F10x High Density devices. */
};
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
void Reset_Handler(void)
{
/* FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
required, then adjust the Register Addresses */
SystemInit_ExtMemCtl();
/* restore original stack pointer */
asm(" LDR r0, =_estack");
asm(" MSR msp, r0");
/* Initialize data and bss */
__Init_Data();
/* Call the application's entry point.*/
main();
}
/**
* @brief initializes data and bss sections
* @param None
* @retval : None
*/
void __Init_Data(void)
{
unsigned long *pulSrc, *pulDest;
/* Copy the data segment initializers from flash to SRAM */
pulSrc = &_sidata;
for(pulDest = &_sdata; pulDest < &_edata; )
{
*(pulDest++) = *(pulSrc++);
}
/* Zero fill the bss segment. */
for(pulDest = &_sbss; pulDest < &_ebss; )
{
*(pulDest++) = 0;
}
}
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
#pragma weak NMI_Handler = Default_Handler
#pragma weak MemManage_Handler = Default_Handler
#pragma weak BusFault_Handler = Default_Handler
#pragma weak UsageFault_Handler = Default_Handler
#pragma weak SVC_Handler = Default_Handler
#pragma weak DebugMon_Handler = Default_Handler
#pragma weak PendSV_Handler = Default_Handler
#pragma weak SysTick_Handler = Default_Handler
#pragma weak WWDG_IRQHandler = Default_Handler
#pragma weak PVD_IRQHandler = Default_Handler
#pragma weak TAMPER_IRQHandler = Default_Handler
#pragma weak RTC_IRQHandler = Default_Handler
#pragma weak FLASH_IRQHandler = Default_Handler
#pragma weak RCC_IRQHandler = Default_Handler
#pragma weak EXTI0_IRQHandler = Default_Handler
#pragma weak EXTI1_IRQHandler = Default_Handler
#pragma weak EXTI2_IRQHandler = Default_Handler
#pragma weak EXTI3_IRQHandler = Default_Handler
#pragma weak EXTI4_IRQHandler = Default_Handler
#pragma weak DMA1_Channel1_IRQHandler = Default_Handler
#pragma weak DMA1_Channel2_IRQHandler = Default_Handler
#pragma weak DMA1_Channel3_IRQHandler = Default_Handler
#pragma weak DMA1_Channel4_IRQHandler = Default_Handler
#pragma weak DMA1_Channel5_IRQHandler = Default_Handler
#pragma weak DMA1_Channel6_IRQHandler = Default_Handler
#pragma weak DMA1_Channel7_IRQHandler = Default_Handler
#pragma weak ADC1_2_IRQHandler = Default_Handler
#pragma weak USB_HP_CAN1_TX_IRQHandler = Default_Handler
#pragma weak USB_LP_CAN1_RX0_IRQHandler = Default_Handler
#pragma weak CAN1_RX1_IRQHandler = Default_Handler
#pragma weak CAN1_SCE_IRQHandler = Default_Handler
#pragma weak EXTI9_5_IRQHandler = Default_Handler
#pragma weak TIM1_BRK_IRQHandler = Default_Handler
#pragma weak TIM1_UP_IRQHandler = Default_Handler
#pragma weak TIM1_TRG_COM_IRQHandler = Default_Handler
#pragma weak TIM1_CC_IRQHandler = Default_Handler
#pragma weak TIM2_IRQHandler = Default_Handler
#pragma weak TIM3_IRQHandler = Default_Handler
#pragma weak TIM4_IRQHandler = Default_Handler
#pragma weak I2C1_EV_IRQHandler = Default_Handler
#pragma weak I2C1_ER_IRQHandler = Default_Handler
#pragma weak I2C2_EV_IRQHandler = Default_Handler
#pragma weak I2C2_ER_IRQHandler = Default_Handler
#pragma weak SPI1_IRQHandler = Default_Handler
#pragma weak SPI2_IRQHandler = Default_Handler
#pragma weak USART1_IRQHandler = Default_Handler
#pragma weak USART2_IRQHandler = Default_Handler
#pragma weak USART3_IRQHandler = Default_Handler
#pragma weak EXTI15_10_IRQHandler = Default_Handler
#pragma weak RTCAlarm_IRQHandler = Default_Handler
#pragma weak USBWakeUp_IRQHandler = Default_Handler
#pragma weak TIM8_BRK_IRQHandler = Default_Handler
#pragma weak TIM8_UP_IRQHandler = Default_Handler
#pragma weak TIM8_TRG_COM_IRQHandler = Default_Handler
#pragma weak TIM8_CC_IRQHandler = Default_Handler
#pragma weak ADC3_IRQHandler = Default_Handler
#pragma weak FSMC_IRQHandler = Default_Handler
#pragma weak SDIO_IRQHandler = Default_Handler
#pragma weak TIM5_IRQHandler = Default_Handler
#pragma weak SPI3_IRQHandler = Default_Handler
#pragma weak UART4_IRQHandler = Default_Handler
#pragma weak UART5_IRQHandler = Default_Handler
#pragma weak TIM6_IRQHandler = Default_Handler
#pragma weak TIM7_IRQHandler = Default_Handler
#pragma weak DMA2_Channel1_IRQHandler = Default_Handler
#pragma weak DMA2_Channel2_IRQHandler = Default_Handler
#pragma weak DMA2_Channel3_IRQHandler = Default_Handler
#pragma weak DMA2_Channel4_5_IRQHandler = Default_Handler
#pragma weak SystemInit_ExtMemCtl = SystemInit_ExtMemCtl_Dummy
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
void Default_Handler(void)
{
/* Go into an infinite loop. */
while (1)
{
}
}
/**
* @brief Dummy SystemInit_ExtMemCtl function
* @param None
* @retval : None
*/
void SystemInit_ExtMemCtl_Dummy(void)
{
}
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。