//********************************************************************** /*   『wave-player』 */ //********************************************************************** //■マクロの定義 #define BYTE unsigned short #define WORD unsigned int #define WWORD unsigned long #define SW_PLAY_SDC PORTB.B7 #define SW_PLAY_EEPROM PORTB.B6 #define SW_LOAD PORTB.B5 #define SW_STOP PORTB.B4 #define LED PORTB.B3 #define ACK 1 #define NO_ACK 0 #define WRITE_CYCLE_TIME 5 //********************************************************************** //■関数および変数の宣言 extern void main(); extern void init_lcd(); extern void init_sdc(); extern void init_ccp_compare(); extern void init_i2c(); extern void EEPROM_24LC1025_Page_Write(WWORD addr, BYTE *msg, WORD len); extern void EEPROM_24LC1025_Page_Read(WWORD addr, BYTE *msg, WORD len); extern void play_sdc(); extern void play_eeprom(); extern void load_sdc2eeprom(); //********************************************************************** //■グローバル変数の定義 char buf[500]; //********************************************************************** //■メイン関数です。 void main() { //ポートの設定 TRISA = 0b11111111; TRISB = 0b11110000; TRISC = 0b00000000; ADCON1.PCFG3 = 1; ADCON1.PCFG2 = 1; ADCON1.PCFG1 = 1; ADCON1.PCFG0 = 1; //PWMの初期化(1)→WAVE再生用に使用します。 PWM1_Init(100000); //100kHz PR2 = 0xFF; PWM1_Set_Duty(PR2 / 2); PWM1_Start(); //PWMの初期化(2)→LCDの輝度電圧(負電圧発生)に使用します。 PWM2_Init(100000); //100kHz PR2 = 0xFF; PWM2_Set_Duty(PR2 / 2); PWM2_Start(); Delay_ms(100); //LCDの初期化 init_lcd(); //SDCの初期化 init_sdc(); //I2Cの初期化 init_i2c(); // while (1) { Lcd_Out(1, 1, "RUN MODE ?"); // if (SW_PLAY_SDC == 0) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1, 1, "PLAY SDC"); play_sdc(); Lcd_Out(1, 1, "STOP "); Delay_ms(500); Lcd_Cmd(_LCD_CLEAR); } if (SW_PLAY_EEPROM == 0) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1, 1, "PLAY EEPROM"); play_eeprom(); Lcd_Out(1, 1, "STOP "); Delay_ms(500); Lcd_Cmd(_LCD_CLEAR); } if (SW_LOAD == 0) { Lcd_Cmd(_LCD_CLEAR); Lcd_Out(1, 1, "LOAD SDC->EEPROM"); load_sdc2eeprom(); Lcd_Out(1, 1, "STOP "); Delay_ms(500); Lcd_Cmd(_LCD_CLEAR); } } } //********************************************************************** //■SDCのWAVEファイルの内容を再生する関数です。 void play_sdc() { WWORD fsize, length, cnt, addr; char character; // Mmc_Fat_Assign("wave.wav", 0); Mmc_Fat_Reset(&fsize); length = 0; for (cnt = 0; cnt < 58; cnt++) { Mmc_Fat_Read(&character); } length += 58; addr = 0; while ((length < fsize) && (SW_STOP == 1)) { Mmc_Fat_Read(&character); PWM1_Set_Duty(character); length++; Delay_us(70); } } //********************************************************************** //■EEPROMの内容を再生する関数です。 void play_eeprom() { WWORD addr; // addr = 0; Soft_I2C_Start(); Soft_I2C_Write(0xA0); Soft_I2C_Write((addr >> 8) & 0xFF); Soft_I2C_Write(addr & 0xFF); Soft_I2C_Start(); Soft_I2C_Write(0xA1); while (addr < 0x10000) { PWM1_Set_Duty(Soft_I2C_Read(ACK)); addr++; Delay_us(50); if (SW_STOP == 0) { break; } } PWM1_Set_Duty(Soft_I2C_Read(NO_ACK)); Soft_I2C_Stop(); // addr = 0; Soft_I2C_Start(); Soft_I2C_Write(0xA8); Soft_I2C_Write((addr >> 8) & 0xFF); Soft_I2C_Write(addr & 0xFF); Soft_I2C_Start(); Soft_I2C_Write(0xA9); while (addr < 0x10000) { PWM1_Set_Duty(Soft_I2C_Read(ACK)); addr++; Delay_us(50); if (SW_STOP == 0) { break; } } PWM1_Set_Duty(Soft_I2C_Read(NO_ACK)); Soft_I2C_Stop(); } //********************************************************************** //■SDCのWAVEファイルの内容をEEPROMに書き込む関数です。 void load_sdc2eeprom() { WWORD fsize, length, cnt, addr; char character; // Mmc_Fat_Assign("wave.wav", 0); Mmc_Fat_Reset(&fsize); length = 0; for (cnt = 0; cnt < 58; cnt++) { Mmc_Fat_Read(&character); } length += 58; addr = 0; while ((length < fsize) && (addr < 0x20000) && (SW_STOP == 1)) { for (cnt = 0; cnt < 128; cnt++) { Mmc_Fat_Read(&character); //1個データを飛ばします。 Mmc_Fat_Read(&character); buf[cnt] = character; } EEPROM_24LC1025_Page_Write(addr, buf, 128); addr += 128; fsize += 128; LongWordToStr(addr, buf); Lcd_Out(2, 1, buf); } Lcd_Cmd(_LCD_CLEAR); } //********************************************************************** //■LCDを初期化する関数です。 sbit LCD_RS at RA5_bit; sbit LCD_EN at RA4_bit; sbit LCD_D7 at RA0_bit; sbit LCD_D6 at RA1_bit; sbit LCD_D5 at RA2_bit; sbit LCD_D4 at RA3_bit; sbit LCD_RS_Direction at TRISA5_bit; sbit LCD_EN_Direction at TRISA4_bit; sbit LCD_D7_Direction at TRISA0_bit; sbit LCD_D6_Direction at TRISA1_bit; sbit LCD_D5_Direction at TRISA2_bit; sbit LCD_D4_Direction at TRISA3_bit; void init_lcd() { short cnt; // Lcd_Init(); Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Out(1, 1, "wave player v1.0"); for (cnt = 0; cnt < 16; cnt++) { Lcd_Chr(2, cnt + 1, 0xFF); Delay_ms(100); } Lcd_Cmd(_LCD_CLEAR); } //********************************************************************** //■SDCを初期化する関数です。 sfr sbit Mmc_Chip_Select at RC6_bit; sfr sbit Mmc_Chip_Select_Direction at TRISC6_bit; void init_sdc() { SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH); if (Mmc_Fat_Init()) { while (1) { Lcd_Out(2, 1, "SDC error!"); Delay_ms(500); Lcd_Out(2, 1, " "); Delay_ms(500); } } SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH); Lcd_Out(2, 1, "SDC complete!"); Delay_ms(500); Lcd_Cmd(_LCD_CLEAR); } //********************************************************************** //■I2Cを初期化する関数です。 sbit Soft_I2C_Scl at RC0_bit; sbit Soft_I2C_Sda at RC1_bit; sbit Soft_I2C_Scl_Direction at TRISC0_bit; sbit Soft_I2C_Sda_Direction at TRISC1_bit; void init_i2c() { Soft_I2C_Init(); } //********************************************************************** //■EEPROMにページ単位でデータを書き込む関数です。 void EEPROM_24LC1025_Page_Write(WWORD addr, BYTE *msg, WORD len) { int cnt; // Soft_I2C_Start(); if ((addr & 0x10000) == 0) Soft_I2C_Write(0xA0); else Soft_I2C_Write(0xA8); Soft_I2C_Write((addr >> 8) & 0xFF); Soft_I2C_Write(addr & 0xFF); for (cnt = 0; cnt < len; cnt++) { Soft_I2C_Write(msg[cnt]); } Soft_I2C_Stop(); // Delay_ms(WRITE_CYCLE_TIME); } //********************************************************************** //■EEPROMからページ単位でデータを読み込む関数です。 void EEPROM_24LC1025_Page_Read(WWORD addr, BYTE *msg, WORD len) { int cnt; // Soft_I2C_Start(); if ((addr & 0x10000) == 0) Soft_I2C_Write(0xA0); else Soft_I2C_Write(0xA8); Soft_I2C_Write((addr >> 8) & 0xFF); Soft_I2C_Write(addr & 0xFF); Soft_I2C_Start(); if ((addr & 0x10000) == 0) Soft_I2C_Write(0xA1); else Soft_I2C_Write(0xA9); for (cnt = 0; cnt < (len - 1); cnt++) { msg[cnt] = Soft_I2C_Read(ACK); } msg[cnt] = Soft_I2C_Read(NO_ACK); Soft_I2C_Stop(); // Delay_ms(WRITE_CYCLE_TIME); } //**********************************************************************