新規記事の投稿を行うことで、非表示にすることが可能です。
2021年02月01日
txinit()
162行〜169行です。
/*
関数名から、送信初期化ということらしい。
TXBSZ は 1100 と定義済み。TXBSZ は送信バッファサイズかな。
txn が TXBSZ 以上だと sysdown(200) を実行する。
txn に 0、txr に TXBSZ を代入。これが初期化ということらしい。
*/
void
txinit(void)
{
if (txn >= TXBSZ)
sysdown(200); // tx buffer overflow has been detected.
txn = 0;
txr = TXBSZ;
}
/*
関数名から、送信初期化ということらしい。
TXBSZ は 1100 と定義済み。TXBSZ は送信バッファサイズかな。
txn が TXBSZ 以上だと sysdown(200) を実行する。
txn に 0、txr に TXBSZ を代入。これが初期化ということらしい。
*/
2021年01月29日
冒頭のコメント文
下記は kit_scope.ino の1〜44行目です。
15行目以降の pin usage は当然ながら、UNO のピン名称となります。UNO のピン名称と MCU の ATmage328 のピン名称の対応関係は、
https://wiki.onakasuita.org/pukiwiki/?Arduino/%E3%83%94%E3%83%B3%E9%85%8D%E7%BD%AE
上記URLにあります。
// Kyutech Arduino Scope Prototype v0.73 Apr 10, 2019
//
// (C) 2012-2019 M.Kurata Kyushu Institute of Technology
//
// for Arduinos with a 5V-16MHz ATmega328.
//
// use with "kit_scope.pde", a Proce55ing GUI sketch.
//
// You don't need to worry about this warning message produced by the IDE.
// "Low memory available, stability problems may occur."
// コンパイル時、下記メッセージが表示されますが、問題ありません。
// "スケッチが使用できるメモリが少なくなっています。動作が不安定になる可能性があります。"
//
//
// Pin usage
//
// A0 trigger level voltage input (connected to D6)
// A1 oscilloscope probe ch1
// A2 oscilloscope probe ch2
// A3 oscilloscope probe ext trigger
// A4 reserved
// A5 reserved
// A6 reserved
// A7 reserved
//
// D0 uart-rx
// D1 uart-tx
// D2 reserved
// D3 calibration pulse wave output
// D4 reserved
// D5 pwm output for generating trigger level voltage
// D6 analog comparator input (trigger level)
// D7 reserved
// D8 reserved
// D9 reserved
// D10 reserved
// D11 reserved
// D12 reserved
// D13 LED output
//
// different usage for dks2014 board.
// A4 fgen-sync
// D8 CH1 mode input 0..[0-10V] 1..[-5..5V] (pull-up needed)
// D9 CH2 mode input 0..[0-10V] 1..[-5..5V] (pull-up needed)
15行目以降の pin usage は当然ながら、UNO のピン名称となります。UNO のピン名称と MCU の ATmage328 のピン名称の対応関係は、
https://wiki.onakasuita.org/pukiwiki/?Arduino/%E3%83%94%E3%83%B3%E9%85%8D%E7%BD%AE
上記URLにあります。
2021年01月28日
Arduino UNO と ATmega328Pのピン配の対応関係、及びUNOピンの説明
kit-scopeのスケッチ内のソースコードを読むためには、Arduino UNO のピン配とATmega328(又は168)のピン配の対応関係を知る必要があります。
https://wiki.onakasuita.org/pukiwiki/?Arduino/%E3%83%94%E3%83%B3%E9%85%8D%E7%BD%AE
上記の説明がわかりやすのではないかと。ご参考までに。
また、UNOピンの説明もあらかじめ見ておくと参考になります。下記がわかりやすいと思いました。
https://dryossy.com/arduino/arduino-pin/
こちらもご参考までに。次はいよいよスケッチの解析か?
https://wiki.onakasuita.org/pukiwiki/?Arduino/%E3%83%94%E3%83%B3%E9%85%8D%E7%BD%AE
上記の説明がわかりやすのではないかと。ご参考までに。
また、UNOピンの説明もあらかじめ見ておくと参考になります。下記がわかりやすいと思いました。
https://dryossy.com/arduino/arduino-pin/
こちらもご参考までに。次はいよいよスケッチの解析か?
2021年01月26日
ATmega328/328Pのデータシート
Arduino UNOには、ATmega328が使用されている。kit-scopeのソースコードを解析するにはATmega328用のデータシートが無いよりはあった方がいいかも。ということで探しました。
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
英文です。下記に日本語のデータシートもあります。両方比較するといいですね。
https://avr.jp/user/DS/PDF/mega328P.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
英文です。下記に日本語のデータシートもあります。両方比較するといいですね。
https://avr.jp/user/DS/PDF/mega328P.pdf
デジタルオシロスコープって?
そもそもデジタルオシロスコープとはどういう仕組みなんでしょう。わかりやすい説明を見つけました。
https://www.iti.iwatsu.co.jp/ja/support/05_14.html
上記にはデジタルオシロスコープの原理図とリアルタイムサンプリング、等価時間サンプリング、プリトリガ、ロールモードの説明があります。参考になりますね。詳しく説明されても理解できるだけの能力が無いので、これくらいで丁度いいのかと思っております。実際、この程度の理解でいいんだか。。。
https://www.iti.iwatsu.co.jp/ja/support/05_14.html
上記にはデジタルオシロスコープの原理図とリアルタイムサンプリング、等価時間サンプリング、プリトリガ、ロールモードの説明があります。参考になりますね。詳しく説明されても理解できるだけの能力が無いので、これくらいで丁度いいのかと思っております。実際、この程度の理解でいいんだか。。。
2021年01月25日
Arduino について
ソフトウエア開発環境のArduinoと、ハードウエアとしてのMCU基板名がArduino-XXXとなっていて、ちょっとわかりにくい(どうしようもないですけど)。
ソフトウエア開発環境のArduinoの特徴は、https://tajimarobotics.com/arduino-sketch-basic-structure/
にあります。プログラミング言語はC++です。
ソフトウエア開発環境のArduinoで作成したソフトウエアはスケッチと呼ばれる。スケッチをハードウエアとしてのMCU基板のArduino-XXX(XXXはUnoとかいろいろ)に書き込むと下記の順でソフトウエアを実行する。
1.setup()は実行時に1回だけ読まれる。変数の初期設定をするところである。
2.loop()は中身に記述した内容を無限ループで実行する。自分のさせたいことを記述するところ。
基本はそうなのですが、理解するのは実際、難しいですよねえ?
ソフトウエア開発環境のArduinoの特徴は、https://tajimarobotics.com/arduino-sketch-basic-structure/
にあります。プログラミング言語はC++です。
ソフトウエア開発環境のArduinoで作成したソフトウエアはスケッチと呼ばれる。スケッチをハードウエアとしてのMCU基板のArduino-XXX(XXXはUnoとかいろいろ)に書き込むと下記の順でソフトウエアを実行する。
1.setup()は実行時に1回だけ読まれる。変数の初期設定をするところである。
2.loop()は中身に記述した内容を無限ループで実行する。自分のさせたいことを記述するところ。
基本はそうなのですが、理解するのは実際、難しいですよねえ?
2021年01月21日
Arduino IDE を勉強し直す
しばらくぶりにArduino IDE を勉強し直すことにします。ハードウエアも散逸してしまったので集め直しです。
Arduino IDE を、九州工業大学の kit_scope のソースコードを追いながら勉強してみようと思っています。初心者にはかなりハードルが高いので、どこまで理解できるのか? 少しずつ進めていこうかなと。。。
Arduino IDE を、九州工業大学の kit_scope のソースコードを追いながら勉強してみようと思っています。初心者にはかなりハードルが高いので、どこまで理解できるのか? 少しずつ進めていこうかなと。。。
2017年12月18日
modeequiv() について調べたこと(備忘録)
ソースコードは下記の通り。
void
modeequiv()
{
static const struct eqdic_s {
byte tkn;
byte tdif;
int rnum;
word wu;
} eqdic[] = {
{20, 2, 52, 4000},
{10, 4, 104, 4000},
{ 4, 10, 260, 10000},
{ 2, 20, 520, 20000},
};
const struct eqdic_s *eq;
int realnum, i;
byte at, crcnt, tokadif, toka, tokanum;
byte ch, chnum, vh, adch, adchT;
word ui1, waituntil, sinterval;
rminit(false);
eq = &eqdic[oscspeed & 3];
tokanum = eq->tkn;
waituntil = eq->wu;
realnum = eq->rnum;
tokadif = eq->tdif;
sinterval = 40; // 20us
uartjob();
// ADMUX reg values
switch(oscinput) {
default:
case 0x00: adch = 0x61; chnum = 1; break;
case 0x01: adch = 0x62; chnum = 1; break;
case 0x02: adch = 0x61; chnum = 2;
tokanum >>= 1;
tokadif <<= 1;
break;
}
adchT = 0x61 + (osctrig & 7);
header(2, 0);
// This data packet contines to MARC-A
sinterval--;
crcnt = 0;
at = 0;
for(toka = 0; toka < tokanum; toka++) {
for(ch = 0; ch < chnum; ch++) {
// reset and initialize timer1
TCCR1B = 0x00; // stop, set normal mode
TCCR1A = 0x00;
TIMSK1 = 0x00; // no irq
ICR1 = 0x0000;
TCNT1 = 0x0000;
TIFR1 = 0x27; // clear flags;
// analog comparator setting
// The D6 pin is the positive input.
// The negative input is A1, A2, A3, or A4 pin.
ACSR = 0x94; // analog comparator off
DIDR1 = 0x03; // disable the digital input func of D6 and D7.
ADMUX = adchT; // select the negative input
ADCSRA = 0x04;
ADCSRB = 0x40;
// start time1 with pre=1/8 (2MHz)
// input capture noise canceler ON
TCCR1B = (osctrig & 0x10) ? 0xc2 : 0x82; // edge selection
ACSR = 0x14; // capture-on, aco to caputure timer1
TIFR1 = 0x27; // clear flags again
ui1 = (tokadif * toka) + (osctdly << 1);
// falling edge detection(rising edge for ICES1)
// doesn't stabilize without a 20usec wait below.
while(TCNT1 < 40)
;
TIFR1 = 0x27;
// wait until a trigger event happens
while(true) {
if (TIFR1 & 0x20) {
// trigger event has happened.
ui1 += ICR1;
at = 0; // a trigger event has happened.
break;
}
if (TCNT1 > waituntil) {
ui1 += TCNT1;
at = 1; // trigger failed.
break;
}
uartjob();
}
// at:0 -> trigger event has happened, 1 -> not happened
ACSR = 0x94; // disable analog comparator
ADCSRB = 0x00;
ADCSRA = 0x84; // adc enable
TCCR1B = 0x1a; // timer1 CTC-ICR1 mode pre1/8
TCCR1A = 0x00; // CTC mode;
ICR1 = ui1;
TIFR1 = 0x27; // clear flags
ADMUX = 0x60; // adc target is A0 pin to get trigger value;
ADCSRB = 0x07; // timer1 capture event;
ADCSRA = 0xf4; // adc auto trigger, force 1st conversion
// wait until the 1st conversion finishes.
while((ADCSRA & 0x10) == 0x00)
uartjob();
vh = ADCH; // trigger level
osctvolt = vh;
ADMUX = adch + ch;
ADCSRA = 0xb4; // clear flag, 1MHz, adate on
if (toka == 0 && ch == 0) { // needed only for the 1st loop
// MARC-A continued
txput1(at);
txput1(vh);
txputcrc(false);
txgo(); // start to trasmit a packet
if (at)
goto ex; // send header only when trigger failed
}
for(i = 0; i < realnum; i++) {
while(true) {
if (TIFR1 & 0x20) {
ICR1 = sinterval;
TIFR1 = 0x27; // clear timer1 flags;
}
if ((ADCSRA & 0x10) != 0x00)
break;
uartjob();
}
vh = ADCH;
ADCSRA = 0xb4; // clear flag, 1MHz, adate on
txput1(vh);
if (++crcnt >= 200) {
crcnt = 0;
// cause crc error on purpose if trigger failed(at > 0).
txputcrc((at > 0) ? true : false);
}
}
}
}
//if (crcnt > 0)
// sysdown(800);
if (crcnt == 40) {
txputcrc((at > 0) ? true : false);
}
else
sysdown(800);
ex:
txfinish(true, true);
}
2017年12月17日
txputには、txput0(byte ch), txput1(byte ch), txputcrc(boolean force_error) がある
ソースコードは下記の通り。
void
txput0(byte ch)
{
// to reduce the cpu consumption,
// venture to omit txn overflow check.
// if programmed properly, such an overflow never occurs.
// rxn(appears later) check is omitted as well.
txbuf[txn++] = ch;
txcrc = 0;
}
void
txput1(byte ch)
{
txbuf[txn++] = ch;
txcrc = crctbl[txcrc ^ ch];
}
void
txputcrc(boolean force_error)
{
txput0((force_error) ? ++txcrc : txcrc);
}
uartjob() について調べたこと(備忘録)
ソースコードは下記になります。
rollmodeだとrmbuf[]にADCH(ADCの上位8bit)を書き込む。
そうじゃないと、UDR0にtxbuf[]を書き込む。
rollmodeだとrmbuf[]にADCH(ADCの上位8bit)を書き込む。
そうじゃないと、UDR0にtxbuf[]を書き込む。
void
uartjob()
{
byte sts;//sts は、status のことらしい
sts = UCSR0A;//UCSRnA - USARTn制御/状態レジスタA (USART Control and Status Register n A)
if ((char)sts < 0) //UCSR0Aの第7bitが1、つまり受信バッファに未読データありということ
rxbuf[rxn++] = UDR0;//UDRn - USARTnデータ レジスタ (USART I/O Data Register n)
//受信バッファにデータがあるのでrxbuf[]に取り込んだ
// in case rxbuf[] overflow, no fatal situation happens.
// because rxn is an 8 bit variable and rxbuf[] size is 256.
if (rmon) {//rmonって何? rmってroll memoryのことらしい
//rmonは、onがtrueの時に1としているみたい、falseなら0
//ここは殆ど通らないところ?
if (TIFR1 & 0x20)//TIFR1 - タイマ/カウンタ1割り込み要求フラグ レジスタ (Timer/Counter 1 Interrupt Flag Register)
//カウンタ1がTOP値になった
TIFR1 = 0x27; // clear timer1 flags; タイマ/カウンタ1割り込み要求フラグを全部クリアしている
if (ADCSRA & 0x10) {//ADCSRA - A/D制御/状態レジスタA (ADC Control and Status Register A)
if (rmon == 1) {
ICR1 = 100 - 1; // 50us
//ICR1は16bitレジスタ カウンタに設定する値
//0.5usを100倍すると50us
ADMUX = 0x62;//ADMUX - A/D多重器選択レジスタ (ADC Multiplexer Select Register)
//0x62 基準電圧はAVCCでアナログ入力はADC2 PC2 下記のコメントと矛盾
rmon = 2;
rmbuf[rmw++] = ADCH; // CH1(A1pin) value
//ADCの値は、8bit精度ならADCHを読むだけで事足りる(ADCLは読まない)
}
else if (rmon == 2) {
ICR1 = 400 - 1; // 200us
//0.5usを400倍すると200us
ADMUX = 0x60;//0x60 基準電圧はAVCCでアナログ入力はADC0 PC0 下記のコメントと矛盾
rmbuf[rmw++] = ADCH; // CH2(A2pin) value
rmon = 3;
}
else {
ICR1 = 500 - 1; // 250us
//0.5usを500倍すると250us
ADMUX = 0x61;//0x61 基準電圧はAVCCでアナログ入力はADC1 PC1 下記のコメントと矛盾
rmon = 1;
osctvolt = ADCH; // trigger level
}
ADCSRA = 0xb4; // clear flags, 1MHz, adate on
//ADCSRA - A/D制御/状態レジスタA (ADC Control and Status Register A)
//システムクロック16分周
return; //in order to release cpu quickly
}
}
if (txr < txn && (sts & 0x20)) {
UCSR0A = (sts & 0xe3) | 0x40;
UDR0 = txbuf[txr++];//UDRn - USARTnデータ レジスタ (USART I/O Data Register n)
//UDR0は送受信バッファ、バッファに送信データを書き込む
}
}