目前共有2篇帖子。 內容轉換:不轉換▼
 
點擊 回復
279 1
【不完整程序】AVR单片机透过蓝牙接收消息
一派護法 十九級
1樓 發表于:2014-9-30 23:07
#include <iom16v.h>
#include <macros.h>
#include "LCD12864.h"

#define FOSC 7372800
#define BAUD 9600
#define EEPMAX 511
#define MSGBEGIN 0x04

#define NEXT 0xf0
#define UP 0x02
#define DOWN 0x06

#define K7 (PINB&BIT(7))

#define K5 (PINB&BIT(5))
#define K4 (PINB&BIT(4))

#define RSVMSG 0 //正在接收消息
#define PTBTM 1 //是否正在显示结尾部分
#define PTTOP 2 //是否正在显示开始部分
unsigned char SA=0x00;

#define FIRSTUSE 0
unsigned char SB;

unsigned int eeploc;
unsigned char msgnum;
unsigned char eeploc_r=MSGBEGIN;
unsigned char msgid_r=0;

char tip[]="目前短信数 ??? ";

void delay(unsigned int n)
{
    unsigned int i;
    while (n--)
        for (i=0;i<1140;i++); //1ms基准延时
}

unsigned char EEPROM_read(unsigned int uiAddress)
{
    /* Wait for completion of previous write */
    while (EECR&BIT(EEWE));
    /* Set up address register */
    EEAR=uiAddress;
    /* Start eeprom read by writing EERE */
    EECR|=(1<<EERE);
    /* Return data from data register */
    return EEDR;
}

void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
    /* Wait for completion of previous write */
    while (EECR&BIT(EEWE));
    /* Set up address and data registers */
    EEAR=uiAddress;
    EEDR=ucData;
    /* Write logical one to EEMWE */
    EECR|=BIT(EEMWE);
    /* Start eeprom write by setting EEWE */
    EECR|=BIT(EEWE);
}

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 displaynum(void)
{
    LCD12864_ClearText();
    LCD12864_Goto(0,1);
    LCD12864_PrintString(tip);

    LCD12864_Goto(5,1);
    LCD12864_WriteData(' ');
    LCD12864_PrintNumber(msgnum/100);
    LCD12864_PrintNumber(msgnum%100/10);
    LCD12864_PrintNumber(msgnum%10);
    LCD12864_Goto(0,0);

    eeploc_r=MSGBEGIN;
    msgid_r=0;
    SA&=~BIT(PTTOP);
    SA&=~BIT(PTBTM);
}

#pragma interrupt_handler UART_Receive:iv_USART_RXC
void UART_Receive(void)
{
    unsigned char Data;
    while (!(UCSRA&BIT(RXC)));
    Data=UDR;
    
    if (SA&BIT(RSVMSG))
    {
        EEPROM_write(eeploc,Data);
        eeploc++;
        if (Data=='\0')
        {
            msgnum++;
            EEPROM_write(0x03,msgnum);
            EEPROM_write(0x01,eeploc/256);
            EEPROM_write(0x02,eeploc%256);
            displaynum();
        }
    }
    else
    {
        switch (Data)
        {
        case 'A':
            SA|=BIT(RSVMSG);
            break;
        case 'E':
            EEPROM_write(0x01,0x00);
            EEPROM_write(0x02,MSGBEGIN); //EEP1、2表示可用空间处
            EEPROM_write(0x03,0x00); //0 messages
            msgnum=0;
            displaynum();
            break;
        }
    }
}

//Display the next message
void display(unsigned char operation)
{
    unsigned char Data;
    unsigned char x=0;
    unsigned char y=0;

    if (msgnum==0)
        return;

    switch (operation)
    {
    case NEXT:
        msgid_r++;
        if (msgid_r>msgnum)
        {
            msgid_r=1;
            eeploc_r=MSGBEGIN;
        }

        //seek to the beginning of the next message
        if (msgid_r>1)
        {
            x=eeploc_r-1;
            do
            {
                if (x>EEPMAX)
                {
                    msgid_r=1;
                    eeploc_r=MSGBEGIN;
                    break;
                }
                Data=EEPROM_read(x);
                x++;
            }while (Data!='\0');
            eeploc_r=x;
            x=0;
        }
        SA|=BIT(PTTOP);
        SA&=~BIT(PTBTM);
        break;
    case DOWN:
        if (SA&BIT(PTBTM))
            return; //return if displaying the end
        if ((eeploc_r-1)%16>0)
            eeploc_r+=16-(eeploc_r-1)%16;
        eeploc_r-=48;
        SA&=~BIT(PTTOP);
        break;
    case UP:
        if (SA&BIT(PTTOP))
            return; //return if displaying the beginning
        if ((eeploc_r-1)%16>0)
            eeploc_r+=16-(eeploc_r-1)%16;
        eeploc_r-=80;
        if (eeploc_r<MSGBEGIN)
            eeploc_r=MSGBEGIN;
        else if (EEPROM_read(eeploc_r-1)=='\0')
            SA|=BIT(PTTOP);
        break;
    }

    LCD12864_ClearText();
    LCD12864_Goto(0,0);
    SA&=~BIT(PTBTM);
    while (1)
    {
        Data=EEPROM_read(eeploc_r);
        if (eeploc_r>=EEPMAX)
        {
            eeploc_r=MSGBEGIN;
            break;
        }
        eeploc_r++;
        if (Data=='\0')
        {
            SA|=BIT(PTBTM);
            break;
        }

        LCD12864_WriteData(Data);
        x++;
        if (x>=16)
        {
            x=0;
            y++;
            if (y==4)
                break;
            LCD12864_Goto(0,y);
        }
    }
}

void key_scan(void)
{
    //Begin to display the first message
    //or display the next message
    if (!K7)
    {
        delay(15);
        if (!K7)
        {
            display(NEXT);
            while (!K7);
            delay(5);
        }
    }

    //Up
    if (!K5)
    {
        delay(15);
        if (!K5)
        {
            display(UP);
            while (!K5);
            delay(5);
        }
    }

    //Down
    if (!K4)
    {
        delay(15);
        if (!K4)
        {
            display(DOWN);
            while (!K4);
            delay(5);
        }
    }
}

void main(void)
{
    DDRA=DDRC=PORTA=PORTC=0xff;
    DDRB=0x00;
    PORTB=0xff;

    SB=EEPROM_read(0x00);
    if (SB&BIT(FIRSTUSE))
    {
        //最后一位为1表示初次开机
        EEPROM_write(0x00,0x00);
        EEPROM_write(0x01,0x00);
        EEPROM_write(0x02,MSGBEGIN); //EEP1、2表示可用空间处
        EEPROM_write(0x03,0x00); //0 messages
    }

    eeploc=EEPROM_read(0x02); //获取可用空间处
    eeploc+=EEPROM_read(0x01)*256;
    msgnum=EEPROM_read(0x03); //get the number of messages

    LCD12864_Initial(); //Initialize LCD
    displaynum();

    DDRD=0x00;
    PORTD=0xff;
    UART_Init();
    SEI();

    while (1)
    {
        key_scan();
    }
}
一派護法 十九級
2樓 發表于:2014-9-30 23:07
#include <iom16v.h>
#include <macros.h>
#include "LCD12864.h"

void LCD12864_Initial(void)
{
    LCD12864_WriteCmd(0x06); //光标设置,读或写一个字符后,地址指针加一,光标加一,整屏不移动
    LCD12864_WriteCmd(0x0c); //显示开关控制,开显示,光标不显示,光标不闪烁
    LCD12864_ClearText();
}

void LCD12864_ClearText(void)
{
    LCD12864_WriteCmd(0x30);
    LCD12864_WriteCmd(0x01);
}

void LCD12864_ChkBusy(void)
{
    LCD12864_DATD=~BIT(7); //检测忙信号时,PX7变成了输入口
    LCD12864_DAT=0xf2;
    LCD12864_RS0;
    LCD12864_RW1;
    LCD12864_E1;
    while (LCD12864_BSY); //注意:如果不改变DDRX,程序将卡死在这里!
    LCD12864_E0;
    LCD12864_DATD=0xff; //恢复PX7为输出口
}

void LCD12864_WriteCmd(unsigned char Data)
{
    LCD12864_ChkBusy();
    LCD12864_RS0;
    LCD12864_RW0;
    LCD12864_DAT=Data;
    LCD12864_E1;
    LCD12864_E0;
}

void LCD12864_WriteData(unsigned char Data)
{
    LCD12864_ChkBusy();
    LCD12864_RS1;
    LCD12864_RW0;
    LCD12864_DAT=Data;
    LCD12864_E1;
    LCD12864_E0;
}

void LCD12864_Goto(unsigned char x, unsigned char y)
{
    switch (y)
    {
    case 1:
        LCD12864_WriteCmd(0x90+x);
        break;
    case 2:
        LCD12864_WriteCmd(0x88+x);
        break;
    case 3:
        LCD12864_WriteCmd(0x98+x);
        break;
    default:
        LCD12864_WriteCmd(0x80+x);
        break;
    }
}

void LCD12864_PrintString(char* pStr)
{
    while (*pStr!='\0')
    {
        LCD12864_WriteData(*pStr);
        pStr++;
    }
}

void LCD12864_PrintNumber(unsigned char num)
{
    LCD12864_WriteData('0'+num);
}

//显示满屏图形
//注意:取模时请不要勾选“字节倒序”复选框,否则显示出来的图像是反的
/*void LCD12864_DisplayPicture(flash unsigned char* imgdata)
{
    unsigned char x,y;
    LCD12864_WriteCmd(0x34); //34 扩充指令动作 8位数据传送

    //显示上半屏128x32
    for (y=0;y<32;y++)
    {
        LCD12864_WriteCmd(0x80+y); //y
        LCD12864_WriteCmd(0x80); //x=0
        for (x=0;x<16;x++)
            LCD12864_WriteData(imgdata[y*16+x]);
    }

    //显示下半屏128x32
    for (y=0;y<32;y++)
    {
        LCD12864_WriteCmd(0x80+y); //y
        LCD12864_WriteCmd(0x88); //x=0
        for (x=0;x<16;x++)
            LCD12864_WriteData(imgdata[(y+32)*16+x]);
    }

    LCD12864_WriteCmd(0x36); //打开绘图开关
    LCD12864_WriteCmd(0x30);
}*/

//清除绘图区
/*void LCD12864_ClearPicture(void)
{
    unsigned char x,y;
    LCD12864_WriteCmd(0x34);
    for (y=0;y<32;y++)
    {
        LCD12864_WriteCmd(0x80+y);
        LCD12864_WriteCmd(0x80);
        for (x=0;x<32;x++)
            LCD12864_WriteData(0x00);
    }
    LCD12864_WriteCmd(0x36);
    LCD12864_WriteCmd(0x30);
}

//在指定位置显示指定大小的图片
//参数x必须是16的倍数!
//参数width必须是8的倍数!
void LCD12864_DisplayImage(flash unsigned char* imgdata, unsigned char x, unsigned char y, unsigned char width, unsigned char height)
{
    unsigned char i;
    unsigned char k=0;
    unsigned char endy,devy; //设备中的结束相对坐标和当前相对坐标
    x/=16;
    width/=8;
    endy=height+y;

    //显示上半屏128x32
    LCD12864_WriteCmd(0x34);
    for (devy=y;devy<32 && devy<endy;devy++)
    {
        LCD12864_WriteCmd(0x80+devy); //y
        LCD12864_WriteCmd(0x80+x); //x
        for (i=0;i<width;i++,k++) //width只表示宽度,x为imgdata中的x坐标
            LCD12864_WriteData(imgdata[k]);
    }

    //显示下半屏128x32
    for (;devy<64 && devy<endy;devy++)
    {
        LCD12864_WriteCmd(0x80+(devy-32)); //y
        LCD12864_WriteCmd(0x88+x); //x
        for (i=0;i<width;i++,k++)
            LCD12864_WriteData(imgdata[k]);
    }

    LCD12864_WriteCmd(0x36);
    LCD12864_WriteCmd(0x30);
}*/

回復帖子

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

本帖信息

點擊數:279 回複數:1
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2014-9-30 23:07
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。