因为电脑中只装了IAR,所以本次编译环境就只能是IAR,所用软件版本是9.32.1。
本次仿真为,纯手写代码,不用任何库,包括启动文件也是手写。
首先是启动文件,该文件是汇编文件,命名为start.s,只写最基本的部分,可以正常启动就行,不需要完整的中断向量表。
MODULE ?cstartup
SECTION CSTACK:DATA:NOROOT(3)
SECTION .intvec:CODE:NOROOT(2)
EXTERN __iar_program_start
EXTERN SysTick_Handler
PUBLIC __vector_table
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD NMI_Handler
DCD SysTick_Handler
THUMB
PUBWEAK Reset_Handler
SECTION .text:CODE:REORDER:NOROOT(2)
Reset_Handler
LDR R0,=__iar_program_start
BX R0
PUBWEAK NMI_Handler
SECTION .text:CODE:REORDER:NOROOT(1)
NMI_Handler
B NMI_Handler
END
接下来是main.c文件,因为只是仿真调速,代码量不多,所以就都写在同一个文件中了。
首先是Systick结构体定义以及定义Systick指针并指向Systick指向的位置,以及初始化和Systick中断的实现,方便计时功能。
typedef struct
{
volatile uint32_t CTRL;
volatile uint32_t LOAD;
volatile uint32_t VAL;
volatile uint32_t CALIB;
}SysTick_Def;
#define SysTick_BASE 0xE000E010
#define SysTick ((SysTick_Def *)(SysTick_BASE))
void SysTick_Init(void)
{
SysTick->LOAD = 800-1;
SysTick->VAL = 0;
SysTick->CTRL = 0x07;
}
static volatile uint32_t TickCount = 0;
void SysTick_Handler(void)
{
TickCount ++;
if(TickCount >= 10001)
{
TickCount = 1;
}
}
uint32_t Get_SysTickCount(void)
{
return TickCount;
}
然后是时钟管理单元RCC和GPIO的结构体的定义。
typedef struct
{
volatile uint32_t CR;
volatile uint32_t CFCR;
volatile uint32_t CIR;
volatile uint32_t APB2RSTR;
volatile uint32_t APB1RSTR;
volatile uint32_t AHBENR;
volatile uint32_t APB2ENR;
volatile uint32_t APB1ENR;
volatile uint32_t BDCR;
volatile uint32_t CSR;
}RCC_TypeDef;
typedef struct
{
volatile uint32_t