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

📄 main._c

📁 跷跷板小车
💻 _C
📖 第 1 页 / 共 2 页
字号:
      while((0xf0&PINA)!=0xf0);
      break;
      }
     }
     keycode=0xff;
    }
    switch(keycode)
    {
        case 0x00:return '1';
        case 0x01:return '2';
        case 0x02:return '3';
        case 0x03:return 'a';
        case 0x04:return '4';
        case 0x05:return '5';
        case 0x06:return '6';
        case 0x07:return 'b';
        case 0x08:return '7';
        case 0x09:return '8';
        case 0x0a:return '9';
        case 0x0b:return 'c';
        case 0x0c:return '*';
        case 0x0d:return '0';
        case 0x0e:return '#';
        case 0x0f:return 'd';
        case 0xff:return 0xff;
        default:return 0xff;
    }
}
 
unsigned char bitchg(unsigned char bit)//四位bit码翻译成行列位置
 {if(bit&0x01) bit=0;
  else if(bit&0x02) bit=1;
  else if(bit&0x04) bit=2;
  else  bit=3;
  return(bit); 
  }    
    
int scannum(void)//键盘输入一整型数据
 {  
  unsigned char strnum[6];
  unsigned char i;
  int keynum=0;
  keyflag=1;
  for(i=6;i>=0;i--)
   {
    do{keycode=key_scanonce();}while(keycode==0xff);//一直扫描键盘,到有按键按下
    if(keycode=='d')                                //是否回车(d号键) ?是 !
	 {
	  delay_nms(10);display_a_char((26-i),0x7f);
      if(strnum[0]=='b')//负数的运算
       {switch(i)
        {
         case 5:keynum=0;break;
         case 4:keynum=(-1)*(strnum[1]);break;
         case 3:keynum=(-1)*(strnum[1]*10+strnum[2]);break;
         case 2:keynum=(-1)*(strnum[1]*100+strnum[2]*10+strnum[3]);break;
         case 1:keynum=(-1)*(strnum[1]*1000+strnum[2]*100+strnum[3]*10+strnum[4]);break;
         case 0:keynum=(-1)*(strnum[1]*10000+strnum[2]*1000+strnum[3]*100+strnum[4]*10+strnum[5]);break;//|keynum|应小于32767
        }
       } 
      else //正数的运算
       {switch(i)
        {
         case 6:keynum=0;break;
         case 5:keynum=strnum[0];break;
         case 4:keynum=strnum[0]*10+strnum[1];break;
         case 3:keynum=strnum[0]*100+strnum[1]*10+strnum[2];break;
         case 2:keynum=strnum[0]*1000+strnum[1]*100+strnum[2]*10+strnum[3];break;
         case 1:keynum=strnum[0]*10000+strnum[1]*1000+strnum[2]*100+strnum[3]*10+strnum[4];break;//keynum应小于32767
        }
       }  
      break;//直接从if中跳出for循环
     }     
    else                                            //是否回车(d号键) ?否 !
	 {
	  if(keycode=='c')                               //是否清除(c号键) ?是 !
       {delay_nms(10);display_a_char((25-i),' ');i+=2;}
      else                                          //是否清除(c号键) ?否 !
       {
	    if(keycode=='b')                            //是否负号(b号键) ?是 !
         {delay_nms(10);display_a_char((25-i),'-');strnum[6-i]=keycode-0x30;}
        else                                        //是否负号(c号键) ?否 !
         {delay_nms(9);display_a_char((26-i),keycode);strnum[6-i]=keycode-0x30;}
       }
     }
   }
 keyflag=0;
 return(keynum);
 }
 
    
/*====================================液晶驱动函数============================*/
//液晶初始化
void lcd_init(void)
 {  
  delay_nms(30);
  lcd_data_port=0xff;
  lcd_data_ddr=0xff;
  lcd_control_port=0x00;
  lcd_control_ddr=0x07;
  lcd_write_command(0x38,0);//显示模式设置一次(此时不管lcd空闲与否)
  lcd_write_command(0x38,1);//显示模式设置(从此之后均需lcd空闲)
  lcd_write_command(0x08,1);//显示关闭
  lcd_write_command(0x01,1);//显示清屏
  lcd_write_command(0x06,1);//显示光标移动设置
  lcd_write_command(0x0c,1);//显示开及光标设置
  delay_nus(30);
  lcd_write_command(0x01,1);//显示清屏
 }


//写指令函数: E="高脉冲" RS="0" RW="0" command为指令,wait_en指定是否要判忙
void lcd_write_command(unsigned char command,unsigned char wait_en)
 {
    if(wait_en)wait_enable();//若wait_en为1,则要检测LCD忙信号,等待其空闲
    lcd_control_port&=~lcd_RS;//RS=0
    lcd_control_port&=~lcd_RW;//RW=0
    lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
    lcd_data_ddr=0xff;
    lcd_data_port=command;
    lcd_control_port|=lcd_EN;//E=1
    lcd_data_port=command;
    lcd_control_port&=~lcd_EN;//重设E=0
 }


//写数据函数: E =高脉冲 RS="1" RW="0"
void lcd_write_data(unsigned char char_data)
 {
    wait_enable();//等待LCD空闲
    lcd_control_port|=lcd_RS;//RS=1数据
    lcd_control_port&=~lcd_RW;//RW=0写
    lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
    lcd_data_ddr=0xff;
    lcd_data_port=char_data;
    lcd_control_port|=lcd_EN;//E=1
    lcd_data_port=char_data;
    lcd_control_port&=~lcd_EN;//重设E=0
 }


//正常读写操作之前必须检测LCD控制器状态:E=1 RS="0" RW="1";DB7: 0 空闲,1 忙。
//检测忙信号,等待LCD空闲函数
void wait_enable(void)
 {
  lcd_busy_ddr&=~busy;//设置busy口为输入
  lcd_control_port&=~lcd_RS;//RS=0
  lcd_control_port|=lcd_RW;//RW=1
  lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
  NOP();
  lcd_control_port|=lcd_EN;//E=1
  while(lcd_busy_pin&busy);//等待LCD_DB7为0
  lcd_control_port&=~lcd_EN;//重设E=0
  lcd_busy_ddr|=busy;//设置busy口为输出
 }

void display_a_char(unsigned char position,unsigned char char_data)//参数position指定位置0~79,char_data为要显示的字符
 {
  unsigned char position_tem;
  if(position<20) //第一行时,地址为0x80到0x93,输入的数值加上0x80, 就是当前的地址值;
   position_tem=position+0x80;
  else if(position<40)//第二行的地址为0xc0到0xd3,当为第二行时position>20,此时地址值应为position+0xc0-0x20即position+0xac;
   position_tem=position+0xac; 
  else if(position<60)//第三行的地址为0x94到0xa7,当为第三行时position>40,此时地址值应为position+0x94-0x40即position+0x6c;
   position_tem=position+0x6c;
  else//第四行的地址为0xd4到0xe7,当为第三行时position>60,此时地址值应为position+0xd4-0x60即position+0x98;
   position_tem=position+0x98; 
  lcd_write_command(position_tem,1);
  lcd_write_data(char_data);
 }
  			    				
//指定位置显示任意大小字符串,psition:位置,prt:要显示的字符串
void display_a_string(unsigned char position,unsigned char *ptr)
 {
  while(*ptr++!='\0')display_a_char(position++,*ptr);//位置++字符串指针++
 }
//指定位置显示一个整数,psition:位置,num:要显示的整数(新写,未测试)
void display_a_number(unsigned char position,int num)
  {
   unsigned char i,flag=0;//flag判断是否出现了有效位
   if(num<0)//是负数则显示'-'然后转为正数显示
	 {display_a_char(position++,'-');num*=-1;}
   for(i=4;i>=0;i--)//依次整除1000,1000,100,10,1得到字符并显示
	 {
	  if(num/nten(i))//非0位,要显示,并把flag置1
	    {
		 flag=1;
		 display_a_char(position++,num/nten(i));
		 num=num%nten(i);
		}
	  else//0位
		{
		 if(flag)display_a_char(position++,'0');//是0位并且是有效位,显示'0'
		}
	 }
  }

//void display_a_number(unsigned char position,int num)
// {
//  int j;
//  unsigned char i,x;
//  if(num>=10000)i=5;
//  else if(num<10000&&num>=1000)i=4;
//  else if(num<1000&&num>=100)i=3;
//  else if(num<100&&num>=10)i=2;
//  else if(num<10&&num>=0)i=1;
//  else if(num<=-10000)i=15;
//  else if(num>-10000&&num<=-1000)i=14;
//  else if(num>-1000&&num<=-100)i=13;
//  else if(num>-100&&num<=-10)i=12;
//  else i=11;
//  if(i<10)
//   {for(;i>0;i--)
//     {
//      j=nten(i-1);
//      x=num/j;
//      display_a_char(position,x+0x30);
//      num=num%j;
//      position++;
//     }
//   }
//  else
//   {
//    i-=10;
//    display_a_char(position,'-');
//    position++;
//    for(;i>0;i--)
//     {
//      j=nten(i);
//      x=num/j;
//      display_a_char(position,x+0x30);
//      num=num%j;
//      position++;
//     }
//   }
// }

//10的n次方转换
int nten(unsigned char n)
 {int m=1;
  for(;n>0;n--)
   {m*=10;}
  return(m);
 }
/*====================================计时函数================================*/
void time_init(void)
 {
  SREG=0x80;
  TIMSK=0x02;
  TCCR0=0x04;                   //T/C0工作于定时方式,系统时钟256分频
  TCNT0=0x06;                   //计数初始值6    
  
 }
/*====================================延时函数================================*/
void delay_ns(unsigned int n)
{
    unsigned int i,j;
    for(i=0;i<n;i++)
	{for(j=1000;j>0;j--)delay_1ms();      
    }
}
//n ms延时函数
void delay_nms(unsigned int n)
{
    unsigned int i;
    n-=n/1000;
    for(;n!=0;n--){for(i=1328;i!=0;i--) ; }
}
//1ms延时函数
void delay_1ms(void)
{
    unsigned int i;
    for(i=1328;i!=0;i--);
}
//n us延时函数
void delay_nus(int n)
 {while(n--);}

/*===================================端口初始化===============================*/
void port_init(void)
{
 PORTA = 0x00;
 DDRA  = 0x00;
 PORTB = 0x00;
 DDRB  = 0x00;
 PORTC = 0x00;
 DDRC  = 0x00;
 PORTD = 0x00;
 DDRD  = 0x00; 
 PORTE = 0x00;
 DDRE  = 0x00; 
}

//call this routine to initialize all peripherals
void init_devices(void)
{
 //stop errant interrupts until set up
 CLI(); //disable all interrupts
 port_init();
 lcd_init();
 wgm_init();
 time_init();
 
 MCUCR = 0x00;
 EMCUCR = 0x00;
 GICR = 0x00;
 TIMSK = 0x00;
 SEI(); //re-enable interrupts
 //all peripherals are now initialized
}

/*==============================T/C0中断服务函数==============================*/
//声明中断名及中断向量号
#pragma interrupt_handler Timer0:8 
void Timer0(void)
 {
  num++;                        //中断次数累加
  if(num==122)           
   {
    num=0;                    //计数到125次,计数值复位,125为理论值,122为试验值
    second++;                //秒加1
    if(second==60)
     {second=0;
      minute++;}            //分进位
    if(keyflag==0)//显示屏右下角显示系统时间mm:ss
     {if(minute<10){display_a_char(75,'0');display_a_number(76,minute);}
      else display_a_number(75,minute);   
      display_a_char(77,':');//分秒之间显示':'  
      if(second<10){display_a_char(78,'0');display_a_number(79,second);}
      else display_a_number(78,second);     
      }
    }
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -