avr: initial implementation for PWM
Signed-off-by: Ron Evans <ron@hybridgroup.com> Edited slightly by Ayke van Laethem
Этот коммит содержится в:
родитель
94358959f5
коммит
fc0ff3a987
5 изменённых файлов: 142 добавлений и 6 удалений
54
src/examples/pwm/pwm.go
Обычный файл
54
src/examples/pwm/pwm.go
Обычный файл
|
@ -0,0 +1,54 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// This example assumes that an RGB LED is connected to pins 3, 5 and 6 on an Arduino.
|
||||||
|
// Change the values below to use different pins.
|
||||||
|
const (
|
||||||
|
redPin = 3
|
||||||
|
greenPin = 5
|
||||||
|
bluePin = 6
|
||||||
|
)
|
||||||
|
|
||||||
|
// cycleColor is just a placeholder until math/rand or some equivalent is working.
|
||||||
|
func cycleColor(color uint8) uint8 {
|
||||||
|
if color < 10 {
|
||||||
|
return color + 1
|
||||||
|
} else if color < 200 {
|
||||||
|
return color + 10
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
machine.InitPWM()
|
||||||
|
|
||||||
|
red := machine.PWM{redPin}
|
||||||
|
red.Configure()
|
||||||
|
|
||||||
|
green := machine.PWM{greenPin}
|
||||||
|
green.Configure()
|
||||||
|
|
||||||
|
blue := machine.PWM{bluePin}
|
||||||
|
blue.Configure()
|
||||||
|
|
||||||
|
var rc uint8
|
||||||
|
var gc uint8 = 20
|
||||||
|
var bc uint8 = 30
|
||||||
|
|
||||||
|
for {
|
||||||
|
rc = cycleColor(rc)
|
||||||
|
gc = cycleColor(gc)
|
||||||
|
bc = cycleColor(bc)
|
||||||
|
|
||||||
|
red.Set(uint16(rc) << 8)
|
||||||
|
green.Set(uint16(gc) << 8)
|
||||||
|
blue.Set(uint16(bc) << 8)
|
||||||
|
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,3 +15,7 @@ func (p GPIO) High() {
|
||||||
func (p GPIO) Low() {
|
func (p GPIO) Low() {
|
||||||
p.Set(false)
|
p.Set(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PWM struct {
|
||||||
|
Pin uint8
|
||||||
|
}
|
||||||
|
|
|
@ -58,3 +58,69 @@ func (p GPIO) Get() bool {
|
||||||
return (val > 0)
|
return (val > 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitPWM initializes the registers needed for PWM.
|
||||||
|
func InitPWM() {
|
||||||
|
// use waveform generation
|
||||||
|
*avr.TCCR0A |= avr.TCCR0A_WGM00
|
||||||
|
|
||||||
|
// set timer 0 prescale factor to 64
|
||||||
|
*avr.TCCR0B |= avr.TCCR0B_CS01 | avr.TCCR0B_CS00
|
||||||
|
|
||||||
|
// set timer 1 prescale factor to 64
|
||||||
|
*avr.TCCR1B |= avr.TCCR1B_CS11
|
||||||
|
|
||||||
|
// put timer 1 in 8-bit phase correct pwm mode
|
||||||
|
*avr.TCCR1A |= avr.TCCR1A_WGM10
|
||||||
|
|
||||||
|
// set timer 2 prescale factor to 64
|
||||||
|
*avr.TCCR2B |= avr.TCCR2B_CS22
|
||||||
|
|
||||||
|
// configure timer 2 for phase correct pwm (8-bit)
|
||||||
|
*avr.TCCR2A |= avr.TCCR2A_WGM20
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure configures a PWM pin for output.
|
||||||
|
func (pwm PWM) Configure() {
|
||||||
|
if pwm.Pin < 8 {
|
||||||
|
*avr.DDRD |= 1 << pwm.Pin
|
||||||
|
} else {
|
||||||
|
*avr.DDRB |= 1 << (pwm.Pin - 8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set turns on the duty cycle for a PWM pin using the provided value. On the AVR this is normally a
|
||||||
|
// 8-bit value ranging from 0 to 255.
|
||||||
|
func (pwm PWM) Set(value uint16) {
|
||||||
|
value8 := value >> 8
|
||||||
|
switch pwm.Pin {
|
||||||
|
case 3:
|
||||||
|
// connect pwm to pin on timer 2, channel B
|
||||||
|
*avr.TCCR2A |= avr.TCCR2A_COM2B1
|
||||||
|
*avr.OCR2B = avr.RegValue(value8) // set pwm duty
|
||||||
|
case 5:
|
||||||
|
// connect pwm to pin on timer 0, channel B
|
||||||
|
*avr.TCCR0A |= avr.TCCR0A_COM0B1
|
||||||
|
*avr.OCR0B = avr.RegValue(value8) // set pwm duty
|
||||||
|
case 6:
|
||||||
|
// connect pwm to pin on timer 0, channel A
|
||||||
|
*avr.TCCR0A |= avr.TCCR0A_COM0A1
|
||||||
|
*avr.OCR0A = avr.RegValue(value8) // set pwm duty
|
||||||
|
case 9:
|
||||||
|
// connect pwm to pin on timer 1, channel A
|
||||||
|
*avr.TCCR1A |= avr.TCCR1A_COM1A1
|
||||||
|
// this is a 16-bit value, but we only currently allow the low order bits to be set
|
||||||
|
*avr.OCR1AL = avr.RegValue(value8) // set pwm duty
|
||||||
|
case 10:
|
||||||
|
// connect pwm to pin on timer 1, channel B
|
||||||
|
*avr.TCCR1A |= avr.TCCR1A_COM1B1
|
||||||
|
// this is a 16-bit value, but we only currently allow the low order bits to be set
|
||||||
|
*avr.OCR1BL = avr.RegValue(value8) // set pwm duty
|
||||||
|
case 11:
|
||||||
|
// connect pwm to pin on timer 2, channel A
|
||||||
|
*avr.TCCR2A |= avr.TCCR2A_COM2A1
|
||||||
|
*avr.OCR2A = avr.RegValue(value8) // set pwm duty
|
||||||
|
default:
|
||||||
|
panic("Invalid PWM pin")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -56,8 +56,8 @@ func initUART() {
|
||||||
// Initialize UART at 115200 baud when running at 16MHz.
|
// Initialize UART at 115200 baud when running at 16MHz.
|
||||||
*avr.UBRR0H = 0
|
*avr.UBRR0H = 0
|
||||||
*avr.UBRR0L = 8
|
*avr.UBRR0L = 8
|
||||||
*avr.UCSR0B = avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 // enable RX and TX
|
*avr.UCSR0B = avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 // enable RX and TX
|
||||||
*avr.UCSR0C = avr.UCSR0C_UCSZ0 // 8-bits data
|
*avr.UCSR0C = avr.UCSR0C_UCSZ01 | avr.UCSR0C_UCSZ00 // 8-bits data
|
||||||
}
|
}
|
||||||
|
|
||||||
func putchar(c byte) {
|
func putchar(c byte) {
|
||||||
|
|
|
@ -183,10 +183,22 @@ const (
|
||||||
out.write(': {description}'.format(**register))
|
out.write(': {description}'.format(**register))
|
||||||
out.write('\n')
|
out.write('\n')
|
||||||
for bitfield in register['bitfields']:
|
for bitfield in register['bitfields']:
|
||||||
out.write('\t{name} = 0x{value:x}'.format(**bitfield))
|
name = bitfield['name']
|
||||||
if bitfield['description']:
|
value = bitfield['value']
|
||||||
out.write(' // {description}'.format(**bitfield))
|
if '{:08b}'.format(value).count('1') == 1:
|
||||||
out.write('\n')
|
out.write('\t{name} = 0x{value:x}'.format(**bitfield))
|
||||||
|
if bitfield['description']:
|
||||||
|
out.write(' // {description}'.format(**bitfield))
|
||||||
|
out.write('\n')
|
||||||
|
else:
|
||||||
|
n = 0
|
||||||
|
for i in range(8):
|
||||||
|
if (value >> i) & 1 == 0: continue
|
||||||
|
out.write('\t{}{} = 0x{:x}'.format(name, n, 1 << i))
|
||||||
|
if bitfield['description']:
|
||||||
|
out.write(' // {description}'.format(**bitfield))
|
||||||
|
n += 1
|
||||||
|
out.write('\n')
|
||||||
out.write(')\n')
|
out.write(')\n')
|
||||||
|
|
||||||
def writeLD(outdir, device):
|
def writeLD(outdir, device):
|
||||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче