极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 353|回复: 5

8F328P-U 的 PWM 訊號產生器

[复制链接]
发表于 2018-9-11 10:45:58 | 显示全部楼层 |阅读模式
頻率範圍: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) {
    case  9: 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()[1], 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);
  }
*/
回复

使用道具 举报

发表于 2018-9-11 11:11:23 | 显示全部楼层
这样子会和其他函数冲突不
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-11 11:31:56 | 显示全部楼层
Timer1:
Timer1 is a 16bit timer.
In the Arduino world the Servo library uses timer1 on Arduino Uno (timer5 on Arduino Mega).

跟 Timer1 有關的會有影響。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-11 11:36:43 | 显示全部楼层
這個主要是用來測試 LGT8F328P的能力,能上到300kHz PWM 的單片機,比市面一般的 8-bit單片機算是優勝的了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-11 11:42:04 | 显示全部楼层
在 Arduino 的支援下,編程的門檻也低,配合了processing 的上位機介面,用很低的價錢,就可以學到和得到很有效的學習工具。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-9-11 12:04:45 | 显示全部楼层
若可接受低的 dutyCycle,工作頻率可以提高到 4MHz (32MHz時鐘,可以到8MHz)。
以下是4MHz時的波形:

4MHzPWM.JPG
回复 支持 反对

使用道具 举报

高级模式  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2018-9-26 23:27 , Processed in 0.044815 second(s), 7 queries , File On.

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表