/*
* shuma.c
*
* Created: 2013-11-27 16:04:42
* Author: Administrator
*/
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#define SET_1(a,b) a|=(1<<b) //某一位,置一
#define CLE_0(a,b) a&=~(1<<b) //某一位,清零
#define uchar unsigned char
#define uint unsigned int
#define shan 0 //闪烁所在位数
#define tiao 1 //调节所在位数
volatile unsigned int shu=0;
volatile unsigned char duan[]={0xc0,0xf9,0xa4,0xb0,0x99, //0~9和灭共阳段码
0x92,0x82,0xf8,0x80,0x90,
0xff};
unsigned char bit=0x00; //标志字节定义
unsigned char ci=0; //用于计数
unsigned char wei=0; //当前闪烁及调节位数
unsigned char yi; //存储数据的千,百,十,个位
unsigned char er;
unsigned char san;
unsigned char si;
void io_int(void)
{
DDRB=0xff; //端口B初始化
PORTB=0xff;
DDRD=0x00; //端口D初始化
PORTD=0xff;
}
void E_write(unsigned int add,unsigned char data) //EEPROM写函数
{
while(EECR&(1<<EEWE));
EEAR=add;
EEDR=data;
EECR|=(1<<EEMWE);
EECR|=(1<<EEWE);
}
unsigned char E_read(unsigned int add) //EEPROM读函数
{
while(EECR&(1<<EEWE));
EEAR=add;
EECR|=(1<<EERE);
return EEDR;
}
void huan_y(void)
{
yi=E_read(0x00); //从EEPROM中读取数据
_delay_ms(20);
er=E_read(0x01);
_delay_ms(20);
san=E_read(0x02);
_delay_ms(20);
si=E_read(0x03);
_delay_ms(20);
shu=(yi)+(er*10)+(san*100)+(si*1000); //数据还原
}
void send_byte(unsigned char shuju) //串行数据发送函数
{
unsigned char i;
for(i=0;i<8;i++)
{
PORTB&=~(1<<PORTB3); //SRCLK 移位 清零
if(shuju&0x80)
PORTB|=(1<<PORTB0); //SER 数据 置一
else
PORTB&=~(1<<PORTB0); //SER 数据 清零
shuju=shuju<<1;
PORTB|=(1<<PORTB3); //SRCLK 移位 置一
}
}
void geng_x(void)
{
E_write(0x00,yi); //向EEPROM写数据
_delay_ms(20);
E_write(0x01,er);
_delay_ms(20);
E_write(0x02,san);
_delay_ms(20);
E_write(0x03,si);
_delay_ms(20);
shu=(yi)+(er*10)+(san*100)+(si*1000); //数据更新
}
void display(unsigned int xian) //显示函数
{
unsigned char ge;
unsigned char shi;
unsigned char bai;
unsigned char qian;
if((bit&0x01)&&(bit&0x02)&&(wei==0)) //个位
{
ge=10;
}
else
ge=xian%10;
if((bit&0x01)&&(bit&0x02)&&(wei==1)) //十位
{
shi=10;
}
else
shi=(xian/10)%10;
if((bit&0x01)&&(bit&0x02)&&(wei==2)) //百位
{
bai=10;
}
else
bai=(xian/100)%10;
if((bit&0x01)&&(bit&0x02)&&(wei==3)) //千位
{
qian=10;
}
else
qian=(xian/1000)%10;
send_byte(duan[ge]); //分别发送每位的数据
send_byte(duan[shi]);
send_byte(duan[bai]);
send_byte(duan[qian]);
PORTB&=~(1<<PORTB2); //RCLK 平行 清零
PORTB|=(1<<PORTB2); //RCLK 平行 置一
PORTB&=~(1<<PORTB1); //O_E 使能 清零
_delay_ms(50);
PORTB|=(1<<PORTB1); //O_E 使能 置一
ci++;
if(ci==12) //闪烁计时处理
{
ci=0;
if((bit&0x01))
CLE_0(bit,shan);
else
SET_1(bit,shan);
}
}
void key_in(void) //按键处理函数
{
unsigned char key; //定义键值记录变量
key=PIND; //获取端口状态
key&=0xf2; //屏蔽无关位
if(key!=0xf2) //有无按键按下判断
{
_delay_ms(20); //延时去抖
if(key==(PIND&0xf2)) //确定按键按下
{
key&=0xf2; //提取当前按键值
while(key==(PIND&0xf2)); //等待按键松手
switch(key) //根据键值处理
{
case 0xf0:if((bit&0x02))//设定
CLE_0(bit,tiao);
else
SET_1(bit,tiao);
break;
case 0xd2:if((bit&0x02))//右移
{
if(wei>0)
wei--;
else
wei=3;
}
break;
case 0xe2:if((bit&0x02))//左移
{
if(wei<3)
wei++;
else
wei=0;
}
break;
case 0xb2:if((bit&0x02))//加加
{
switch(wei)
{
case 0:if(yi<9) yi++; else yi=0;break;
case 1:if(er<9) er++; else er=0;break;
case 2:if(san<9)san++;else san=0;break;
case 3:if(si<9) si++; else si=0;break;
}
}
break;
case 0x72:if((bit&0x02))//减减
{
switch(wei)
{
case 0:if(yi>0) yi--; else yi=9;break;
case 1:if(er>0) er--; else er=9;break;
case 2:if(san>0)san--;else san=9;break;
case 3:if(si>0) si--; else si=9;break;
}
}
break;
default :;break;
}
geng_x();
}
}
}
void time_int(void)
{
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1L=0xf0;
TCNT1H=0xd8;
SET_1(TIMSK,2);
sei();
}
ISR(TIMER1_OVF_vect)
{
CLE_0(TIMSK,2);
TCNT1L=0xf0;
TCNT1H=0xd8;
shu++;
SET_1(TIMSK,2);
}
int main(void)
{
io_int();
huan_y();
while(1) //主循环
{
display(shu);
key_in();
}
} |