//******************************************************* // RF-2200 figure FM Radio // // MCU: ATtiny13 // hfuse:FBh BOD 2.7V // lfuse:22h 0.6MHz // // FM tuner module : NS953M (NIIGATA SEIMITSU CO., LTD.) // // Compiler: AVR-GCC 3.4.5 // AVR-LIBC 1.4.2 // binutils 2.16.1 // // 2006.2.14 KAWAKAMI Yukio // 2006.3.3 電源が切れないことがあるのを修正 // 2006.4.11 NS953M R6レジスタの設定値の間違いを修正 // 2007.11.6 NS953M R5レジスタの   〃 //******************************************************* #include #include #include #define NOP asm volatile("nop\n"::) #define WDR asm volatile("wdr\n"::) #define SLEEP asm volatile("sleep\n"::) typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; // NS953M レジスタ初期値 R0 はクリアしておき、後で再設定する PROGMEM uchar InitReg[] = { 0x00, 0x00, 0xC0, 0x37, 0xD8, 0x5D, 0x88, 0x4C, 0x09, 0x4D, 0x28, 0x8C, 0x04, 0x00 }; // ポート設定(PB) #define POWER_LOCK 0 // PB #define SWITCH 1 #define RSSO 2 #define SDA 3 #define SCL 4 #define EEPROM_CH 1 // チャンネル番号保存アドレス #define EEPROM_FREQ_START 8 // 周波数プリセット値の開始アドレス // TWI(I2C)動作のマクロ設定 #define SCL_H \ DDRB &= ~(1< 250){ TCNT0 = 250; } } } //******************************************************* // メインルーチン //******************************************************* int main (void) { uint freq; uchar ch; cli(); // 割り込み禁止 // ポート設定 PORTB = (1<= 28){ ch = 0; } freq = get_freq(ch); // EEPROMから周波数取得 set_freq(freq); // 周波数設定 while (!(PINB & (1<= 28){ // 次のチャンネル ch = 0; } freq = get_freq(ch); if (freq == 0xFFFF){ ch = 0; freq = get_freq(ch); } set_freq(freq); } else { // 300ms以上の長押し write_eeprom(EEPROM_CH, ch); // チャンネル番号保存 cli(); PORTB &= ~(1<> 8) | 0xC0; // R2 TWI_start(); // NS953Mに設定 TWI_send(0xC8); // スレーブアドレス + Write TWI_send(1); // R1 TWI_send(r1); TWI_send(r2); TWI_stop(); TWI_start(); TWI_send(0xC8); // スレーブアドレス + Write TWI_send(7); // R7 TWI_send(r7); TWI_stop(); } //******************************************************* // チャンネル番号から周波数取得 //******************************************************* uint get_freq(uchar ch){ uint freq; // EEPROMから周波数値(10kHz単位)読み込み freq = read_eeprom(EEPROM_FREQ_START + (ch * 2)); freq |= (uint)read_eeprom(EEPROM_FREQ_START + (ch * 2) + 1) << 8; return freq; } //************************************************************ // TWI 開始条件 //************************************************************ void TWI_start(void){ SDA_H; SCL_H; SDA_L; } //************************************************************ // TWI 8bit 送信 //************************************************************ void TWI_send(uchar data){ char bit; SCL_L; for (bit = 0; bit < 8; bit++){ if (data & 0x80){ SDA_H; } else { SDA_L; } SCL_H; WAIT_SCL_H; // SCL=Hになるまで待つ data <<= 1; SCL_L; } SDA_H; SCL_L; // ACK受信 内容は無視 SCL_H; NOP; SCL_L; } //************************************************************ // TWI 8bit 受信 //************************************************************ uchar TWI_recv(uchar nack){ char bit; uchar data; SDA_H; SCL_L; data = 0; for (bit = 0; bit < 8; bit++){ SCL_H; WAIT_SCL_H; // SCL=Hになるまで待つ data <<= 1; if (PINB & (1<