?? toy16.c
字號:
///////////////////////////2008/03/14//OK///////////////////////////////////
#include <avr/io.h>
#include <avr/iom8.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include "chistring.h"
///////////////////////////////////////////////////////////////////////
#define uchar unsigned char
uchar eeindex[16][5] __attribute__((section(".eeprom")));////EEPROM索引數組
uchar edit[16][5]; ////臨時編輯數組編好后存入EEPROM
const prog_uchar tabdisp[]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,
0X7F,0X6F,0X77,0X7C,0X39,0X5E,0X79,0X71,
0x3d,0x76,0x0e,0x74,0x38,0x54,0x5c,0x73,0x67,0x50,0x64,0x78,0x3e,0x6e}; ///for editor 7segled
////////////////////編輯卡數碼管字模共陰極管0,1,,Z////////////////////////////////////////
///////////////////16點陣漢字字模在頭文件chistring.h//////////////////////////////////////////
//////////////////////////////////LED顯示漢字play//////////////////////
uchar hanz1[32],hanz2[32],hanz3[32],hanz4[32],hanz5[32];///5個漢字數組
uchar dsp1,dsp2,dsp3,dsp4,dsp5; ////從EEPROM索引表中取得的漢字索引號
void ply(void) //
{
uchar i;
uchar temp=0;
while(1) ////按鍵S1改變temp切換顯示內容
{
PORTC=0XFF;
DDRC=0;
if (!((PINC)&(1<<PORTC3)))
{
_delay_ms(30);
if (!((PINC)&(1<<PORTC3)))
{
do
{
PORTB=0XFF;
PORTD=0XFF;
}
while(!((PINC)&(1<<PORTC3)));
_delay_ms(30);
temp++;
if (temp>15) //temp:0,1,2..F
temp=0;
}
}
///////////////////用temp取得eeprom漢字組合索引
dsp1=eeprom_read_byte(eeindex[temp]); //
dsp2=eeprom_read_byte(eeindex[temp]+1); //
dsp3=eeprom_read_byte(eeindex[temp]+2); //
dsp4=eeprom_read_byte(eeindex[temp]+3);
dsp5=eeprom_read_byte(eeindex[temp]+4);
i=0;
while ( i<=31 )
{
hanz1[i]=pgm_read_byte(playdsp[dsp1]+i); //取得漢字字模,字模數組在頭文件中
hanz2[i]=pgm_read_byte(playdsp[dsp2]+i);
hanz3[i]=pgm_read_byte(playdsp[dsp3]+i);
hanz4[i]=pgm_read_byte(playdsp[dsp4]+i);
hanz5[i]=pgm_read_byte(playdsp[dsp5]+i);
i++;
}
if (((PINC&(1<<PORTC5))&&(PINC&(1<<PORTC4)))||((!(PINC&(1<<PORTC5)))&&(!(PINC&(1<<PORTC4))) ) ) ////正向
{ ////正向正字或反向反字
_delay_ms(20); //延時顯示,給以換向緩沖時間
i=0;
while (i<=30)
{
PORTB=hanz1[i]; //B口顯示下半字,偶數字節
i++;
PORTD=hanz1[i]; //D口顯示上半字,奇數字節
i++;
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=0;
while (i<=30)
{
PORTB=hanz2[i];
i++;
PORTD=hanz2[i];
i++;
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=0;
while (i<=30)
{
PORTB=hanz3[i];
i++;
PORTD=hanz3[i];
i++;
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=0;
while (i<=30)
{
PORTB=hanz4[i];
i++;
PORTD=hanz4[i];
i++;
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=0;
while (i<=30)
{
PORTB=hanz5[i];
i++;
PORTD=hanz5[i];
i++;
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(8);
}
else if (((!(PINC&(1<<PORTC5)))&&((PINC&(1<<PORTC4))))||((PINC&(1<<PORTC5))&&(!(PINC&(1<<PORTC4)))) )
{ ////反向正字或正向反字
_delay_ms(20); //////延時顯示,給以換向緩沖時間
PORTB=0XFF;
PORTD=0XFF;
i=32;
while (i>=1)
{
i--;
PORTD=hanz5[i];
i--;
PORTB=hanz5[i];
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=32;
while (i>=1)
{
i--;
PORTD=hanz4[i];
i--;
PORTB=hanz4[i];
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=32;
while (i>=1)
{
i--;
PORTD=hanz3[i];
i--;
PORTB=hanz3[i];
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=32;
while (i>=1)
{
i--;
PORTD=hanz2[i];
i--;
PORTB=hanz2[i];
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(2);
i=32;
while (i>=1)
{
i--;
PORTD=hanz1[i];
i--;
PORTB=hanz1[i];
_delay_ms(1);
}
PORTB=0XFF;
PORTD=0XFF;
_delay_ms(8);
}
}
}
//////////////////////////////編輯卡/////////////////////////////////
//////////////////////////////數碼管顯示
uchar pos1,pos2,pos3,pos4;
static uchar dotpos=1; //編輯卡顯示,點位置從左往右 1,, 4
uchar dspbuf1,dspbuf2,dspbuf3,dspbuf4;
void eep_disp()
{
PORTB=0;
DDRB=0XFF;
DDRC=0X0F;
dspbuf1=pgm_read_byte(tabdisp+pos1); ////取得4個管子字段碼
dspbuf2=pgm_read_byte(tabdisp+pos2);
dspbuf3=pgm_read_byte(tabdisp+pos3);
dspbuf4=pgm_read_byte(tabdisp+pos4);
PORTB=dspbuf1;
if (dotpos==1)
PORTB=PORTB|0x80; ////加小數點顯示
PORTC=0XF1; ////C口控制數碼管位
_delay_ms(5); //PORTC.0=1
PORTC=0XF0;
PORTB=dspbuf2;
if (dotpos==2)
PORTB=PORTB|0x80;
PORTC=0XF2; //PORTC.1=1
_delay_ms(5);
PORTC=0XF0;
PORTB=dspbuf3;
if (dotpos==3)
PORTB=PORTB|0x80;
PORTC=0XF4; //PORTC.2=1
_delay_ms(5);
PORTC=0XF0;
PORTB=dspbuf4;
if (dotpos==4)
PORTB=PORTB|0x80;
PORTC=0XF8; //PORTC.3=1
_delay_ms(5);
PORTC=0XF0;
}
//////////////////////查鍵/////////////////////////////////////////
uchar keychek(void)
{
DDRC=0X0F;
PORTC=0XF0; ////關顯示
DDRB=0xF0;
PORTB=0X0F; ////PORTB.7..PORTB.4 輸出 0,查低4位引腳 PINB.3..PINB.0
if ((PINB!=0x0f)||!((PINC)&(1<<PORTC4))) //有鍵返回1,否則返回0
return 1;
else
return 0;
}
/////////////////////取得鍵值//////////////////////////////////////
uchar kval=0xff;
void key(void)
{
DDRB=0XF0; ////PORTB7..4 OUT PORTB3..0 IN
uchar kvalc; ////臨時中間值
keychek();
if (keychek()==1) ////如果有鍵
{
_delay_ms(20); ////延時消抖
keychek(); ////再查
if (keychek()==1) ////真實有鍵
////B口高位輪流置0,檢查低位和PC4取得鍵值
{
PORTC=0Xf0; ////C口
PORTB=0XEF; ////B口PORTB.4=〉0
kvalc=0;
if (!((PINB)&(1<<PORTB0)))
kval=kvalc+0;
else if (!((PINB)&(1<<PORTB1)))
kval=kvalc+1;
else if (!((PINB)&(1<<PORTB2)))
kval=kvalc+2;
else if(!((PINB)&(1<<PORTB3)))
kval=kvalc+3;
else if (!((PINC)&(1<<PORTC4)))
kval=kvalc+37; //kval=37
else
{
PORTB=0XDF;
PORTC=0Xf0;
kvalc=4;
if (!((PINB)&(1<<PORTB0)))
kval=kvalc+0;
else if (!((PINB)&(1<<PORTB1)))
kval=kvalc+1;
else if (!((PINB)&(1<<PORTB2)))
kval=kvalc+2;
else if(!((PINB)&(1<<PORTB3)))
kval=kvalc+3;
else if (!((PINC)&(1<<PORTC4)))
kval=kvalc+34; //kval=38
else
{
PORTB=0XBF;
PORTC=0Xf0;
kvalc=8;
if (!((PINB)&(1<<PORTB0)))
kval=kvalc+0;
else if (!((PINB)&(1<<PORTB1)))
kval=kvalc+1;
else if (!((PINB)&(1<<PORTB2)))
kval=kvalc+2;
else if(!((PINB)&(1<<PORTB3)))
kval=kvalc+3;
else if (!((PINC)&(1<<PORTC4)))
kval=kvalc+31; //kval=39
else
{
PORTB=0X7F;
PORTC=0Xf0;
kvalc=12;
if (!((PINB)&(1<<PORTB0)))
kval=kvalc+0;
else if (!((PINB)&(1<<PORTB1)))
kval=kvalc+1;
else if (!((PINB)&(1<<PORTB2)))
kval=kvalc+2;
else if(!((PINB)&(1<<PORTB3)))
kval=kvalc+3;
else if (!((PINC)&(1<<PORTC4)))
kval=kvalc+28; //kval=40
}
}
}
}
do{
}while (((PINB&0x0f)!=0x0f)||!((PINC)&(1<<PORTC4))); //until key up
_delay_ms(30); //////等待按鍵釋放
}
else
kval=255; //////無鍵返回鍵值255
}
/////////////////////////////控制鍵處理
void Ctrkey(void)
{
PORTC=0Xf0;
switch (kval)
{
case 37: ////鍵值37,小數點右移動---->
if (dotpos<4) ////最多移到4位
dotpos++;
else
dotpos=4;
kval=0xff; ////1次按鍵處理完
break;
case 38: ////鍵值38,點左移 <-----
if (dotpos>1) ////最多移動到1位
dotpos--;
else
dotpos=1;
kval=0xff;
break;
case 39: ////鍵值39移到下一行數據最多到第15行,從0列開始,
if (pos1<15)
{pos1++;pos2=0;
pos3=(edit[pos1][pos2])/10; ////下一行0列元素值10位數
pos4=(edit[pos1][pos2])%10; ////下一行0列元素值個位數
}
else
{pos1=0;
pos3=(edit[pos1][pos2])/10;
pos4=(edit[pos1][pos2])%10;
}
kval=0xff;
break;
case 40: ////鍵值40,把編輯的1行5個元素值存入eeprom索引數組
eeprom_busy_wait();
eeprom_write_byte(eeindex[pos1],*(edit[pos1]));
eeprom_busy_wait();
eeprom_write_byte(eeindex[pos1]+1,*(edit[pos1]+1));
eeprom_busy_wait();
eeprom_write_byte(eeindex[pos1]+2,*(edit[pos1]+2));
eeprom_busy_wait();
eeprom_write_byte(eeindex[pos1]+3,*(edit[pos1]+3));
eeprom_busy_wait();
eeprom_write_byte(eeindex[pos1]+4,*(edit[pos1]+4));
kval=0xff;
break;
default:;
}
}
////////////////////////////////數字鍵處理
void Numkey(void)
{
PORTC=0Xf0;
switch (dotpos) //////按照小數點位置分別處理對應各個數碼管的數字
{
case 1: //////第1位輸入范圍0..f:選擇16個短句
pos1=kval;
if (pos1>15)
pos1=0;
pos3=(edit[pos1][pos2])/10; ////改變了1位,3、4位顯示隨同改變
pos4=(edit[pos1][pos2])%10;
kval=0xff; ////1次按鍵處理完/
break;
case 2: //////2位輸入范圍0..4:選擇5個字
pos2=kval;
if (pos2>4)
pos2=0;
pos3=(edit[pos1][pos2])/10; ////改變了2位,3、4位隨同改變
pos4=(edit[pos1][pos2])%10;
kval=0xff;
break;
case 3: //////3位輸入范圍0..4;可選擇0,,49共50個字
pos3=kval;
if (pos3>4)
pos3=4;
edit[pos1][pos2]=pos3*10+pos4; ////要相應改變數組元素值
kval=0xff;
break;
case 4: //////4位輸入范圍0..9,和3位配合給出數組元素的值
pos4=kval;
if (pos4>9)
pos4=9;
edit[pos1][pos2]=pos3*10+pos4; ////要相應改變數組元素值
kval=0xff;
break;
default:;
}
}
//////////////////////////////////////////////////////////////////////
void eep_acc(void)
{
uchar m,n;
for (m=0;m<15;m++) ////////初次啟動時檢查eeprom,為0xff時寫0
{
for (n=0;n<5;n++)
{
eeprom_busy_wait();
if (eeprom_read_byte(eeindex[m]+n)==0xff) //initial
{
eeprom_busy_wait();
eeprom_write_byte(eeindex[m]+n,0);
}
}
}
for (m=0;m<15;m++) //////把索引數組拷貝到臨時數組以便編輯
{for (n=0;n<4;n++)
{
eeprom_busy_wait();
edit[m][n]=eeprom_read_byte(eeindex[m]+n);
}
}
pos1=0; ///////數碼管的1、2位顯示,從臨時數組00單元顯示
pos2=0;
pos3=(edit[pos1][pos2])/10; //數碼管的3、4位顯示,顯示十進位元素的十位、個位
pos4=(edit[pos1][pos2])%10;
while(1) //////數碼管顯示和按鍵處理無限循環
{
eep_disp();
key();
if(kval!=0xff) //////如果有鍵
{
if (kval>36) //////鍵值大于36按控制鍵處理
{
Ctrkey();
}
else //////否則按數字鍵處理
Numkey();
}
}
}
////////////////////////////////////////////////
void main(void)
{ PORTC=0xf0;
DDRC=0x0f;
if ((PINC)&(1<<PORTC5)) /////
{ PORTB=0xff; DDRB=0xff;
PORTD=0xff; DDRD=0xff;
ply();
}
else eep_acc();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -