diff --git a/build/MDK/project.uvprojx b/build/MDK/project.uvprojx index 0725efb..b287fa9 100644 --- a/build/MDK/project.uvprojx +++ b/build/MDK/project.uvprojx @@ -78,7 +78,7 @@ 0 - 1 + 0 0 afterbuild.bat @@ -224,7 +224,7 @@ 1 0 8 - 1 + 0 0 0 3 @@ -433,6 +433,11 @@ 1 ..\..\src\Driver\usart_debug.c + + stepper.c + 1 + ..\..\src\Driver\stepper.c + diff --git a/src/Driver/delay.c b/src/Driver/delay.c index 3760027..6b0e815 100644 --- a/src/Driver/delay.c +++ b/src/Driver/delay.c @@ -9,7 +9,7 @@ *******************************************************************************/ /* Includes ------------------------------------------------------------------*/ #include "delay.h" -#include "stdio.h" + /* Definition ----------------------------------------------------------------*/ u16 TimeTick; volatile u32 sys_Time; @@ -27,9 +27,9 @@ void (*SysTick_CB)(void); void SysTick_init() { if (SysTick_Config((SystemCoreClock / 8) / 1000)) //系统滴答时钟1ms - while (1) - ; - SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); + while (1) + ; + SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); } /******************************************************************************* * @brief 绑定滴答时钟事件 diff --git a/src/Driver/e34.c b/src/Driver/e34.c new file mode 100644 index 0000000..7ac9b1a --- /dev/null +++ b/src/Driver/e34.c @@ -0,0 +1,84 @@ +/******************************************************************************* + * @file E34.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2017-12-22 10:18:04 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "e34.h" +/* Definition ----------------------------------------------------------------*/ +ring_buffer E34_RX_BUF; +ring_buffer *pE34_RX_BUF = &E34_RX_BUF; +/* Functions -----------------------------------------------------------------*/ +/******************************************************************************* + * @brief E34模块初始化 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void E34_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + USART_InitTypeDef USART_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能GPIO时钟 + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //使能USART3时钟 + + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13; //GPIOB11与GPIOB10 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 + GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PA9,PA10 + GPIO_ResetBits(GPIOB, GPIO_Pin_12 | GPIO_Pin_13); + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3); //GPIOB10复用为USART3 + GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3); //GPIOB11复用为USART3 + //USART3 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_10; //GPIOB11与GPIOB10 + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 + GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10,PB11 + + USART_InitStructure.USART_BaudRate = 115200; //一般设置为 9600; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为 8 位数据格式 + 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_E34, &USART_InitStructure); //初始化串口 + USART_ClearFlag(USART_E34, USART_FLAG_TC | USART_FLAG_RXNE | USART_FLAG_IDLE); + USART_ITConfig(USART_E34, USART_IT_RXNE, ENABLE); + + NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //串口1中断通道 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级3 + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级3 + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 aPcCmuTxBuf_1 + NVIC_Init(&NVIC_InitStructure); + + USART_Cmd(USART_E34, ENABLE); //使能串口 +} + +/******************************************************************************* + * @brief 串口3中断接收 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void USART3_IRQHandler(void) //串口1中断服务程序 +{ + if ((USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)) + { + u8 data = USART_ReceiveData(USART3); + if (ring_buffer_write(pE34_RX_BUF, data)) + led_set_value(0, 1); + } + // USART_ClearITPendingBit(USART3, USART_IT_RXNE); +} + +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/inc/usart_debug.h b/src/Driver/inc/bsp.h similarity index 75% rename from src/Driver/inc/usart_debug.h rename to src/Driver/inc/bsp.h index 7192242..93124c8 100644 --- a/src/Driver/inc/usart_debug.h +++ b/src/Driver/inc/bsp.h @@ -1,22 +1,27 @@ /******************************************************************************* - * @file usart_debug.h + * @file bsp.h * @Author: MQjehovah mail:MQjehovah@hotmail.com * @version 1.0.0 - * @date 2016.3.18 + * @date 2018-01-24 10:10:21 * @brief ****************************************************************************** * @attention *******************************************************************************/ -#ifndef _USART_DEBUG_H -#define _USART_DEBUG_H +#ifndef __BSP_H +#define __BSP_H /* Includes ------------------------------------------------------------------*/ +#include "stdio.h" +#include "stm32f4xx.h" #include "stm32f4xx_conf.h" +#include "ring_buffer.h" #include "delay.h" -#include +#include "usart.h" +#include "stepper.h" +#include "e34.h" +#include "led.h" /* Definition ----------------------------------------------------------------*/ -#define USART_DEBUG USART1 /* Exported Functions --------------------------------------------------------*/ -void usart_debug_init(void); -/*********************************END OF FILE**********************************/ + #endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/inc/delay.h b/src/Driver/inc/delay.h index 874d74c..a165959 100644 --- a/src/Driver/inc/delay.h +++ b/src/Driver/inc/delay.h @@ -8,9 +8,9 @@ * @attention *******************************************************************************/ #ifndef __DELAY_H -#define __DELAY_H +#define __DELAY_H /* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_conf.h" +#include "bsp.h" /* Definition ----------------------------------------------------------------*/ /* Exported Functions --------------------------------------------------------*/ diff --git a/src/Driver/inc/e34.h b/src/Driver/inc/e34.h new file mode 100644 index 0000000..97ac4dc --- /dev/null +++ b/src/Driver/inc/e34.h @@ -0,0 +1,23 @@ +/******************************************************************************* + * @file E34.h + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2017-12-22 10:18:31 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +#ifndef __E34_H +#define __E34_H +/* Includes ------------------------------------------------------------------*/ +#include "bsp.h" +/* Definition ----------------------------------------------------------------*/ +#define USART_E34 USART3 +#define E34_send_char(ch) usart_send_char(USART_E34, ch) +#define E34_send_str(str) usart_send_str(USART_E34, str) +/* Exported Functions --------------------------------------------------------*/ +extern struct _ring_buffer *pE34_RX_BUF; +void E34_Init(void); + +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/inc/led.h b/src/Driver/inc/led.h new file mode 100644 index 0000000..7f26fa1 --- /dev/null +++ b/src/Driver/inc/led.h @@ -0,0 +1,20 @@ +/******************************************************************************* + * @file led.h + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2018/01/24 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +#ifndef __LED_H +#define __LED_H +/* Includes ------------------------------------------------------------------*/ +#include "bsp.h" +/* Definition ----------------------------------------------------------------*/ + +/* Exported ------------------------------------------------------------------*/ +void led_init(void); +void led_set_value(u8 index, u8 value); +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/inc/ring_buffer.h b/src/Driver/inc/ring_buffer.h new file mode 100644 index 0000000..ad1eb01 --- /dev/null +++ b/src/Driver/inc/ring_buffer.h @@ -0,0 +1,32 @@ +/******************************************************************************* + * @file ring_buffer.h + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2016/07/26 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +#ifndef _RING_BUFFER_H +#define _RING_BUFFER_H + +/* Includes ------------------------------------------------------------------*/ +#include "BSP.h" +/* Definition ----------------------------------------------------------------*/ +#define RX_BUFFER_SIZE 64 + +typedef struct _ring_buffer +{ + char buffer[RX_BUFFER_SIZE]; //缓冲区 + u16 head; //缓冲区头指针 + u16 tail; //缓冲区尾指针 + u32 lenth; //缓冲区已使用长度 +} ring_buffer; + +/* Exported Functions --------------------------------------------------------*/ +u8 ring_buffer_write(ring_buffer *r, unsigned char c); +u8 ring_buffer_read(ring_buffer *r, char *c); +void ring_buffer_flush(ring_buffer *r); + +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/inc/stepper.h b/src/Driver/inc/stepper.h new file mode 100644 index 0000000..1ef5fbe --- /dev/null +++ b/src/Driver/inc/stepper.h @@ -0,0 +1,58 @@ +/******************************************************************************* + * @file stepper.h + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2018/01/23 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +#ifndef __STEPPER_H +#define __STEPPER_H +/* Includes ------------------------------------------------------------------*/ +#include "bsp.h" +/* Definition ----------------------------------------------------------------*/ +#define STEP_EN GPIO_SetBits(GPIOB, GPIO_Pin_4) + +#define ANGEL_PER_STEP (1.8f) //步距角1.8° +#define STEP_PER_CIRCLE (360 / ANGEL_PER_STEP) //电机转动一圈的步数 +#define STEP_DIV (4) //电机驱动细分值 +#define PUL_PER_CIRCLE (STEP_PER_CIRCLE * STEP_DIV) //电机转动一圈的脉冲数 + +typedef struct +{ + u8 id; //电机id + u8 dir_pos; //电机正向方向(顺时针) + u16 div; //电机驱动细分 + u8 running; //标记电机是否在运行 + + char en; + char dir; + long step; + int speed; + int target_speed; + + u32 current_puase; //当前的脉冲数 + u32 current_step; //当前的步数 + u32 passed_puase; //走过的脉冲数 + u32 target_puase; //设置的目标步数 + + u32 f_puase; //当前频率脉冲数(本算法S型加减速的过程是离散的,每个点(频率)运行一定步数) + u16 f_index; //当前频率在表中所处位置() + u16 *table_step; //步数表 + u16 *table_time; //时间表(即当前频率电机一个脉冲所需时间,用于赋值定时器arr) + + u32 start_step; //启动阶段步数 + u16 start_f; //启动阶段的频率个数 + u32 stop_step; //停止阶段步数 + TIM_TypeDef *TIMx; //电机的驱动定时器 + +} STEPPER; +/* Exported ------------------------------------------------------------------*/ +extern STEPPER stepper; +void stepper_tim_init(u16 arr, u16 psc); +void stepper_pwm_init(u16 arr, u16 psc); +void stepper_set_enable(u8 value); +void stepper_set_dir(u8 value); +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/inc/usart.h b/src/Driver/inc/usart.h new file mode 100644 index 0000000..65db4f4 --- /dev/null +++ b/src/Driver/inc/usart.h @@ -0,0 +1,31 @@ +/******************************************************************************* + * @file usart.h + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2017-12-22 10:25:23 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +#ifndef __USART_H +#define __USART_H +/* Includes ------------------------------------------------------------------*/ +#include "bsp.h" +/* Definition ----------------------------------------------------------------*/ +#define USART3_RX_EN //使能串口中断接收 +#define DEBUG +#define USART_DEBUG USART1 + +#define USART_RX_EN GPIO_ResetBits(GPIOB, GPIO_Pin_5) +#define USART_TX_EN GPIO_SetBits(GPIOB, GPIO_Pin_5) +/* Exported Functions --------------------------------------------------------*/ +void usart_send_char(USART_TypeDef *USARTx, char c); +void usart_send_str(USART_TypeDef *USARTx, char *senddata); +void usart_send_number(USART_TypeDef *USARTx, unsigned long n, u8 base); +#ifdef DEBUG +void usart_debug_init(u32 bound); +void debug_send_char(u8 c); +void debug_send_str(char *str); +#endif +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/led.c b/src/Driver/led.c new file mode 100644 index 0000000..af759dd --- /dev/null +++ b/src/Driver/led.c @@ -0,0 +1,65 @@ +/******************************************************************************* + * @file led.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2018/01/24 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "led.h" +/* Definition ----------------------------------------------------------------*/ + +/* Functions -----------------------------------------------------------------*/ +/******************************************************************************* + * @brief LED初始化 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void led_init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); //使能GPIOF时钟 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 + GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化 + GPIO_SetBits(GPIOC, GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15); +} + +/******************************************************************************* + * @brief LED开关 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void led_set_value(u8 index, u8 value) +{ + switch (index) + { + case 0: + if (value) + GPIO_ResetBits(GPIOC, GPIO_Pin_13); + else + GPIO_SetBits(GPIOC, GPIO_Pin_13); + break; + case 1: + if (value) + GPIO_ResetBits(GPIOC, GPIO_Pin_14); + else + GPIO_SetBits(GPIOC, GPIO_Pin_14); + break; + case 2: + if (value) + GPIO_ResetBits(GPIOC, GPIO_Pin_15); + else + GPIO_SetBits(GPIOC, GPIO_Pin_15); + break; + } +} + +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/ring_buffer.c b/src/Driver/ring_buffer.c new file mode 100644 index 0000000..3f773a9 --- /dev/null +++ b/src/Driver/ring_buffer.c @@ -0,0 +1,62 @@ +/******************************************************************************* + * @file ring_buffer.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2016/07/26 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "ring_buffer.h" +/* Definition ----------------------------------------------------------------*/ + +/* Functions -----------------------------------------------------------------*/ + +/******************************************************************************* + * @brief 环形缓冲区写一个字节 + * @param r:缓冲区指针 c:存入的字节 + * @retval 0:写入失败 1:写入成功 + * @Note None +*******************************************************************************/ +u8 ring_buffer_write(ring_buffer *r, unsigned char c) +{ + u16 i = (r->tail + 1) % RX_BUFFER_SIZE; + if (i != r->head) + { + r->buffer[r->tail] = c; + r->tail = i; + r->lenth++; + return 1; + } + return 0; +} +/******************************************************************************* + * @brief 环形缓冲区读一个字节 + * @param r:缓冲区指针 c:读出字节存放的地址 + * @retval 0:读取失败 1:读取成功 + * @Note None +*******************************************************************************/ +u8 ring_buffer_read(ring_buffer *r, char *c) +{ + if (r->head == r->tail) + return 0; + *c = r->buffer[r->head]; + r->head = (r->head + 1) % RX_BUFFER_SIZE; + r->lenth--; + return 1; +} +/******************************************************************************* + * @brief 缓冲区清空 + * @param None + * @retval None + * @Note 此处仅复位了指针,并没有删除缓冲区的内容 +*******************************************************************************/ +void ring_buffer_flush(ring_buffer *r) +{ + r->head = 0; + r->tail = 0; + r->lenth = 0; +} + +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/stepper.c b/src/Driver/stepper.c new file mode 100644 index 0000000..73f281a --- /dev/null +++ b/src/Driver/stepper.c @@ -0,0 +1,166 @@ +/******************************************************************************* + * @file stepper.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2018/01/23 + * @brief 42步进电机 转矩0.5N·M 步距角1.8° + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "stepper.h" +#include "shell.h" +/* Definition ----------------------------------------------------------------*/ +STEPPER stepper = {0}; +/* Functions -----------------------------------------------------------------*/ +/******************************************************************************* + * @brief 步进电机IO口初始化 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void stepper_gpio_init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE); //使能PORTA PORTB时钟 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //PB4-EN + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 + GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PB3-PUL + // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能(如果是采用定时器PWM输出需要配制成AF模式) + GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB3 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10-DIR + GPIO_Init(GPIOA, &GPIO_InitStructure); +} + +/******************************************************************************* + * @brief 通用定时器中断初始化 + * @param arr:自动重装值。 psc:时钟预分频数 + * @retval None + * @Note 定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us. + Ft=定时器工作频率,单位:Mhz 84M + 定时器3,用来计时控制步进电机加减速周期 +*******************************************************************************/ +void stepper_tim_init(u16 arr, u16 psc) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + + stepper_gpio_init(); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); ///使能TIM3时钟 + + TIM_DeInit(TIM3); + TIM_TimeBaseInitStructure.TIM_Period = arr - 1; //自动重装载值100ms + TIM_TimeBaseInitStructure.TIM_Prescaler = psc - 1; //定时器分频8400 + TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 + TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //初始化TIM3 + TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //允许定时器3更新中断 + + NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //定时器3中断 + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级1 + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3 + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + TIM_Cmd(TIM3, ENABLE); //使能定时器3 +} + +/******************************************************************************* + * @brief 定时器PWM输出初始化 + * @param arr:自动重装值。 psc:时钟预分频数 + * @retval None + * @Note None +*******************************************************************************/ +void stepper_pwm_init(u16 arr, u16 psc) +{ + TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + stepper_gpio_init(); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //TIM2时钟使能 + + GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_TIM2); //GPIOB3复用为定时器2 + + TIM_TimeBaseStructure.TIM_Prescaler = psc - 1; //定时器分频 + TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式 + TIM_TimeBaseStructure.TIM_Period = arr - 1; //自动重装载值 + TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; + TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //初始化定时器2 + + //初始化TIM2 Channel2 PWM模式 + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2 + // TIM_OCInitStructure.TIM_Pulse = arr >> 1; + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 + // TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; //?????? + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性低 + TIM_OC2Init(TIM2, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1 + + TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR2上的预装载寄存器 + TIM_ARRPreloadConfig(TIM2, ENABLE); //ARPE使能 + // TIM_CCPreloadControl(TIM2, ENABLE); + // TIM_CtrlPWMOutputs(TIM4, ENABLE); + // TIM_Cmd(TIM2, DISABLE); //使能TIM2 + TIM_Cmd(TIM2, ENABLE); //使能TIM2 +} + +/******************************************************************************* + * @brief 设置步进电机使能 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void stepper_set_enable(u8 value) +{ + if (value) + GPIO_ResetBits(GPIOB, GPIO_Pin_4); + else + GPIO_SetBits(GPIOB, GPIO_Pin_4); + stepper.en = value; +} + +/******************************************************************************* + * @brief 设置步进电机方向 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void stepper_set_dir(u8 value) +{ + if (value) + GPIO_ResetBits(GPIOA, GPIO_Pin_10); + else + GPIO_SetBits(GPIOA, GPIO_Pin_10); + stepper.dir = value; +} + +char flag = 0; +/******************************************************************************* + * @brief 定时器3中断服务函数 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void TIM3_IRQHandler(void) +{ + if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //溢出中断 + { + if (stepper.step > 0) + { + if (flag) + { + flag = 0; + stepper.step--; + GPIO_SetBits(GPIOB, GPIO_Pin_3); + } + else + { + flag++; + GPIO_ResetBits(GPIOB, GPIO_Pin_3); + } + } + } + TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除中断标志位 +} +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/stepper_s.c b/src/Driver/stepper_s.c new file mode 100644 index 0000000..77bdcca --- /dev/null +++ b/src/Driver/stepper_s.c @@ -0,0 +1,223 @@ +/******************************************************************************* + * @file stepper_s.1.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2018-02-28 14:15:45 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "stepper.h" +/* Definition ----------------------------------------------------------------*/ +STEPPER motor; +STEPPER *pmotor = &motor; +/* Functions -----------------------------------------------------------------*/ +/******************************************************************************* + * @brief 步进电机GPIO口初始化 + * @param None + * @retval None + * @Note 用户自己实现 +*******************************************************************************/ +void Motor_GPIO_Init(void) +{ + // GPIO_InitTypeDef GPIO_InitStructure; + // RCC_APB2PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); + + // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; + // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + // GPIO_Init(GPIOA, &GPIO_InitStructure); + // GPIO_ResetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4); +} + +#if ADV_TIM_ENABLE +/******************************************************************************* + * @brief 高级定时器驱动S型电机驱动 + * @param None + * @retval None + * @Note 使用高级定时器1,使用TIM_RepetitionCounter参数跳过细分中断 + 减少中断的次数 +*******************************************************************************/ +void Initial_PWM_Motor1(void) +{ + TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); + Motor_GPIO_Init(); + TIM_DeInit(TIM1); + //中断NVIC设置:允许中断,设置优先级 + NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PWM1_PreemptionPriority; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = PWM1_SubPriority; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + TIM_BaseInitStructure.TIM_Period = 1000; + TIM_BaseInitStructure.TIM_Prescaler = 5; + TIM_BaseInitStructure.TIM_ClockDivision = 0; + TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_BaseInitStructure.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIM1, &TIM_BaseInitStructure); + + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM2模式 + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //信号输出到对应的输出引脚 + TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //互补信号输出到对应的输出引脚 + TIM_OCInitStructure.TIM_Pulse = 50; //脉冲宽度 + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //互补输出高电平有效 + TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补输出高电平有效 + TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //输出空闲状态为1 + TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //互补输出空闲状态为0 + TIM_OC1Init(TIM1, &TIM_OCInitStructure); //OC1通道初始化 + + TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); + TIM_ARRPreloadConfig(TIM1, ENABLE); + + //清中断,以免一启用中断后立即产生中断 + TIM_ClearFlag(TIM1, TIM_FLAG_Update); + //使能TIM1中断源 + TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); + TIM_Cmd(TIM1, DISABLE); + TIM_CtrlPWMOutputs(TIM1, ENABLE); //使能PWM输出 +} +#endif + +/******************************************************************************* + * @brief 电机驱动定时器初始化 + * @param None + * @retval None + * @Note 使用定时器TIM2,输出PWM,每次脉冲进入中断 +*******************************************************************************/ +void Motor_PWM_Init(void) +{ + TIM_TimeBaseInitTypeDef TIM_BaseInitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + TIM_OCInitTypeDef TIM_OCInitStructure; + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); + Motor_GPIO_Init(); + TIM_DeInit(TIM2); + //中断NVIC设置:允许中断,设置优先级 + NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //更新事件 TIM2_IRQHandler + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3 + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级1 + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //允许中断 + NVIC_Init(&NVIC_InitStructure); + TIM_BaseInitStructure.TIM_Period = 1000; + TIM_BaseInitStructure.TIM_Prescaler = 5; + TIM_BaseInitStructure.TIM_ClockDivision = 0; + TIM_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; + TIM_BaseInitStructure.TIM_RepetitionCounter = 0; + TIM_TimeBaseInit(TIM2, &TIM_BaseInitStructure); + + TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM2模式 + TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //信号输出到对应的输出引脚 + TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //互补信号输出到对应的输出引脚 + TIM_OCInitStructure.TIM_Pulse = 500; //脉冲宽度 + TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //互补输出高电平有效 + TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补输出高电平有效 + TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //输出空闲状态为1 + TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //互补输出空闲状态为0 + TIM_OC1Init(TIM2, &TIM_OCInitStructure); //OC1通道初始化 + + TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); + TIM_ARRPreloadConfig(TIM2, ENABLE); + //清中断,以免一启用中断后立即产生中断 + TIM_ClearFlag(TIM2, TIM_FLAG_Update); + //使能TIM1中断源 + TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); + TIM_Cmd(TIM2, DISABLE); + //TIM_CtrlPWMOutputs(TIM2,ENABLE); //使能PWM输出 +} + +/******************************************************************************* + * @brief 计算S型曲线表 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void Calculate_S_Table(void) +{ +} + +/******************************************************************************* + * @brief 电机初始化函数 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void MOTOR_Init(void) +{ + Motor_PWM_Init(); //初始化电机驱动PWM + /* 初始化电机参数 */ +} + +/******************************************************************************* + * @brief 定时器2中断函数 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void TIM2_IRQHandler(void) +{ + TIM2->SR = (u16)~TIM_FLAG_Update; + if (1 == pmotor->en) + { + //位置计算 + if (pmotor->dir_pos == pmotor->dir) + { + pmotor->current_puase++; + } + else + { + pmotor->current_puase--; + } + pmotor->current_step = pmotor->current_puase / pmotor->div; + + pmotor->passed_puase++; //总脉冲个数 + pmotor->f_puase++; //以该频率脉冲输出的脉冲个数 + + //对称反转??? + // if (pmotor->RevetDot == pmotor->PulsesHaven) + // { + // pmotor->pulsecount = pmotor->Step_Table[pmotor->CurrentIndex]; + // } + if (pmotor->f_puase >= pmotor->table_step[pmotor->f_index]) //一个频率的步数走完 + { + if (pmotor->passed_puase <= pmotor->start_step) //如果是起步阶段 + { + if (pmotor->f_index < pmotor->start_f - 1) + { + pmotor->f_index++; //进入下一个频率阶段 + pmotor->f_puase = 0; + if (pmotor->f_index >= pmotor->start_f) //启动阶段的步数没有走完,禁止进入下一阶段的频率 + pmotor->f_index = pmotor->start_f; + } + } + if (pmotor->target_puase - pmotor->passed_puase <= pmotor->stop_step) //停止阶段 + { + // if (pmotor->f_index < pmotor->StartTableLength - 1) + // { + // pmotor->f_index = pmotor->StartTableLength + pmotor->StopTableLength - pmotor->CurrentIndex; + // } + // pmotor->f_index++; + // pmotor->f_puase = 0; + // if (pmotor->f_index >= pmotor->StartTableLength + pmotor->StopTableLength) + // pmotor->CurrentIndex = pmotor->StartTableLength + pmotor->StopTableLength - 1; + } + pmotor->TIMx->ARR = pmotor->table_time[pmotor->f_index]; //设置周期 + pmotor->TIMx->CCR1 = (pmotor->table_time[pmotor->f_index]) >> 1; //设置占空比 + } + //旋转预定脉冲数,停止,running=0,可以进行下一次旋转 + if (pmotor->passed_puase >= pmotor->target_puase && pmotor->passed_puase > 3) + { + pmotor->en = 0; + pmotor->running = 0; + pmotor->f_index = 0; + TIM_Cmd(pmotor->TIMx, DISABLE); //DISABLE + } + } +} + +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/usart.c b/src/Driver/usart.c new file mode 100644 index 0000000..0505506 --- /dev/null +++ b/src/Driver/usart.c @@ -0,0 +1,167 @@ +/******************************************************************************* + * @file USART.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2017.8.24 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "usart.h" +/* Definition ----------------------------------------------------------------*/ + +/* Functions -----------------------------------------------------------------*/ +/******************************************************************************* + * @brief 串口发送一个字节 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void usart_send_char(USART_TypeDef *USARTx, char c) +{ + USART_SendData(USARTx, c); + while (RESET == USART_GetFlagStatus(USARTx, USART_FLAG_TXE)) + ; +} +/******************************************************************************* + * @brief USART发送字符串 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void usart_send_str(USART_TypeDef *USARTx, char *senddata) +{ + while ('\0' != *senddata) // \0 表示字符串结束标志,通过检测是否字符串末尾 + { + USART_SendData(USARTx, *senddata++); + while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET) + ; + } +} + +/******************************************************************************* + * @brief 打印数字,带进制转换 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void usart_send_number(USART_TypeDef *USARTx, unsigned long n, u8 base) +{ + unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars. + unsigned long i = 0; + + if (n == 0) + { + usart_send_char(USARTx, '0'); + return; + } + + while (n > 0) + { + buf[i++] = n % base; + n /= base; + } + + for (; i > 0; i--) + usart_send_char(USARTx, (char)(buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10)); +} + +//加入以下代码,支持printf函数,而不需要选择use MicroLIB +#if 1 +#pragma import(__use_no_semihosting) +//标准库需要的支持函数 +struct __FILE +{ + int handle; +}; + +FILE __stdout; +//定义_sys_exit()以避免使用半主机模式 +_sys_exit(int x) +{ + x = x; +} +//重定义fputc函数 +int fputc(int ch, FILE *f) +{ + USART_SendData(USART_DEBUG, ch); + while (RESET == USART_GetFlagStatus(USART_DEBUG, USART_FLAG_TXE)) + ; + return ch; +} +#endif + +#ifdef DEBUG +/******************************************************************************* + * @brief 初始化串口1,用于printf输出 + * @param bound:波特率 + * @retval None + * @Note None +*******************************************************************************/ +void usart_debug_init(u32 bound) +{ + GPIO_InitTypeDef GPIO_InitStructure; + USART_InitTypeDef USART_InitStructure; + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能GPIOB时钟 + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能USART1时钟 + //串口1对应引脚复用映射 + GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); //GPIOB9复用为USART1 + GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); //GPIOB10复用为USART1 + //USART1端口配置 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 + GPIO_Init(GPIOB, &GPIO_InitStructure); + //485收发使能端口 + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 + GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 + //USART1 初始化设置 + USART_InitStructure.USART_BaudRate = bound; //波特率设置 + USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式 + 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(USART1, &USART_InitStructure); //初始化串口3 + USART_Cmd(USART1, ENABLE); //使能串口3 + USART_ClearFlag(USART1, USART_FLAG_TC); +} + +/******************************************************************************* + * @brief 串口发送1个字符 + * @param USARTx:串口端口 c:要发送的字符 + * @retval None + * @Note None +*******************************************************************************/ +void debug_send_char(u8 c) +{ + USART_TX_EN; + simple_delay_us(100); + usart_send_char(USART_DEBUG, c); + simple_delay_us(100); + USART_RX_EN; +} + +/******************************************************************************* + * @brief 串口发送字符串 + * @param USARTx:串口端口 str:要发送的字符串 + * @retval None + * @Note None +*******************************************************************************/ +void debug_send_str(char *str) +{ + USART_TX_EN; + simple_delay_us(100); + usart_send_str(USART_DEBUG, str); + simple_delay_us(100); + USART_RX_EN; +} +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/Driver/usart_debug.c b/src/Driver/usart_debug.c deleted file mode 100644 index 519e949..0000000 --- a/src/Driver/usart_debug.c +++ /dev/null @@ -1,123 +0,0 @@ -/******************************************************************************* - * @file USART.c - * @Author: MQjehovah mail:MQjehovah@hotmail.com - * @version 1.0.0 - * @date 2017.11.22 - * @brief - ****************************************************************************** - * @attention -*******************************************************************************/ -/* Includes ------------------------------------------------------------------*/ -#include "usart_debug.h" -/* Definition ----------------------------------------------------------------*/ - -/* Functions -----------------------------------------------------------------*/ -/******************************************************************************* - * @brief 串口初始化 - * @param None - * @retval None - * @Note None -*******************************************************************************/ -void usart_debug_init() -{ - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); //使能GPIOB时钟 - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //使能USART1时钟 - //串口1对应引脚复用映射 - GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); //GPIOB9复用为USART1 - GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1); //GPIOB10复用为USART1 - //USART1端口配置 - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能 - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 - GPIO_Init(GPIOB, &GPIO_InitStructure); - //串口使能R/D初始化设置 - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //普通输出模式 - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 - GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化 - //USART1 初始化设置 - USART_InitStructure.USART_BaudRate = 115200; //波特率设置 - USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式 - 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(USART1, &USART_InitStructure); //初始化串口3 - USART_Cmd(USART1, ENABLE); //使能串口3 - USART_ClearFlag(USART1, USART_FLAG_TC); - //Usart1 NVIC 配置 - NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //串口1中断通道 - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //抢占优先级3 - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3 - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 - NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、 - USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启相关中断 - GPIO_SetBits(GPIOB, GPIO_Pin_5); //发送模式 -} - -/******************************************************************************* - * @brief 串口1中断函数 - * @param None - * @retval None - * @Note None -*******************************************************************************/ -void USART1_IRQHandler(void) -{ - if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //如果寄存器中有数据 - { - u8 data = USART_ReceiveData(USART1); - // Parser(data); - } - if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) - { - USART_ClearITPendingBit(USART1, USART_IT_TC); - } -} - -//不使用半主机模式 -#if 1 //如果没有这段,则需要在target选项中选择使用USE microLIB -#pragma import(__use_no_semihosting) -struct __FILE -{ - int handle; -}; -FILE __stdout; - -void _sys_exit(int x) -{ - x = x; -} -#endif -#ifdef __GNUC__ -/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf - set to 'Yes') calls __io_putchar() */ -int _write(int fd, char *pBuffer, int size) -{ - for (int i = 0; i < size; i++) - { - USART_SendData(USART_DEBUG, pBuffer[i]); - while (USART_GetFlagStatus(USART_DEBUG, USART_FLAG_TXE) == RESET) - ; - } - return size; -} -#else -int fputc(int ch, FILE *f) -{ - /* Place your implementation of fputc here */ - /* e.g. write a character to the USART */ - USART_SendData(USART_DEBUG, ch); - /* Loop until the end of transmission */ - while (USART_GetFlagStatus(USART_DEBUG, USART_FLAG_TXE) == RESET) - ; - return ch; -} -#endif /* __GNUC__ */ -/*********************************END OF FILE**********************************/ diff --git a/src/Startup/system_stm32f4xx.c b/src/Startup/system_stm32f4xx.c index c837ca1..427d377 100644 --- a/src/Startup/system_stm32f4xx.c +++ b/src/Startup/system_stm32f4xx.c @@ -2,24 +2,24 @@ ****************************************************************************** * @file system_stm32f4xx.c * @author MCD Application Team - * @version V1.8.0 - * @date 09-November-2016 + * @version V1.4.0 + * @date 04-August-2014 * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. * This file contains the system clock configuration for STM32F4xx devices. - * - * 1. This file provides two functions and one global variable to be called from + * + * 1. This file provides two functions and one global variable to be called from * user application: * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier * and Divider factors, AHB/APBx prescalers and Flash settings), - * depending on the configuration made in the clock xls tool. - * This function is called at startup just after reset and + * depending on the configuration made in the clock xls tool. + * This function is called at startup just after reset and * before branch to main program. This call is made inside * the "startup_stm32f4xx.s" file. * * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used - * by the user application to setup the SysTick + * by the user application to setup the SysTick * timer or configure other parameters. - * + * * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must * be called whenever the core clock is changed * during program execution. @@ -29,7 +29,7 @@ * configure the system clock before to branch to main program. * * 3. If the system clock source selected by user fails to startup, the SystemInit() - * function will do nothing and HSI still used as system clock source. User can + * function will do nothing and HSI still used as system clock source. User can * add some code to deal with this issue inside the SetSysClock() function. * * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define @@ -181,7 +181,7 @@ *----------------------------------------------------------------------------- *============================================================================= *============================================================================= - * Supported STM32F411xx/STM32F410xx devices + * Supported STM32F411xx devices *----------------------------------------------------------------------------- * System Clock source | PLL (HSI) *----------------------------------------------------------------------------- @@ -227,65 +227,10 @@ * SDIO and RNG clock | *----------------------------------------------------------------------------- *============================================================================= - *============================================================================= - * Supported STM32F446xx devices - *----------------------------------------------------------------------------- - * System Clock source | PLL (HSE) - *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 180000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 180000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB1 Prescaler | 4 - *----------------------------------------------------------------------------- - * APB2 Prescaler | 2 - *----------------------------------------------------------------------------- - * HSE Frequency(Hz) | 8000000 - *----------------------------------------------------------------------------- - * PLL_M | 8 - *----------------------------------------------------------------------------- - * PLL_N | 360 - *----------------------------------------------------------------------------- - * PLL_P | 2 - *----------------------------------------------------------------------------- - * PLL_Q | 7 - *----------------------------------------------------------------------------- - * PLL_R | NA - *----------------------------------------------------------------------------- - * PLLI2S_M | NA - *----------------------------------------------------------------------------- - * PLLI2S_N | NA - *----------------------------------------------------------------------------- - * PLLI2S_P | NA - *----------------------------------------------------------------------------- - * PLLI2S_Q | NA - *----------------------------------------------------------------------------- - * PLLI2S_R | NA - *----------------------------------------------------------------------------- - * I2S input clock | NA - *----------------------------------------------------------------------------- - * VDD(V) | 3.3 - *----------------------------------------------------------------------------- - * Main regulator output voltage | Scale1 mode - *----------------------------------------------------------------------------- - * Flash Latency(WS) | 5 - *----------------------------------------------------------------------------- - * Prefetch Buffer | ON - *----------------------------------------------------------------------------- - * Instruction cache | ON - *----------------------------------------------------------------------------- - * Data cache | ON - *----------------------------------------------------------------------------- - * Require 48MHz for USB OTG FS, | Disabled - * SDIO and RNG clock | - *----------------------------------------------------------------------------- - *============================================================================= ****************************************************************************** * @attention * - *

© COPYRIGHT 2016 STMicroelectronics

+ *

© COPYRIGHT 2014 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. @@ -293,8 +238,8 @@ * * http://www.st.com/software_license_agreement_liberty_v2 * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. @@ -308,8 +253,8 @@ /** @addtogroup stm32f4xx_system * @{ - */ - + */ + /** @addtogroup STM32F4xx_System_Private_Includes * @{ */ @@ -334,30 +279,30 @@ /************************* Miscellaneous Configuration ************************/ /*!< Uncomment the following line if you need to use external SRAM or SDRAM mounted - on STM324xG_EVAL/STM324x7I_EVAL/STM324x9I_EVAL boards as data memory */ -#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F469_479xx) || defined(STM32F413_423xx) + on STM324xG_EVAL/STM324x7I_EVAL/STM324x9I_EVAL boards as data memory */ +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) /* #define DATA_IN_ExtSRAM */ -#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx || STM32F413_423xx */ +#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */ -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) /* #define DATA_IN_ExtSDRAM */ -#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ +#endif /* STM32F427_437x || STM32F429_439xx */ -#if defined(STM32F410xx) || defined(STM32F411xE) -/*!< Uncomment the following line if you need to clock the STM32F410xx/STM32F411xE by HSE Bypass +#if defined (STM32F411xE) +/*!< Uncomment the following line if you need to clock the STM32F411xE by HSE Bypass through STLINK MCO pin of STM32F103 microcontroller. The frequency cannot be changed - and is fixed at 8 MHz. + and is fixed at 8 MHz. Hardware configuration needed for Nucleo Board: - SB54, SB55 OFF - R35 removed - SB16, SB50 ON */ + ?SB54, SB55 OFF + ?R35 removed + ?SB16, SB50 ON */ /* #define USE_HSE_BYPASS */ -#if defined(USE_HSE_BYPASS) +#if defined (USE_HSE_BYPASS) #define HSE_BYPASS_INPUT_FREQUENCY 8000000 -#endif /* USE_HSE_BYPASS */ -#endif /* STM32F410xx || STM32F411xE */ - +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F411xE */ + /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ @@ -366,54 +311,43 @@ /******************************************************************************/ /************************* PLL Parameters *************************************/ -#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx) - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ - #define PLL_M 25 -#elif defined(STM32F412xG) || defined(STM32F413_423xx) || defined (STM32F446xx) - #define PLL_M 8 -#elif defined (STM32F410xx) || defined (STM32F411xE) - #if defined(USE_HSE_BYPASS) - #define PLL_M 8 - #else /* !USE_HSE_BYPASS */ - #define PLL_M 16 - #endif /* USE_HSE_BYPASS */ -#else -#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */ +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) +/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ +#define PLL_M 8 +#else /* STM32F411xE */ +#if defined (USE_HSE_BYPASS) +#define PLL_M 8 +#else /* STM32F411xE */ +#define PLL_M 16 +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */ /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ #define PLL_Q 7 -#if defined(STM32F446xx) -/* PLL division factor for I2S, SAI, SYSTEM and SPDIF: Clock = PLL_VCO / PLLR */ -#define PLL_R 7 -#elif defined(STM32F412xG) || defined(STM32F413_423xx) -#define PLL_R 2 -#else -#endif /* STM32F446xx */ - -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) -#define PLL_N 360 -/* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 2 -#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ - #if defined (STM32F40_41xxx) #define PLL_N 336 /* SYSCLK = PLL_VCO / PLL_P */ #define PLL_P 2 #endif /* STM32F40_41xxx */ -#if defined(STM32F401xx) +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +#define PLL_N 360 +/* SYSCLK = PLL_VCO / PLL_P */ +#define PLL_P 2 +#endif /* STM32F427_437x || STM32F429_439xx */ + +#if defined (STM32F401xx) #define PLL_N 336 /* SYSCLK = PLL_VCO / PLL_P */ #define PLL_P 4 #endif /* STM32F401xx */ -#if defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F412xG) || defined(STM32F413_423xx) +#if defined (STM32F411xE) #define PLL_N 400 /* SYSCLK = PLL_VCO / PLL_P */ -#define PLL_P 4 -#endif /* STM32F410xx || STM32F411xE || STM32F412xG || STM32F413_423xx */ +#define PLL_P 4 +#endif /* STM32F411xx */ /******************************************************************************/ @@ -433,21 +367,21 @@ * @{ */ -#if defined(STM32F40_41xxx) - uint32_t SystemCoreClock = 168000000; +#if defined (STM32F40_41xxx) +uint32_t SystemCoreClock = 168000000; #endif /* STM32F40_41xxx */ -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) - uint32_t SystemCoreClock = 180000000; -#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) +uint32_t SystemCoreClock = 180000000; +#endif /* STM32F427_437x || STM32F429_439xx */ -#if defined(STM32F401xx) - uint32_t SystemCoreClock = 84000000; +#if defined (STM32F401xx) +uint32_t SystemCoreClock = 84000000; #endif /* STM32F401xx */ -#if defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F412xG) || defined(STM32F413_423xx) - uint32_t SystemCoreClock = 100000000; -#endif /* STM32F410xx || STM32F401xE || STM32F412xG || STM32F413_423xx */ +#if defined (STM32F411xE) +uint32_t SystemCoreClock = 100000000; +#endif /* STM32F401xx */ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; @@ -461,8 +395,8 @@ __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9} static void SetSysClock(void); -#if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM) -static void SystemInit_ExtMemCtl(void); +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) +static void SystemInit_ExtMemCtl(void); #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ /** @@ -475,49 +409,41 @@ static void SystemInit_ExtMemCtl(void); /** * @brief Setup the microcontroller system - * Initialize the Embedded Flash Interface, the PLL and update the + * Initialize the Embedded Flash Interface, the PLL and update the * SystemFrequency variable. * @param None * @retval None */ void SystemInit(void) { - /* FPU settings ------------------------------------------------------------*/ - #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + /* FPU settings ------------------------------------------------------------*/ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ - #endif - /* Reset the RCC clock configuration to the default reset state ------------*/ - /* Set HSION bit */ - RCC->CR |= (uint32_t)0x00000001; - - /* Reset CFGR register */ - RCC->CFGR = 0x00000000; - - /* Reset HSEON, CSSON and PLLON bits */ - RCC->CR &= (uint32_t)0xFEF6FFFF; - - /* Reset PLLCFGR register */ - RCC->PLLCFGR = 0x24003010; - - /* Reset HSEBYP bit */ - RCC->CR &= (uint32_t)0xFFFBFFFF; - - /* Disable all interrupts */ - RCC->CIR = 0x00000000; - -#if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM) - SystemInit_ExtMemCtl(); +#endif + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set HSION bit */ + RCC->CR |= (uint32_t)0x00000001; + /* Reset CFGR register */ + RCC->CFGR = 0x00000000; + /* Reset HSEON, CSSON and PLLON bits */ + RCC->CR &= (uint32_t)0xFEF6FFFF; + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x24003010; + /* Reset HSEBYP bit */ + RCC->CR &= (uint32_t)0xFFFBFFFF; + /* Disable all interrupts */ + RCC->CIR = 0x00000000; +#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM) + SystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */ - - /* Configure the System clock source, PLL Multiplier and Divider factors, - AHB/APBx prescalers and Flash settings ----------------------------------*/ - SetSysClock(); - - /* Configure the Vector Table location add offset address ------------------*/ + /* Configure the System clock source, PLL Multiplier and Divider factors, + AHB/APBx prescalers and Flash settings ----------------------------------*/ + SetSysClock(); + /* Configure the Vector Table location add offset address ------------------*/ #ifdef VECT_TAB_SRAM - SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ #else - SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ #endif } @@ -526,525 +452,286 @@ void SystemInit(void) * The SystemCoreClock variable contains the core clock (HCLK), it can * be used by the user application to setup the SysTick timer or configure * other parameters. - * + * * @note Each time the core clock (HCLK) changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: - * + * * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) - * + * * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) - * - * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * or HSI_VALUE(*) multiplied/divided by the PLL factors. - * + * * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * + * in voltage and temperature. + * * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value * 25 MHz), user has to ensure that HSE_VALUE is same as the real * frequency of the crystal used. Otherwise, this function may * have wrong result. - * + * * - The result of this function could be not correct when using fractional * value for HSE crystal. - * + * * @param None * @retval None */ void SystemCoreClockUpdate(void) { - uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; -#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) - uint32_t pllr = 2; -#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx */ - /* Get SYSCLK source -------------------------------------------------------*/ - tmp = RCC->CFGR & RCC_CFGR_SWS; - - switch (tmp) - { + uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; + /* Get SYSCLK source -------------------------------------------------------*/ + tmp = RCC->CFGR & RCC_CFGR_SWS; + switch (tmp) + { case 0x00: /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; + SystemCoreClock = HSI_VALUE; + break; case 0x04: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; - case 0x08: /* PLL P used as system clock source */ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N - SYSCLK = PLL_VCO / PLL_P - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; - pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - -#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) || defined(STM32F469_479xx) - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - else - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } -#elif defined(STM32F410xx) || defined(STM32F411xE) -#if defined(USE_HSE_BYPASS) - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_BYPASS_INPUT_FREQUENCY / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } -#else - if (pllsource == 0) - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } -#endif /* USE_HSE_BYPASS */ -#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F412xG || STM32F413_423xx || STM32F446xx || STM32F469_479xx */ - pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; - SystemCoreClock = pllvco/pllp; - break; -#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) - case 0x0C: /* PLL R used as system clock source */ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N - SYSCLK = PLL_VCO / PLL_R - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; - pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; - if (pllsource != 0) - { - /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - else - { - /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); - } - - pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >>28) + 1 ) *2; - SystemCoreClock = pllvco/pllr; - break; -#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx */ + SystemCoreClock = HSE_VALUE; + break; + case 0x08: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N + SYSCLK = PLL_VCO / PLL_P + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; + pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } + else + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } +#elif defined (STM32F411xE) +#if defined (USE_HSE_BYPASS) + if (pllsource != 0) + { + /* HSE used as PLL clock source */ + pllvco = (HSE_BYPASS_INPUT_FREQUENCY / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } +#else + if (pllsource == 0) + { + /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); + } +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */ + pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; + SystemCoreClock = pllvco/pllp; + break; default: - SystemCoreClock = HSI_VALUE; - break; - } - /* Compute HCLK frequency --------------------------------------------------*/ - /* Get HCLK prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; - /* HCLK frequency */ - SystemCoreClock >>= tmp; + SystemCoreClock = HSI_VALUE; + break; + } + /* Compute HCLK frequency --------------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; + /* HCLK frequency */ + SystemCoreClock >>= tmp; } /** - * @brief Configures the System clock source, PLL Multiplier and Divider factors, + * @brief Configures the System clock source, PLL Multiplier and Divider factors, * AHB/APBx prescalers and Flash settings - * @Note This function should be called only once the RCC clock configuration - * is reset to the default reset state (done in SystemInit() function). + * @Note This function should be called only once the RCC clock configuration + * is reset to the default reset state (done in SystemInit() function). * @param None * @retval None */ static void SetSysClock(void) { -#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx)|| defined(STM32F469_479xx) -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* Enable HSE */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { - /* Select regulator voltage output Scale 1 mode */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_VOS; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - -#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F412xG) || defined(STM32F446xx) || defined(STM32F469_479xx) - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; -#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx || STM32F412xG || STM32F446xx || STM32F469_479xx */ - -#if defined(STM32F401xx) || defined(STM32F413_423xx) - /* PCLK2 = HCLK / 1*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; -#endif /* STM32F401xx || STM32F413_423xx */ - -#if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx) - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); -#endif /* STM32F40_41xxx || STM32F401xx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx */ - -#if defined(STM32F412xG) || defined(STM32F413_423xx) || defined(STM32F446xx) - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24) | (PLL_R << 28); -#endif /* STM32F412xG || STM32F413_423xx || STM32F446xx */ - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx) + /******************************************************************************/ + /* PLL (clocked by HSE) used as System clock source */ + /******************************************************************************/ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + /* Enable HSE */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON); + /* Wait till HSE is ready and if Time out is reached exit */ + do { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; } - -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) - /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ - PWR->CR |= PWR_CR_ODEN; - while((PWR->CSR & PWR_CSR_ODRDY) == 0) + while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + if ((RCC->CR & RCC_CR_HSERDY) != RESET) { + HSEStatus = (uint32_t)0x01; } - PWR->CR |= PWR_CR_ODSWEN; - while((PWR->CSR & PWR_CSR_ODSWRDY) == 0) + else { - } - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; -#endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ - -#if defined(STM32F40_41xxx) || defined(STM32F412xG) - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; -#endif /* STM32F40_41xxx || STM32F412xG */ - -#if defined(STM32F413_423xx) - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_3WS; -#endif /* STM32F413_423xx */ - -#if defined(STM32F401xx) - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; + HSEStatus = (uint32_t)0x00; + } + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 1 mode */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR |= PWR_CR_VOS; + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; +#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; +#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx */ +#if defined (STM32F401xx) + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; #endif /* STM32F401xx */ - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) + /* Enable the Over-drive to extend the clock frequency to 180 Mhz */ + PWR->CR |= PWR_CR_ODEN; + while((PWR->CSR & PWR_CSR_ODRDY) == 0) + { + } + PWR->CR |= PWR_CR_ODSWEN; + while((PWR->CSR & PWR_CSR_ODSWRDY) == 0) + { + } + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; +#endif /* STM32F427_437x || STM32F429_439xx */ +#if defined (STM32F40_41xxx) + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; +#endif /* STM32F40_41xxx */ +#if defined (STM32F401xx) + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; +#endif /* STM32F401xx */ + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -#elif defined(STM32F410xx) || defined(STM32F411xE) -#if defined(USE_HSE_BYPASS) -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ - __IO uint32_t StartUpCounter = 0, HSEStatus = 0; - - /* Enable HSE and HSE BYPASS */ - RCC->CR |= ((uint32_t)RCC_CR_HSEON | RCC_CR_HSEBYP); - - /* Wait till HSE is ready and if Time out is reached exit */ - do - { - HSEStatus = RCC->CR & RCC_CR_HSERDY; - StartUpCounter++; - } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); - - if ((RCC->CR & RCC_CR_HSERDY) != RESET) - { - HSEStatus = (uint32_t)0x01; - } - else - { - HSEStatus = (uint32_t)0x00; - } - - if (HSEStatus == (uint32_t)0x01) - { + else + { + /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +#elif defined (STM32F411xE) +#if defined (USE_HSE_BYPASS) + /******************************************************************************/ + /* PLL (clocked by HSE) used as System clock source */ + /******************************************************************************/ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + /* Enable HSE and HSE BYPASS */ + RCC->CR |= ((uint32_t)RCC_CR_HSEON | RCC_CR_HSEBYP); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CR & RCC_CR_HSERDY; + StartUpCounter++; + } + while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + if ((RCC->CR & RCC_CR_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + if (HSEStatus == (uint32_t)0x01) + { + /* Select regulator voltage output Scale 1 mode */ + RCC->APB1ENR |= RCC_APB1ENR_PWREN; + PWR->CR |= PWR_CR_VOS; + /* HCLK = SYSCLK / 1*/ + RCC->CFGR |= RCC_CFGR_HPRE_DIV1; + /* PCLK2 = HCLK / 2*/ + RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; + /* PCLK1 = HCLK / 4*/ + RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; + /* Configure the main PLL */ + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | + (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); + /* Enable the main PLL */ + RCC->CR |= RCC_CR_PLLON; + /* Wait till the main PLL is ready */ + while((RCC->CR & RCC_CR_PLLRDY) == 0) + { + } + /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ + FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; + /* Select the main PLL as system clock source */ + RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); + RCC->CFGR |= RCC_CFGR_SW_PLL; + /* Wait till the main PLL is used as system clock source */ + while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + configuration. User can add here some code to deal with this error */ + } +#else /* HSI will be used as PLL clock source */ /* Select regulator voltage output Scale 1 mode */ RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS; - /* HCLK = SYSCLK / 1*/ RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - /* PCLK2 = HCLK / 2*/ RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; - /* PCLK1 = HCLK / 4*/ RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | - (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); - + RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (PLL_Q << 24); /* Enable the main PLL */ RCC->CR |= RCC_CR_PLLON; - /* Wait till the main PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; - /* Select the main PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= RCC_CFGR_SW_PLL; - /* Wait till the main PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); { } - } - else - { /* If HSE fails to start-up, the application will have wrong clock - configuration. User can add here some code to deal with this error */ - } -#else /* HSI will be used as PLL clock source */ - /* Select regulator voltage output Scale 1 mode */ - RCC->APB1ENR |= RCC_APB1ENR_PWREN; - PWR->CR |= PWR_CR_VOS; - - /* HCLK = SYSCLK / 1*/ - RCC->CFGR |= RCC_CFGR_HPRE_DIV1; - - /* PCLK2 = HCLK / 2*/ - RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; - - /* PCLK1 = HCLK / 4*/ - RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; - - /* Configure the main PLL */ - RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (PLL_Q << 24); - - /* Enable the main PLL */ - RCC->CR |= RCC_CR_PLLON; - - /* Wait till the main PLL is ready */ - while((RCC->CR & RCC_CR_PLLRDY) == 0) - { - } - - /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ - FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS; - - /* Select the main PLL as system clock source */ - RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); - RCC->CFGR |= RCC_CFGR_SW_PLL; - - /* Wait till the main PLL is used as system clock source */ - while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); - { - } -#endif /* USE_HSE_BYPASS */ -#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */ +#endif /* USE_HSE_BYPASS */ +#endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx */ } -#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM) -#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ - defined(STM32F469xx) || defined(STM32F479xx) + /** - * @brief Setup the external memory controller. - * Called in startup_stm32f4xx.s before jump to main. - * This function configures the external memories (SRAM/SDRAM) - * This SRAM/SDRAM will be used as program data memory (including heap and stack). - * @param None - * @retval None - */ -void SystemInit_ExtMemCtl(void) -{ - __IO uint32_t tmp = 0x00; - - register uint32_t tmpreg = 0, timeout = 0xFFFF; - register uint32_t index; - - /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */ - RCC->AHB1ENR |= 0x000001F8; - - /* Delay after an RCC peripheral clock enabling */ - tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN); - - /* Connect PDx pins to FMC Alternate function */ - GPIOD->AFR[0] = 0x00CCC0CC; - GPIOD->AFR[1] = 0xCCCCCCCC; - /* Configure PDx pins in Alternate function mode */ - GPIOD->MODER = 0xAAAA0A8A; - /* Configure PDx pins speed to 100 MHz */ - GPIOD->OSPEEDR = 0xFFFF0FCF; - /* Configure PDx pins Output type to push-pull */ - GPIOD->OTYPER = 0x00000000; - /* No pull-up, pull-down for PDx pins */ - GPIOD->PUPDR = 0x00000000; - - /* Connect PEx pins to FMC Alternate function */ - GPIOE->AFR[0] = 0xC00CC0CC; - GPIOE->AFR[1] = 0xCCCCCCCC; - /* Configure PEx pins in Alternate function mode */ - GPIOE->MODER = 0xAAAA828A; - /* Configure PEx pins speed to 100 MHz */ - GPIOE->OSPEEDR = 0xFFFFC3CF; - /* Configure PEx pins Output type to push-pull */ - GPIOE->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - GPIOE->PUPDR = 0x00000000; - - /* Connect PFx pins to FMC Alternate function */ - GPIOF->AFR[0] = 0xCCCCCCCC; - GPIOF->AFR[1] = 0xCCCCCCCC; - /* Configure PFx pins in Alternate function mode */ - GPIOF->MODER = 0xAA800AAA; - /* Configure PFx pins speed to 50 MHz */ - GPIOF->OSPEEDR = 0xAA800AAA; - /* Configure PFx pins Output type to push-pull */ - GPIOF->OTYPER = 0x00000000; - /* No pull-up, pull-down for PFx pins */ - GPIOF->PUPDR = 0x00000000; - - /* Connect PGx pins to FMC Alternate function */ - GPIOG->AFR[0] = 0xCCCCCCCC; - GPIOG->AFR[1] = 0xCCCCCCCC; - /* Configure PGx pins in Alternate function mode */ - GPIOG->MODER = 0xAAAAAAAA; - /* Configure PGx pins speed to 50 MHz */ - GPIOG->OSPEEDR = 0xAAAAAAAA; - /* Configure PGx pins Output type to push-pull */ - GPIOG->OTYPER = 0x00000000; - /* No pull-up, pull-down for PGx pins */ - GPIOG->PUPDR = 0x00000000; - - /* Connect PHx pins to FMC Alternate function */ - GPIOH->AFR[0] = 0x00C0CC00; - GPIOH->AFR[1] = 0xCCCCCCCC; - /* Configure PHx pins in Alternate function mode */ - GPIOH->MODER = 0xAAAA08A0; - /* Configure PHx pins speed to 50 MHz */ - GPIOH->OSPEEDR = 0xAAAA08A0; - /* Configure PHx pins Output type to push-pull */ - GPIOH->OTYPER = 0x00000000; - /* No pull-up, pull-down for PHx pins */ - GPIOH->PUPDR = 0x00000000; - - /* Connect PIx pins to FMC Alternate function */ - GPIOI->AFR[0] = 0xCCCCCCCC; - GPIOI->AFR[1] = 0x00000CC0; - /* Configure PIx pins in Alternate function mode */ - GPIOI->MODER = 0x0028AAAA; - /* Configure PIx pins speed to 50 MHz */ - GPIOI->OSPEEDR = 0x0028AAAA; - /* Configure PIx pins Output type to push-pull */ - GPIOI->OTYPER = 0x00000000; - /* No pull-up, pull-down for PIx pins */ - GPIOI->PUPDR = 0x00000000; - -/*-- FMC Configuration -------------------------------------------------------*/ - /* Enable the FMC interface clock */ - RCC->AHB3ENR |= 0x00000001; - /* Delay after an RCC peripheral clock enabling */ - tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN); - - FMC_Bank5_6->SDCR[0] = 0x000019E4; - FMC_Bank5_6->SDTR[0] = 0x01115351; - - /* SDRAM initialization sequence */ - /* Clock enable command */ - FMC_Bank5_6->SDCMR = 0x00000011; - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - while((tmpreg != 0) && (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* Delay */ - for (index = 0; index<1000; index++); - - /* PALL command */ - FMC_Bank5_6->SDCMR = 0x00000012; - timeout = 0xFFFF; - while((tmpreg != 0) && (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* Auto refresh command */ - FMC_Bank5_6->SDCMR = 0x00000073; - timeout = 0xFFFF; - while((tmpreg != 0) && (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* MRD register program */ - FMC_Bank5_6->SDCMR = 0x00046014; - timeout = 0xFFFF; - while((tmpreg != 0) && (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* Set refresh count */ - tmpreg = FMC_Bank5_6->SDRTR; - FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); - - /* Disable write protection */ - tmpreg = FMC_Bank5_6->SDCR[0]; - FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); - -#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) - /* Configure and enable Bank1_SRAM2 */ - FMC_Bank1->BTCR[2] = 0x00001011; - FMC_Bank1->BTCR[3] = 0x00000201; - FMC_Bank1E->BWTR[2] = 0x0fffffff; -#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ -#if defined(STM32F469xx) || defined(STM32F479xx) - /* Configure and enable Bank1_SRAM2 */ - FMC_Bank1->BTCR[2] = 0x00001091; - FMC_Bank1->BTCR[3] = 0x00110212; - FMC_Bank1E->BWTR[2] = 0x0fffffff; -#endif /* STM32F469xx || STM32F479xx */ - - (void)(tmp); -} -#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */ -#elif defined (DATA_IN_ExtSRAM) -/** - * @brief Setup the external memory controller. Called in startup_stm32f4xx.s + * @brief Setup the external memory controller. Called in startup_stm32f4xx.s * before jump to __main * @param None * @retval None - */ + */ +#ifdef DATA_IN_ExtSRAM /** * @brief Setup the external memory controller. * Called in startup_stm32f4xx.s before jump to main. @@ -1055,151 +742,144 @@ void SystemInit_ExtMemCtl(void) */ void SystemInit_ExtMemCtl(void) { -/*-- GPIOs Configuration -----------------------------------------------------*/ -/* - +-------------------+--------------------+------------------+--------------+ - + SRAM pins assignment + - +-------------------+--------------------+------------------+--------------+ - | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 | - | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 | - | PD4 <-> FMC_NOE | PE3 <-> FMC_A19 | PF2 <-> FMC_A2 | PG2 <-> FMC_A12 | - | PD5 <-> FMC_NWE | PE4 <-> FMC_A20 | PF3 <-> FMC_A3 | PG3 <-> FMC_A13 | - | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF4 <-> FMC_A4 | PG4 <-> FMC_A14 | - | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF5 <-> FMC_A5 | PG5 <-> FMC_A15 | - | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF12 <-> FMC_A6 | PG9 <-> FMC_NE2 | - | PD11 <-> FMC_A16 | PE10 <-> FMC_D7 | PF13 <-> FMC_A7 |-----------------+ - | PD12 <-> FMC_A17 | PE11 <-> FMC_D8 | PF14 <-> FMC_A8 | - | PD13 <-> FMC_A18 | PE12 <-> FMC_D9 | PF15 <-> FMC_A9 | - | PD14 <-> FMC_D0 | PE13 <-> FMC_D10 |-----------------+ - | PD15 <-> FMC_D1 | PE14 <-> FMC_D11 | - | | PE15 <-> FMC_D12 | - +------------------+------------------+ -*/ - /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ - RCC->AHB1ENR |= 0x00000078; - - /* Connect PDx pins to FMC Alternate function */ - GPIOD->AFR[0] = 0x00cc00cc; - GPIOD->AFR[1] = 0xcccccccc; - /* Configure PDx pins in Alternate function mode */ - GPIOD->MODER = 0xaaaa0a0a; - /* Configure PDx pins speed to 100 MHz */ - GPIOD->OSPEEDR = 0xffff0f0f; - /* Configure PDx pins Output type to push-pull */ - GPIOD->OTYPER = 0x00000000; - /* No pull-up, pull-down for PDx pins */ - GPIOD->PUPDR = 0x00000000; - - /* Connect PEx pins to FMC Alternate function */ - GPIOE->AFR[0] = 0xcccccccc; - GPIOE->AFR[1] = 0xcccccccc; - /* Configure PEx pins in Alternate function mode */ - GPIOE->MODER = 0xaaaaaaaa; - /* Configure PEx pins speed to 100 MHz */ - GPIOE->OSPEEDR = 0xffffffff; - /* Configure PEx pins Output type to push-pull */ - GPIOE->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - GPIOE->PUPDR = 0x00000000; - - /* Connect PFx pins to FMC Alternate function */ - GPIOF->AFR[0] = 0x00cccccc; - GPIOF->AFR[1] = 0xcccc0000; - /* Configure PFx pins in Alternate function mode */ - GPIOF->MODER = 0xaa000aaa; - /* Configure PFx pins speed to 100 MHz */ - GPIOF->OSPEEDR = 0xff000fff; - /* Configure PFx pins Output type to push-pull */ - GPIOF->OTYPER = 0x00000000; - /* No pull-up, pull-down for PFx pins */ - GPIOF->PUPDR = 0x00000000; - - /* Connect PGx pins to FMC Alternate function */ - GPIOG->AFR[0] = 0x00cccccc; - GPIOG->AFR[1] = 0x000000c0; - /* Configure PGx pins in Alternate function mode */ - GPIOG->MODER = 0x00080aaa; - /* Configure PGx pins speed to 100 MHz */ - GPIOG->OSPEEDR = 0x000c0fff; - /* Configure PGx pins Output type to push-pull */ - GPIOG->OTYPER = 0x00000000; - /* No pull-up, pull-down for PGx pins */ - GPIOG->PUPDR = 0x00000000; - -/*-- FMC Configuration ------------------------------------------------------*/ - /* Enable the FMC/FSMC interface clock */ - RCC->AHB3ENR |= 0x00000001; - -#if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx) - /* Configure and enable Bank1_SRAM2 */ - FMC_Bank1->BTCR[2] = 0x00001011; - FMC_Bank1->BTCR[3] = 0x00000201; - FMC_Bank1E->BWTR[2] = 0x0fffffff; -#endif /* STM32F427_437xx || STM32F429_439xx || STM32F446xx || STM32F469_479xx */ - -#if defined(STM32F40_41xxx) - /* Configure and enable Bank1_SRAM2 */ - FSMC_Bank1->BTCR[2] = 0x00001011; - FSMC_Bank1->BTCR[3] = 0x00000201; - FSMC_Bank1E->BWTR[2] = 0x0fffffff; + /*-- GPIOs Configuration -----------------------------------------------------*/ + /* + +-------------------+--------------------+------------------+--------------+ + + SRAM pins assignment + + +-------------------+--------------------+------------------+--------------+ + | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> FMC_A10 | + | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | PG1 <-> FMC_A11 | + | PD4 <-> FMC_NOE | PE3 <-> FMC_A19 | PF2 <-> FMC_A2 | PG2 <-> FMC_A12 | + | PD5 <-> FMC_NWE | PE4 <-> FMC_A20 | PF3 <-> FMC_A3 | PG3 <-> FMC_A13 | + | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF4 <-> FMC_A4 | PG4 <-> FMC_A14 | + | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | PF5 <-> FMC_A5 | PG5 <-> FMC_A15 | + | PD10 <-> FMC_D15 | PE9 <-> FMC_D6 | PF12 <-> FMC_A6 | PG9 <-> FMC_NE2 | + | PD11 <-> FMC_A16 | PE10 <-> FMC_D7 | PF13 <-> FMC_A7 |-----------------+ + | PD12 <-> FMC_A17 | PE11 <-> FMC_D8 | PF14 <-> FMC_A8 | + | PD13 <-> FMC_A18 | PE12 <-> FMC_D9 | PF15 <-> FMC_A9 | + | PD14 <-> FMC_D0 | PE13 <-> FMC_D10 |-----------------+ + | PD15 <-> FMC_D1 | PE14 <-> FMC_D11 | + | | PE15 <-> FMC_D12 | + +------------------+------------------+ + */ + /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ + RCC->AHB1ENR |= 0x00000078; + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x00cc00cc; + GPIOD->AFR[1] = 0xcccccccc; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xaaaa0a0a; + /* Configure PDx pins speed to 100 MHz */ + GPIOD->OSPEEDR = 0xffff0f0f; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xcccccccc; + GPIOE->AFR[1] = 0xcccccccc; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xaaaaaaaa; + /* Configure PEx pins speed to 100 MHz */ + GPIOE->OSPEEDR = 0xffffffff; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0x00cccccc; + GPIOF->AFR[1] = 0xcccc0000; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xaa000aaa; + /* Configure PFx pins speed to 100 MHz */ + GPIOF->OSPEEDR = 0xff000fff; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0x00cccccc; + GPIOG->AFR[1] = 0x000000c0; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0x00080aaa; + /* Configure PGx pins speed to 100 MHz */ + GPIOG->OSPEEDR = 0x000c0fff; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + /*-- FMC Configuration ------------------------------------------------------*/ + /* Enable the FMC/FSMC interface clock */ + RCC->AHB3ENR |= 0x00000001; +#if defined (STM32F427_437xx) || defined (STM32F429_439xx) + /* Configure and enable Bank1_SRAM2 */ + FMC_Bank1->BTCR[2] = 0x00001011; + FMC_Bank1->BTCR[3] = 0x00000201; + FMC_Bank1E->BWTR[2] = 0x0fffffff; +#endif /* STM32F427_437xx || STM32F429_439xx */ +#if defined (STM32F40_41xxx) + /* Configure and enable Bank1_SRAM2 */ + FSMC_Bank1->BTCR[2] = 0x00001011; + FSMC_Bank1->BTCR[3] = 0x00000201; + FSMC_Bank1E->BWTR[2] = 0x0fffffff; #endif /* STM32F40_41xxx */ + /* + Bank1_SRAM2 is configured as follow: + In case of FSMC configuration + NORSRAMTimingStructure.FSMC_AddressSetupTime = 1; + NORSRAMTimingStructure.FSMC_AddressHoldTime = 0; + NORSRAMTimingStructure.FSMC_DataSetupTime = 2; + NORSRAMTimingStructure.FSMC_BusTurnAroundDuration = 0; + NORSRAMTimingStructure.FSMC_CLKDivision = 0; + NORSRAMTimingStructure.FSMC_DataLatency = 0; + NORSRAMTimingStructure.FSMC_AccessMode = FMC_AccessMode_A; -/* - Bank1_SRAM2 is configured as follow: - In case of FSMC configuration - NORSRAMTimingStructure.FSMC_AddressSetupTime = 1; - NORSRAMTimingStructure.FSMC_AddressHoldTime = 0; - NORSRAMTimingStructure.FSMC_DataSetupTime = 2; - NORSRAMTimingStructure.FSMC_BusTurnAroundDuration = 0; - NORSRAMTimingStructure.FSMC_CLKDivision = 0; - NORSRAMTimingStructure.FSMC_DataLatency = 0; - NORSRAMTimingStructure.FSMC_AccessMode = FMC_AccessMode_A; + FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; + FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; + FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; + FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; + FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; + FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; + FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; + FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; + FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; + FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; + FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; + FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &NORSRAMTimingStructure; - FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; - FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; - FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM; - FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; - FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; - FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; - FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; - FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; - FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; - FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; - FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; - FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &NORSRAMTimingStructure; + In case of FMC configuration + NORSRAMTimingStructure.FMC_AddressSetupTime = 1; + NORSRAMTimingStructure.FMC_AddressHoldTime = 0; + NORSRAMTimingStructure.FMC_DataSetupTime = 2; + NORSRAMTimingStructure.FMC_BusTurnAroundDuration = 0; + NORSRAMTimingStructure.FMC_CLKDivision = 0; + NORSRAMTimingStructure.FMC_DataLatency = 0; + NORSRAMTimingStructure.FMC_AccessMode = FMC_AccessMode_A; - In case of FMC configuration - NORSRAMTimingStructure.FMC_AddressSetupTime = 1; - NORSRAMTimingStructure.FMC_AddressHoldTime = 0; - NORSRAMTimingStructure.FMC_DataSetupTime = 2; - NORSRAMTimingStructure.FMC_BusTurnAroundDuration = 0; - NORSRAMTimingStructure.FMC_CLKDivision = 0; - NORSRAMTimingStructure.FMC_DataLatency = 0; - NORSRAMTimingStructure.FMC_AccessMode = FMC_AccessMode_A; + FMC_NORSRAMInitStructure.FMC_Bank = FMC_Bank1_NORSRAM2; + FMC_NORSRAMInitStructure.FMC_DataAddressMux = FMC_DataAddressMux_Disable; + FMC_NORSRAMInitStructure.FMC_MemoryType = FMC_MemoryType_SRAM; + FMC_NORSRAMInitStructure.FMC_MemoryDataWidth = FMC_MemoryDataWidth_16b; + FMC_NORSRAMInitStructure.FMC_BurstAccessMode = FMC_BurstAccessMode_Disable; + FMC_NORSRAMInitStructure.FMC_AsynchronousWait = FMC_AsynchronousWait_Disable; + FMC_NORSRAMInitStructure.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low; + FMC_NORSRAMInitStructure.FMC_WrapMode = FMC_WrapMode_Disable; + FMC_NORSRAMInitStructure.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState; + FMC_NORSRAMInitStructure.FMC_WriteOperation = FMC_WriteOperation_Enable; + FMC_NORSRAMInitStructure.FMC_WaitSignal = FMC_WaitSignal_Disable; + FMC_NORSRAMInitStructure.FMC_ExtendedMode = FMC_ExtendedMode_Disable; + FMC_NORSRAMInitStructure.FMC_WriteBurst = FMC_WriteBurst_Disable; + FMC_NORSRAMInitStructure.FMC_ContinousClock = FMC_CClock_SyncOnly; + FMC_NORSRAMInitStructure.FMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; + FMC_NORSRAMInitStructure.FMC_WriteTimingStruct = &NORSRAMTimingStructure; + */ +} +#endif /* DATA_IN_ExtSRAM */ - FMC_NORSRAMInitStructure.FMC_Bank = FMC_Bank1_NORSRAM2; - FMC_NORSRAMInitStructure.FMC_DataAddressMux = FMC_DataAddressMux_Disable; - FMC_NORSRAMInitStructure.FMC_MemoryType = FMC_MemoryType_SRAM; - FMC_NORSRAMInitStructure.FMC_MemoryDataWidth = FMC_MemoryDataWidth_16b; - FMC_NORSRAMInitStructure.FMC_BurstAccessMode = FMC_BurstAccessMode_Disable; - FMC_NORSRAMInitStructure.FMC_AsynchronousWait = FMC_AsynchronousWait_Disable; - FMC_NORSRAMInitStructure.FMC_WaitSignalPolarity = FMC_WaitSignalPolarity_Low; - FMC_NORSRAMInitStructure.FMC_WrapMode = FMC_WrapMode_Disable; - FMC_NORSRAMInitStructure.FMC_WaitSignalActive = FMC_WaitSignalActive_BeforeWaitState; - FMC_NORSRAMInitStructure.FMC_WriteOperation = FMC_WriteOperation_Enable; - FMC_NORSRAMInitStructure.FMC_WaitSignal = FMC_WaitSignal_Disable; - FMC_NORSRAMInitStructure.FMC_ExtendedMode = FMC_ExtendedMode_Disable; - FMC_NORSRAMInitStructure.FMC_WriteBurst = FMC_WriteBurst_Disable; - FMC_NORSRAMInitStructure.FMC_ContinousClock = FMC_CClock_SyncOnly; - FMC_NORSRAMInitStructure.FMC_ReadWriteTimingStruct = &NORSRAMTimingStructure; - FMC_NORSRAMInitStructure.FMC_WriteTimingStruct = &NORSRAMTimingStructure; -*/ - -} -#elif defined (DATA_IN_ExtSDRAM) +#ifdef DATA_IN_ExtSDRAM /** * @brief Setup the external memory controller. * Called in startup_stm32f4xx.s before jump to main. @@ -1210,175 +890,156 @@ void SystemInit_ExtMemCtl(void) */ void SystemInit_ExtMemCtl(void) { - register uint32_t tmpreg = 0, timeout = 0xFFFF; - register uint32_t index; + register uint32_t tmpreg = 0, timeout = 0xFFFF; + register uint32_t index; + /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface + clock */ + RCC->AHB1ENR |= 0x000001FC; + /* Connect PCx pins to FMC Alternate function */ + GPIOC->AFR[0] = 0x0000000c; + GPIOC->AFR[1] = 0x00007700; + /* Configure PCx pins in Alternate function mode */ + GPIOC->MODER = 0x00a00002; + /* Configure PCx pins speed to 50 MHz */ + GPIOC->OSPEEDR = 0x00a00002; + /* Configure PCx pins Output type to push-pull */ + GPIOC->OTYPER = 0x00000000; + /* No pull-up, pull-down for PCx pins */ + GPIOC->PUPDR = 0x00500000; + /* Connect PDx pins to FMC Alternate function */ + GPIOD->AFR[0] = 0x000000CC; + GPIOD->AFR[1] = 0xCC000CCC; + /* Configure PDx pins in Alternate function mode */ + GPIOD->MODER = 0xA02A000A; + /* Configure PDx pins speed to 50 MHz */ + GPIOD->OSPEEDR = 0xA02A000A; + /* Configure PDx pins Output type to push-pull */ + GPIOD->OTYPER = 0x00000000; + /* No pull-up, pull-down for PDx pins */ + GPIOD->PUPDR = 0x00000000; + /* Connect PEx pins to FMC Alternate function */ + GPIOE->AFR[0] = 0xC00000CC; + GPIOE->AFR[1] = 0xCCCCCCCC; + /* Configure PEx pins in Alternate function mode */ + GPIOE->MODER = 0xAAAA800A; + /* Configure PEx pins speed to 50 MHz */ + GPIOE->OSPEEDR = 0xAAAA800A; + /* Configure PEx pins Output type to push-pull */ + GPIOE->OTYPER = 0x00000000; + /* No pull-up, pull-down for PEx pins */ + GPIOE->PUPDR = 0x00000000; + /* Connect PFx pins to FMC Alternate function */ + GPIOF->AFR[0] = 0xcccccccc; + GPIOF->AFR[1] = 0xcccccccc; + /* Configure PFx pins in Alternate function mode */ + GPIOF->MODER = 0xAA800AAA; + /* Configure PFx pins speed to 50 MHz */ + GPIOF->OSPEEDR = 0xAA800AAA; + /* Configure PFx pins Output type to push-pull */ + GPIOF->OTYPER = 0x00000000; + /* No pull-up, pull-down for PFx pins */ + GPIOF->PUPDR = 0x00000000; + /* Connect PGx pins to FMC Alternate function */ + GPIOG->AFR[0] = 0xcccccccc; + GPIOG->AFR[1] = 0xcccccccc; + /* Configure PGx pins in Alternate function mode */ + GPIOG->MODER = 0xaaaaaaaa; + /* Configure PGx pins speed to 50 MHz */ + GPIOG->OSPEEDR = 0xaaaaaaaa; + /* Configure PGx pins Output type to push-pull */ + GPIOG->OTYPER = 0x00000000; + /* No pull-up, pull-down for PGx pins */ + GPIOG->PUPDR = 0x00000000; + /* Connect PHx pins to FMC Alternate function */ + GPIOH->AFR[0] = 0x00C0CC00; + GPIOH->AFR[1] = 0xCCCCCCCC; + /* Configure PHx pins in Alternate function mode */ + GPIOH->MODER = 0xAAAA08A0; + /* Configure PHx pins speed to 50 MHz */ + GPIOH->OSPEEDR = 0xAAAA08A0; + /* Configure PHx pins Output type to push-pull */ + GPIOH->OTYPER = 0x00000000; + /* No pull-up, pull-down for PHx pins */ + GPIOH->PUPDR = 0x00000000; + /* Connect PIx pins to FMC Alternate function */ + GPIOI->AFR[0] = 0xCCCCCCCC; + GPIOI->AFR[1] = 0x00000CC0; + /* Configure PIx pins in Alternate function mode */ + GPIOI->MODER = 0x0028AAAA; + /* Configure PIx pins speed to 50 MHz */ + GPIOI->OSPEEDR = 0x0028AAAA; + /* Configure PIx pins Output type to push-pull */ + GPIOI->OTYPER = 0x00000000; + /* No pull-up, pull-down for PIx pins */ + GPIOI->PUPDR = 0x00000000; + /*-- FMC Configuration ------------------------------------------------------*/ + /* Enable the FMC interface clock */ + RCC->AHB3ENR |= 0x00000001; + /* Configure and enable SDRAM bank1 */ + FMC_Bank5_6->SDCR[0] = 0x000039D0; + FMC_Bank5_6->SDTR[0] = 0x01115351; + /* SDRAM initialization sequence */ + /* Clock enable command */ + FMC_Bank5_6->SDCMR = 0x00000011; + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + /* Delay */ + for (index = 0; index<1000; index++); + /* PALL command */ + FMC_Bank5_6->SDCMR = 0x00000012; + timeout = 0xFFFF; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + /* Auto refresh command */ + FMC_Bank5_6->SDCMR = 0x00000073; + timeout = 0xFFFF; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + /* MRD register program */ + FMC_Bank5_6->SDCMR = 0x00046014; + timeout = 0xFFFF; + while((tmpreg != 0) & (timeout-- > 0)) + { + tmpreg = FMC_Bank5_6->SDSR & 0x00000020; + } + /* Set refresh count */ + tmpreg = FMC_Bank5_6->SDRTR; + FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); + /* Disable write protection */ + tmpreg = FMC_Bank5_6->SDCR[0]; + FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); + /* + Bank1_SDRAM is configured as follow: - /* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface - clock */ - RCC->AHB1ENR |= 0x000001FC; - - /* Connect PCx pins to FMC Alternate function */ - GPIOC->AFR[0] = 0x0000000c; - GPIOC->AFR[1] = 0x00007700; - /* Configure PCx pins in Alternate function mode */ - GPIOC->MODER = 0x00a00002; - /* Configure PCx pins speed to 50 MHz */ - GPIOC->OSPEEDR = 0x00a00002; - /* Configure PCx pins Output type to push-pull */ - GPIOC->OTYPER = 0x00000000; - /* No pull-up, pull-down for PCx pins */ - GPIOC->PUPDR = 0x00500000; - - /* Connect PDx pins to FMC Alternate function */ - GPIOD->AFR[0] = 0x000000CC; - GPIOD->AFR[1] = 0xCC000CCC; - /* Configure PDx pins in Alternate function mode */ - GPIOD->MODER = 0xA02A000A; - /* Configure PDx pins speed to 50 MHz */ - GPIOD->OSPEEDR = 0xA02A000A; - /* Configure PDx pins Output type to push-pull */ - GPIOD->OTYPER = 0x00000000; - /* No pull-up, pull-down for PDx pins */ - GPIOD->PUPDR = 0x00000000; + FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2; + FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 6; + FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4; + FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 6; + FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2; + FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2; + FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2; - /* Connect PEx pins to FMC Alternate function */ - GPIOE->AFR[0] = 0xC00000CC; - GPIOE->AFR[1] = 0xCCCCCCCC; - /* Configure PEx pins in Alternate function mode */ - GPIOE->MODER = 0xAAAA800A; - /* Configure PEx pins speed to 50 MHz */ - GPIOE->OSPEEDR = 0xAAAA800A; - /* Configure PEx pins Output type to push-pull */ - GPIOE->OTYPER = 0x00000000; - /* No pull-up, pull-down for PEx pins */ - GPIOE->PUPDR = 0x00000000; - - /* Connect PFx pins to FMC Alternate function */ - GPIOF->AFR[0] = 0xcccccccc; - GPIOF->AFR[1] = 0xcccccccc; - /* Configure PFx pins in Alternate function mode */ - GPIOF->MODER = 0xAA800AAA; - /* Configure PFx pins speed to 50 MHz */ - GPIOF->OSPEEDR = 0xAA800AAA; - /* Configure PFx pins Output type to push-pull */ - GPIOF->OTYPER = 0x00000000; - /* No pull-up, pull-down for PFx pins */ - GPIOF->PUPDR = 0x00000000; - - /* Connect PGx pins to FMC Alternate function */ - GPIOG->AFR[0] = 0xcccccccc; - GPIOG->AFR[1] = 0xcccccccc; - /* Configure PGx pins in Alternate function mode */ - GPIOG->MODER = 0xaaaaaaaa; - /* Configure PGx pins speed to 50 MHz */ - GPIOG->OSPEEDR = 0xaaaaaaaa; - /* Configure PGx pins Output type to push-pull */ - GPIOG->OTYPER = 0x00000000; - /* No pull-up, pull-down for PGx pins */ - GPIOG->PUPDR = 0x00000000; - - /* Connect PHx pins to FMC Alternate function */ - GPIOH->AFR[0] = 0x00C0CC00; - GPIOH->AFR[1] = 0xCCCCCCCC; - /* Configure PHx pins in Alternate function mode */ - GPIOH->MODER = 0xAAAA08A0; - /* Configure PHx pins speed to 50 MHz */ - GPIOH->OSPEEDR = 0xAAAA08A0; - /* Configure PHx pins Output type to push-pull */ - GPIOH->OTYPER = 0x00000000; - /* No pull-up, pull-down for PHx pins */ - GPIOH->PUPDR = 0x00000000; - - /* Connect PIx pins to FMC Alternate function */ - GPIOI->AFR[0] = 0xCCCCCCCC; - GPIOI->AFR[1] = 0x00000CC0; - /* Configure PIx pins in Alternate function mode */ - GPIOI->MODER = 0x0028AAAA; - /* Configure PIx pins speed to 50 MHz */ - GPIOI->OSPEEDR = 0x0028AAAA; - /* Configure PIx pins Output type to push-pull */ - GPIOI->OTYPER = 0x00000000; - /* No pull-up, pull-down for PIx pins */ - GPIOI->PUPDR = 0x00000000; - -/*-- FMC Configuration ------------------------------------------------------*/ - /* Enable the FMC interface clock */ - RCC->AHB3ENR |= 0x00000001; - - /* Configure and enable SDRAM bank1 */ - FMC_Bank5_6->SDCR[0] = 0x000039D0; - FMC_Bank5_6->SDTR[0] = 0x01115351; - - /* SDRAM initialization sequence */ - /* Clock enable command */ - FMC_Bank5_6->SDCMR = 0x00000011; - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - while((tmpreg != 0) & (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* Delay */ - for (index = 0; index<1000; index++); - - /* PALL command */ - FMC_Bank5_6->SDCMR = 0x00000012; - timeout = 0xFFFF; - while((tmpreg != 0) & (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* Auto refresh command */ - FMC_Bank5_6->SDCMR = 0x00000073; - timeout = 0xFFFF; - while((tmpreg != 0) & (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* MRD register program */ - FMC_Bank5_6->SDCMR = 0x00046014; - timeout = 0xFFFF; - while((tmpreg != 0) & (timeout-- > 0)) - { - tmpreg = FMC_Bank5_6->SDSR & 0x00000020; - } - - /* Set refresh count */ - tmpreg = FMC_Bank5_6->SDRTR; - FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1)); - - /* Disable write protection */ - tmpreg = FMC_Bank5_6->SDCR[0]; - FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF); - -/* - Bank1_SDRAM is configured as follow: - - FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2; - FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 6; - FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4; - FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 6; - FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2; - FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2; - FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2; - - FMC_SDRAMInitStructure.FMC_Bank = SDRAM_BANK; - FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b; - FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_11b; - FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b; - FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4; - FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3; - FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable; - FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2; - FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_disable; - FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1; - FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure; -*/ - + FMC_SDRAMInitStructure.FMC_Bank = SDRAM_BANK; + FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b; + FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_11b; + FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b; + FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4; + FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_3; + FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable; + FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2; + FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_disable; + FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_1; + FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure; + */ } -#endif /* DATA_IN_ExtSDRAM && DATA_IN_ExtSRAM */ +#endif /* DATA_IN_ExtSDRAM */ /** @@ -1388,8 +1049,8 @@ void SystemInit_ExtMemCtl(void) /** * @} */ - + /** * @} - */ + */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/src/User/inc/main.h b/src/User/inc/main.h index 8bae36e..4204d51 100644 --- a/src/User/inc/main.h +++ b/src/User/inc/main.h @@ -12,7 +12,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_conf.h" #include "delay.h" -#include "usart_debug.h" +#include "usart.h" /* Definition ----------------------------------------------------------------*/ /* Exported Functions --------------------------------------------------------*/ diff --git a/src/User/inc/shell.h b/src/User/inc/shell.h new file mode 100644 index 0000000..a471c7f --- /dev/null +++ b/src/User/inc/shell.h @@ -0,0 +1,33 @@ +/******************************************************************************* + * @file shell.h + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2017.5.9 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +#ifndef __SHELL_H +#define __SHELL_H +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_conf.h" +/* Definition ----------------------------------------------------------------*/ +#define PROMPT "\033[33m MQjehovah>> \033[0m" + +#define SHELL_USART USART3 +#define CMD_REC_BUF_LEN 64 //指令接收缓冲区长度 +#define CMD_ARG_MAX_CNT 8 //指令参数最大个数 + +#define shell_read_char(ch) ring_buffer_read(pE34_RX_BUF, ch) +#define shell_send_char(ch) usart_send_char(SHELL_USART, ch) +#define shell_send_str(str) usart_send_str(SHELL_USART, str) +#define shell_send_number(num, base) usart_send_number(SHELL_USART, num, base) + +extern char *CMDList[]; +/* Exported Functions --------------------------------------------------------*/ +void shell_loop(void); +char *shell_readline(char *buffer); +int shell_process(char *cmd); +u8 string_compare(char *str1, char *str2); +#endif +/*********************************END OF FILE**********************************/ diff --git a/src/User/main.c b/src/User/main.c index 20153e3..e335f95 100644 --- a/src/User/main.c +++ b/src/User/main.c @@ -10,6 +10,8 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stdio.h" +#include "stepper.h" +#include "shell.h" /* Definition ----------------------------------------------------------------*/ /* Functions -----------------------------------------------------------------*/ @@ -22,11 +24,13 @@ int main(void) { SysTick_init(); - usart_debug_init(); + E34_Init(); + stepper_tim_init(50, 84); + // stepper_pwm_init(125, 84); + stepper_set_enable(0); while (1) { - printf("this is a test project\r\n"); - simple_delay_ms(1000); + shell_loop(); } } diff --git a/src/User/shell.c b/src/User/shell.c new file mode 100644 index 0000000..76068fe --- /dev/null +++ b/src/User/shell.c @@ -0,0 +1,204 @@ +/******************************************************************************* + * @file shell.c + * @Author: MQjehovah mail:MQjehovah@hotmail.com + * @version 1.0.0 + * @date 2017.11.22 + * @brief + ****************************************************************************** + * @attention +*******************************************************************************/ +/* Includes ------------------------------------------------------------------*/ +#include "shell.h" +#include "ring_buffer.h" +#include "USART.h" +#include "delay.h" +#include +/* Definition ----------------------------------------------------------------*/ +char CMD_LINE_BUF[CMD_REC_BUF_LEN]; //指令接收缓冲区 + +/* Functions -----------------------------------------------------------------*/ +/******************************************************************************* + * @brief shell循环 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +void shell_loop(void) +{ + while (1) + { + char *cmd = shell_readline(CMD_LINE_BUF); + shell_process(cmd); + simple_delay_ms(100); + } +} +/******************************************************************************* + * @brief 从缓冲区中读取一行指令 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +char *shell_readline(char *buffer) +{ + u32 seek = 0; + shell_send_str(PROMPT); + while (1) + { + // if (pE34_RX_BUF->lenth <= 0) + // continue; + if (!shell_read_char(&buffer[seek])) + continue; + switch (buffer[seek]) + { + case '\r': /* Enter */ + case '\n': //回车表示命令输入结束 + shell_send_str("\r\n"); + if (seek == 0) + return (char *)-1; //空指令不处理 + buffer[seek] = '\0'; //字符串末尾添加结束符 + // shell_send_str(buffer); + return buffer; + case '\0': /* nul */ + continue; + case 0x03: /* ^C - break */ + //CTRL+C表示取消命令输入 + return ((char *)-1); + case 0x15: /* ^U - erase line */ + continue; + case 0x17: /* ^W - erase word */ + //CTRL+W表示删除一个词 + continue; + case 0x08: /* ^H - backspace */ + case 0x7F: /* DEL - backspace */ + //表示删除一个字符 + if (seek > 0) + { + shell_send_str("\b \b"); + seek--; + } + continue; + default: + shell_send_char(buffer[seek]); + seek++; + break; + } //switch + } +} +/******************************************************************************* + * @brief 指令处理程序 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +int shell_process(char *cmd) +{ + static char *argv[CMD_ARG_MAX_CNT] = {0}; + u8 argc = 0; + argv[argc++] = cmd; + + if (cmd == (char *)-1) //获取指令数据错误 + return 0; + //分词 + while (1) + { + if (*cmd == '\0') + break; + if (*cmd == ' ') + { + *cmd = '\0'; + argv[argc++] = ++cmd; + continue; + } + cmd++; + } + if (string_compare(argv[0], "help")) + { + shell_send_str("Support Command:\r\n"); + shell_send_str("help: show help info.\r\n"); + shell_send_str("time: show system time.\r\n"); + shell_send_str("info: show system info.\r\n"); + shell_send_str("step: set step pwm frequest.\r\n"); + shell_send_str("reboot: reboot system.\r\n"); + return 1; + } + if (string_compare(argv[0], "time")) + { + shell_send_number(sys_Time, 10); + shell_send_str("\r\n"); + return 1; + } + if (string_compare(argv[0], "info")) + { + u32 CpuID[3]; + u32 Lock_Code; + CpuID[0] = *(u32 *)(0x1ffff7e8); + CpuID[1] = *(u32 *)(0x1ffff7ec); + CpuID[2] = *(u32 *)(0x1ffff7f0); + //加密算法,很简单的加密算法 + Lock_Code = (CpuID[0] >> 1) + (CpuID[1] >> 2) + (CpuID[2] >> 3); + shell_send_str("Chip Id:0x"); + shell_send_number(Lock_Code, 16); + shell_send_str("\r\n"); + shell_send_str("stack:0x"); + shell_send_number(*(u32 *)0x8000000 - __get_MSP(), 16); + shell_send_str("\r\n"); + return 1; + } + if (string_compare(argv[0], "step")) + { + u32 addr = 0; + if (argc > 1) + { + if (argv[1][0] == '0' && argv[1][1] == 'x') + { + addr = strtol(argv[1], (char **)NULL, 16); + } + else + { + addr = strtol(argv[1], (char **)NULL, 10); + } + } + // nARR = (1000000 / (8000)) - 1; + // TIM_SetAutoreload(TIM2, 125); + // TIM_SetCompare2(TIM2, 125 >> 1); + stepper.step = addr; + shell_send_number(addr, 10); + shell_send_str("\r\n"); + return 1; + } + if (string_compare(argv[0], "load")) + { + // Ymodem_Receive((uint8_t *)ymodem_rec_buf); + return 1; + } + if (string_compare(argv[0], "reboot")) + { + __disable_fault_irq(); + NVIC_SystemReset(); + return 1; + } + shell_send_str("Unsupport Command\r\n"); + return 0; +} +/******************************************************************************* + * @brief 字符串比较 + * @param None + * @retval None + * @Note None +*******************************************************************************/ +u8 string_compare(char *str1, char *str2) +{ + int seek = 0; + while (1) + { + if (str1[seek] == str2[seek]) + { + if (str1[seek++] == '\0') + return 1; + continue; + } + return 0; + } +} + +/*********************************END OF FILE**********************************/ diff --git a/tool/stm32-cli/templates/template.c b/tool/stm32-cli/templates/template.c index d502f5c..349367d 100644 --- a/tool/stm32-cli/templates/template.c +++ b/tool/stm32-cli/templates/template.c @@ -13,4 +13,4 @@ /* Functions -----------------------------------------------------------------*/ -/*********************************END OF FILE**********************************/ \ No newline at end of file +/*********************************END OF FILE**********************************/