atmega16L(对eeprom写数据后再读出来)
/*atmega16的eeprom是一个16位的地址和一个8位的数据
心得与体会:
1、记得以前用51操作at24c04时忽视了一个问题,就是只管往存储器里面写数据而不管数据是否写得下的问题。例如这款单片机中自带的eeprom是8位的数据,当写入的数据大于255时,就会出错,发现自己写入的数据不能正确的读出来
2、一个程序可以有多个任务,可以用定时器中断让cpu在不同的任务(功能函数之间切换),从而更加均匀合理地完成硬件资源的分配,达到更好的效果
*/
#include
#define uchar unsigned char
#define uint unsigned int
#define wei PORTD
#define duan PORTB
uchar t1[]={0xc0,0xfc,0x89,0x83,0xa6,0x92,0x90,0xc7,0x80,0x82}; //0-9
uchar t11[]={0x40,0x7c,0x09,0x03,0x26,0x12,0x10,0x47,0x00,0x02};//0-9共阳,带小数点
uchar t2[]={0x70,0xb0,0xd0,0xe0};
uchar t3[]={0x0e,0x0d,0x0b,0x07};
uint i;
uint j;
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=200;y>0;y--);
}
void init_display()
{
DDRB=0XFF;
DDRD=0XFF;
}
void timer0_init()
{
TCNT0=0X00;//定时器0的定时初值
TCCR0=0X03;//定时器0的计数预分频取64
TIMSK=0X01;//使能T/c0中断
SREG=0X80;//使能总中断
}
void adc_init()
{
ADCSRA=0Xe3;//自由转换方式,8分频,若为0xC7,则为单次转换,输入电压改变后,输出不变
ADMUX=0X07;//外部参考电压,输入为通道7
}
void init_device()
{
init_display();
timer0_init();
adc_init();
}
uint adc_convert()
{
uint temp1,temp2;
temp1=(uint)ADCL;
temp2=(uint)ADCH;
temp2=(temp2<<8)+temp1;
return temp2;
}
uint conv(uint i)
{
long x;
uint y;
x=(5000*(long)i)/1023;
y=(uint) x;
return y;
}
void display(uint z)
{
wei =t3[3];
duan=t1[z/1000];
delay(5);
wei =t3[2];
duan=t1[(z%1000)/100];
delay(5);
wei =t3[1];
duan=t1[(z%100)/10];
delay(5);
wei =t3[0];
duan=t1[z%10];
delay(5);
}
/*写eeprom子函数*/
void w_eep(uint add,uint dat)//dat为代写数据,add为eeprom某单元地址
{
while(EECR&(1< EEAR=add;//设定单元地址
EEDR=dat;//将数据写入eeprom
EECR|=(1< EECR|=(1<}
/*读eeprom子函数*/
uint r_eep(uint add)
{
while(EECR&(1< EEAR=add;//设定单元地址
EECR|=(1< return EEDR;//返回读出的数据
}
void main()
{
uint value;
init_device();
w_eep(488,123);
while(1)
{
display(value);
if(j>25)
{
j=0;
r_eep(488);//使用中断的方法定时从eeprom中读出数据,其余时间执行display函数
value=r_eep(488);
}
}
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0=0X00;
i++;
if(i>=10)
{
i=0;
j++;
}
}
阅读(4241) | 评论(0) | 转发(0) |