AVR Programming: Learning to Write Software for Hardware (Make Community, LLC)

サーボの駆動 / じりじりと左右に振ってみる

PB1から出力されるPWM波をサーボの信号端子に入力する。 #include <avr/io.h> #include <util/delay.h> int main(){ TCCR1A |= (1 << WGM11); TCCR1B |= (1 << WGM12) | (1 << WGM13); // 16ビット、Fast PWMモード TCCR1B |= (1 << CS11); // 8MHzを8分周してカウント ICR1 = 20000;</util/delay.h></avr/io.h>…

サーボの駆動 / タイマー1を16ビットFast PWMモードで使う

PWM / タイマー1を使ってOC1Aピン(PB1)、OC1Bピン(PB2)からPWM波を出力する -ではタイマー1を8ビットモードにしてPWM波を生成したが、今度は16ビットモードでPWM波を生成する。 #include <avr/io.h> int main(){ // ウェーブフォームモードの設定。16ビット、Fast PWM</avr/io.h>…

PWM / OCnA[B]ピン以外からもPWM波を出力する

PWM / タイマー1を使ってOC1Aピン(PB1)、OC1Bピン(PB2)からPWM波を出力する - PWM / タイマー2を使ってOC2Aピン(PB3)、OC2Bピン(PD3)からPWM波を出力する - PWM / タイマー0を使ってOC0Aピン(PD6)、OC0Bピン(PD5)からPWM波を出力する -ではタイマーをFast PW…

PWM / タイマー1を使ってOC1Aピン(PB1)、OC1Bピン(PB2)からPWM波を出力する

今度はタイマー1 (16ビット)を使ってOC1Aピン(PB1)、OC1Bピン(PB2)からPWM波を出力する。タイマー1は16ビットタイマーであるがここでは8ビットモードにして使ってみる。 #include <avr/io.h> /* タイマー1 (16ビット)を使ってOC1Aピン(PB1)、OC1Bピン(PB2)からPWM波を</avr/io.h>…

PWM / タイマー2を使ってOC2Aピン(PB3)、OC2Bピン(PD3)からPWM波を出力する

今度はタイマー2 (8ビット)を使ってOC2Aピン(PB3)、OC2Bピン(PD3)からPWM波を出力する。タイマー0 (8ビット)とほぼ同じである。 #include <avr/io.h> /* タイマー2 (8ビット)を使ってOC2Aピン(PB3)、OC2Bピン(PD3)からPWM波を出力する。 */ int main(){ TCCR2A |= (1 <</avr/io.h>…

PWM / タイマー0を使ってOC0Aピン(PD6)、OC0Bピン(PD5)からPWM波を出力する

タイマーを使うときは必ず、(1)ウェーブフォームモードを設定し、(2)クロックの分周比を設定し、(3)出力モードを設定する。 #include <avr/io.h> /* タイマー0 (8ビット)を使ってOC0Aピン(PD6)、OC0Bピン(PD5)からPWM波を出力する。 */ int main(){ TCCR0A |= (1 << WG</avr/io.h>…

PWM / タイマーは使わずにループだけでPWMを実現する

pp.204-206 #include <avr/io.h> #include <util/delay.h> void pwm_PORTB(uint8_t pin, int duty){ uint8_t _pin = (1 << pin); DDRB |= _pin; // 指定されたピンのIOをOUTにし、 for(int i=0; i<100; i++){ // 1周期の間に全部で100回ループするが、 if(i < duty){PORTB |= _pin;} </util/delay.h></avr/io.h>…

タイマーカウンターペリフェラル / PWM以外のまとめ

p.198 まとめ しかるべきウェーブフォームモードビットをセットして、ノーマルモード(デフォルト)かCTCモードかいずれかに設定する。 クロックの分周比を選択する。プリスケーラービットは、セットしないとプリスケーラーが接続されずにタイマーカウンターが…

タイマーカウンター0、1を組み合わせる / AM波を送信する

https://github.com/ti-nspire/AVR/tree/master/amRadio タイマー0で搬送波を生成し、タイマー1から割り込みをかけて搬送波の出力をon/offする(要するに振幅変調のようなものをかける)。 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include "scale16.h" static inline </avr/interrupt.h></util/delay.h></avr/io.h>…

Software CPU Clock Speed Control (p.194)非公式訳

CPUのクロック速度をソフトウェアで制御する AVRマイコンのデータシートを見ると、9.12.2 CLKPR - Clock Prescale Register というセクションがあります(訳註: 2018年DS40002061A版)。このレジスタの下位4ビットCLKPS<3:0>を使うと、1~256の範囲(ただし2の…

Burning Fuses: Enabling the High-Speed CPU Clock (p.193)非公式訳

ヒューズビットを設定する: 高速CPUクロックが使えるようにする まさかと思うかもしれませんが、AVRマイコンのほとんどはシステムCPUクロックが8分周された状態で出荷されます。つまり特に設定しない限り8分の1の速度で動作するということです。なぜAtmel社…

タイマーカウンター0、CTCモード、トグル出力を試す、を応用して音を鳴らす

https://github.com/ti-nspire/AVR/tree/master/timerAudio pp.184-188 タイマーカウンター0、CTCモード、トグル出力を試す -の続き。 https://ti-nspire.hatenablog.com/entry/2019/04/16/100444 https://ti-nspire.hatenablog.com/entry/2019/05/25/113241…

タイマーカウンター0、CTCモード、トグル出力を試す

アッスィラスコウプ CTCはClear Timer on Compare match。 WGMはWaveform Generation Mode。 TCCR0はタイマーカウンター0のTimer/Counter Control Register。 OCR0はタイマーカウンター0のOutput Compare Register。 システムクロックを8MHz、1024分周比、ト…

タイマーカウンターペリフェラルの概要

pp.177-180 クロックソースはシステムクロックでも外部ソースでもよい。 現在のカウント数は内部タイマーカウンターレジスターTCNTnに格納される。 TCNTnへは任意の値を書き込むこともできる。だから0にリセットすることが可能。 タイマーコンペアユニットは…

タイマーカウンターペリフェラルを使ってみる / タイマーカウンター1

https://github.com/ti-nspire/AVR/tree/master/reactionTime タイマーカウンター1を使って人の反応時間を計ってみる。 #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> extern "C" { #include "USART.h" #include "support.h" } // タイマーカウンター1を使うことにする。 s</avr/interrupt.h></util/delay.h></avr/io.h>…

Volatile and ISRs: The Bottom Line (p.175)非公式訳

volatileとISR: 大切なこと 函数(main()も含む)とISRとで同じグローバル変数を共有する場合、その変数はvolatileとして宣言しなければなりません。 ISRが実行されているかどうかは函数の側からは直接見えないため、その変数が函数のスコープ内で変化するかど…

外部割り込み / ピン変化割り込みPCINT / 容量性センサー

pp.166-176 https://github.com/ti-nspire/AVR/tree/master/capSense 容量性センサーは、2枚のアルミフォイルを紙で絶縁して作った。 一定時間での充放電の回数を数える。手をかざすと容量が増えて、一定時間での充放電回数が減る。その回数がしきい値を下回…

外部割り込みを試す / ピン変化割り込みPCINT18 (PD2)

https://github.com/ti-nspire/AVR/tree/master/helloInterrupt_PCINT 外部割り込みを試す / INT0 (PD2) -と同じことを今度はピン変化割り込みPCINT18 (PD2)で実行してみる。 割り込みを使うときは、ISR(割り込みベクタ)を定義しておいたうえで、割り込みに…

Interrupts: Under the Hood (p.161)非公式訳

割り込みのしくみ 割り込みはハードウェア寄りの機能ですが、魔法ではありませんし、そのしくみを知ればいつか割り込みがらみのバグを見つけ出すことになったときに役に立つかもしれません。 AVRのあらゆる機能がそうであるように、割り込みも各種レジスタの…

The ISR() is a Special Function (p.160)非公式訳

ISRは特殊な函数 ISRは函数ではありますが、普通の函数と大きく異なる点が2つあります。1つは返値のないことです。もう1つは、引数として割り込みベクタしか受け付けないことです。つまりISRには引数が直接渡せないため、ISRとデータをやり取りするためには…

外部割り込みを試す / INT0 (PD2)

https://github.com/ti-nspire/AVR/tree/master/helloInterrupt INT0 (PD2)、INT1 (PD3)へは、立ち上がり、立ち下がり、変化したとき、ローレベルのとき、という4種類で割り込みがかけられる。 PD2、PD3を含めすべてのIOピンへはピン変化割り込み(PCINT)がか…

ADCペリフェラル / 読み取るチャンネルを切り換える

https://github.com/ti-nspire/AVR/tree/master/night_light ADCペリフェラル自体は1個しか内蔵されていないのでマルチプレクサを使ってチャンネルを切り換える。 #include <avr/io.h> extern "C" { #include <util/delay.h> } static inline void initADC(){ ADMUX |= (1 << REFS0);</util/delay.h></avr/io.h>…

ADCペリフェラル / free runningモードを試す / AD変換値をシリアル通信でPCへ送る

https://github.com/ti-nspire/AVR/tree/master/slow_scope (.vi含む) ADCSRAレジスタのADATEビットをセットしてfree runningモードにする。テキストはpyserialでデータを受けているが、ここではLabVIEWを使ってみる。 #include <avr/io.h> extern "C" { #include <util/delay.h> #in</util/delay.h></avr/io.h>…

ADCペリフェラル / CdSを使った明るさセンサー / 上位3ビット値(0~7)だけを8セグメントLEDバーに表示する

https://github.com/ti-nspire/AVR/tree/master/lightSensor #include "mylib.h" #include <avr/io.h> #include <util/delay.h> void initADC(){ //static inline void initADC(){ ADMUX |= (1 << REFS0); // 基準電圧としてAVCCを使うことにする。 //ADCSRA |= (1 << ADPS2); // ADC</util/delay.h></avr/io.h>…

CdS (硫化カドミウム)を使った明るさセンサー / 分圧抵抗の目安

p.133 想定される範囲を満遍なく測りたいときは下のように分圧抵抗を決める。 キャドゥミァムサぉルふぁイドゥ

"How the ADC Works: Successive Approximation" (p.130のコラム)の非公式訳

ADCのしくみ: 逐次比較 AVRは基本的にはディジタルICです。ではどうして、入力端子に印加されたアナログ電圧がわかるのでしょうか? 実は正確な電圧は計れません。しかし巧みに判断を繰り返すことで、ある程度の範囲までは絞り込めます。AVRのADCで使われてい…

ディジタル入力としてAVRに接続したタクトスイッチでpyserialと通信する

https://github.com/ti-nspire/AVR/tree/master/bossButton2 pyserialモジュールでシリアル通信をする。webbrowserモジュールでWebページを開く。 -ではポケコンからpyserialへ向けてバイトデータを送り込んだが、今度はAVRから同じことをしてみる。 3つのタ…

pyserialモジュールでシリアル通信をする。webbrowserモジュールでWebページを開く。

import serial import webbrowser sp = serial.Serial("COM4", 9600, timeout=2) # serial.Serialクラスを実体化する。timeoutは秒単位。 sp.flush() # シリアルバッファーをクリアする。しなくてもよい。 while(1): # .read(1)でシリアルポートから1バイト…

排列に格納したいくつかの音を順番に鳴らす / FGからパルスを送り込んで一定のテンポで鳴らす

https://github.com/ti-nspire/AVR/tree/master/Music_Box_Pulse 今度は、スイッチでLHを切り換える代わりにFGからパルスを送り込んでみる。プログラムは、パルス入力用に全面的に書き換えることはせずに、排列に格納したいくつかの音を順番に鳴らす -で作っ…

排列に格納したいくつかの音を順番に鳴らす

https://github.com/ti-nspire/AVR/tree/master/Music_Box https://ti-nspire.hatenablog.com/entry/2019/04/16/100444では、鳴らす音をシリアルポートから指定したが、今度はあらかじめ排列にノートをいくつか仕込んでおいて、スイッチを押すたびにそのノー…