//********************************************************************** /*   <SPIテスト(マスターモード&スレーブモード)>  ■マスターの処理    ・ADC開始コマンドを送信する。    ・ADC(CH1)のデータを受信する。(データ受信コマンド「CH1」)    ・ADC(CH2)のデータを受信する。(データ受信コマンド「CH2])    ・ADC(CH3)のデータを受信する。(データ受信コマンド「CH3])    ・ADC(CH4)のデータを受信する。(データ受信コマンド「CH4])    ・CH1~CH4のデータをLCDに表示する。  ■スレーブの処理    ・マスターからのコマンドを受信する。    ・ADC開始コマンドであれば、CH1~CH4をAD変換する。    ・データ受信コマンドであれば、指定されたチャネルのデータを送信する。 */ //********************************************************************** //■■■関数宣言■■■ extern void main(); extern void SPI1_Write_Ss(unsigned short data_); extern unsigned short SPI1_Read_Ss(unsigned short buffer); //********************************************************************** //■■■マクロ定義■■■ //LCD sbit LCD_RS at RA6_bit; sbit LCD_EN at RA7_bit; sbit LCD_D7 at RB7_bit; sbit LCD_D6 at RB6_bit; sbit LCD_D5 at RB3_bit; sbit LCD_D4 at RB0_bit; sbit LCD_RS_Direction at TRISA6_bit; sbit LCD_EN_Direction at TRISA7_bit; sbit LCD_D7_Direction at TRISB7_bit; sbit LCD_D6_Direction at TRISB6_bit; sbit LCD_D5_Direction at TRISB3_bit; sbit LCD_D4_Direction at TRISB0_bit; //SPI sbit Slave_Select at RB5_bit; sbit Slave_Select_Direction at TRISB5_bit; sbit SCK_Direction at TRISB4_bit; //switch sbit SW_MODE at RA5_bit; #define MASTER_MODE 1 #define SLAVE_MODE 0 //ADC #define ADC_START 0 #define ADC_CH_1 1 #define ADC_CH_2 2 #define ADC_CH_3 3 #define ADC_CH_4 4 //other #define INPUT_MODE 1 #define OUTPUT_MODE 0 #define WORD unsigned int #define BYTE unsigned short //********************************************************************** //■■■SPI書き込み関数(スレーブセレクト型)■■■ void SPI1_Write_Ss(unsigned short data_) { Slave_Select = 0; SPI1_Write(data_); Slave_Select = 1; } //********************************************************************** //■■■SPI読み込み関数(スレーブセレクト型)■■■ BYTE SPI1_Read_Ss(unsigned short buffer) { BYTE rd, dummy; // Slave_Select = 0; rd = SPI1_Read(dummy); Slave_Select = 1; return (rd); } //********************************************************************** //■■■メイン関数■■■ void main() { int ad1, ad2, ad3, ad4; short dummy, mode; char buf[8]; double ad; // OSCCON = 0b01110000; ANSEL = 0b00001111; TRISA = 0b11101111; //LCD初期化 Lcd_Init(); Lcd_Cmd(_LCD_CLEAR); Lcd_Cmd(_LCD_CURSOR_OFF); Lcd_Out(1, 1, "SPI test"); if (SW_MODE == 1) { //マスターモード Lcd_Out(2, 1, " -> Master mode"); } else { //スレーブモード Lcd_Out(2, 1, " -> Slave mode"); } Delay_ms(1000); Lcd_Cmd(_LCD_CLEAR); //ADC初期化 ADC_Init(); //SPI初期化 if (SW_MODE == 1) { //マスターモード mode = MASTER_MODE; // Slave_Select = 1; Slave_Select_Direction = OUTPUT_MODE; SPI1_Init(); SSPSTAT.CKE = 0; // Lcd_Out(1, 1, "1:"); Lcd_Out(1, 9, "2:"); Lcd_Out(2, 1, "3:"); Lcd_Out(2, 9, "4:"); Delay_us(500); } else { //スレーブモード mode = SLAVE_MODE; // Slave_Select_Direction = INPUT_MODE; SPI1_Init(); SSPSTAT.CKE = 0; // SCK_Direction = INPUT_MODE; //SCKピンを入力モードにする。 SSPCON.SSPM3 = 0; SSPCON.SSPM2 = 1; SSPCON.SSPM1 = 0; SSPCON.SSPM0 = 0; } // while (1) { switch (mode) { case MASTER_MODE: //マスターモード //ADC開始コマンド SPI1_Write_Ss(ADC_START); Delay_us(500); //データ受信コマンド(CH1) SPI1_Write_Ss(ADC_CH_1); Delay_us(100); ad1 = SPI1_Read_Ss(dummy) << 8; ad1 |= SPI1_Read_Ss(dummy); Delay_us(100); //データ受信コマンド(CH2) SPI1_Write_Ss(ADC_CH_2); Delay_us(100); ad2 = SPI1_Read_Ss(dummy) << 8; ad2 |= SPI1_Read_Ss(dummy); Delay_us(100); //データ受信コマンド(CH3) SPI1_Write_Ss(ADC_CH_3); Delay_us(100); ad3 = SPI1_Read_Ss(dummy) << 8; ad3 |= SPI1_Read_Ss(dummy); Delay_us(100); //データ受信コマンド(CH4) SPI1_Write_Ss(ADC_CH_4); Delay_us(100); ad4 = SPI1_Read_Ss(dummy) << 8; ad4 |= SPI1_Read_Ss(dummy); Delay_us(100); //データ表示(CH1) ad = ad1; ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out(1, 3, &buf[1]); //データ表示(CH2) ad = ad2; ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out(1, 11, &buf[1]); //データ表示(CH3) ad = ad3; ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out(2, 3, &buf[1]); //データ表示(CH4) ad = ad4; ad = ad * 4.8828125; WordToStr(ad, buf); Lcd_Out(2, 11, &buf[1]); // Delay_ms(100); break; case SLAVE_MODE: //スレーブモード switch (SPI1_Read(dummy)) { case ADC_START: //ADC開始コマンド ad1 = ADC_Get_Sample(0); ad2 = ADC_Get_Sample(1); ad3 = ADC_Get_Sample(2); ad4 = ADC_Get_Sample(3); break; case ADC_CH_1: //データ受信コマンド(CH1) SPI1_Write((ad1 >> 8) & 0xFF); SPI1_Write(ad1 & 0xFF); break; case ADC_CH_2: //データ受信コマンド(CH2) SPI1_Write((ad2 >> 8) & 0xFF); SPI1_Write(ad2 & 0xFF); break; case ADC_CH_3: //データ受信コマンド(CH3) SPI1_Write((ad3 >> 8) & 0xFF); SPI1_Write(ad3 & 0xFF); break; case ADC_CH_4: //データ受信コマンド(CH4) SPI1_Write((ad4 >> 8) & 0xFF); SPI1_Write(ad4 & 0xFF); break; } break; } } } //**********************************************************************