#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();
}
}