Attiny 2313 Pic 16F628A

Başlatan mas, 24 Nisan 2012, 20:28:09

mas

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;
			}
	  };
}