πŸ’Ύ
EC
  • Introduction
  • EC Course
    • Syllabus
    • Preparation for EC
    • Tutorial
      • Tutorial: arduino-stm32
        • Tutorial: arduino-stm32 Installation
        • Tutorial: arduino-stm32 Part1
        • Tutorial: arduino-stm32 Part2
      • Tutorial: MDK uVision
        • Tutorial: Installing MDK uVision
        • Tutorial: Create a Project with uVision
        • Tutorial: Adding library header in uVision
        • Tutorial: Re-using Project Configuration
        • Debugging in uVision
      • Tutorial: PlatformIO in CLion
      • Tutorial: PlatformIO in VSCode
      • Tutorial: Repository Management
      • Tutorial: Managing library header files
      • Tutorial: PinName Configuration
      • Tutorial: Bitwise Macro
      • Tutorial: Custom initialization
      • Tutorial: Documentation
      • Tutorial: Creating Application API
      • Tutorial: 7-Segment Display
      • Tutorial: DC motor driver connection
      • Tutorial: USART with TeraTerm
      • Tutorial: Finite State Machine programming
      • Tutorial: Bluetooth
      • Tutorial: Zigbee with Nucleo board
    • LAB
      • LAB Report Template
      • LAB: Smart mini-fan with STM32-duino
      • LAB: Portable Fan with mbed
      • LAB: GPIO Digital InOut
      • LAB: GPIO Digital InOut 7-segment
      • LAB: EXTI & SysTick
      • LAB: Timer & PWM
      • LAB: Stepper Motor
      • LAB: Input Capture - Ultrasonic
      • LAB: USART - LED, Bluetooth
      • LAB: ADC - IR reflective sensor
      • LAB: Line Tracing RC Car
    • Sample code
      • Code Templates
    • Hardware
      • Nucleo-F411RE
      • LAB Hardware
        • Electronic Chips
        • HUINS Embedded Kit
    • Projects
      • Line Tracing Car Project
      • Design Project
        • Past Projects
      • Project Grading Criteria
    • Study Resource for MCU
      • Hexa-Decimal Table
      • Bitwise Op for Register
      • System Clock
      • Timer
      • USART
      • ADC
  • STM32 M4 Programming
    • Documentation
      • C++ API Docs
    • Firmware Library
      • PinName Configuration
      • GPIO Digital
      • RCC
      • EXTI_SysTick
      • TIMER
      • USART
    • Troubleshooting
    • mbed for STM32
      • Tutorial: mbed-Part 1
      • Tutorial: mbed - Part 2
      • Tutorial: mbed - Part 3
      • Using mbed API on uVision
    • mbed OS
  • Other Programming
    • Arduino
    • Socket Programming
      • Window Socket Programming
      • Arduino WiFi
    • Cube-MX
    • Github
    • Markdown
      • Example: API documentation
    • MATLAB
  • C Programming
    • C-Programming Lessons
      • Installing Visual Studio Community
        • Visual Studio Community 2022
      • Installing VS Code(Mac/Linux)
      • Creating Header Lib
      • Pointer
      • Array
      • 2D Array
      • Structure
      • Dynamic Alloc
      • Bitwise Operation
  • Numerical Programming
    • Syllabus
    • Preparation for NP
    • Math Review
    • Tutorial
      • TA Session Video
      • Tutorial: NP Library Header Files
      • Tutorial - Sine Taylor
      • Tutorial: Passing a Function, Function callback
      • Tutorial: Nonlinear solver
      • Tutorial: Differentiation
      • Tutorial: Integration
      • Tutorial: Matrix Structure
      • Tutorial: Eigenvalue problem
      • Tutorial: ODE-IVP
      • Tutorial: Curve Fitting
      • Tutorial: Create Github Repos of NP lib
      • Tutorial: Version Control in Github
      • Tutorial: Documentation with Markdown
      • Exercise: Version Control and Documentation
    • Example: MATLAB
    • Example: NP Library
    • Assignment
      • Assignment Factorial and Power
      • Assignment: Version Control and Documentation
    • Problem Bank
Powered by GitBook
On this page
  • Introduction
  • Requirement
  • Tutorial: STM-Arduino
  • Procedure
  • Tutorial: STM32F4xx
  • 1. Tutorial: DC motor driver connection
  • Problem 1: RC servo motor
  • Procedure
  • Problem 2: DC motor
  • Procedure
  • Reference
  • Troubleshooting
  • 1. motor PWM duty ratio for different DIR
  • 2. Motor does not run under duty 0.5
  • 3. Check and give different Interrupt Priority

Was this helpful?

  1. EC Course
  2. LAB

LAB: Timer & PWM

Servo motor and DC motor

Date: 2023-10-19

Author/Partner:

Github: repository link

Demo Video: Youtube link

Introduction

Create a simple program that control a sevo motor and a DC motor with PWM output.

You must submit

  • LAB Report (*.md & *.pdf)

  • Zip source files(main*.c, ecRCC.h, ecGPIO.h, ecSysTick.c etc...).

    • Only the source files. Do not submit project files

Requirement

Hardware

  • MCU

    • NUCLEO-F411RE

  • Actuator/Sensor/Others:

    • 3 LEDs and load resistance

    • RC Servo Motor (SG90)

    • DC motor (5V)

    • DC motor driver(LS9110s)

    • breadboard

Software

  • Keil uVision, CMSIS, EC_HAL library

Tutorial: STM-Arduino

We are going to create a simple program that run DC - Motor by giving pwm signal as input.

Press the reset button(black) and verify the operation. If you press the user button, DC-Motor will turn on.

Procedure

  1. Create a new project under the directory \EC\LAB\LAB_PWM

  2. Open Arduino IDE and Create a new program named as β€˜TU_arduino_PWM.ino’.

  3. Write the following code.

  4. upload and run.

const int pwmPin = 11;   // PWM pin
const int buttonPin = 3;  // button pin

int buttonState = HIGH;

void setup() {
  pinMode(pwmPin, OUTPUT);
 
 // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), motorOperation, CHANGE);
}

void loop() {

  if (buttonState == LOW){
    for (int i = 0; i < 10; i++){
      analogWrite(pwmPin, 40 + 10*i);
      delay(100);
    }
  
    for (int i = 10; i > 0; i--){
      analogWrite(pwmPin, 40 + 10*i);
      delay(100);
    }
  }
  else{
    analogWrite(pwmPin, 0);
  }
}

void motorOperation(){
  buttonState = digitalRead(buttonPin);
}

Tutorial: STM32F4xx

1. Tutorial: DC motor driver connection

Understand how to connect a DC motor to the motor driver (LS9110s).


Problem 1: RC servo motor

An RC servo motor is a tiny and light weight motor with high output power. It is used to control rotation angles, approximately 180 degrees (90 degrees in each direction) and commonly applied in RC car, and Small-scaled robots. The angle of the motor can be controlled by the pulse width (duty ratio) of PWM signal. The PWM period should be set at 20ms or 50Hz. Refer to the datasheet of the RC servo motor for detailed specifications.

1-1. Create HAL library

Download files:

Then, change the library files as

  • ecTIM.h, ecTIM.c

  • ecPWM.h, ecPWM.c

Declare and define the following functions in your library. You must update your header files located in the directory EC \lib\.

ecTIM.h

// Timer Period setup
void TIM_init(TIM_TypeDef *TIMx, uint32_t msec);
void TIM_period(TIM_TypeDef* TIMx, uint32_t msec);
void TIM_period_ms(TIM_TypeDef* TIMx, uint32_t msec);
void TIM_period_us(TIM_TypeDef* TIMx, uint32_t usec);

// Timer Interrupt setup
void TIM_UI_init(TIM_TypeDef* TIMx, uint32_t msec);
void TIM_UI_enable(TIM_TypeDef* TIMx);
void TIM_UI_disable(TIM_TypeDef* TIMx);


// Timer Interrupt Flag 
uint32_t is_UIF(TIM_TypeDef *TIMx);
void clear_UIF(TIM_TypeDef *TIMx);

ecPWM.h

/* PWM Configuration using PinName_t Structure */

/* PWM initialization */
// Default: 84MHz PLL, 1MHz CK_CNT, 50% duty ratio, 1msec period
void PWM_init(PinName_t pinName);
void PWM_pinmap(PinName_t pinName, TIM_TypeDef **TIMx, int *chN);


/* PWM PERIOD SETUP */
// allowable range for msec:  1~2,000
void PWM_period(PinName_t pinName,  uint32_t msec);	
void PWM_period_ms(PinName_t pinName,  uint32_t msec);	// same as PWM_period()
// allowable range for usec:  1~1,000
void PWM_period_us(PinName_t pinName, uint32_t usec);


/* DUTY RATIO SETUP */
// High Pulse width in msec
void PWM_pulsewidth(PinName_t pinName, uint32_t pulse_width_ms);
void PWM_pulsewidth_ms(PinName_t pinName, uint32_t pulse_width_ms);  // same as void PWM_pulsewidth
// Duty ratio 0~1.0
void PWM_duty(PinName_t pinName, float duty);

Procedure

Make a simple program that changes the angle of the RC servo motor that rotates back and forth from 0 deg to 180 degree within a given period of time.

Reset to '0' degree by pressing the push button (PC13).

  • Button input has to be an External Interrupt

  • Use Port A Pin 1 as PWM output pin for TIM2_CH2.

  • Use Timer interrupt of period 500msec.

  • Angle of RC servo motor should rotate from 0Β° to 180Β° and back 0Β° at a step of 10Β° at the rate of 500msec.

You need to observe how the PWM signal output is generated as the input button is pushed, using an oscilloscope. You need to capture the Oscilloscope output in the report.

  1. Create a new project under the directory \repos\EC\LAB\LAB_PWM

  • The project name is β€œLAB_PWM”.

  • Create a new source file named as β€œLAB_PWM_RCmotor.c”

You MUST write your name on the source file inside the comment section.

2. Include your updated library in \repos\EC\lib\ to your project.

  • ecPinNames.h ecPinNames.c

  • ecGPIO.h, ecGPIO.c

  • ecRCC.h, ecRCC.c

  • ecEXTI.h, ecEXTI.c

  • ecTIM.h, ecTIM.c

  • ecPWM.h ecPWM.h

  1. Connect the RC servo motor to MCU pin (PA1) , VCC and GND

  2. Increase the angle of RC servo motor from 0Β° to 180Β° with a step of 10Β° every 500msec. After reaching 180Β°, decrease the angle back to 0Β°. Use timer interrupt IRQ.

  3. When the button is pressed, it should reset to the angle 0Β° and start over. Use EXT interrupt.

Configuration

Type
Port - Pin
Configuration

Button

Digital In (PC13)

Pull-Up

PWM Pin

AF (PA1)

Push-Pull, Pull-Up, Fast

PWM Timer

TIM2_CH2 (PA1)

TIM2 (PWM) period: 20msec, Duty ratio: 0.5~2.5msec

Timer Interrupt

TIM3

TIM3: Timer Interrupt of 500 msec

Circuit Diagram

You need to include the circuit diagram

Discussion

  1. Derive a simple logic to calculate CRR and ARR values to generate x[Hz] and y[%] duty ratio of PWM. How can you read the values of input clock frequency and PSC?

Answer discussion questions

  1. What is the smallest and highest PWM frequency that can be generated for Q1?

    Answer discussion questions

Code

Explain your source code with necessary comments.

// YOUR MAIN CODE ONLY
// YOUR CODE

Example Code

Sample Code : Timer Interrupt IRQ

#include "stm32f411xe.h"
#include "ecGPIO.h"
#include "ecRCC.h"
#include "ecTIM.h"


#define LED_PIN	5
uint32_t _count = 0;
void setup(void);


int main(void) {
	// Initialization --------------------------------------------------
	setup();
	
	// Infinite Loop ---------------------------------------------------
	while(1){}
}


// Initialization
void setup(void){
	RCC_PLL_init();				// System Clock = 84MHz
	GPIO_init(GPIOA, LED_PIN, OUTPUT);	// calls RCC_GPIOA_enable()
	TIM_UI_init(TIM2, 1);			// TIM2 Update-Event Interrupt every 1 msec 
	TIM_UI_enable(TIM2);
}

void TIM2_IRQHandler(void){
	if(is_UIF(TIM2)){			// Check UIF(update interrupt flag)
		_count++;
		if (_count > 1000) {
			LED_toggle();		// LED toggle every 1 sec
			_count = 0;
		}
		clear_UIF(TIM2); 		// Clear UI flag by writing 0
	}
}

Sample Code : PWM output

#include "stm32f411xe.h"
#include "math.h"

// #include "ecSTM32F411.h"
#include "ecPinNames.h"
#include "ecGPIO.h"
#include "ecSysTick.h"
#include "ecRCC.h"
#include "ecTIM.h"
#include "ecPWM.h"   // ecPWM2.h


// Definition Button Pin & PWM Port, Pin
#define BUTTON_PIN 13
#define PWM_PIN PA_5
void setup(void);


int main(void) {
	// Initialization --------------------------------------------------
	setup();	
	
	// Infinite Loop ---------------------------------------------------
	while(1){
		LED_toggle();		
		for (int i=0; i<5; i++) {						
			PWM_duty(PWM_PIN, (float)0.2*i);			
			delay_ms(1000);
		}		
	}
}


// Initialiization 
void setup(void) {	
	RCC_PLL_init();
	SysTick_init();
		
	// PWM of 20 msec:  TIM2_CH1 (PA_5 AFmode)
	GPIO_init(GPIOA, 5, EC_AF);
	PWM_init(PWM_PIN);	
	PWM_period(PWM_PIN, 20);   // 20 msec PWM period
}

Results

Experiment images and results

Show experiment images /results


Problem 2: DC motor

Procedure

Make a simple program that rotates a DC motor that changes the duty ratio from 25% -->75%--> 25% --> and so on.

The rotating speed level changes every 2 seconds.

By pressing the push button (PC13), toggle from Running and stopping the DC motor

  1. Use the same project.

  • Create a new source file named β€œLAB_PWM_DCmotor.c”

  • You need to eliminate the other source file that contains main() from the project

    • e.g. Eliminate "β€œLAB_PWM_RCmotor.c” from the project

You MUST write your name on the source file inside the comment section.

  1. Connect DC motor and DC motor driver.

  • PA_0 for the DC motor PWM

  • PC_2 for Direction Pin

  1. Change DC motor from LOW Speed to HIGH Speed for every 2 seconds

  • e.g. 25% -->75%--> 25% --> and so on.

  1. When Button is pressed, it should PAUSE or CONTINUE motor run

Configuration

Function
Port - Pin
Configuration

Button

Digital In (PC13)

Pull-Up

Direction Pin

Digital Out (PC2)

Push-Pull

PWM Pin

AF (PA0)

Push-Pull, Pull-Up, Fast

PWM Timer

TIM2_CH1 (PA0)

TIM2 (PWM) period: 1msec (1kHz)

Timer Interrupt

TIM3

TIM3: Timer Interrupt of 500 msec

Circuit Diagram

You need to include the circuit diagram

Code

Explain your source code with necessary comments.

// YOUR MAIN CODE ONLY
// YOUR CODE

Results

Experiment images and results

Show experiment images /results

Reference

Complete list of all references used (github, blog, paper, etc)

Troubleshooting

1. motor PWM duty ratio for different DIR

When, DIR=0 duty=0.8--> PWM 0.8 // μ‹€μ œ λͺ¨ν„°μ— μ „λ‹¬λ˜λŠ” pwm

Whe, DIR=1 duty=0.8--> PWM 0.2 // μ‹€μ œ λͺ¨ν„°μ— μ „λ‹¬λ˜λŠ” PWM

*** a solution ***

float targetPWM;  // pwm for motor input 
float duty=abs(DIR-targetPWM); // duty with consideration of DIR=1 or 0

PWM_duty(PWM_PIN, duty);

2. Motor does not run under duty 0.5

SOL) Configure motor PWM period as 1kHz

3. Check and give different Interrupt Priority

Check if you have different NVIC priority number for each IRQs

(Option) You can write Troubleshooting section



### 4. Print a string for BT (USART1)
Use `sprintf()`

```c++
#define _CRT_SECURE_NO_WARNINGS    // sprintf λ³΄μ•ˆ 경고둜 μΈν•œ 컴파일 μ—λŸ¬ λ°©μ§€
#include <stdio.h>     // sprintf ν•¨μˆ˜κ°€ μ„ μ–Έλœ 헀더 파일

char BT_string[20]=0;

int main()
{
	sprintf(BT_string, "DIR:%d PWM: %0.2f\n", dir, duty);    // 문자, μ •μˆ˜, μ‹€μˆ˜λ₯Ό λ¬Έμžμ—΄λ‘œ λ§Œλ“¦
	USART1_write(BT_string, 20);
	// ...
}

https://dojang.io/mod/page/view.php?id=352 **

PreviousLAB: EXTI & SysTickNextLAB: Stepper Motor

Last updated 7 months ago

Was this helpful?

image

image

Your code goes here:

Add

First, you MUST read

image

Your code goes here:

Add

ecPinNames.h ecPinNames.c
ecTIM_student.h, ecTIM_student.c
ecPWM_student.h, ecPWM_student.c
ADD Code LINK such as github
demo video link
Tutorial: DC motor driver connection
ADD Code LINK such as github
demo video link
Tutorial: arduino-stm32 Part2 | EC
Tutorial: DC motor driver connection | EC
Logo
Logo