//----------------------------------------------------------------------------- // Note // 温度/湿度を取得し、シリアルで送信する // PICの周波数を32Mhzに設定 //----------------------------------------------------------------------------- #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 #define DHT11_IO 0b00000100 #define SW_IO RA5 #define TEMPERATURE_MODE 0 #define HUMIDITY_MODE 1 #define TX_UART_SIZE 3 volatile unsigned char uart_tx_msg[TX_UART_SIZE] = {0}; volatile unsigned char uart_tx_cnt = 0; void interrupt isr_ctrl( void ) { if( TXIF ) { if( uart_tx_cnt < TX_UART_SIZE ) { TXREG = uart_tx_msg[ uart_tx_cnt ]; uart_tx_cnt++; } else { TXIE = 0; } if( uart_tx_cnt >= TX_UART_SIZE ) { uart_tx_cnt = 0; TXIE = 0; } TXIF = 0; } } int main(int argc, char** argv) { short i,j; unsigned char b; unsigned char dht11_data[5] = {0}; unsigned char old_io = 0; unsigned char work,work1,work2; short dht11_mode = TEMPERATURE_MODE; unsigned char send = 1; unsigned short send_cnt = 0; OSCCON = 0b01110000 ; // 内部クロック8MHz OPTION_REG = 0b00000000 ;// 7bit目が0でプルアップ抵抗が有効 ANSELA = 0b00000000 ; // すべてデジタルI/Oに割当てる TRISA = 0b00101000 ; // RA3,5を入力にし、他は出力に設定 PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) WPUA = 0b00100100 ; // RA2,5にプルアップ抵抗に設定 TXSTA = 0x24; // 送信情報設定:非同期モード 8ビット・ノンパリティ RCSTA = 0x90; // 受信情報設定 BAUDCON = 0x08; // 16bit SPBRG = 0x40; // ボーレートを9600(高速モード)に設定 SPBRGH = 0x03; RXDTSEL = 0; TXCKSEL = 0; TXIE = 0; TXIF = 0; PEIE = 1; GIE = 1; // 初期データをセット old_io = SW_IO; // Io初期状態を設定 TRISA |= DHT11_IO; // 電源の立ち上がりを管理 __delay_ms(1000); for(;;) { // Low 出力 TRISA &= ~DHT11_IO; PORTA &= ~DHT11_IO; __delay_ms(20); // Hi 出力 TRISA |= DHT11_IO; // Low信号の確認開始を遅延する __delay_us(10); // Lowになるまで待つ while( (PORTA & DHT11_IO) != 0 ) { // Hiの間処理無し } // Hi になるのを待つ while( (PORTA & DHT11_IO) == 0 ) { // Lowの間処理無し } for(i=0; i<5; i++) { b = 0; for(j=0; j<8; j++) { // Lowになるまで待つ while( (PORTA & DHT11_IO) != 0 ) { // Hiの間処理無し } // Hi になるのを待つ while( (PORTA & DHT11_IO) == 0 ) { // Lowの間処理無し } // 50usec wait __delay_us(50); // データをシフト b = b << 1; // IOがHiなら1をセット if( (PORTA & DHT11_IO) != 0 ) b |= 0x01; } // データをセット dht11_data[i] = b; } // データ転送完了待ち // Lowになるまで待つ while( (PORTA & DHT11_IO) != 0 ) { // Hiの間処理無し } // 5sec Wait for( i=0; i<500; i++ ) { if( (old_io!=SW_IO) && (SW_IO == 0) ) { if( dht11_mode == TEMPERATURE_MODE ) dht11_mode = HUMIDITY_MODE; else dht11_mode = TEMPERATURE_MODE; send = 1; } old_io = SW_IO; // 1sec毎に再表示 send_cnt++; if( send_cnt > 100 ) { send_cnt = 0; send = 1; } if( send != 0 ) { if( dht11_mode == TEMPERATURE_MODE ) work = dht11_data[2]; else work = dht11_data[0]; work1 = work%10; work /= 10; work2 = work; // 送信データ構築 uart_tx_msg[0] = 0x00; // 少数点位置の設定 uart_tx_msg[1] = 0x0f & 0x00; uart_tx_msg[2] = work2 << 4; uart_tx_msg[2] |= work1; uart_tx_cnt = 0; TXIE = 1; // 送信開始 send = 0; } __delay_ms(10); } } return (EXIT_SUCCESS); }