Last active
May 13, 2018 21:19
-
-
Save bigjosh/cafe41aaec7046380f16a8e53e97d57d to your computer and use it in GitHub Desktop.
PWM Motor control code for AIRBOAT running on ATTINY10
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Attiny10 AIRBOAT PWM Motor control code | |
* | |
* Created: 12/2/2016 6:17:47 PM | |
* Author : josh | |
*/ | |
#include <avr/io.h> | |
#include <util/delay.h> | |
// MOTOR FUNCTIONS | |
// =============== | |
// Note that register values are hard coded rather than #defined because they | |
// can not just be moved around. They depend on the Timer hardware of the specific chip/pin. | |
// Motor is controller by an N-MOSFET which is connected to pin OC0B (pin #3 on ATTINY10 SOT-23). | |
// 1 output turns motor on, 0 is off. | |
// Initialize the motor pin. Sets to output mode, which will drive pin LOW. | |
// Call this as soon as possible after reset to keep the mosfet from floating and turning on the motor. | |
static void initMotor() { | |
DDRB |= _BV(1); // Set pin to output mode. It will already be low because IO ports default to 0 on reset. | |
} | |
// Turn the motor completely off- disconnects from PWM generator | |
static void motorOff(void) { | |
TCCR0A &= ~( _BV(COM0B0) | _BV(COM0B1) ); // Set COM0B0 and COM0B1 to 0, "Normal port operation, OC0B disconnected"Z | |
// Will revert the pin output back to PORT value, which we always keep at the default (zero). | |
} | |
// Set motor PWM | |
// match sets the duty cycle and should be between 0 and top. 0=completely off, top=full on. | |
// top sets the frequency where PWM frequency = F_CPU/top. The minimum resolution allowed is 2-bit (top set to 0x0003). | |
// Note: Currently disables OCR0A, but could easily be changed to preserve OCR0A through speed changes if wanted. | |
// Note: Clobbers ICR0 for TOP function. | |
// Note: Resets all used registers each time from scratch for safety from glitches. This is probably unnecessary... | |
// http://electronics.stackexchange.com/questions/139575/how-often-do-avrs-actually-glitch-and-need-a-watch-dog-reset-in-the-real-world/144318 | |
static void setMotorPWM( uint16_t match , uint16_t top ) { | |
if (match==0) { // Special case this because the PWM generator still generates a pulse at 0 duty cycle | |
// "If the OCR1x is set equal to BOTTOM (0x0000) the output will be a narrow spike for each TOP+1 timer clock cycle." | |
motorOff(); | |
} else { | |
TCCR0A = | |
_BV(COM0B1) | // Clear OC0B on compare match (non-inverting) | |
_BV(WGM01) // Mode 14 1110, Fast PWM TOP=ICR0 | |
; // Note that this clears the OC0A COM bits as side effect, but those could be preserved if wanted | |
TCCR0B = | |
_BV( WGM03) | _BV( WGM02 ) | // Mode 14 1110, Fast PWM TOP=ICR0 | |
_BV( CS00 ) // prescaler=clk/1 | |
; | |
OCR0B = match; | |
ICR0 = top; // Counter top value - resets to zero when we get here | |
if (TCNT0 > top ) { // Handle the glitch in the case where changing TOP leads a missed match and a full wrap of TCNT | |
TCNT0 = top-1; | |
} | |
// Note that there is a silicon bug that might make this not work on older parts: | |
// http://electronics.stackexchange.com/questions/97596/attiny85-pwm-why-does-com1a0-need-to-be-set-before-pwm-b-will-work | |
} | |
} | |
int main(void) | |
{ | |
DDRB |= _BV( 2 ); // Set pin PB2 to output so we can blink an attached LED for feedback | |
initMotor(); | |
while (1) | |
{ | |
PINB |= _BV( 2 ); // Blink LED once per cycle so we know we are running! | |
_delay_ms(500); | |
setMotorPWM( 10 , 100 ); | |
_delay_ms(1000); | |
setMotorPWM( 100 , 1000 ); | |
_delay_ms(1000); | |
setMotorPWM( 1000 , 10000 ); | |
_delay_ms(1000); | |
motorOff(); | |
_delay_ms(1000); | |
setMotorPWM( 20 , 100 ); | |
_delay_ms(1000); | |
setMotorPWM( 50 , 100 ); | |
_delay_ms(1000); | |
setMotorPWM( 80 , 100 ); | |
_delay_ms(1000); | |
motorOff(); | |
_delay_ms(1000); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment