作者共發了35篇帖子。 內容轉換:不轉換▼
 
點擊 回復
1846 34
【單片機實際應用】開機時在MySQL數據庫中自動記錄開機時間和室內溫度(由DS18B20通過串口提供)
一派護法 十九級
1樓 發表于:2015-6-28 11:31
最終效果:
一派護法 十九級
2樓 發表于:2015-6-28 11:32
数据表結構圖:
一派護法 十九級
3樓 發表于:2015-6-28 11:34
數據表結構:
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;
一派護法 十九級
4樓 發表于:2015-6-28 11:35
我使用的操作系統:Fedora Linux 22
單片機型號:AVR ATMega16
一派護法 十九級
5樓 發表于:2015-6-28 11:39
單片機所用晶振:7.3728MHz
串口線:USB轉串口線(設備地址:/dev/ttyUSB0)
一派護法 十九級
6樓 發表于:2015-6-28 11:42
下面公佈程序源代碼。
【單片機部分】
[文件列表]
delay.c
delay.h
DS18B20.c
DS18B20.h
IR.c
IR.h
pce.c
UART.c
UART.h
一派護法 十九級
7樓 發表于:2015-6-28 11:43
[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
}
一派護法 十九級
8樓 發表于:2015-6-28 11:43
[delay.h]
void delay(unsigned int n);
void delay_us(unsigned int n);
void delay500us(void);
void delay560us(void);
一派護法 十九級
9樓 發表于:2015-6-28 11:44
[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
}
一派護法 十九級
10樓 發表于:2015-6-28 11:44
[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);
一派護法 十九級
11樓 發表于:2015-6-28 11:45
[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);
    }
}
一派護法 十九級
12樓 發表于:2015-6-28 11:45
[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);
一派護法 十九級
13樓 發表于:2015-6-28 11:46
[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();
    }
}
一派護法 十九級
14樓 發表于:2015-6-28 11:47

回復:13樓

那個Octopus都拼錯了。算了,反正沒什麼影響。

一派護法 十九級
15樓 發表于:2015-6-28 11:48
[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);
}
一派護法 十九級
16樓 發表于:2015-6-28 11:48
[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);
一派護法 十九級
17樓 發表于:2015-6-28 11:49
單片機端程序完畢
程序編譯用的軟件是ACC AVR(我在Linux系統下開了個XP虛擬機運行的)
一派護法 十九級
18樓 發表于:2015-6-28 11:49

回復:17樓

* ICC AVR

一派護法 十九級
19樓 發表于:2015-6-28 11:51
【計算機部分】
[文件列表]
autorun.sh (設為開機自動運行)
conn.h
logview.c
Makefile
powerlog2.c
temperature.c
temperature.h
UART.c
UART.h
一派護法 十九級
20樓 發表于:2015-6-28 11:51
[autorun.sh]
cd /home/octopus/Programs/powerlog
./powerlog2 on

注意:第一行要指定程序文件所在目錄!
一派護法 十九級
21樓 發表于:2015-6-28 11:51
[conn.h]
#define SERVER_NAME "localhost"
#define DB_USER "root"
#define DB_PASSWD "YOUR_PASSWORD"
#define DB_NAME "server"
一派護法 十九級
22樓 發表于:2015-6-28 11:52
[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;
}
一派護法 十九級
23樓 發表于:2015-6-28 11:52
[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

一派護法 十九級
24樓 發表于:2015-6-28 11:53
[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;
}

一派護法 十九級
25樓 發表于:2015-6-28 11:53
[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);
}

一派護法 十九級
26樓 發表于:2015-6-28 11:53
[temperature.h]
void get_temperature(float* temp);
void tempstr(float* temp, char* str);
一派護法 十九級
27樓 發表于:2015-6-28 11:53
[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);
}


一派護法 十九級
28樓 發表于:2015-6-28 11:53
[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();

一派護法 十九級
29樓 發表于:2015-6-28 11:54
單片機端程序完畢
一派護法 十九級
30樓 發表于:2015-6-30 09:59
補充: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&deg;C";
fclose($fp);
?>

輸出:
Flag: 0x0 (Useless)
Data: 0xaf, 0x1b, 0x25
Temperature: 27.37°C

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:1846 回複數:34
評論數: ?
作者:巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2015-11-17 19:39
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用共享創意姓名標示-相同方式分享 3.0 Unported許可協議進行許可。