//----------------------------------------------------------------------------- // Note // 受信したデータを3桁の7セグに表示する(シリアル) // PICの周波数を32Mhzに設定 //----------------------------------------------------------------------------- #include #include #include #include #include // コンフィグレーションBIT1 設定 #pragma config FOSC = INTOSC // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin) #pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable (PWRT enabled) #pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input) #pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled) #pragma config CPD = OFF // Data Memory Code Protection (Data memory code protection is disabled) #pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled) #pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin) #pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled) // コンフィグレーションBIT2 設定 #pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off) #pragma config PLLEN = ON // PLL Enable (4x PLL enabled) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset) #pragma config BORV = HI // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), high trip point selected.) #pragma config LVP = OFF // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming) #define _XTAL_FREQ 32000000 // オシレータ周波数 32Mhzの場合 #define SEVEN_SEG_IO_ON 0 #define SEVEN_SEG_IO_OFF 1 #define SEVEN_SEG_SIZE 3 #define UART_RX_SIZE 3 #define TIMER0_INIT_CNT 155 #define SEG_LED_A RA2 #define SEG_LED_B RA0 #define SEG_LED_C RC3 #define SEG_LED_D RC7 #define SEG_LED_E RB7 #define SEG_LED_F RA1 #define SEG_LED_G RC4 #define SEG_LED_DP RC6 #define SEG_DEGI_1 RA5 #define SEG_DEGI_2 RA4 #define SEG_DEGI_3 RC5 const unsigned char seg_led[18] = { {0b00111111}, // 0 {0b00000110}, // 1 {0b01011011}, // 2 {0b01001111}, // 3 {0b01100110}, // 4 {0b01101101}, // 5 {0b01111101}, // 6 {0b00100111}, // 7 {0b01111111}, // 8 {0b01101111}, // 9 {0b00000001}, // a {0b00000010}, // b {0b00000100}, // c {0b00001000}, // d {0b00010000}, // e {0b00100000}, // f {0b01000000}, // g {0b10000000} // dp }; volatile bool uart_rx_flg = false; volatile unsigned char uart_rx_cnt = 0; volatile unsigned char uart_rx_buf[ UART_RX_SIZE ] = {0}; volatile unsigned char uart_rx_dat[ UART_RX_SIZE ] = {0}; volatile unsigned char seven_seg_data[ SEVEN_SEG_SIZE ] = {0}; volatile unsigned char seven_seg_flg = 0; void seven_seg_ctrl( void ); void out_seven_seg(short , short ); void interrupt isr_ctrl( void ) { static short i; // タイマ if( TMR0IF ) { // シリアル通信のタイムアウト発生 // タイマ割り込みを禁止にする。 TMR0IE = 0; TMR0 = TIMER0_INIT_CNT; // シリアルデータを初期化 memset( (void *)uart_rx_buf, 0, sizeof(uart_rx_buf)); uart_rx_cnt = 0; uart_rx_flg = false; TMR0IF = 0; } // シリアル受信 if( RCIF ) { if( FREE == 0 && OERR == 0 ) { // 受信データをバッファヘ保存 uart_rx_buf[uart_rx_cnt] = RCREG; uart_rx_cnt++; // 最後のシリアルデータを受け取った時 if( uart_rx_cnt >= UART_RX_SIZE ) { // タイムアウト停止 TMR0 = TIMER0_INIT_CNT; TMR0IE = 0; for(i=0 ;i<3; i++) uart_rx_dat[i] = uart_rx_buf[i]; uart_rx_cnt = 0; uart_rx_flg = true; } else { // タイマのカウントを開始 TMR0 = TIMER0_INIT_CNT; TMR0IE = 1; } } else { RCSTA = 0; RCSTA = 0x90; } RCIF = 0; } } int main(int argc, char** argv) { OSCCON = 0b01110000 ; // 内部クロック8MHz ANSELA = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISA = 0b00001000 ; // ピンは全て出力に割当てる(RA3は入力のみとなる) PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) ANSELB = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISB = 0b00100000 ; // RB5を入力,他は全て出力に割当てる PORTB = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) ANSELC = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISC = 0b00000000 ; // ピンは全て出力に割当てる PORTC = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) TXSTA = 0x04; // 送信情報設定:非同期モード 8ビット・ノンパリティ RCSTA = 0x90; // 受信情報設定 BAUDCON = 0x08; // 16bit SPBRG = 0x40; // ボーレートを9600(高速モード)に設定 SPBRGH = 0x03; RXDTSEL = 0; OPTION_REG = 0b00000111 ; // 内部クロックでTIMER0を使用、プリスケーラカウント値 1:256 TMR0 = TIMER0_INIT_CNT; // タイマー0の初期化 RCIE = 1; RCIF = 0; PEIE = 1; GIE = 1; for(;;) { // 新しいデータを受信 if( uart_rx_flg ) { // 7seg の制御へ渡す seven_seg_data[0] = 0x0f & uart_rx_dat[2]; seven_seg_data[1] = 0x0f & (uart_rx_dat[2]>>4); seven_seg_data[2] = 0x0f & uart_rx_dat[1]; seven_seg_flg = uart_rx_dat[0]; uart_rx_flg = false; } // 7seg 表示制御 seven_seg_ctrl(); } return (EXIT_SUCCESS); } void seven_seg_ctrl( void ) { static unsigned char seq_digi = 0; unsigned char out; bool enable; switch( seq_digi ) { case 0: // 100の位 out = seg_led[seven_seg_data[2]]; // DP if( (seven_seg_flg & 0b00000100) != 0 ) out |= 0b10000000; // 表示か非表示か判定する enable = false; if( seven_seg_data[2] != 0 ) enable = true; if( (seven_seg_flg & 0b00000100) != 0 ) enable = true; if( !enable ) out = 0; break; case 1: // 10の位 out = seg_led[seven_seg_data[1]]; // DP if( (seven_seg_flg & 0b00000010) != 0 ) out |= 0b10000000; // 表示か非表示か判定する enable = false; if( seven_seg_data[2] != 0 ) enable = true; if( seven_seg_data[1] != 0 ) enable = true; if( (seven_seg_flg & 0b00000110) != 0 ) enable = true; if( !enable ) out = 0; break; case 2: // 1の位 out = seg_led[seven_seg_data[0]]; // DP if( (seven_seg_flg & 0b00000001) != 0 ) out |= 0b10000000; break; default: seq_digi = 0; out = 0; break; } out_seven_seg( out, seq_digi ); __delay_ms(5); seq_digi++; if( seq_digi > 2 ) seq_digi = 0; } void out_seven_seg(short seg, short digi) { // a点灯 if( (seg & 0x01) != 0 ) SEG_LED_A = SEVEN_SEG_IO_ON; else SEG_LED_A = SEVEN_SEG_IO_OFF; // b点灯 if( (seg & 0x02) != 0 ) SEG_LED_B = SEVEN_SEG_IO_ON; else SEG_LED_B = SEVEN_SEG_IO_OFF; // c点灯 if( (seg & 0x04) != 0 ) SEG_LED_C = SEVEN_SEG_IO_ON; else SEG_LED_C = SEVEN_SEG_IO_OFF; // d点灯 if( (seg & 0x08) != 0 ) SEG_LED_D = SEVEN_SEG_IO_ON; else SEG_LED_D = SEVEN_SEG_IO_OFF; // e点灯 if( (seg & 0x10) != 0 ) SEG_LED_E = SEVEN_SEG_IO_ON; else SEG_LED_E = SEVEN_SEG_IO_OFF; // f点灯 if( (seg & 0x20) != 0 ) SEG_LED_F = SEVEN_SEG_IO_ON; else SEG_LED_F = SEVEN_SEG_IO_OFF; // g点灯 if( (seg & 0x40) != 0 ) SEG_LED_G = SEVEN_SEG_IO_ON; else SEG_LED_G = SEVEN_SEG_IO_OFF; // DP点灯 if( (seg & 0x80) != 0 ) SEG_LED_DP = SEVEN_SEG_IO_ON; else SEG_LED_DP = SEVEN_SEG_IO_OFF; // 表示桁指定 if( digi == 0 ) SEG_DEGI_1 = SEVEN_SEG_IO_ON; else SEG_DEGI_1 = SEVEN_SEG_IO_OFF; if( digi == 1 ) SEG_DEGI_2 = SEVEN_SEG_IO_ON; else SEG_DEGI_2 = SEVEN_SEG_IO_OFF; if( digi == 2 ) SEG_DEGI_3 = SEVEN_SEG_IO_ON; else SEG_DEGI_3 = SEVEN_SEG_IO_OFF; }