/***************************************************************** Ultrasonic wave transmiter(TX) By JA3OOK T.nakamura v1 2017/11 ------------------------------------------------------------------ 開発環境 MPLAB X IDE MPLAB XC8 C Compiler Free mode ******************************************************************/ // refer \c:Program Files(x86)\Microchip\xc8\v1.40\docs\chips\16f1619.html #pragma config BOREN = OFF //Brown-out Reset enable #pragma config WRT =OFF //Write protection off #pragma config FOSC = INTOSC//INTOSC oscillator: I/O function on CLKIN pin #pragma config PLLEN =OFF //4x PLL is enabled when software sets the SPLLEN bit #pragma config MCLRE =OFF //MCLR disabled #pragma config WDTE =OFF //WDT disabled #pragma config CP =ON //Code protection on #pragma config LVP =OFF //High-voltage on MCLR/VPP must be used for programming #pragma config PWRTE =OFF //Power-up Timer Enable #pragma config IESO =OFF //Internal External Switchover mode disabled #pragma config FCMEN =OFF //Fail-Safe Clock Monitor disabled #include "pic16f1619.h" #include #include "lcd_v2.h" #define MHz 000000 #define _XTAL_FREQ 16MHz //PIC_OSC_FREQ // Program name, Version and author #define prog_name "Ultrasonic TX" #define ver " v1 " #define author "by JA3OOK " //入力ポートは Rxx を記述 出力ポートは LATxx を記述 #define mode_port RC3 // ショートピン #define send_sonic_portP LATA1 // to Ultra-soni-speaker #define send_sonic_portN LATB4 // to Ultra-soni-speaker #define send_serial LATC1 // send-Serial #define led_port LATC4 // 内蔵LED #define initial_wait 4 // 電源投入後、送信開始までの秒数 // 超音波送信データ //   可能な文字コードは 0x21以上 0x5A以下 最後は ; //   文字数は ; を含め10文字以内 // デモ・データ unsigned char demo_1[] = "ABC;" ; unsigned char demo_1_leng = 4 ; unsigned char demo_2[] = "XYZ;" ; unsigned char demo_2_leng = 4 ; // オシロでの波形観測用データ bit:1010101010・・・ ; on Ultrasonic unsigned char str_x55[]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,';'} ; unsigned char str_x55_leng = 10 ; unsigned int t1count ; // タイマー設定値 unsigned int tm1_count ; // タイマーの割込み発生回数をカウントする変数 unsigned int t2count ; // タイマー設定値 unsigned int t3count ; // タイマー設定値 unsigned int tm3_count ; // タイマーの割込み発生回数をカウントする変数 unsigned char mode; // 立ち上げ時のモード bit time_unit_flag ; // time_unit ごとにON(time_unit:タイマー1で設定 例えば0.5秒) bit alternate_Sonic; // 超音波周波数発生 bit alternate_led; // LED点滅 unsigned char time_u_count ; unsigned char TXch ; // Serial send 1 char signed char bit_addr ; unsigned int timer ; //temporaryタイマー用(符号無し16ビット長) unsigned char i ; //temporary work unsigned char j ; //temporary work unsigned char str[21] ; //temporary work void interrupt InterTimer( void ){ // タイマー割込み if (TMR1IF) { // タイマー1(タイムユニット発生用)の割込み発生か? TMR1H = (t1count >> 8); // タイマーの初期化 TMR1L = (t1count & 0x00FF) ; // タイマーの初期化 TMR1IF = 0 ; // タイマー割込フラグをリセット tm1_count ++ ; // 割込み発生回数をカウント if(tm1_count >= 4){ //(割込間隔×左記回数)毎 tm1_count = 0; time_unit_flag = 1; } } if (TMR2IF) { // タイマー2(超音波サイクルの1/2)の割込み発生か? TMR2IF = 0 ; // タイマー割込フラグをリセット if(alternate_Sonic){ send_sonic_portP = 1; send_sonic_portN = 0; alternate_Sonic = 0; }else{ send_sonic_portP = 0; if(mode == 'A' && !mode_port){ send_sonic_portN = 0; } else{ send_sonic_portN = 1; } alternate_Sonic = 1; } } if (TMR3IF) { // タイマー3(シリアル通信速度決定用)の割込み発生か? TMR3H = (t3count >> 8); // タイマーの初期化 TMR3L = (t3count & 0x00FF) ; // タイマーの初期化 TMR3IF = 0 ; // タイマー割込フラグをリセット // tm3_count ++ ; // 割込み発生回数をカウント // if(tm3_count >= 4){ //(割込間隔×左記回数)毎 // tm3_count = 0; if(bit_addr == -1){ //Start bit send_serial = 0 ; TMR2IE = 1 ; // タイマー割込 bit_addr ++ ; } else{ if(bit_addr <= 7){ if((TXch >> bit_addr) & 0b00000001){ send_serial = 1 ; TMR2IE = 0 ; // タイマー割込 } else{ send_serial = 0 ; TMR2IE = 1 ; // タイマー割込 } bit_addr ++ ; } else{// 8 <= bit_addr //Stop bit send_serial = 1 ; TMR2IE = 0 ; // タイマー割込 bit_addr = 8; ; TXch = 0; } } } } void Serial_OutCh(char outChar){ //一文字送信 while(TXch); //送信可能になるまで待つ TXch = outChar; //送信するためにデータを格納 bit_addr = -1 ; } void Eusart_OutStr(const char * s, char n){ // n文字送信 char i; char j; j = n-1; for(i=0; i<=j; i++){ Serial_OutCh(*s++); } } void Analize_msg(void){ time_unit_flag = 0; alternate_led = 0; time_u_count = 0 ; alternate_Sonic = 0 ; TXch = 0 ; bit_addr = 8; ; while(1){ //無限loop if(time_unit_flag){ time_unit_flag = 0; time_u_count ++; if(time_u_count == 1){ led_port = 1; //内蔵LED __delay_ms(10); led_port = 0; //内蔵LED if(mode == 'A' && mode_port){ Eusart_OutStr(demo_1, demo_1_leng); // デモ・データ1 } else{ if(mode == 'A' && !mode_port){ Eusart_OutStr(demo_1, demo_1_leng); // デモ・データ1 } else{ if(mode_port){ Eusart_OutStr(demo_2, demo_2_leng); // デモ・データ2 } else{ if(!mode_port){ Eusart_OutStr(str_x55, str_x55_leng); // bit:1010101010・・・ on Usonic } } } } } if(time_u_count >= 4 ) { time_u_count = 0; } } } } void main(void){ OSCCON = 0b01111010; //internal OSC 16Mz OPTION_REG = 0b10000011; //All weak pull-ups are disabled (except MCLR, if it is enabled) //Prescaler is assigned to the Timer0 module, 1 : 16 ANSELA= 0b00000000; //All デジタル(既定値:アナログ) TRISA = 0b00011000; //RA4:Echo=SMT1SIG RA3:input(dummy) PORTA = 0b00000000; //初期化 ANSELB= 0b00000000; //All デジタル(既定値:アナログ) TRISB = 0b00000000; // PORTB = 0b00000000; //初期化 ANSELC= 0b00000000; //All デジタル(既定値:アナログ) TRISC = 0b01001100; // PORTC = 0b01001000; //初期化 if(mode_port){ mode = 'A'; } else{ mode = 'B'; } //タイマー:タイムユニット発生用 0.125s // 割込間隔が0.125sの場合 カウント数 = (16,000,000*0.125)/(4*8) =62,500 // (Fosc=16MHz Prescale=8 において) T1CON = 0b00110100; // Fosc/4、Prescaler 1:8 t1count = -62500; // カウントの初期値(nカウントでオーバー) TMR1H = (t1count >> 8); // タイマーの初期化 TMR1L = (t1count & 0x00FF) ; // タイマーの初期化 TMR1IF = 0 ; // タイマー割込フラグを0 tm1_count = 0 ; // 割込み発生の回数カウンターを0 //タイマー:超音波周期(40,000Hz=25μs)の1/2(=12.5μs) // 割込間隔が12.5μsの場合 カウント数 = (16,000,000*0.0000125)/(4*1*1) = 50 // (Fosc=16MHz scaler=各1 において) CCP2CON = 0b00000000; // Capture/Compare/PWM off T2HLT = 0b10000000; // Fosc/4, TIMER OPERATING MODES=00000=Software gate T2CLKCON = 0b00000000; // Fosc/4 T2CON = 0b00000000; // Prescaler 1:1 Postscaler 1:1 t2count = 50; // タイマー用カウントの初期値 PR2 = t2count; // タイマーとの比較値の設定(nカウントでオーバー) TMR2IF = 0 ; // タイマー割込フラグを0 //タイマー:シリアル通信速度(ボー)用 基本速度20ボー = 1/20=0.05s // 割込間隔が0.05sの場合 カウント数 = (16,000,000*0.05)/(4*8) =25,000 // (Fosc=16MHz Prescale=8 において) T3CON = 0b00110100; // Fosc/4 、Prescaler 1:8 t3count = -25000; // カウントの初期値(nカウントでオーバー) TMR3H = (t3count >> 8); // タイマーの初期化 TMR3L = (t3count & 0x00FF) ; // タイマーの初期化 TMR3IF = 0 ; // タイマー割込フラグを0 tm3_count = 0 ; // 割込み発生の回数カウンターを0 /* //debug タイマー:シリアル通信速度(ボー)用 基本速度110ボー = 1/110=0.009091s // 割込間隔が0.009091sの場合 カウント数 = (16,000,000*0.009091)/(4*8) =4546 // (Fosc=16MHz Prescale=8 において) T3CON = 0b00110100; // Fosc/4 、プリスケーラカウント値 1:8 t3count = -4546; // カウントの初期値(nカウントでオーバー) TMR3H = (t3count >> 8); // タイマーの初期化 TMR3L = (t3count & 0x00FF) ; // タイマーの初期化 TMR3IF = 0 ; // タイマー0割込フラグを0 tm3_count = 0 ; // 割込み発生の回数カウンターを0 */ // 送信開始まで待つ for(i = 1; i <= initial_wait; i ++){ led_port=1; //内蔵LED timer=1; while(timer--){__delay_ms(500);}; //Wait 1s led_port=0; //内蔵LED timer=1; while(timer--){__delay_ms(500);}; //Wait 1s } TMR1ON = 1 ; //タイムユニット発生用 TMR1IE = 1 ; //タイマー割込をマスクしない T2ON = 1 ; //超音波周期用 TMR2IE = 1 ; //タイマー割込をマスクしない TMR2IE = 0 ; //タイマー割込をマスク TMR3ON = 1; //シリアル通信速度(ボー)用 TMR3IE = 1 ; //タイマー割込をマスクしない PEIE = 1 ; // 周辺割込みをマスクしない GIE = 1 ; // 全割込み処理をマスクしない Analize_msg(); }