Timer測試

回覆文章
cajhbb
系統管理員
文章: 983
註冊時間: 2018年 6月 30日, 02:16

Timer測試

文章 cajhbb »

http://www.technoblogy.com/show?3AAM
https://www.block.tw/blog/arduino-88-le ... x-max7219/ 8X8教學網
https://xantorohara.github.io/led-matri ... fe80bcbc80 8x8程式產生器
https://atceiling.blogspot.com/2017/03/ ... atrix.html 8X8教學網
https://shop.mirotek.com.tw/tutorial/arduino-max7219/ MAX7219
https://itcgs.tcgs.tc.edu.tw/yute?cid=2461 函式庫說明
https://rover2.net/2020/12/attiny85%E8% ... %E6%98%8E/ attiny85腳位說明
https://blog.jmaker.com.tw/ds1302/ 時間模組
https://blog.jmaker.com.tw/arduino-ds1302-lcd/
https://www.bing.com/videos/riverview/r ... &FORM=VIRE DS3231
http://www.technoblogy.com/show?1ZIY 內部20M good
http://www.technoblogy.com/show?P6X 8MHZ
https://www.gadgetronicx.com/attiny85-t ... nterrupts/ 時鐘程式
https://greatli69.pixnet.net/blog/post/447813695 arduino timer
http://www.ndfweb.cn/hk/news-778.html timer 使用範例 Good
https://medium.com/%E9%96%B1%E7%9B%8A%E ... e057f2ca5f 使用範例
https://hackmd.io/@yencheng/KGHS_ARDUINO 機器人加課
https://cabinet79.blogspot.com/2015/03/ ... sters.html Timer定時
https://hankgogorobot.blogspot.com/2018 ... timer.html 定時中斷
https://www.youtube.com/watch?v=w-WuRpywZ5w 影片中斷觸發
https://zh-tw.hwlibre.com/timer-arduino/ Arduino 計時器如何工作?
https://www.youtube.com/watch?v=0TIoYq5spGU arduino timer詳細說明 good
https://shop.mirotek.com.tw/tutorial/arduino-max7219/ 米羅的程式 點矩陣 亮度=7
https://sites.google.com/view/rayarduino/led-max-7219 8x8 max7219 good
https://forum.arduino.cc/t/attiny-85-and-spi/313613/4 attiny85 tinySPI.h
https://www.youtube.com/watch?v=jPkv8xJ2ddM attiny85 矩陣串列
https://akuzechie.blogspot.com/2021/06/ ... -with.html 上式程式
cajhbb
系統管理員
文章: 983
註冊時間: 2018年 6月 30日, 02:16

為何要外接石英振盪器

文章 cajhbb »

16位元產生器
MAX7219P.zip
(7.75 KiB) 已下載 4 次

請問attiny85接8x8 LED矩形做成一個時鐘,為何要外接石英振盪器
使用外接石英振盪器(例如32.768kHz的石英晶體)來驅動ATtiny85有幾個主要原因:

準確性:石英振盪器提供非常高的時間準確性,這對於製作時鐘非常重要。內建的振盪器可能會受到溫度和電源電壓的影響,而石英振盪器則不會。

穩定性:石英振盪器的頻率非常穩定,不會隨時間變化,這意味著你的時鐘會保持一致的準確性。

功耗:使用低頻率的石英振盪器可以降低ATtiny85的功耗,這對於電池供電的裝置非常有利。

計時精度:石英振盪器可以提供精確的1秒計時,這對於製作時鐘非常重要。內建的振盪器可能無法提供如此精確的計時。
---------------------------------------------------------------------------------------------
若直接用attiny85內部的計時器,來製作時鐘會有何問題?
使用ATtiny85內部的計時器製作時鐘可能會遇到以下幾個問題:

準確性不足:ATtiny85內部的振盪器(RC振盪器)並不像石英振盪器那樣準確。它容易受到溫度和電源電壓變化的影響,這會導致時間累積誤差。

穩定性差:內部振盪器的頻率穩定性較差,長時間運行後可能會偏移,導致時鐘的計時不準確。

熱漂移:內部RC振盪器的頻率會隨溫度變化而改變,這會進一步影響時鐘的準確性。例如,在不同環境溫度下,時間誤差可能會更明顯。

長期可靠性:由於內部振盪器的固有不穩定性,長期使用可能會導致更大的時間偏差,需要定期校正。

總而言之,雖然使用內部計時器可以簡化電路設計並減少元件數量,但如果你希望製作一個準確且穩定的時鐘,建議使用外部石英振盪器。這樣可以確保你的時鐘長期保持準確。
cajhbb
系統管理員
文章: 983
註冊時間: 2018年 6月 30日, 02:16

Re: 8x8-clock

文章 cajhbb »

以上程式請加註解,且外接8MHz的石英振盪器,要接Arduino 開發板的那幾個腳位,如何計算時,分,秒?請說明
當然,下面是加上註解後的程式碼以及外接8MHz石英振盪器到Arduino開發板腳位的說明。這裡還包括如何計算時、分和秒。

材料準備:
Arduino 開發板(例如 Arduino Uno)

8MHz 石英振盪器

7段顯示器(4位數字)

74HC595 移位寄存器(可選,視需要而定)

電阻和導線

外接8MHz石英振盪器:
8MHz 石英振盪器的兩個腳位分別接到 Arduino 的 XTAL1 和 XTAL2 腳位上。具體如下:

XTAL1 (引腳9)

XTAL2 (引腳10)

並且需要在 Arduino 上安裝對應的電容(一般來說是 22pF)到地。
cajhbb
系統管理員
文章: 983
註冊時間: 2018年 6月 30日, 02:16

CTC與normal

文章 cajhbb »

在Arduino編程中,Timer1是一個16位的計時/計數器,可以用來處理時間和計數的各種應用,像是PWM產生、計時等。其中,Timer1可以運行在多種模式下,包括Normal模式和CTC(Clear Timer on Compare Match)模式。下面是這兩種模式的區別:

Normal模式
簡介:這是計時器的基本模式,在這種模式下,計時器只是從0開始遞增,直到達到其最大值(65535 for 16-bit timer),然後回到0並再次開始遞增。 應用:

溢出中斷:當計數器達到其最大值並回到0時會觸發溢出中斷,這在計時應用中是非常有用的。

精確的計時器:適用於需要精確計時的應用。

簡單應用:運行循環計數的應用程序。

主要特點:

每次計數器值達到最大值並回到0時會觸發溢出中斷。

應用簡單,控制方便。

CTC模式
簡介:CTC模式允許計時器在計數達到一個比較值(由用戶設置)時觸發事件,然後將計數器自動清零。這是一種更先進的計數模式。 應用:

PWM(脈衝寬度調製):用於生成精確的PWM信號。

定時器割接點:適用於需要精確定時的應用,像是控制事件的發生頻率。

計數驅動應用程序:需要重複性事件發生的應用程序。

主要特點:

計數器達到設定的比較值時觸發比較中斷。

可以通過設置比較值來控制計時器周期。

提供更多靈活性和控制精確性的應用場景。
cajhbb
系統管理員
文章: 983
註冊時間: 2018年 6月 30日, 02:16

arduino寫一個時鐘程式,用內部的16MHz,使用Timer1請建議一個準確度佳,TCNT1及OCR1A,OCR1B的設定值

文章 cajhbb »

計時器設置
Arduino UNO上的Timer1是一個16位計時器,這意味著計時器可以從0計數到65535。內部16MHz時鐘頻率以及預分頻(Prescaler)設置將影響計時器的準確性。在這裡,我們將使用CTC模式來設置Timer1,以實現精確的秒計時。

計算OCR值
要設置Timer1以每秒觸發一個中斷,我們需要正確計算比較寄存器OCR1A的值。我們假設預分頻設置為256,這意味著計時器的計數頻率為16MHz / 256 = 62500Hz。 在CTC模式下,計時器將在計數達到OCR1A值時清零並觸發中斷。因此,我們需要設置OCR1A以便計數到62500來表示一秒:

代碼: 選擇全部

OCR1A = (目標計數時間 * 計數頻率) - 1
OCR1A = (1秒 * 62500) - 1 = 62499
程式碼範例

代碼: 選擇全部

const long interval = 1000;  // interval time in milliseconds for the clock to update
long previousMillis = 0;    // will store last time the timer was updated
volatile boolean timeToCount = false;

void setup() {
  // 設置Timer1以CTC模式運行
  TCCR1A = 0;               // 設置計時器控制寄存器A [WGM12: CTC模式,定義波形產生模式]
  TCCR1B |= (1 << WGM12);   // 設置計時器控制寄存器B [設置WGM12位]
  TCCR1B |= (1 << CS12);    // 設置預分頻為256
  OCR1A = 62499;            // 設置計時器頂值為62500 - 1
    
  // 啓用比較中斷
  TIMSK1 |= (1 << OCIE1A);
  
  // 初始化序列埠
  Serial.begin(9600);
  
  //全局中斷
  sei();
}

void loop() {
  if(timeToCount){
    timeToCount = false;

    unsigned long currentMillis = millis();
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      Serial.println("1 second has passed");
    }
  }
}

ISR(TIMER1_COMPA_vect) {
  timeToCount = true;
}
每次中斷服務子程序(ISR)觸發時,計數器將設置為true,這樣loop()函數就可以記錄每秒並打印消息。你可以根據需要調整計數或其他功能。

這種方法可以保證你時鐘程式的高准確性。
cajhbb
系統管理員
文章: 983
註冊時間: 2018年 6月 30日, 02:16

完成arduino CTC比較中斷1秒

文章 cajhbb »

完成arduino CTC比較中斷1秒

代碼: 選擇全部

/* Timer1(16bits)最大值65535計時1秒,將針腳13LED反相 
石英振盪=16MHz + 設定CTC模式(Clear Timer on Compare Match)
TCCR1A要設-->WGM11=0 WGM10=0
TCCR1B要設-->WGM13=0 WGM12=1 (除頻256-->CS12=1 CS11=0 CS10=0)
<註>1.CS12=1 CS11=0 CS10=0 查表:除256
<註>2.使用除頻器除256,16M/256=62500Hz
<註>3.OCR1A=(目標時間*計數頻率)-1-->OCR1A=(1秒*62500)-1=62499次
<註>4.比較器中斷法,數值不可以超過65535,否則要換方法
<註>5.比較中斷62499次,才可以得到1秒!
*/
#include<avr/io.h>
#include<avr/interrupt.h>
#define PINLED 13 //內建第13腳位的LED燈
//volatile uint16_t cntInt=0;//中斷次數值(volatile的宣告方式適合中斷後,計數不會被更改)
volatile bool stateLED=LOW;//LED目前為(滅)
uint32_t preTime,curTime;//前次時間,目前時間
volatile bool flag1s=false;//旗熛判斷(是否達1秒)
//----------Timer1設為CTC模式比較中斷模式 ------------
void init_timer1_CTC(){
 // 設置Timer1以CTC模式運行
 TCCR1A=TCCR1A &(~(1<<WGM11))&(~(1<<WGM10));//設為0
 TCCR1B=TCCR1B &(~(1<<WGM13));//設為0
 TCCR1B=TCCR1B |((1<<WGM12));//設為1
//暫存器TCCR1B(CS12=1,CS11=0,CS10=0)設置預分頻為256
 TCCR1B=TCCR1B &(~(1<<CS11))&(~(1<<CS10));//
 TCCR1B=TCCR1B |((1<<CS12));// 
 OCR1A = 62499;   // 設置比較值為62500 - 1
 TIMSK1 |= (1 << OCIE1A);//啓用比較中斷
 sei();//啟動中斷功能
}
//---------設定arduino 接腳輸出------------------------
void init_pin(){
  pinMode(PINLED, OUTPUT);//設為輸出
  digitalWrite(PINLED,stateLED);
}
//----------------------------------------------------
void setup() {
  Serial.begin(9600);//序列傳輸
  init_pin();//呼叫 arduino接腳輸出設定
  init_timer1_CTC();//呼叫timer1設為CTC的函式
  curTime=micros();//紀錄目前時間
}

void loop() {
  if(flag1s){ //旗標等於1秒時
    preTime=curTime;//目前覆蓋於前次
    curTime=micros();//現在歸零
    Serial.println(curTime-preTime);//輸出所需的1秒鐘,誤差為多少
    flag1s=false;//等待下一個1秒的旗標
  }

}
//-------以下為比較中斷服務函式----------------------------
//計數器1
ISR(TIMER1_COMPA_vect){
    stateLED=!stateLED;//1秒後反相輸出
    digitalWrite(PINLED,stateLED);
    flag1s=true;//設定1秒旗標,供主迴圈使用
}

回覆文章