Picproje Elektronik Sitesi

DERLEYİCİLER => PIC C => Konuyu başlatan: mas - 24 Nisan 2012, 20:28:09

Başlık: Attiny 2313 Pic 16F628A
Gönderen: mas - 24 Nisan 2012, 20:28:09
Merhaba arkadaşlar, attiny 2313 için yazılmış c programını 16f628 de çalışlışacak şekilde derlemek istiyorum. kendi iç osilatörü kullanılırsa port sayıları tutuyor gibi. programın hangi editör de yazıldığını bilmiyorum. elimde yanlızca hex ve c dosyaları mevcut. yardım için şimdiden teşekkürler..

/* ***********************************************************************
**
**  Copyright (C) 2010  Bogdan Raducanu
**
**  Timer for UV exposure box with extra functions:
** -stops counting if box lid is opened
**
**  For personal use only!
**
*********************************************************************** */


#define F_CPU 4000000
#include <avr/io.h>
#include <inttypes.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define BOX_OPEN PD5
#define BOX_OPEN_PIN PIND
#define BOX_OPEN_PORT PORTD
#define BOX_OPEN_DDR DDRD

#define UV_ON PD4
#define UV_ON_PORT PORTD

#define SEG_A PB6
#define SEG_A_PORT PORTB
#define SEG_B PB2
#define SEG_B_PORT PORTB
#define SEG_C PD3
#define SEG_C_PORT PORTD
#define SEG_D PD1
#define SEG_D_PORT PORTD
#define SEG_E PD0
#define SEG_E_PORT PORTD
#define SEG_F PB5
#define SEG_F_PORT PORTB
#define SEG_G PD6
#define SEG_G_PORT PORTD
#define SEG_DP PD2
#define SEG_DP_PORT PORTD

#define c1 PB7
#define c1_PORT PORTB
#define c1_PORT_DDR DDRB
#define c2 PB4
#define c2_PORT PORTB
#define c2_PORT_DDR DDRB
#define c3 PB3
#define c3_PORT PORTB
#define c3_PORT_DDR DDRB
#define c4 PB0
#define c4_PORT PORTB
#define c4_PORT_DDR DDRB

#define S1 PD3
#define S1_PIN PIND
#define S1_DDR DDRD
#define S1_PORT PORTD
#define S2 PD2
#define S2_PIN PIND
#define S2_DDR DDRD
#define S2_PORT PORTD
#define S3 PD1
#define S3_PIN PIND
#define S3_DDR DDRD
#define S3_PORT PORTD
#define S4 PD0
#define S4_PIN PIND
#define S4_DDR DDRD
#define S4_PORT PORTD

#define TIMER_PAUSE 1
#define TIMER_RUNNING 2
#define TIMER_DONE 3

#define BUTTON_PAUSE 4
#define BUTTON_UP 3
#define BUTTON_DOWN 2
#define BUTTON_MEM 1

#define MEM_SIZE 4
//define here as many times as needed, form is minute, second, minute, second etc.
uint8_t memory[MEM_SIZE*2] = { 2, 0, 5, 30, 1, 30, 25, 0};

volatile uint8_t dig1, dig2, dig3, dig4, dp_pos, dig_no, button, min, sec, frame_no, running, state_no, mem_index;
volatile uint8_t digits[5];
volatile uint8_t dig_calc[17] = {63, 6, 91, 79, 102, 109, 125, 7, 127, 111, 118, 121, 56, 94, 92, 84,0 };
//0,1,2,3,4,5,6,7,8,9, H, E, L, d, o, n, none


//converts from integer to two digits for minutes and seconds
//supresses the first zero for minutes when less than 10
void display_prep(uint8_t min, uint8_t sec)
{
uint8_t temp = 0;
while(min>9)
{
temp++;
min -=10;
}
if(temp == 0) digits[1] = 16; else digits[1] = temp;
digits[2] = min;
temp = 0;
while(sec>9)
{
temp++;
sec -=10;
}
digits[3] = temp;
digits[4] = sec;

}


//read the button function
int button_read(void)
{
int result = 0;
//all common anodes are zero to make sure led is off.
// make one for common cathodes.
c1_PORT&=~(_BV(c1)) ;
c2_PORT&=~(_BV(c2)) ;
c3_PORT&=~(_BV(c3)) ;
c4_PORT&=~(_BV(c4)) ;

//make all switch pins input, and pull up
S1_PORT|=_BV(S1);
S1_DDR&=~(_BV(S1));
S2_PORT|=_BV(S2);
S2_DDR&=~(_BV(S2));
S3_PORT|=_BV(S3);
S3_DDR&=~(_BV(S3));
S4_PORT|=_BV(S4);
S4_DDR&=~(_BV(S4));

//read the buttons
if(!(S1_PIN&(1<<S1))) result = 1;
if(!(S2_PIN&(1<<S2))) result = 2;
if(!(S3_PIN&(1<<S3))) result = 3;
if(!(S4_PIN&(1<<S4))) result = 4;

//make all switch pins out
S1_DDR|=_BV(S1);
S2_DDR|=_BV(S2);
S3_DDR|=_BV(S3);
S4_DDR|=_BV(S4);

return result;
}


//displays required info on a certain digit
void digit_display(uint8_t dig_info, uint8_t digit_no, uint8_t dp_pos)
{
button = button_read(); //read the buttons every 5ms
dig_info = dig_calc[dig_info]; //find the digits corresponding to each code
if (dig_info & (1<<0)) SEG_A_PORT&=~(_BV(SEG_A)); else SEG_A_PORT|=_BV(SEG_A);
if (dig_info & (1<<1)) SEG_B_PORT&=~(_BV(SEG_B)); else SEG_B_PORT|=_BV(SEG_B);
if (dig_info & (1<<2)) SEG_C_PORT&=~(_BV(SEG_C)); else SEG_C_PORT|=_BV(SEG_C);
if (dig_info & (1<<3)) SEG_D_PORT&=~(_BV(SEG_D)); else SEG_D_PORT|=_BV(SEG_D);
if (dig_info & (1<<4)) SEG_E_PORT&=~(_BV(SEG_E)); else SEG_E_PORT|=_BV(SEG_E);
if (dig_info & (1<<5)) SEG_F_PORT&=~(_BV(SEG_F)); else SEG_F_PORT|=_BV(SEG_F);
if (dig_info & (1<<6)) SEG_G_PORT&=~(_BV(SEG_G)); else SEG_G_PORT|=_BV(SEG_G);

if(dp_pos == digit_no) SEG_DP_PORT&=~(_BV(SEG_DP)); else SEG_DP_PORT|=_BV(SEG_DP);

if (digit_no ==1) c1_PORT|=_BV(c1); else c1_PORT&=~(_BV(c1)) ;
if (digit_no ==2) c2_PORT|=_BV(c2); else c2_PORT&=~(_BV(c2)) ;
if (digit_no ==3) c3_PORT|=_BV(c3); else c3_PORT&=~(_BV(c3)) ;
if (digit_no ==4) c4_PORT|=_BV(c4); else c4_PORT&=~(_BV(c4)) ;
}



//timer is set to overflow each 5ms, 200times per second a digit is display, which means
//display is 50fps (it used to be 25, but changed to 50 for less flicker)
ISR(TIMER1_OVF_vect)
{
TCNT1H=0xB1; //changed it to suit my oscillator, found AD2F right value, shoud be B1Df
TCNT1L=0xDF; //for quartz crystal

digit_display(digits[dig_no], dig_no, dp_pos); //display one digit

dig_no++;
if(dig_no==5) //after doing a full display and 20ms passed
{
dig_no = 1;
frame_no++;

if(frame_no == 51) // 1 second should have passed after 50 frames
{
frame_no = 0;
if(state_no == TIMER_RUNNING) //if the timer is running decrease the number of seconds/minutes
{
if(sec==0)
{
if(min>0)
{
min--;
sec=59;
}
else //stop the timer
state_no = TIMER_DONE;
}
else sec--;
}
}
}
}



void main(void)
{
//all pins out
PORTB=0xFF;
DDRB=0xFF;
PORTD=0xFF;
DDRD=0xFF;
//except for box open pin
BOX_OPEN_DDR &=~(_BV(BOX_OPEN));


// Timer/Counter 0 STOPPED
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization, system clk, 4MHz, OVF interrupt
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Ext Interrupt OFF
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x80;

// Universal Serial Interface Disabled
USICR=0x00;


// Analog Comparator: Off
ACSR=0x80;

// Enable global Interrupts
sei();


//Initialization
dp_pos = 2; //decimal point after second digit
mem_index = 0; //choose first memory location
min = memory[mem_index];
sec = memory[mem_index+1];

state_no = TIMER_PAUSE; //start from PAUSE state

uint8_t button_pressed = 0;
uint8_t blink_counter = 0;
UV_ON_PORT&=~(_BV(UV_ON)); //turn off uv leds

while (1) //main loop
      {
//PAUSE state
//allows changing time with UP/DOWN/MEM button
//allows UV exposure start if box lid is closed
while(state_no == TIMER_PAUSE)
{
if(blink_counter>127) display_prep(min, sec); 
else
{
digits[1] = 16;//blank display
digits[2] = 16;
digits[3] = 16;
digits[4] = 16;
}
if(button_pressed==0)
{
if(button == BUTTON_UP)
{
button_pressed = button;
if(sec>49)
{
sec =0;
if(min<99) min++;
}
else sec+=10;
}
if(button == BUTTON_DOWN)
{
button_pressed = button;
if(sec<10)
{
sec = 50;
if(min>0) min--;
}
else sec-=10;
}

if(button == BUTTON_MEM)
{
button_pressed = button;
mem_index+=2;
if(mem_index == MEM_SIZE*2) mem_index = 0;
min = memory[mem_index];
sec = memory[mem_index+1];
}

if(button == BUTTON_PAUSE) //start the timer only if box is closed
{
//button_pressed = button;

if(BOX_OPEN_PIN&(1<<BOX_OPEN))
{
UV_ON_PORT|=_BV(UV_ON); //turn ON uv leds
state_no = TIMER_RUNNING;
}
while(button!=0);
}

}

if(button == 0) button_pressed = 0;
_delay_ms(3);
blink_counter++;
}

//RUNNING state
//counter is decreased
//exits to PAUSE if lid opens of PAUSE button is pressed
while(state_no == TIMER_RUNNING)
{
display_prep(min, sec);
if(button == BUTTON_PAUSE)
{
UV_ON_PORT&=~(_BV(UV_ON)); //turn off uv leds
state_no = TIMER_PAUSE;
while(button!=0);
}
if(!(BOX_OPEN_PIN&(1<<BOX_OPEN)))  //if the box is opened
{
UV_ON_PORT&=~(_BV(UV_ON)); //turn off uv leds
state_no = TIMER_PAUSE; //and jump to pause rutine
}
}

//DONE state
//Dispays 'donE'
//Any button returns to PAUSE
while(state_no == TIMER_DONE)
{
UV_ON_PORT&=~(_BV(UV_ON)); //turn off uv leds
dp_pos = 0;
if(button !=0) //any button press exits.
{
dp_pos = 2;
state_no = TIMER_PAUSE;
while(button!=0);
}
digits[1] = 13;
digits[2] = 14;
digits[3] = 15;
digits[4] = 11;
}
  };
}