巨大八爪鱼
武林盟主 二十一级
|
#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(); } }

|
巨大八爪鱼
武林盟主 二十一级
|
#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); }*/

|