| 
          【單片機實際應用】開機時在MySQL數據庫中自動記錄開機時間和室內溫度(由DS18B20通過串口提供) | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
            
              最終效果:               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
            
              数据表結構圖:               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              數據表結構: CREATE TABLE IF NOT EXISTS `PowerLog` (   `LogID` int(11) NOT NULL,   `LogTime` datetime NOT NULL,   `LogFlag` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'TEST',   `LogTimeZone` varchar(10) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'UTC+8',   `ComputerIP` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT '192.168.0.4',   `Temperature` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'NO DATA' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              我使用的操作系統:Fedora Linux 22 單片機型號:AVR ATMega16              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              單片機所用晶振:7.3728MHz 串口線:USB轉串口線(設備地址:/dev/ttyUSB0)              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              下面公佈程序源代碼。 【單片機部分】 [文件列表] delay.c delay.h DS18B20.c DS18B20.h IR.c IR.h pce.c UART.c UART.h              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [delay.c] #include "delay.h"
  //延时n毫秒 void delay(unsigned int n) {     unsigned int i;     while (n--)         for (i=0;i<1140;i++); //1ms基准延时 }
  void delay_us(unsigned int n) {     if (n==0)         return;     while (--n); }
  //延时0.5ms void delay500us(void) {     unsigned int i;     for (i=0;i<570;i++); //1140*0.5=570 }
  //延迟0.56ms void delay560us(void) {     unsigned int i;     for (i=0;i<638;i++); //1140*0.56=638.4 }              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [delay.h] void delay(unsigned int n); void delay_us(unsigned int n); void delay500us(void); void delay560us(void);              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [DS18B20.c] #include <iom16v.h> #include <macros.h> #include "delay.h" #include "DS18B20.h"
  unsigned char DSFlags=0xff; unsigned char DSTN,DSTD;
  void DS18B20_Init(void) {     DQ_OUT;     DQ_1;     delay_us(6);     DQ_0;     delay_us(600);     DQ_1;     delay_us(120);     if (DQ)         DSFlags|=BIT(DSERR);     else         DSFlags&=~BIT(DSERR);     delay_us(620); }
  void DS18B20_Read(unsigned char* dat) {     unsigned char i;     for (i=0;i<8;i++)     {         DQ_OUT;         DQ_1;         delay_us(2);         DQ_0;         delay_us(4);         DQ_1;         delay_us(6);         *dat>>=1;
          if (DQ)             *dat|=0x80;         else             *dat&=0x7f;         delay_us(60);     } }
  void DS18B20_Write(unsigned char dat) {     unsigned char i;     for (i=0;i<8;i++)     {         DQ_OUT;         DQ_1;         delay_us(2);         DQ_0;         if (dat&0x01)             DQ_IN;         else             DQ_OUT;         delay_us(30);         DQ_1;         delay_us(3);         dat>>=1;     }     delay_us(10); }
  void DS18B20_ReadyReadTemp(void) {     DS18B20_Init();     DS18B20_Write(0xcc);     DS18B20_Write(0x44);     delay_us(20);
      DS18B20_Init();     DS18B20_Write(0xcc);     DS18B20_Write(0xbe); }
  void DS18B20_Measure(void) {     unsigned char tl,th,tltemp;     DS18B20_ReadyReadTemp();     DS18B20_Read(&tl);     DS18B20_Read(&th);
      if ((th&0xf8)!=0x00)     {         DSFlags|=BIT(DSNEG);         tl=~tl;         th=~th;         tltemp=tl+1;         tl=tltemp;         if (tltemp>=255)             th++;     }     else         DSFlags&=~BIT(DSNEG);
      DSTN=th*16+tl/16;     DSTD=(tl&0x0f)*625/100; //*6.25 }              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [DS18B20.h] #define DSNEG 4 #define DSERR 6
  #define DQ (PINB&BIT(1)) #define DQ_0 PORTB&=~BIT(1) #define DQ_1 PORTB|=BIT(1) #define DQ_IN DDRB&=~BIT(1) //write #define DQ_OUT DDRB|=BIT(1) //read
  extern unsigned char DSFlags; extern unsigned char DSTN; extern unsigned char DSTD;
  void DS18B20_Init(void); void DS18B20_Read(unsigned char* dat); void DS18B20_Write(unsigned char dat); void DS18B20_ReadyReadTemp(void); void DS18B20_Measure(void);              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [IR.c] #include <iom16v.h> #include <macros.h> #include "delay.h" #include "UART.h" #include "IR.h"
  unsigned int hightime,lowtime; unsigned char tlow; unsigned char IRCode[4];
  unsigned char IRDataBuffer[8]; unsigned int IRDataLength=0; unsigned int IRStrID=0;
  void IR_Init(void) {     SEI();     IR_INT_ON;     IR_OFF;     MCUCR=0x02; //外中断0下降沿触发
      TCCR1A=0x00;     TCCR1B=0x02; //定时器1设为8分频,也就相当于51单片机接12M晶振 }
  //键码引导码 void IR_KeyCodeBegin(void) {     IR_ON;     delay(9); //9ms高电平     IR_OFF;     delay(4); //4.5ms低电平     delay500us(); }
  //数据引导码 void IR_DataBegin(void) {     IR_ON;     delay(3);     IR_OFF;     delay(1); }
  //发送0 void IR_Send0(void) {     IR_ON;     delay560us();     IR_OFF;     delay560us(); }
  //发送1 void IR_Send1(void) {     IR_ON;     delay560us();     IR_OFF;     delay560us();     delay560us();     delay560us(); }
  //发送尾码,使接收端能确定最后一位是0还是1 void IR_Stop(void) {     IR_ON;     delay560us();     IR_OFF; }
  //发送一个字节 void IR_SendByte(unsigned char Data) {     unsigned char i;     for (i=0;i<8;i++)     {         if (Data&BIT(i))             IR_Send1();         else             IR_Send0();     } }
  //发送一个字符串 void IR_SendString(char* pStr) {     unsigned int i;     unsigned int len=0;
      char* tp=pStr;     while (*tp!='\0')     {         len++;         tp++;     }
      IR_DataBegin();     IR_SendByte(len%256);     IR_SendByte(len/256);     for (i=0;*pStr!='\0';i++)     {         if (i>5 && i%8==0)         {             IR_Stop();             delay(108);             IR_DataBegin();         }         IR_SendByte(*pStr);         pStr++;     }     IR_Stop(); }
  //★发送一个完整的按键码 //usercode为用户码,16位 //keycode为键码,8位 void IR_SendKeyCode(unsigned int usercode, unsigned char keycode) {     IR_KeyCodeBegin();     IR_SendByte(usercode/256); //用户码高8位     IR_SendByte(usercode%256); //用户码低8位     IR_SendByte(keycode); //键码     IR_SendByte(~keycode); //键码的反码     IR_Stop(); //使接收端能区分最后一位是1还是0 }
  void IR_PressKey(unsigned char keycode) {     IR_SendKeyCode(IR_USERCODE,keycode); }
  //红外接收中断 void IR_Receive(void) {     unsigned char tmp;     unsigned char flag=0x00;     IR_INT_OFF;     IR_ReceiveBegin();     if (lowtime>2650 && lowtime<3350 && hightime>650 && hightime<1350)     {         //红外数据接收         if (IRStrID==0)         {             IR_ReceiveByte(&tmp);             IRDataLength=tmp;             IR_ReceiveByte(&tmp);             IRDataLength+=tmp*256;             flag|=BIT(7);         }         for (tmp=0;tmp<8;tmp++)         {             IR_ReceiveByte(&IRDataBuffer[tmp]);             IRStrID++;             if (IRStrID>=IRDataLength)             {                 IRStrID=0;                 flag|=BIT(6);                 break;             }         }
          //在108ms的间隔时间中趁机把数据发给电脑         if (flag&BIT(7))         {             //起始码             UART_Send(0x40);             UART_Send(0xf5);             UART_Send(IRDataLength/256);             UART_Send(IRDataLength%256);         }         for (tmp=0;tmp<8;tmp++)             UART_Send(IRDataBuffer[tmp]);         if (flag&BIT(6))         {             //终止码             UART_Send('E');             UART_Send(0x00);         }     }     else if (lowtime>9200 && lowtime<9500 && hightime>4600 && hightime<4900)     {         //红外遥控解码         IR_ReceiveByte(&IRCode[0]);         IR_ReceiveByte(&IRCode[1]);         IR_ReceiveByte(&IRCode[2]);         IR_ReceiveByte(&IRCode[3]);         UART_Send(0x40);         UART_Send(0xf1); //finish         UART_Send(IRCode[0]);         UART_Send(IRCode[1]);         UART_Send(IRCode[2]);         UART_Send(IRCode[3]);     }     else     {         //UART_Send(0x40);         //UART_Send(0x4f);     }     IR_INT_ON; }
  void IR_ReceiveBegin(void) {     TCNT1H=0x00;     TCNT1L=0x00;     while (!IR); //给低电平计时     tlow=TCNT1L;     lowtime=TCNT1H;     lowtime=lowtime*256+tlow;     IR_CLEAR_TIMER; //定时器1清除标志位,注意是写1清零
      TCNT1H=0x00;     TCNT1L=0x00;     while (IR && !IR_TIMER_OUT); //给高电平计时     tlow=TCNT1L;     hightime=TCNT1H*256+tlow;     IR_CLEAR_TIMER; }
  void IR_ReceiveByte(unsigned char* Data) {     unsigned char i;     for (i=0;i<8;i++)     {         TCNT1H=0x00;         TCNT1L=0x00;         while (!IR); //给低电平计时         tlow=TCNT1L;         lowtime=TCNT1H;         lowtime=lowtime*256+tlow;         IR_CLEAR_TIMER;
          TCNT1H=0x00;         TCNT1L=0x00;         while (IR && !IR_TIMER_OUT); //给高电平计时         tlow=TCNT1L;         hightime=TCNT1H*256+tlow;         IR_CLEAR_TIMER;
          if (hightime>1150)             *Data|=BIT(i);         else             *Data&=~BIT(i);     } }              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [IR.h] #define IR (PIND&BIT(2)) //receiver #define IR_ON PORTB|=BIT(0) //sender #define IR_OFF PORTB&=~BIT(0) #define IR_USERCODE 0x18e0 #define IR_INT_ON GICR|=BIT(INT0) #define IR_INT_OFF GICR&=~BIT(INT0) #define IR_TIMER_OUT (TIFR&BIT(TOV1)) #define IR_CLEAR_TIMER TIFR|=BIT(TOV1)
  void IR_Init(void); void IR_KeyCodeBegin(void); void IR_DataBegin(void); void IR_Send0(void); void IR_Send1(void); void IR_Stop(void);
  void IR_SendByte(unsigned char Data); void IR_SendString(char* pStr); void IR_SendKeyCode(unsigned int usercode, unsigned char keycode); void IR_PressKey(unsigned char keycode);
  #pragma interrupt_handler IR_Receive:iv_INT0; void IR_Receive(void); void IR_ReceiveBegin(void); void IR_ReceiveByte(unsigned char* Data);              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [pce.c] #include <iom16v.h> #include <macros.h> #include "delay.h" #include "IR.h" #include "UART.h" #include "DS18B20.h"
  void UART_Execute(void) {     switch (UART_Buffer[0])     {     case 0x80:         //发送测试信息         UART_SendString("****************\n");         UART_SendString("It works. -- PCE\n");         UART_SendString("          -- By Octpus\n");         UART_SendString("**********************\n");         UART_ClearBuffer();         break;     case 0x81:         switch (UART_Buffer[1])         {         case 0xf0:             //反码查询             if (UART_Pos>=3)             {                 UART_Send(UART_Buffer[0]);                 UART_Send(UART_Buffer[1]);                 UART_Send(~UART_Buffer[1]);                 UART_ClearBuffer();             }             break;         default:             if (UART_Pos>=2)                 UART_ThrowError();             break;         }         break;     case 0x82:         //测试红外遥控(适用于12864液晶显示)         if (UART_Pos>=2)         {             if (UART_Buffer[1]==0x40)                 IR_SendString("****************It works. -- PCE    -- By Octpus&&&&简体中文^^$$$");             else if (UART_Buffer[1]==0x20)                 IR_SendString("Yes");             else                 IR_PressKey(0x00);             UART_Send(0xa5);             UART_ClearBuffer();         }         break;     case 0x83:         //读取温度         DS18B20_Measure();         UART_Send(DSFlags);         UART_Send(DSTN);         UART_Send(DSTD);         UART_ClearBuffer();         break;
      case 0x00:         //无命令         break;     case '*':     case '#':     default:         UART_ThrowError();         break;     } }
  void main(void) {     DDRB=0xff;     PORTB=0xff;     DDRD=0xf3; //两个外中断口设为输入     PORTD=0xff;
      IR_Init();     UART_Init();     //UART_SendString("#### POWER ON ####\n");
      UART_Send(0x60);     UART_Send(0x85);     DS18B20_Init();     UART_Send(DSFlags);
      while (1)     {         UART_Execute();     } }              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
            
              回復:13樓 那個Octopus都拼錯了。算了,反正沒什麼影響。
               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [UART.c] #include <iom16v.h> #include <macros.h> #include "UART.h"
  unsigned char UART_Buffer[256]={0x00}; unsigned char UART_Pos=0;
  void UART_Init(void) {     UCSRB=0x00; //禁止发送和接收     UCSRA=0x02; //倍速异步模式USX=1     UCSRC=0x06;
      UBRRL=(FOSC/8/(BAUD+1))%256; //设置波特率     UBRRH=(FOSC/8/(BAUD+1))/256;
      UCSRB|=BIT(RXEN); //允许接收     UCSRB|=BIT(TXEN); //允许发送     UCSRB|=BIT(RXCIE); //允许接收中断 }
  void UART_Send(unsigned char Data) {     while (!(UCSRA&BIT(UDRE))); //如果数据寄存器不为空(0)就等待     UDR=Data;     while (!(UCSRA&BIT(TXC))); //等待数据发送完毕     UCSRA|=BIT(TXC); //清除发送标志 }
  void UART_SendString(char* pStr) {     while (*pStr!='\0')     {         UART_Send(*pStr);         pStr++;     } }
  void UART_ClearBuffer(void) {     UART_Pos=0;     UART_Buffer[0]=0x00; }
  void UART_ThrowError(void) {     UART_Send('?');     UART_Send(UART_Buffer[0]);     UART_ClearBuffer(); }
  void UART_Receive(void) {     while (!(UCSRA&BIT(RXC)));     UART_Buffer[UART_Pos]=UDR;     UART_Pos++;     UART_Send(UDR); }              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [UART.h] #define FOSC 7372800 #define BAUD 9600
  extern unsigned char UART_Buffer[256]; extern unsigned char UART_Pos;
  void UART_Init(void); void UART_Send(unsigned char Data); void UART_SendString(char* pStr); void UART_ClearBuffer(void); void UART_ThrowError(void);
  #pragma interrupt_handler UART_Receive:iv_USART_RX void UART_Receive(void);              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              單片機端程序完畢 程序編譯用的軟件是ACC AVR(我在Linux系統下開了個XP虛擬機運行的)              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
            
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              【計算機部分】 [文件列表] autorun.sh (設為開機自動運行) conn.h logview.c Makefile powerlog2.c temperature.c temperature.h UART.c UART.h              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [autorun.sh] cd /home/octopus/Programs/powerlog ./powerlog2 on
  注意:第一行要指定程序文件所在目錄!              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [conn.h] #define SERVER_NAME "localhost" #define DB_USER "root" #define DB_PASSWD "YOUR_PASSWORD" #define DB_NAME "server"              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [logview.c] #include <stdio.h> #include <stdlib.h> #include <string.h> #include <mysql.h> #include "conn.h"
  int main(int argc, char* argv[]) {     MYSQL conn;     mysql_init(&conn);     if (!mysql_real_connect(&conn, SERVER_NAME, DB_USER, DB_PASSWD, DB_NAME, 0, NULL, 0))     {         printf("Cannot connect to the database server.\n");         return 1;     }     mysql_query(&conn, "SET NAMES utf8");          printf("Powerlog Version 2.2\n");     FILE* file = fopen("powerlog.txt", "w");     char title[] = "ID\tTIME\n";     printf(title);     fwrite(title, strlen(title), 1, file);          char sql[] = "SELECT LogID, LogTime FROM PowerLog WHERE LogFlag = 'POWER ON' AND ComputerIP = '192.168.0.4' ORDER BY LogTime DESC";     mysql_query(&conn, sql);     MYSQL_RES* rs = mysql_store_result(&conn);     MYSQL_ROW row;     char line[100];     unsigned int i;     for (i = 0; row = mysql_fetch_row(rs); i++)     {         int id = atoi(row[0]);         char timestr[50];         sprintf(timestr, "%s", row[1]);                  sprintf(line, "%d\t%s\n", id, timestr);         if (i < 20)             printf(line);         fwrite(line, strlen(line), 1, file);     }          fclose(file);     mysql_free_result(rs);     mysql_close(&conn);     return 0; }              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [Makefile] MYSQL=-I/usr/include/mysql -L/usr/lib64/mysql -lmysqlclient
  powerlog2: powerlog2.o logview.o     gcc powerlog2.o temperature.o UART.o -o powerlog2 $(MYSQL)     gcc logview.o -o logview $(MYSQL)
  powerlog2.o: powerlog2.c conn.h temperature.o UART.o     gcc -c powerlog2.c $(MYSQL)      temperature.o: temperature.c temperature.h     gcc -c temperature.c
  UART.o: UART.c UART.h     gcc -c UART.c
  logview.o: logview.c conn.h     gcc -c logview.c $(MYSQL)      clean:     rm powerlog2 *.o
               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [powerlog2.c] //Version: 2.2 #include <stdio.h> #include <string.h> #include <mysql.h> #include <unistd.h> #include "conn.h" #include "temperature.h" #include "UART.h"
  int main(int argc, char* argv[]) {     char uartopened = 1;     if (UART_Open() == 0)         uartopened = 0;          MYSQL conn;     mysql_init(&conn);     if (!mysql_real_connect(&conn, SERVER_NAME, DB_USER, DB_PASSWD, DB_NAME, 0, NULL, 0))     {         printf("Cannot connect to the database server.\n");         return 1;     }     mysql_query(&conn, "SET NAMES utf8");          printf("Powerlog Version 2.2\n");     printf("Welcome\n");          char sql[200];     memset(sql, 0, sizeof(char) * 200);     char sql2[100]; // the Backup Query, which is executed when the main sql is corrupted     memset(sql2, 0, sizeof(char) * 100);     char temp[8];     int i = 10;     float f;     if (argc >= 2 && strcmp(argv[1], "on") == 0)     {         strcat(sql, "INSERT INTO PowerLog (LogTime, LogFlag, Temperature) VALUES (NOW(), 'POWER ON', TRIM('");         strcat(sql2, "INSERT INTO PowerLog (LogTime, LogFlag, Temperature) VALUES (NOW(), 'POWER ON', 'Query Error')");     }     else     {         // only for development         strcat(sql, "INSERT INTO PowerLog (LogTime, Temperature) VALUES (NOW(), TRIM('");         strcat(sql2, "INSERT INTO PowerLog (LogTime, Temperature) VALUES (NOW(), 'Query Error')");     }     if (uartopened == 1)     {         get_temperature(&f); // avoid the first possible error value         while (i--)         {             usleep(10000);             get_temperature(&f);             tempstr(&f, temp);             strcat(sql, temp);         }     }     else         strcat(sql, "UART Unavailable");     strcat(sql, "'))");     int result = mysql_query(&conn, sql);     if (result == 1)         mysql_query(&conn, sql2);          //Display the time     mysql_query(&conn, "SELECT now()");     MYSQL_RES* rs = mysql_store_result(&conn);     MYSQL_ROW row = mysql_fetch_row(rs);     char buffer[100];     sprintf(buffer, "%s", row[0]);     printf("MySQL Time: %s\n", buffer);     mysql_free_result(rs);          mysql_close(&conn);     if (uartopened == 1)         USART_Close();     return 0; }
               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [temperature.c] #include <stdio.h> #include <unistd.h> #include "UART.h"
  #define DSNEG 4 #define DSERR 6
  #define BIT(n) 1<<n
  char buffer[513];
  void get_temperature(float* temp) {     UART_Send(0x83);     usleep(100000);     UART_Receive(buffer);     if (buffer[1] & BIT(DSERR))         *temp = -999.99;     else     {         *temp = buffer[2] * 1.00 + buffer[3] * 0.01;         if (buffer[1] & BIT(DSNEG))             *temp = -*temp;     } }
  void tempstr(float* temp, char* str) {     sprintf(str, "%.2f℃\t", *temp); }
               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [temperature.h] void get_temperature(float* temp); void tempstr(float* temp, char* str);              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [UART.c] #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // UNIX Standard Function Definitions #include <fcntl.h> // File Control Definitions #include <errno.h> // File Control Definitions #include <termios.h> // POSIX Terminal Control Definitions #include "UART.h"
  struct termios tty; struct termios tty_old; int UART_id = 0;
  int UART_Open(void) {     memset(&tty, 0, sizeof(tty));     UART_id = open(UART_PORT, O_RDWR | O_NOCTTY | O_NDELAY);     if (UART_id < 0)     {         printf("Warning: Cannot open the serial port!\n");         return 0;     }          /* Error Handling */     if (tcgetattr(UART_id, &tty) != 0)     {         printf("Error: %d from tcgetattr: %s \n", errno,strerror(errno));         return 0;     }          /* Save old tty parameters */     tty_old = tty;          /* Set Baud Rate */     cfsetospeed(&tty, (speed_t)B9600);     cfsetispeed(&tty, (speed_t)B9600);          /* Setting other Port Stuff */     tty.c_cflag &= ~PARENB; // Make 8n1     tty.c_cflag &= ~CSTOPB;     tty.c_cflag &= ~CSIZE;     tty.c_cflag |= CS8;          tty.c_cflag &= ~CRTSCTS; // no flow control     tty.c_cc[VMIN] = 1; // read doesn't block     tty.c_cc[VTIME] = 5; // 0.5 second read timeout     tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines          /* Make raw */     cfmakeraw(&tty);          /* Flush Port, then applies attributes */     tcflush(UART_id, TCIFLUSH);     if (tcsetattr(UART_id, TCSANOW, &tty) != 0)     {         printf("Error: %d from tcgetattr \n", errno);         return 0;     }          return UART_id; }
  void UART_Send(unsigned char Byte) {     write(UART_id, &Byte, 1);     // It was definitely not necessary to write byte per byte, also int n_written = write( UART_id, cmd, sizeof(cmd) -1) worked fine. }
  int UART_Receive(char* buf) {     int len = read(UART_id, buf, 512);     buf[len] = '\0';     return len; }
  void USART_Close() {     close(UART_id); }
 
               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              [UART.h] #define UART_PORT "/dev/ttyUSB0"
  int UART_Open(void); void UART_Send(unsigned char Byte); int UART_Receive(char* buf); void USART_Close();
               
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              單片機端程序完畢              
                       | 
        
                
          
            
                         一派護法 十九級              | 
          
            
            
             
              補充:PHP讀取DS18B20溫度值的示例程序 <?php define("DSNEG", 4); define("DSERR", 6); function BIT($n) {     return 1 << $n; } function decodeTemperature($flags, $TN, $TD) {     if ($flags & BIT(DSERR)) {         $value = "Error";     } else {         $value = $TN * 1.00 + $TD * 0.01;         if ($flags & BIT(DSNEG)) {             $value = -$value;         }     }     return $value; }
  $filename = "/dev/ttyUSB0"; $fp = fopen($filename, "a+"); fwrite($fp, "\x83"); $flag = fread($fp, 1); $data = fread($fp, 3); printf("<b>Flag:</b> 0x%x (Useless)<br>\n", $flag); printf("<b>Data:</b> 0x%x, 0x%x, 0x%x<br>\n", ord($data{0}), ord($data{1}), ord($data{2})); $temperature = decodeTemperature(ord($data{0}), ord($data{1}), ord($data{2})); echo "<b>Temperature:</b> $temperature°C"; fclose($fp); ?>
  輸出: Flag: 0x0 (Useless) 
Data: 0xaf, 0x1b, 0x25 
Temperature: 27.37°C              
                       |