Added all PWM pins for arduino nano.

This commit is contained in:
Marvin Blum
2017-04-01 02:13:03 +02:00
parent 2af06f8e0a
commit 6074be0eff
3 changed files with 76 additions and 30 deletions

View File

@@ -20,6 +20,21 @@ const unsigned char A7 = 0x15;
void analog_read_duty_cycle(); void analog_read_duty_cycle();
unsigned char map_analog_pin(unsigned char); unsigned char map_analog_pin(unsigned char);
void pins_init(){
sei();
// enable ADC (128 bit ADPS scaling factor 0x07) to read analog values
ADCSRA = _BV(ADEN)|_BV(ADIE)|0x07;
// clear timer to compare match for PWM output
TCCR0A |= _BV(WGM01)|_BV(WGM00);
TCCR1A |= _BV(WGM01)|_BV(WGM00);
TCCR2A |= _BV(WGM21)|_BV(WGM20);
// enable interrupt on timer overflow for PWM output
TIMSK0 |= _BV(TOIE0);
}
void pin_mode(unsigned char pin, unsigned char mode){ void pin_mode(unsigned char pin, unsigned char mode){
if(pin > A7){ if(pin > A7){
return; return;
@@ -122,12 +137,10 @@ unsigned int analog_read(unsigned char pin){
return 0; return 0;
} }
// enable ADC (128 bit ADPS scaling factor 0x07),
// disable digital input buffer (DIDR0) // disable digital input buffer (DIDR0)
ADCSRA = _BV(ADEN)|_BV(ADIE)|0x07;
ADMUX = _BV(REFS0)|pin; ADMUX = _BV(REFS0)|pin;
DIDR0 |= _BV(pin); DIDR0 |= _BV(pin);
ADCSRA |= _BV(ADSC); // start ADCSRA |= _BV(ADSC); // start conversion
// wait for it to finish // wait for it to finish
while(ADCSRA&_BV(ADSC)); while(ADCSRA&_BV(ADSC));
@@ -136,23 +149,54 @@ unsigned int analog_read(unsigned char pin){
return ADC; return ADC;
} }
// TODO support more than pin 6!
void analog_write(unsigned char pin, unsigned char value){ void analog_write(unsigned char pin, unsigned char value){
// write digital if possible
if(value == 0){
digital_write(pin, LOW);
return;
}
else if(value == 255){
digital_write(pin, HIGH);
return;
}
if(pin != 3 && pin != 5 && pin != 6 && pin != 9 && pin != 10 && pin != 11){ if(pin != 3 && pin != 5 && pin != 6 && pin != 9 && pin != 10 && pin != 11){
return; return;
} }
pin_mode(pin, OUTPUT); // 1. clear timer on compare match (pins_init)
// 2. set interrupt on overflow (pins_init) and value to compare to
// clear timer on compare match // 3. set timer scaling to 1, which starts the timer
TCCR0A |= _BV(COM0A1)|_BV(WGM01)|_BV(WGM00); if(pin == 3){
TCCR2A |= _BV(COM2B1);
// set interrupt on overflow and value to compare to OCR2B = value;
TIMSK0 |= _BV(TOIE0); TCCR2B |= _BV(CS20)|_BV(CS21);
OCR0A = value; }
else if(pin == 5){
// set timer scaling to 1, which starts the timer TCCR0A |= _BV(COM0B1);
TCCR0B |= _BV(CS00)|_BV(CS02); OCR0B = value;
TCCR0B |= _BV(CS00)|_BV(CS02);
}
else if(pin == 6){
TCCR0A |= _BV(COM0A1);
OCR0A = value;
TCCR0B |= _BV(CS00)|_BV(CS02);
}
else if(pin == 9){
TCCR1A |= _BV(COM1A1);
OCR1A = value;
TCCR1B |= _BV(CS10)|_BV(CS11);
}
else if(pin == 10){
TCCR1A |= _BV(COM1B1);
OCR1B = value;
TCCR1B |= _BV(CS10)|_BV(CS11);
}
else if(pin == 11){
TCCR2A |= _BV(COM2A1);
OCR2A = value;
TCCR2B |= _BV(CS20)|_BV(CS21);
}
} }
// maps A0-A7 to 0-7 // maps A0-A7 to 0-7
@@ -165,11 +209,5 @@ unsigned char map_analog_pin(unsigned char pin){
} }
// analog to digital converter interrupt handler // analog to digital converter interrupt handler
ISR(ADC_vect){ // required, but does not need to do anything
// required but not used... ISR(ADC_vect){}
}
// fast PWM overflow interrupt handler
ISR(TIMER0_OVF_vect){
// required but not used...
}

View File

@@ -15,6 +15,7 @@ extern const unsigned char A5;
extern const unsigned char A6; extern const unsigned char A6;
extern const unsigned char A7; extern const unsigned char A7;
void pins_init();
void pin_mode(unsigned char, unsigned char); void pin_mode(unsigned char, unsigned char);
int digital_read(unsigned char); int digital_read(unsigned char);
void digital_write(unsigned char, unsigned char); void digital_write(unsigned char, unsigned char);

21
main.c
View File

@@ -1,6 +1,4 @@
#include <avr/io.h> //#include <util/delay.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h> #include <stdio.h>
#include "ard/serial.h" #include "ard/serial.h"
#include "ard/pins.h" #include "ard/pins.h"
@@ -19,7 +17,7 @@ int main(){
void prepare(){ void prepare(){
// enable global interrupts and serial port // enable global interrupts and serial port
sei(); pins_init();
serial_init(9600); serial_init(9600);
// digital input/output example // digital input/output example
@@ -33,6 +31,8 @@ void prepare(){
// PWM example // PWM example
pin_mode(A1, INPUT); pin_mode(A1, INPUT);
pin_mode(6, OUTPUT);
pin_mode(11, OUTPUT);
} }
unsigned char pwm = 0; unsigned char pwm = 0;
@@ -49,18 +49,25 @@ void loop(){
// anlog input example // anlog input example
/*int analog1 = analog_read(A1); /*int analog1 = analog_read(A1);
int analog2 = analog_read(A2); int analog2 = analog_read(A2);
char out[15]; char out[15];
sprintf(out, "%d %d", analog1, analog2); sprintf(out, "%d %d", analog1, analog2);
serial_write(out, 15);*/ serial_write(out, 15);*/
// PWM example // PWM example
int analog = map(analog_read(A1), 0, 1023, 0, 255); int analog = map(analog_read(A1), 0, 1023, 0, 255);
analog_write(3, analog); analog_write(11, analog);
analog_write(6, analog);
if(analog < 128){
digital_write(6, HIGH);
}
else{
digital_write(6, LOW);
}
char out[15]; char out[15];
sprintf(out, "%d", analog); sprintf(out, "%d", analog);
serial_write(out, 15); serial_write(out, 15);
_delay_ms(25); //_delay_ms(25);
} }