目前共有35篇帖子。
【單片機實際應用】開機時在MySQL資料庫中自動記錄開機時間和室內溫度(由DS18B20通過串口提供)
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

注意:第一行要指定程序文件所在目錄!

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2024 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。