//----------------------------------------------------------------------------- // 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 TX_UART_SIZE 3 #define VOLTAGE_REFERENCE 5000 #define VOLTAGE_RESOLUTION 1024 #define R1_OHM 10000 volatile unsigned char uart_tx_msg[TX_UART_SIZE] = {0}; volatile unsigned char uart_tx_cnt = 0; const unsigned short temperature_ohm_tbl[101] = { 28255, 27006, 25822, 24697, 23629, 22614, 21650, 20733, 19861, 19032, 18243, 17491, 16776, 16095, 15445, 14826, 14236, 13674, 13137, 12625, 12136, 11669, 11223, 10797, 10389, 10000, 9628, 9272, 8931, 8605, 8293, 7994, 7708, 7434, 7171, 6919, 6678, 6446, 6224, 6011, 5807, 5610, 5422, 5241, 5067, 4900, 4739, 4585, 4437, 4294, 4157, 4025, 3897, 3775, 3657, 3544, 3434, 3329, 3228, 3130, 3036, 2945, 2857, 2773, 2691, 2612, 2537, 2463, 2392, 2324, 2258, 2194, 2133, 2073, 2016, 1960, 1906, 1854, 1804, 1755, 1708, 1663, 1618, 1576, 1534, 1494, 1455, 1418, 1382, 1346, 1312, 1279, 1247, 1216, 1185, 1156, 1128, 1100, 1073, 1047, 1022 }; 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) { unsigned short ad_data; long r2_ohm,voltage; unsigned short temperature; unsigned short decimal_point; short i,work1,work2,work3; OSCCON = 0b01110000 ; // 内部クロック8MHz ANSELA = 0b00010000 ; // AN3をアナログにし、他はデジタルI/Oに割当てる TRISA = 0b00011010 ; // RA1,3,4を入力にし、他は出力に割当てる PORTA = 0b00000000 ; // 出力ピンの初期化(全てLOWにする) ADCON1 = 0b10100000 ; // 右寄せ、Fosc/32,VDDをリファレンスにする ADCON0 = 0b00001101 ; // AN3を使用する __delay_us(5); // ch設定後、反映待ち 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; for(;;) { // AD 変換 GO_nDONE = 1; // 変換開始 // アナログをデジタルに変換 while( GO_nDONE ) { // wait } ad_data = ADRESH; ad_data = (ad_data << 8) | ADRESL; // 計算 voltage = ((long)VOLTAGE_REFERENCE * (long)ad_data) / VOLTAGE_RESOLUTION; r2_ohm = ((long)R1_OHM * (long)voltage) / (VOLTAGE_REFERENCE - voltage); if( r2_ohm >= temperature_ohm_tbl[0] ) { temperature = 0; decimal_point = 0; } else if( r2_ohm <= temperature_ohm_tbl[99] ) { temperature = 99; decimal_point = 0; } else { for(i=0; i<99; i++) { if( r2_ohm >= temperature_ohm_tbl[i+1] ) { temperature = i; // 小数点を割合で算出 work1 = temperature_ohm_tbl[i] - temperature_ohm_tbl[i+1]; work2 = r2_ohm - temperature_ohm_tbl[i+1]; if( work1 != 0 ) decimal_point = (work2*10)/work1; else decimal_point = 0; break; } } } // 位で分割 work1 = temperature % 10; temperature /= 10; work2 = temperature; // 送信データ構築 uart_tx_msg[0] = 0x02; // 少数点位置の設定 uart_tx_msg[1] = 0x0f & work2; uart_tx_msg[2] = (work1<< 4) | decimal_point; uart_tx_cnt = 0; TXIE = 1; // 送信開始 __delay_ms( 1000 ); } return (EXIT_SUCCESS); }