真空管アンプを作成した場合、そのアンプの周波数特性を自動的に測定したいと考えているのですが、そのために先ず必要となるのが信号発生器です。
理想的には、10Hz~100kHzまでを出力が一定のまま連続的にスイープできれば良いのですが、今回は周波数の範囲を低域限定(10Hz~100Hz)とし、出力が一定になるようにALC(自動レベル制御)回路を付加しました。
ALCについては、「自動レベル制御(ALC)の実験」を参照ください。
//********************************************************************** static unsigned char tbl[72] = { 127, 138, 149, 160, 170, 181, 191, 200, 209, 217, 224, 231, 237, 242, 246, 250, 252, 254, 254, 254, 252, 250, 246, 242, 237, 231, 224, 217, 209, 200, 191, 181, 170, 160, 149, 138, 127, 116, 105, 94, 84, 73, 63, 54, 45, 37, 30, 23, 17, 12, 8, 4, 2, 0, 0, 0, 2, 4, 8, 12, 17, 23, 30, 37, 45, 54, 63, 73, 84, 94, 105, 116, }; //********************************************************************** void sin10hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(1387); } if (PORTA.F5 == 0) return; } } void sin20hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(693); } if (PORTA.F5 == 0) return; } } void sin30hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(460); } if (PORTA.F5 == 0) return; } } void sin40hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(345); } if (PORTA.F5 == 0) return; } } void sin50hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(275); } if (PORTA.F5 == 0) return; } } void sin60hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(228); } if (PORTA.F5 == 0) return; } } void sin70hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(195); } if (PORTA.F5 == 0) return; } } void sin80hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(170); } if (PORTA.F5 == 0) return; } } void sin90hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(151); } if (PORTA.F5 == 0) return; } } void sin100hz() { unsigned char cnt; while (1) { for (cnt = 0; cnt < 72; cnt++) { PORTB = tbl[cnt]; Delay_us(137); } if (PORTA.F5 == 0) return; } } //********************************************************************** void main() { CMCON = 0b00000111; // コンパレータは使用しない。 ANSEL = 0b00000000; // A/D変換は使用しない。 TRISA = 0b11111111; TRISB = 0b00000000; while (1) { switch (PORTA & 0b00011111) { case 0: break; case 1: sin10hz(); break; case 2: sin20hz(); break; case 3: sin30hz(); break; case 4: sin40hz(); break; case 5: sin50hz(); break; case 6: sin60hz(); break; case 7: sin70hz(); break; case 8: sin80hz(); break; case 9: sin90hz(); break; case 10: sin100hz(); break; default: break; } } } //**********************************************************************