8F328P-U 的 PWM 訊號產生器
頻率範圍:250Hz ~ 150kHz (改動 operatingFrequency 值)* 註:若更改 clockFrequency 值 為 32,頻率可提高至 300kHz
佔空比: 0% ~ 100% (改動 dutycycle 值)
=======================================
//PWM_generator
#define PWMoutput 9
#define clockFrequencyMHz 16
#define operatingFrequency 150000
byte dutyCycle = 50;
unsigned int dutyCycleAdjusted = 40;
void setup() {
setInternalClock(clockFrequencyMHz);
pinMode(PWMoutput, OUTPUT); //D9
Serial.begin(115200);
setupPWM16();
dutyCycleAdjusted = map(dutyCycle, 0, 100, 0, ICR1);
analogWrite16(PWMoutput, dutyCycleAdjusted);
}
void loop() {
checkSerialSetDutyCycle();
}
void setInternalClock(byte clock) {
sysClock(INT_OSC); //use internal 32MHz RC clock
CLKPR = 0x80;
switch (clock) {
case 32: CLKPR = 0x00; //Divider=1, =>32MHz/1 = 32MHz
break;
case 16: CLKPR = 0x01; //Divider=2, =>32MHz/2 = 16MHz
break;
}
}
void setupPWM16() {
DDRB |= _BV(PB1) | _BV(PB2); /* set pins as outputs */
TCCR1A = _BV(COM1A1) | _BV(COM1B1)/* non-inverting PWM */
| _BV(WGM11); /* mode 14: fast PWM, TOP=ICR1 */
TCCR1B = _BV(WGM13) | _BV(WGM12)
| _BV(CS10); /* no prescaler */
ICR1 = ((clockFrequencyMHz * 1000000) / operatingFrequency)-1; /* TOP counter value (freeing OCR1A*/
//ICR1 = 16; /* TOP counter value (freeing OCR1A*/
}
/* Comments about the setup
Changing ICR1 will effect the amount of bits of resolution.
ICR1 = 0xffff; (65535) 16-bit resolution
ICR1 = 0x7FFF; (32767) 15-bit resolution
ICR1 = 0x3FFF; (16383) 14-bit resolution etc....
Changing the prescaler will effect the frequency of the PWM signal.
Frequency[Hz}=CPU/(ICR1+1) where in this case CPU=16 MHz
16-bit PWM will be>>> 16000000/(65535+1)=244,14Hz
*/
/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
switch (pin) {
case9: OCR1A = val; break;
case 10: OCR1B = val; break;
}
}
void checkSerialSetDutyCycle() {
// check if data has been sent from the computer:
if (Serial.available()) {
// read the most recent byte (which will be from 0 to 255):
dutyCycle = Serial.read();
// set the brightness of the LED:
if (dutyCycle == 0) {
dutyCycleAdjusted = 0;
digitalWrite(PWMoutput, LOW);
}
else {
setupPWM16();
dutyCycleAdjusted = map(dutyCycle, 0, 100, 0, ICR1);
analogWrite16(PWMoutput, dutyCycleAdjusted);
}
}
}
/* ================================================
// Processing control program
import processing.serial.*;
Serial port;
void setup() {
size(201, 150);
println("Available serial ports:");
// if using Processing 2.1 or later, use Serial.printArray()
println(Serial.list());
// Uses the first port in this list (number 0). Change this to select the port
// corresponding to your Arduino board. The last parameter (e.g. 9600) is the
// speed of the communication. It has to correspond to the value passed to
// Serial.begin() in your Arduino sketch.
port = new Serial(this, Serial.list(), 115200);
// If you know the name of the port used by the Arduino board, you can specify
// it directly like this.
//port = new Serial(this, "COM1", 9600);
}
void draw() {
// draw a gradient from black to white
for (int i = 0; i < 200; i++) {
stroke(i);
line(i, 0, i, 150);
}
// write the current X-position of the mouse to the serial port as
// a single byte
port.write(mouseX/2);
// port.write(0);
}
*/
:o这样子会和其他函数冲突不 Timer1:
Timer1 is a 16bit timer.
In the Arduino world the Servo library uses timer1 on Arduino Uno (timer5 on Arduino Mega).
跟 Timer1 有關的會有影響。 這個主要是用來測試 LGT8F328P的能力,能上到300kHz PWM 的單片機,比市面一般的 8-bit單片機算是優勝的了。 在 Arduino 的支援下,編程的門檻也低,配合了processing 的上位機介面,用很低的價錢,就可以學到和得到很有效的學習工具。 若可接受低的 dutyCycle,工作頻率可以提高到 4MHz (32MHz時鐘,可以到8MHz)。
以下是4MHz時的波形:
學習了,剛開始使用這塊U:dizzy:
謝謝。
页:
[1]