⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toy16.c

📁 使用ATMEL的Mega8完成的一个摇棒显示玩具
💻 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 + -