1) Появился незначительный паразитный засвет сегментов, немного побороть получилось, но всё же...
2) В коде используются переменные и функции которые теоретически не нужны, такие как, например, чтение/запись даты, они же занимают место в камушке. Можно ли безболезненно их убрать?
3) Я собираюсь ставить большие индикаторы, хотель использовать две uln2803, но ситуёвина такова, что она инвертирует сигнал, ясное дело, что для исправления сего дела нужно программно инвертировать сигнал идущий на сегменты и сигналы управления индикаторами. С первым справился, а вот со вторым нихвига не вышло, на индикаторах вылазит всякая чепуха.
Привожу мой код:
Код: Выделить всё
#include<avr/io.h>
#define F_CPU 8000000UL
#include<util/delay.h>
#include<avr/interrupt.h>
int day=6,dd=4,mm=4,yy=20;
unsigned int sec, min=13, hr=4;
const unsigned int num[]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
int d0,d1,d2,d3;
volatile unsigned int count,count1;
#define digit 4
#define dataPort PORTB
#define controlPortD PORTD
#define controlPortC PORTC
#define controlPortA PORTA
#define controlPortD_Mask 0x83
#define controlPortC_Mask 0x03
#define controlPortA_Mask 0x7F
#define segmentOff -1
#define sw PINA
#define set 4
#define ok 3
#define up 2
#define down 1
#define setEvent (sw & (1<<set))
#define okEvent (sw & (1<<ok))
#define upEvent (sw & (1<<up))
#define downEvent (sw & (1<<down))
#define LEDPORT PORTA
#define secLed 5
char blinkFlag;
volatile char onFlag=0x00;
#define timeFormat 24
enum
{
hour=1,
minute,
date,
month,
year,
};
char segOn[12]={0x04,0x08,0x10,0x20}; // выводы на разряды индикаторов
void display();
void updateTime();
ISR(TIMER1_OVF_vect)
{
display();
TCNT1 = 61590;
}
void selectSeg(int count)
{
if(count < 5)
{
controlPortA&=controlPortA_Mask;
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
controlPortD|=segOn[count];
}
else if(count == 5)
{
controlPortA|=segOn[count];
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
}
else if(count == -1)
{
controlPortA&=controlPortA_Mask;
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
}
else
{
controlPortA&=controlPortA_Mask;
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
controlPortC|=segOn[count];
}
}
void segment(int count, int seg)
{
if(blinkFlag == seg)
{
if(onFlag)
{
selectSeg(segmentOff);
}
else
selectSeg(count);
}
else
{
selectSeg(count);
}
}
void display()
{
count1++;
if(count1>400)
{
count1=0;
onFlag=!onFlag;
}
count++;
if(count>digit)
count=0;
switch(count%digit)
{
case 0:
segment(count,minute);
dataPort=num[d0];
break;
case 1:
segment(count,minute);
dataPort=num[d1];
break;
case 2:
segment(count,hour);
dataPort=num[d2];
break;
case 3:
segment(count,hour);
dataPort=num[d3];
break;
}
}
void timer1_init()
{
// set up timer with prescaler = 8
TCCR1B |= (1 << CS10);
//TCCR1B &= ~(1 << CS10);
//TCCR1B &= (1 << CS11);
//TCCR1B &= ~(1 << CS12);
TCNT1 = 63500;
TIMSK |= (1 << TOIE1);
sei();
}
int bcdtochar(char num)
{
return ((num/16 * 10) + (num % 16));
}
int dectobcd(char num)
{
return ((num/10)<<4) + (num % 10);
}
void RTC_start()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR&0x80)==0x00);
}
void device()
{
TWDR=0xD0; //RTC write (slave address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWDR=0x00; // word address write
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void RTC_stp()
{
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //stop communication
}
void RTC_read()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR&0x80)==0x00);
TWDR=0xD0; //RTC запись (slave address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWDR=0x00; //RTC запись (word address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //start RTC communication again
while ((TWCR&0x80)==0x00);
TWDR=0xD1; // RTC command to read
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void sec_init(unsigned char d)
{
TWDR=d; //инициализация секунд
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void min_init(unsigned char d)
{
TWDR=d; //инициализация минут
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void hr_init(unsigned char d)
{
TWDR=d; //инициализация часов
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void day_init(unsigned char d)
{
TWDR=d; //days init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void date_init(unsigned char d)
{
TWDR=d; //date init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void month_init(unsigned char d)
{
TWDR=d; //month init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void yr_init(unsigned char d)
{
TWDR=d; //year init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
int sec_rw()
{
/*int g[3];*/
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC чтение секунд
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int min_rw()
{
TWCR|=(1<<TWINT); //RTC чтение минут
TWCR|=(1<<TWEA);
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int hr_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC чтение часов
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int day_rd()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC day read
while((TWCR&0x80)==0x00);
return bcdtochar(TWDR);
}
int date_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC date read
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int month_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC month read
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int yr_rw()
{
TWCR|=(1<<TWINT); //RTC year read
TWCR&=(~(1<<TWEA));
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
void setTime()
{
RTC_start();
device();
sec_init(0);
min_init(dectobcd(min));
hr_init(dectobcd(hr));
day_init(dectobcd(day));
date_init(dectobcd(dd));
month_init(dectobcd(mm));
yr_init(dectobcd(yy));
RTC_stp();
}
void RTC()
{
RTC_read();
sec=sec_rw();
min=min_rw();
hr=hr_rw();
day=day_rd();
dd=date_rw();
mm=month_rw();
yy=yr_rw();
RTC_stp();
}
char getPara(char count)
{
while(1)
{
updateTime();
if(!upEvent)
{
count1=0;
onFlag=0x00;
count++;
if(blinkFlag == hour)
{
if(timeFormat == 12)
{
if(count>12)
count=0;
}
else
{
if(count > 23)
count=0;
}
hr=count;
}
else if(blinkFlag == minute)
{
if(count>59)
count=0;
min=count;
}
else if(blinkFlag == month)
{
if(count > 12)
count=1;
mm=count;
}
else if(blinkFlag == date)
{
if(mm == 4 || mm == 6 || mm == 9 || mm == 11)
{
if(count > 30)
count=1;
}
else if(mm == 1 || mm == 3 || mm == 5 || mm == 7 || mm == 8 || mm == 10 || mm == 12)
{
if(count >31)
count=1;
}
else
{
int y=2000+yy;
if(y/4 == 0 && y/400 == 0)
{
if(count > 29)
count=1;
}
else
{
if(count > 28)
count=1;
}
}
dd=count;
}
else if(blinkFlag == year)
{
if(count >99)
count=0;
yy=count;
}
_delay_ms(100);
}
else if(!(downEvent))
{
count--;
_delay_ms(100);
}
else if(!okEvent)
{
_delay_ms(300);
return count;
}
}
}
void settingTime()
{
blinkFlag=1;
hr=getPara(hr);
blinkFlag++;
min=getPara(min);
blinkFlag=0;
}
void updateTime()
{
d0=min%10;
d1=min/10;
d2=hr%10;
d3=hr/10;
}
int main(void)
{
/*unsigned long int Time;*/
DDRB=0xff;
DDRA=0xE0;
PORTA=0x1E;
DDRD=0xff;
DDRC=0xff;
timer1_init();
while(1)
{
RTC();
updateTime();
_delay_ms(500);
LEDPORT|=1<<secLed;
_delay_ms(500);
LEDPORT&=~(1<<secLed);
if (!setEvent)
{
settingTime();
setTime();
}
}
}
Также привожу оригинальный исходник:
Код: Выделить всё
#include<avr/io.h>
#define F_CPU 8000000UL
#include<util/delay.h>
#include<avr/interrupt.h>
int day=6,dd=1,mm=3,yy=19;
unsigned int sec, min=13, hr=4;
const unsigned int num[]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
int d0,d1,d2,d3,d4,d5,d6,d7,d8,d9;
volatile unsigned int count,count1;
#define digit 13
#define dataPort PORTB
#define controlPortD PORTD
#define controlPortC PORTC
#define controlPortA PORTA
#define controlPortD_Mask 0x83
#define controlPortC_Mask 0x03
#define controlPortA_Mask 0x7F
#define segmentOff -1
#define sw PINA
#define set 4
#define ok 3
#define up 2
#define down 1
#define setEvent (sw & (1<<set))
#define okEvent (sw & (1<<ok))
#define upEvent (sw & (1<<up))
#define downEvent (sw & (1<<down))
#define LEDPORT PORTA
#define secLed 5
#define BUZPORT PORTD
#define buzzer 7
char blinkFlag;
volatile char onFlag=0x00;
#define timeFormat 24
enum
{
hour=1,
minute,
date,
month,
year,
};
char segOn[12]={0x04,0x08,0x10,0x20,0x40,0x80,0x40,0x80,0x10,0x20,0x04,0x08};
void display();
void updateTime();
ISR(TIMER1_OVF_vect)
{
display();
TCNT1 = 64000;
}
void selectSeg(int count)
{
if(count < 5)
{
controlPortA&=controlPortA_Mask;
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
controlPortD|=segOn[count];
}
else if(count == 5)
{
controlPortA|=segOn[count];
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
}
else if(count == -1)
{
controlPortA&=controlPortA_Mask;
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
}
else
{
controlPortA&=controlPortA_Mask;
controlPortC&=controlPortC_Mask;
controlPortD&=controlPortD_Mask;
controlPortC|=segOn[count];
}
}
void segment(int count, int seg)
{
if(blinkFlag == seg)
{
if(onFlag)
selectSeg(segmentOff);
else
selectSeg(count);
}
else
{
selectSeg(count);
}
}
void display()
{
count1++;
if(count1>400)
{
count1=0;
onFlag=!onFlag;
}
count++;
if(count>digit)
count=0;
switch(count%digit)
{
case 0:
segment(count,minute);
dataPort=num[d0];
break;
case 1:
segment(count,minute);
dataPort=num[d1];
break;
case 2:
segment(count,hour);
dataPort=num[d2];
break;
case 3:
segment(count,hour);
dataPort=num[d3];
break;
case 4:
segment(count,date);
dataPort=num[d4];
break;
case 5:
segment(count,date);
dataPort=num[d5];
break;
case 6:
segment(count,month);
dataPort=num[d6];
break;
case 7:
segment(count,month);
dataPort=num[d7];
break;
case 8:
segment(count,year);
dataPort=num[d8];
break;
case 9:
segment(count,year);
dataPort=num[d9];
break;
}
}
void timer1_init()
{
// set up timer with prescaler = 8
TCCR1B |= (1 << CS11);
//TCCR1B &= ~(1 << CS10);
//TCCR1B &= (1 << CS11);
//TCCR1B &= ~(1 << CS12);
TCNT1 = 63500;
TIMSK |= (1 << TOIE1);
sei();
}
int bcdtochar(char num)
{
return ((num/16 * 10) + (num % 16));
}
int dectobcd(char num)
{
return ((num/10)<<4) + (num % 10);
}
void RTC_start()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR&0x80)==0x00);
}
void device()
{
TWDR=0xD0; //RTC write (slave address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWDR=0x00; // word address write
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void RTC_stp()
{
TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO); //stop communication
}
void RTC_read()
{
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while((TWCR&0x80)==0x00);
TWDR=0xD0; //RTC write (slave address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWDR=0x00; //RTC write (word address)
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); //start RTC communication again
while ((TWCR&0x80)==0x00);
TWDR=0xD1; // RTC command to read
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void sec_init(unsigned char d)
{
TWDR=d; //second init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void min_init(unsigned char d)
{
TWDR=d; //minute init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void hr_init(unsigned char d)
{
TWDR=d; //hour init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void day_init(unsigned char d)
{
TWDR=d; //days init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void date_init(unsigned char d)
{
TWDR=d; //date init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void month_init(unsigned char d)
{
TWDR=d; //month init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
void yr_init(unsigned char d)
{
TWDR=d; //year init
TWCR=(1<<TWINT)|(1<<TWEN);
while(!(TWCR&(1<<TWINT)));
}
int sec_rw()
{
int g[3];
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC second read
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int min_rw()
{
TWCR|=(1<<TWINT); //RTC minute read
TWCR|=(1<<TWEA);
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int hr_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC hour read
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int day_rd()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC day read
while((TWCR&0x80)==0x00);
return bcdtochar(TWDR);
}
int date_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC date read
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int month_rw()
{
TWCR|=(1<<TWINT)|(1<<TWEA); //RTC month read
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
int yr_rw()
{
TWCR|=(1<<TWINT); //RTC year read
TWCR&=(~(1<<TWEA));
while((TWCR & 0x80)==0x00);
return bcdtochar(TWDR);
}
void setTime()
{
RTC_start();
device();
sec_init(0);
min_init(dectobcd(min));
hr_init(dectobcd(hr));
day_init(dectobcd(day));
date_init(dectobcd(dd));
month_init(dectobcd(mm));
yr_init(dectobcd(yy));
RTC_stp();
}
void RTC()
{
RTC_read();
sec=sec_rw();
min=min_rw();
hr=hr_rw();
day=day_rd();
dd=date_rw();
mm=month_rw();
yy=yr_rw();
RTC_stp();
}
char getPara(char count)
{
while(1)
{
updateTime();
if(!upEvent)
{
count1=0;
onFlag=0x00;
count++;
if(blinkFlag == hour)
{
if(timeFormat == 12)
{
if(count>12)
count=0;
}
else
{
if(count > 23)
count=0;
}
hr=count;
}
else if(blinkFlag == minute)
{
if(count>59)
count=0;
min=count;
}
else if(blinkFlag == month)
{
if(count > 12)
count=1;
mm=count;
}
else if(blinkFlag == date)
{
if(mm == 4 || mm == 6 || mm == 9 || mm == 11)
{
if(count > 30)
count=1;
}
else if(mm == 1 || mm == 3 || mm == 5 || mm == 7 || mm == 8 || mm == 10 || mm == 12)
{
if(count >31)
count=1;
}
else
{
int y=2000+yy;
if(y/4 == 0 && y/400 == 0)
{
if(count > 29)
count=1;
}
else
{
if(count > 28)
count=1;
}
}
dd=count;
}
else if(blinkFlag == year)
{
if(count >99)
count=0;
yy=count;
}
_delay_ms(200);
}
else if(!(downEvent))
{
count--;
if(blinkFlag == year)
{
if(count<0)
count=99;
}
_delay_ms(100);
}
else if(!okEvent)
{
_delay_ms(1000);
return count;
}
}
}
void settingTime()
{
blinkFlag=1;
hr=getPara(hr);
blinkFlag++;
min=getPara(min);
blinkFlag++;
dd=getPara(dd);
blinkFlag++;
mm=getPara(mm);
blinkFlag++;
yy=getPara(yy);
blinkFlag=0;
}
void updateTime()
{
d0=min%10;
d1=min/10;
d2=hr%10;
d3=hr/10;
d4=dd%10;
d5=dd/10;
d6=mm%10;
d7=mm/10;
d8=yy%10;
d9=yy/10;
}
int main(void)
{
unsigned long int Time;
DDRB=0xff;
DDRA=0xE0;
PORTA=0x1E;
DDRD=0xff;
DDRC=0xff;
timer1_init();
while(1)
{
RTC();
updateTime();
_delay_ms(500);
LEDPORT|=1<<secLed;
_delay_ms(500);
LEDPORT&=~(1<<secLed);
if (!setEvent)
{
settingTime();
setTime();
}
}
}