/***************************************************************** Ultrasonic wave receiver(RX) 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 #include #include "lcd_v2.h" #define MHz 000000 #define _XTAL_FREQ 16MHz //PIC_OSC_FREQ // Program name, Version and author #define prog_name "Ultrasonic RX" #define ver " v1 " #define author "by JA3OOK " //入力ポートは Rxx を記述 出力ポートは LATxx を記述 #define LCD_VDD LATC0 // VDD of LCD #define led_port LATC4 // LED #define RA4 RA4 // Echo-pin of US-015改 // 超音波受信・照合データ //   可能な文字コードは 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 Usonic 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 t3count ; // タイマー設定値 unsigned int t3count2 ; // t3countの1.5倍値 unsigned int tm3_count ; // タイマーの割込み発生回数をカウントする変数 unsigned char RXch ; // Serial recv 1 char unsigned char bit_addr ; bit RXch_end; //1:コマンド終了記号を受信した 0:コマンド終了記号を未だ受信していない #define rxStr_max 11 //POST記号の ; を含めた最長バイト数+1 unsigned char rxStr[rxStr_max]; //受け取ったコマンド文字列 unsigned char rx_str_loc; //コマンド中の文字の位置(0から始まる) 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(IOCAF4) {// RA4 1→0 変化割込み発生か? if(t3count2 == -25000){ __delay_ms(3); } if(!RA4){ Lcd_goto(0x4E); // debug Lcd_putch('i'); // debug Lcd_goto(0x40); // debug IOCAF4 = 0; IOCIE = 0; //All PORT-pin change interrupt IOCAN4 = 0; //Interrupt-on-Change Negative Edge RXch = 0; bit_addr = 0 ; TMR3H = (t3count2 >> 8); // 1.5倍のタイマー初期化 TMR3L = (t3count2 & 0x00FF) ; // TMR3IF = 0 ; // タイマー割込フラグをリセット TMR3IE = 1; //タイマー割込 TMR3ON = 1 ; //シリアル通信速度(ボー)用 } } if (TMR3IF) { // タイマー3(シリアル通信速度)の割込み発生か? TMR3H = (t3count >> 8); // タイマーの初期化 TMR3L = (t3count & 0x00FF) ; // タイマーの初期化 TMR3IF = 0 ; // タイマー割込フラグをリセット // Lcd_puts("intTMR3"); // tm3_count ++ ; // 割込み発生回数をカウント // if(tm3_count >= 4){ //(割込間隔×左記回数)毎 // tm3_count = 0; if(bit_addr <= 7){ //データビット? if(RA4){ // Lcd_putch('1'); // debug RXch = RXch | (1 << bit_addr); } else{ // Lcd_putch('0'); // debug RXch = RXch | (0 << bit_addr); } bit_addr ++ ; } else{ if(bit_addr == 8){ //データビットは受け取り終了? Lcd_goto(0x40); // debug Lcd_putch(RXch); // debug Lcd_putch(' '); // debug Char2hex(RXch, str); // debug Lcd_puts(str) ; // debug Lcd_puts(" ") ; // debug if(RA4){//Stop bit if(RXch >= 0x21 && RXch <= 0x5A){ if(rx_str_loc < rxStr_max){ //入るだけ貯める rxStr[rx_str_loc] = RXch; rx_str_loc ++; } if(RXch == ';'){ //コマンドの終了文字;semicolon RXch_end = 1; } } else{ TMR3H = (t3count2 >> 8); // 1.5倍のタイマー初期化 TMR3L = (t3count2 & 0x00FF) ; // } } else{ // RXch = '?' ; TMR3H = (t3count2 >> 8); // 1.5倍のタイマー初期化 TMR3L = (t3count2 & 0x00FF) ; // } Lcd_goto(0x4E); Lcd_putch(' '); Lcd_goto(0x40); //LCDの表示位置を一行目左端 bit_addr ++ ; } else{ // bit_addr == 9 ストップビットの次のビット if(RA4){ //次の文字列を待つべきか? TMR3IE = 0; //タイマー割込 IOCAN4 = 1; //Interrupt-on-Change Negative Edge IOCIE = 1; //All PORT-pin change interrupt } else{ //文字列中の次の文字のスタートビット RXch = 0 ; bit_addr = 0; } } } } } void Analize_msg(void){ rx_str_loc = 0; // コマンドの先頭文字(1文字目) RXch_end = 0; bit_addr = 0; while(1){ //無限loop //コマンドの記録と表示 if(RXch_end){// Monitor mode かつ 文字列受信終了 i = strncmp(rxStr, demo_1, demo_1_leng); if(i == 0){ led_port = 1; __delay_ms(10); led_port = 0; } else{ i = strncmp(rxStr, demo_2, demo_2_leng); if(i == 0){ led_port = 1; __delay_ms(10); led_port = 0; } else{ i = strncmp(rxStr, str_x55, str_x55_leng); if(i == 0){ led_port = 1; __delay_ms(10); led_port = 0; } } } Lcd_goto(0x00); Lcd_puts(" "); Lcd_goto(0x00); for(i=0; i < rxStr_max; i ++){ Lcd_putch(rxStr[i]); if(rxStr[i] == ';'){ break; } } Lcd_goto(0x40); //LCDの表示位置を一行目左端 rx_str_loc = 0; RXch_end = 0; } } } void main(void){ // see Data sheet PIC16F1619 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 // LCDのVDDをONする前は、LCDへのすべてのポートはlowであること。 ANSELA= 0b00000000; //All デジタル(既定値:アナログ) TRISA = 0b00011000; //RA4:RX-pin echo of US-015改 PORTA = 0b00010000; //初期化 ANSELB= 0b00000000; //All デジタル(既定値:アナログ) TRISB = 0b00000000; // PORTB = 0b00000000; //初期化 ANSELC= 0b00000000; //All デジタル(既定値:アナログ) TRISC = 0b01001000; // Magnet-SW,Magnet-SW PORTC = 0b01001000; //初期化 //タイマー:シリアル通信速度(ボー)用 基本速度20ボー = 1/20=0.05s // カウント数 = (16,000,000*0.05)/(4*8) =25,000 // (Fosc=16MHz Prescale=8 において) T3CON = 0b00110100; // Fosc/4 、プリスケーラカウント値 1:8 // T1GCON= 0b00000000; t3count = -25000; // カウントの初期値(nカウントでオーバー) TMR3H = (t3count >> 8); // タイマーの初期化 TMR3L = (t3count & 0x00FF) ; // タイマーの初期化 TMR3IF = 0 ; // タイマー0割込フラグを0 tm3_count = 0 ; // 割込み発生の回数カウンターを0 t3count2 = t3count - t3count/2; // t3countの1.5倍 //LCD initialize and cleare // LCDのVDDをONする前は、LCDへのすべてのポートはlowであること。 LCD_VDD = 1; __delay_ms(40); //低電圧でも動作させたいので長めを設定 Lcd_init(); Lcd_clear(); Lcd_write(0b00001100); //Display on, no cursor, no blinking Lcd_goto(0x00); //LCDの表示位置を一行目左端 Lcd_puts(prog_name); //LCDにメッセージを表示 Lcd_goto(0x40); //LCDの表示位置を二行目左端 Lcd_puts(ver); //LCDにメッセージを表示 Lcd_puts(author); //LCDにメッセージを表示 // for Super-sonic sensor RA4 IOCAP4 = 0; //Interrupt-on-Change Positive disabled IOCAN4 = 1; //Interrupt-on-Change Negative Edge IOCAF4 = 0; //sensor_port pin interuupt flag for(i = 1; i <= 4; i ++){ led_port=1; //内蔵LED timer=1; while(timer--){__delay_ms(500);}; //Wait 1sec. led_port=0; //内蔵LED timer=1; while(timer--){__delay_ms(500);}; //Wait 1sec. } Lcd_clear(); TMR3ON = 0 ; //シリアル通信速度(ボー)用 TMR3IF = 0 ; // タイマー割込フラグをリセット TMR3IE = 0 ; //タイマー割込 IOCIE = 1 ; // All PORT-pin change interrupt RCIE = 0 ; // 受信割り込みをマスクしない PEIE = 1 ; // 周辺割込みをマスクしない GIE = 1 ; // 全割込み処理をマスクしない Analize_msg(); }