AnsweredAssumed Answered

Controlling PWM duty cycle through USART command

Question asked by eniayekan.makinde on Sep 7, 2015
Latest reply on Sep 7, 2015 by Clive One
hello pls i need help with controlling my PWM duty cycle using usart command. i atiched together some codes but whenever i try to build it it returns error (    [cc] collect2.exe: error: ld returned 1 exit status) im using STM32F407 Disco. please whats wrong with this code?


#include "defines.h"
#include "stm32f4xx.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"
#include <misc.h>
#include <stm32f4xx_usart.h>
#include "stm32f4_discovery.h"
#include "TecsploitUtils.h"

#define BUFFER_SIZE 16

volatile char received_buffer[BUFFER_SIZE+1];


static uint8_t DataReceivedCounter = 0; //tracks the number of characters received so far, reset after each command

//function prototypes
void USARTCommandReceived(char * command);
void ClearCommand();
void Delay(int nCount);
void ConfigureUsart(int baudrate);
void TM_LEDS_Init(void);
void TM_TIMER_Init(void);
void TM_PWM_Init(int timepulse);


//Configures the USART using pin B6 as TX and B7 as RX and the passed in baudrate
void ConfigureUsart(int baudrate){
    //structures used configure the hardware
    GPIO_InitTypeDef GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef NVIC_InitStructure;

    //enable the clocks for the GPIOB and the USART
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    //Initialise pins GPIOB 6 and GPIOB 7
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; //we are setting the pin to be alternative function
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    //Connect the TX and RX pins to their alternate function pins
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1); //
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

    //configure USART
    USART_InitStruct.USART_BaudRate = baudrate;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_Parity = USART_Parity_No;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //enable send and receive (Tx and Rx)
    USART_Init(USART1, &USART_InitStruct);

    //Enable the interupt
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    // finally this enables the complete USART1 peripheral
    USART_Cmd(USART1, ENABLE);
}

//writes out a string to the passed in usart. The string is passed as a pointer
void SendData(USART_TypeDef* USARTx, volatile char *s){

    while(*s){
        // wait until data register is empty
        while( !(USARTx->SR & 0x00000040) );
        USART_SendData(USARTx, *s);
        *s++;
    }
}


void TM_LEDS_Init(void) {
    GPIO_InitTypeDef GPIO_InitStruct;

    /* Clock for GPIOD */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    /* Alternating functions for pins */
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4);
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4);

    /* Set pins */
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    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;
    GPIO_Init(GPIOD, &GPIO_InitStruct);
}

void TM_TIMER_Init(void) {
    TIM_TimeBaseInitTypeDef TIM_BaseStruct;

    /* Enable clock for TIM4 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/*
    TIM4 is connected to APB1 bus, which has on F407 device 42MHz clock
    But, timer has internal PLL, which double this frequency for timer, up to 84MHz
    Remember: Not each timer is connected to APB1, there are also timers connected
    on APB2, which works at 84MHz by default, and internal PLL increase
    this to up to 168MHz

    Set timer prescaller
    Timer count frequency is set with

    timer_tick_frequency = Timer_default_frequency / (prescaller_set + 1)

    In our case, we want a max frequency for timer, so we set prescaller to 0
    And our timer will have tick frequency

    timer_tick_frequency = 84000000 / (0 + 1) = 84000000
*/
    TIM_BaseStruct.TIM_Prescaler = 0;
    /* Count up */
    TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;

    TIM_BaseStruct.TIM_Period = 8399; /* set to 25kHz PWM for motor */
    TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_BaseStruct.TIM_RepetitionCounter = 0;
    /* Initialize TIM4 */
    TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
    /* Start count on TIM4 */
    TIM_Cmd(TIM4, ENABLE);
}

void TM_PWM_Init(int timepulse)
{

    TIM_OCInitTypeDef TIM_OCStruct;


    TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low;


    TIM_OCStruct.TIM_Pulse = timepulse; /* 75% duty cycle */
    TIM_OC3Init(TIM4, &TIM_OCStruct);
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);


}

void USART1_IRQHandler(void){
    //check the type of interrupt to make sure we have received some data.
    if( USART_GetITStatus(USART1, USART_IT_RXNE) ){
        char t = USART1->DR; //Read the character that we have received

        if( (DataReceivedCounter < BUFFER_SIZE) && t != 13 ){
            received_buffer[DataReceivedCounter] = t;
            DataReceivedCounter++;
        }
        else{ // otherwise reset the character counter and print the received string
            DataReceivedCounter = 0;
            //only raise a command event if the enter key was pressed otherwise just clear
            if(t == 13){
                USARTCommandReceived(received_buffer);
            }

            ClearCommand();

        }
    }
}

void USARTCommandReceived(char * command){
    SendData(USART1, received_buffer);

    if  (compare (command,"LMF1") == 0){
        TM_PWM_Init(6299);
    }else {
        TM_PWM_Init(0000);

    }
}
void ClearCommand(){
    int i =0;
    for(i=0;i < BUFFER_SIZE; i++){
        received_buffer[i] = 0;
    }

}

void Delay(int nCount) {
  while(nCount--) {
  }
}


int main(void) {

            ConfigureUsart(9600);

            SystemInit();

            TM_LEDS_Init();

            TM_TIMER_Init();



      SendData(USART1, "maksaero1 USART connection initialized");

      while (1){}
      Delay(900000) ;

}

Attachments

Outcomes