DC motor control project part2 Initsys.c & Initsys.h

Initsys程式包含main.c用到的各種function

Initsys.c

========================================================================

標頭檔

#include "stm32f4xx.h"
#include "Initsys.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"

全域變數

TIM_OCInitTypeDef TIM_OCStruct;

--------------------------------------------------------------------------------------------------------

delay_ms呼叫此函數可以讓系統暫停輸入值的mini second

void delay_ms(uint32_t nms){     
volatile uint32_t temp,tempval;    
SysTick->LOAD=(uint32_t)nms*21000;//168000000/8
SysTick->VAL =0x00;           
SysTick->CTRL=0x01 ;   
do
{
temp=SysTick->CTRL;
tempval=SysTick->VAL;
}
while(temp==1);  
SysTick->CTRL=0x00;       
SysTick->VAL =0X00;            

}

--------------------------------------------------------------------------------------------------------

PD0的外部終斷起使化

void Configure_PD0(void) {
 /* Set variables used */
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
/* Enable clock for GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Enable clock for SYSCFG */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* Set pin as input */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);   
/* Tell system that you will use PD0 for EXTI_Line0 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0);
/* PD0 is connected to EXTI_Line0 */
EXTI_InitStruct.EXTI_Line = EXTI_Line0;
/* Enable interrupt */
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
/* Interrupt mode */
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
/* Triggers on rising and falling edge */
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
/* Add to EXTI */
EXTI_Init(&EXTI_InitStruct);
 設定優先級
    /* Add IRQ vector to NVIC */
    /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x01;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);

}

--------------------------------------------------------------------------------------------------------

PD1的外部終斷起使化

void Configure_PD1(void) {
    /* Set variables used */
    GPIO_InitTypeDef GPIO_InitStruct;
    EXTI_InitTypeDef EXTI_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
    
    /* Enable clock for GPIOD */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    /* Enable clock for SYSCFG */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    
    /* Set pin as input */
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_Init(GPIOD, &GPIO_InitStruct);
    
    /* Tell system that you will use PD1 for EXTI_Line1 */
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource1);
    
    /* PD0 is connected to EXTI_Line1 */
    EXTI_InitStruct.EXTI_Line = EXTI_Line1;
    /* Enable interrupt */
    EXTI_InitStruct.EXTI_LineCmd = ENABLE;
    /* Interrupt mode */
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Triggers on rising and falling edge */
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
    /* Add to EXTI */
    EXTI_Init(&EXTI_InitStruct);
  設定優先級
    /* Add IRQ vector to NVIC */
    /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */
    NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;
    /* Set priority */
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00;
    /* Set sub priority */
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00;
    /* Enable interrupt */
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    /* Add to NVIC */
    NVIC_Init(&NVIC_InitStruct);
}

--------------------------------------------------------------------------------------------------------GPIO設定包含PD13用來量測系統頻率,PC6789用來產生PWM控制馬達轉速

void motorcontrolGPIO_setup(){
GPIO_InitTypeDef GPIO_InitStruct;
/*Indicator Light*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_13;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOD, &GPIO_InitStruct);

/*motor encoder read state pin*/
/* Enable clock for GPIOC */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
/* Set pin as input */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOC, &GPIO_InitStruct);
/*motor PWM control pin*/
/* Clock for GPIOD */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* Set pins */
GPIO_InitStruct.GPIO_Pin =  GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
/* Alternating functions for pins */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM4);
GPIO_Init(GPIOB, &GPIO_InitStruct);
}

--------------------------------------------------------------------------------------------------------序列阜設定使用USART2

void USARTInit(){
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
//Enable the preiph clock for USART2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
//Enable the GPIO clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
//setup the GPIO pin for Tx and Rx
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;
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(GPIOA,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2);
//test freq led PD13
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_Init(GPIOD,&GPIO_InitStructure);
//USART2 setting
USART_InitStructure.USART_BaudRate=115200;
USART_InitStructure.USART_WordLength=USART_WordLength_8b;
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(USART2,&USART_InitStructure);
USART_Cmd(USART2,ENABLE);
}

--------------------------------------------------------------------------------------------------------

USART2_send_byte和USART_puts都是序列阜傳值的函數

void USART2_send_byte(uint8_t byte){
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);//??????
USART2->DR=byte;
}
void USART_puts(USART_TypeDef* USARTx,volatile char *str){
while(*str)
{
while(!(USARTx->SR&0x040));
//while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET)//此行與上一行作用相同
USART_SendData(USARTx, *str);
*str++;
}
}

--------------------------------------------------------------------------------------------------------

做ASCII與整數直轉換的函數

uint8_t toascii(uint8_t data){
if(data<10)
return data+48;
else
switch(data){
case 10:
return 65;
break;
case 11:
return 66;
break;
case 12:
return 67;
break;
case 13:
return 68;
break;
case 14:
return 69;
break;
case 15:
return 70;
break;
}
}

--------------------------------------------------------------------------------------------------------

做序列阜整數值的輸出

void to_ascii_print(uint16_t count){
uint8_t TX_DATA[12],i=0;
TX_DATA[i++]=32;
short int temp=0;
uint32_t d0,d1,d2,d3,d4,d5,t5,t4,t3,t2,t1;
if(count>>15==1){//negetive
TX_DATA[i++]='-';
temp=~count+1;
}
else{
temp=count;
}
t5=(temp/10000);
t4=(temp-(t5*10000))/1000;
t3=(temp-(t5*10000)-(t4*1000))/100;
t2=(temp-(t5*10000)-(t4*1000)-(t3*100))/10;
t1=temp-(t5*10000+t4*1000+t3*100+t2*10);
TX_DATA[i++]=toascii(t5);
TX_DATA[i++]=toascii(t4);
TX_DATA[i++]=toascii(t3);
TX_DATA[i++]=toascii(t2);
TX_DATA[i++]=toascii(t1);
TX_DATA[i++]=32;
TX_DATA[i++]='\r';
TX_DATA[i++]='\n';
USART2_Send(TX_DATA,sizeof(TX_DATA));
}

--------------------------------------------------------------------------------------------------------

PWM的功能設定

//PWM_Timer use TIM4
void PWM_Timer_set(){

//Initialize TIM4
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
//Enable clock for TIM4
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);

TIM_BaseStruct.TIM_Prescaler        =0;
TIM_BaseStruct.TIM_CounterMode      =TIM_CounterMode_Up;
TIM_BaseStruct.TIM_Period           =8399;
TIM_BaseStruct.TIM_ClockDivision    =TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter=0;
TIM_TimeBaseInit(TIM4,&TIM_BaseStruct);
//84000000/10000-1=8399
//use this setting we can have 10khz clock
TIM_Cmd(TIM4,ENABLE);
TIM_OCStruct.TIM_OCMode=TIM_OCMode_PWM2;
TIM_OCStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OCStruct.TIM_OCPolarity=TIM_OCPolarity_Low;
}

--------------------------------------------------------------------------------------------------------

設定PWM duty cycle的函示

void pwm_dutucycle(uint16_t Pin, float dutycycle){
TIM_OCStruct.TIM_Pulse=(uint16_t)((dutycycle/10000)*8399);
switch (Pin)
{
case GPIO_Pin_6:
TIM_OC1Init(TIM4,&TIM_OCStruct);
TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);
break;
case GPIO_Pin_7:
TIM_OC2Init(TIM4,&TIM_OCStruct);
TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
break;
case GPIO_Pin_8:
TIM_OC3Init(TIM4,&TIM_OCStruct);
TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
break;
  case GPIO_Pin_9:
TIM_OC4Init(TIM4,&TIM_OCStruct);
  TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);
break;
  default:
break;
}
}

--------------------------------------------------------------------------------------------------------

系統頻率timer的設定

//SampleTimer use TIM2
void TIM2_steup(){
TIM_TimeBaseInitTypeDef TIM_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
TIM_InitStruct.TIM_Prescaler = 84;//TIM2 is in APB1 bar(42mhz) but it will *2 as it freq
//so we first devide by 84 the tim clock now is 1mhz
TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_InitStruct.TIM_Period = 5000;
//let TIM_Period =5000 the timer will be triggered every 0.005 sec 200hz system
TIM_InitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM2,&TIM_InitStruct);
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM2,ENABLE);
}

--------------------------------------------------------------------------------------------------------

系統頻率timer的優先級設定

void TIM_IRQn(){
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

Initsys.h

========================================================================
#ifndef _Initsys_h_
#define _Initsys_h_
#include <stm32f4xx.h>
#include "stm32f4xx_gpio.h"
#define INPUT 0
#define OUTPUT 1
void delay_ms(uint32_t nms);
void Configure_PD0(void);
void Configure_PD1(void);
void motorcontrolGPIO_setup();
void USARTInit();
void USART2_send_byte(uint8_t byte);
void USART_puts(USART_TypeDef* USARTx,volatile char *str);
void USART2_Send(uint8_t *Buffer, uint8_t Length);
uint8_t toascii(uint8_t data);
void to_ascii_print(uint16_t count);
void PWM_Timer_set();
void pwm_dutucycle(uint16_t Pin, float dutycycle);
void TIM2_steup();
void TIM_IRQn();
#endif

留言

這個網誌中的熱門文章

freeRTOS Deleting a Task

05 Software Timer Management

Interrupt Management