sajt u izradi..
English French German Italian Portuguese Russian Spanish
Digital Thermometer -200 to 1350 [max31855][atmega8][Source File]
Created: Monday, 26.August.2013. 18:16
/*
 * Created: 05.06.13. 08:22PM
 * Author: Branislav Kešelj / http://kbblog.net
 * 	   
 * ATMEGA 8
 * 
 *FUSE
 *------------------ 
 * H-> 0xC9
 * L-> 0x6f
 *------------------
 *
 */ 
#define F_CPU 8000000UL //Define the clock speed
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
uint32_t display; 
uint8_t digit=0;
uint8_t error_flag=0x00;
uint8_t alarm_flag=0x00;
uint16_t menu_flag=0x00;
int16_t ALx_data[5];
char eedata[] EEMEM = {0x20,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x03,0x00,
						0x21,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,
						0x22,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
						0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
						
// ----------------------------------------------------------------------------------------------------------------
						
#define PROG 0x38
#define DOWN 0x34
#define UP 0x2C
#define SET 0x1C
#define UP_DOWN_TIME 0x190 // after 2.5ms*400
#define UP_DOWN_SPEED 0x05 // 5*2.5ms+2.5ms, 1+ || 1-
#define RESET_TIME 0x1F40 //8000*2.5 = 20s
#define BLINK_TIME 0x64  // 2.5ms*100
uint8_t key_flag=0x00;
uint16_t up_down_time = 0x00;
uint8_t up_down_speed =0x00;
uint16_t reset_time = 0x00; //  20s
uint8_t blink_time_ = 0x00;
uint8_t scan_key()
	{
	uint8_t key_status;
	key_status = PINB & 0x3C;
	
	if(key_status != 0x3C)
		{
		if(key_status == PROG || key_status == DOWN || key_status == UP || key_status == SET)
			{ // one key press
			if(key_flag != 0x80)
				{
				if(key_flag==key_status)
					{
					reset_time=RESET_TIME; //8000*2.5 = 20s
					blink_time_=0x01;
					key_flag++;
					return key_status;
					}
					else if(!key_flag) key_flag=key_status;
					
				if(up_down_time && (key_status == UP || key_status == DOWN) )
					{
					if(up_down_time == UP_DOWN_TIME)
						{
						if(up_down_speed == UP_DOWN_SPEED)
							{
							key_flag=0x00;
							up_down_speed=0x00;	
							}	
							else up_down_speed++;
						}
						else up_down_time++;				
					}	
				}
			}
			else key_flag=0x80;
		}
		else 
			{
			key_flag=0;
			up_down_time=(up_down_time) ? 1:0;
			up_down_speed=0x00;
			}			
	return 0;
	}
// ----------------------------------------------------------------------------------------------------------------
	
void reset()
	{
	if(reset_time)	
		{
		reset_time--;
		if(!reset_time)
			{
			menu_flag =0 ;
			alarm_flag =(alarm_flag & 0x01) ? 0:alarm_flag;	
			}
		}	
	}
// ----------------------------------------------------------------------------------------------------------------
void blink_time()
	{
	if(blink_time_)
		{
		blink_time_++;
		if((blink_time_ & 0x7F)==BLINK_TIME)
			{
			if(blink_time_ & 0x80) blink_time_=0x01;
				else blink_time_=0x81;   	
			}
		}	
	}
// ----------------------------------------------------------------------------------------------------------------
	
#define LED_OUT_ON PD6
#define LED_OUT_OFF PD7
#define OUT_ PB0
#define OUT_INVERT PB1	
	
void alarm_out_on()
	{
	PORTB |= (1<<OUT_);
	PORTB &= ~ (1<<OUT_INVERT);
	PORTD |= (1<<LED_OUT_ON);
	PORTD &= ~ (1<<LED_OUT_OFF);
	}
void alarm_out_off()
	{	
	PORTB &= ~ (1<<OUT_);
	PORTD &= ~ (1<<LED_OUT_ON);
	if(alarm_flag & 0x80) 
		{
		PORTB |= (1<<OUT_INVERT);
		PORTD |= (1<<LED_OUT_OFF); 
		}
		else 
			{
			PORTB &= ~ (1<<OUT_INVERT);
			PORTD &= ~ (1<<LED_OUT_OFF);
			}
	}
	
// ----------------------------------------------------------------------------------------------------------------
#define DS PD3 // Serial Data
#define SCL PD4 // Shift Clock
#define E PD5 // Latch Clock
void bin2display(int16_t v)
	{
	display=0;	
	uint16_t d[]={1000,100,10,1};
	for(uint8_t i=0;i<4;i++)
		{
		display+=v/d[i]; // 
		display<<=5;
		v-=(v/d[i])*d[i];			
		}
	}
void wrt_595(uint8_t output)
	{
	for(uint8_t i=0;i<8;i++)
		{
		if(output & 0x80) PORTD |= (1 << DS); // send 1
			else PORTD &= ~(1 << DS); // send 0
		PORTD |= (1 << SCL); // Shift Clock HI
		PORTD &= ~(1 << SCL); // Shift Clock LOW
		output<<=1;
		}
	PORTD |= (1 << E); // Latch Clock HI
	PORTD &= ~(1 << E); // Latch Clock LOW
	}
	
void wrt_display()
	{	
	uint8_t digit_num[]={0x20,0x10,0x08,0x04,0x02};
	uint8_t char_[]={0xED,0x28,0xB5,0xB9,0x78,0xD9,0xDD,0xA8,0xFD,0xF8,
					0xD5,0x00,0x10,0xD5,0x14,0xC5,0x3E,0xBE,0xBC,0x9B,0x08,0x22,0x9B,0xAB};	//  0-9, .C,None,-,E,r,C,.A,.H,.P,.S,.-,.1,.2,.3
					
	PORTC &=0x01; // display turn off	
	wrt_595(char_[(display>>(digit*5)) & 0x1f]);
	PORTC=(PORTC & 0x01)+digit_num[digit]; // display turn on
	digit++;	
	if(digit == 0x05) digit=0; 	
	}	
// ----------------------------------------------------------------------------------------------------------------
#define READ_TIME 0x64 // 100*2.5ms
#define ERROR_TIME 0x04 // 
#define SCK PD0 // Serial Data
#define CS PD1 // Shift Clock
#define SO PD2 // Latch Clock
uint16_t temp;
uint8_t read_time = 0; 
uint16_t error_time=0;
void read_max31855()
	{	
	uint16_t dataH;
	uint16_t dataL;
	
	if (!(read_time)) 
		{
		read_time=READ_TIME;
		dataH=0;
		dataL=0;
		PORTD &= ~(1<<CS);
		_delay_us(1);
		PORTD &= ~(1<<SCK);
		_delay_us(1);
		for (int i=31; i>=0; i--)
			{
			PORTD |= (1<<SCK);
			_delay_us(1);
			if(i>15 && PIND & (1<<SO)) dataH |= (1 << (i-16));
				else if (i<16 && PIND & (1<<SO)) dataL |= (1 << i);
			PORTD &= ~(1<<SCK);
			_delay_us(1);
			}
		PORTD |= (1<<CS); // new conversion enable ... ~0.25s
		if(dataH & 0x01)
			{
			//Err-1 - thermocouple is open (no connections)
			//Err-2 - thermocouple is short-circuited to GND
			//Err-3	- thermocouple is short-circuited to VCC
				
			error_time=ERROR_TIME;
			error_flag=((dataL & 0x07)/2+1)+0x14;
			display=0xD73980+error_flag; // Err-X, X-> 1,2,3
			}
			else
				{
				if(!error_time)
					{
					error_flag=0x00;
					temp=dataH>>4;	//
					if(!menu_flag && !(alarm_flag&0x03))
						{
						bin2display(temp);
						display+=0x0A; // .C
						if(temp<=0x384) display+= 0xb00000; // temp>=900.C = leading digit ON
						}	
					}
					else error_time--;		
				}								
		}
		else read_time--;
	}
	
void int_max31855()
	{
	PORTD |= (1<<CS); // conversion enable ... ~0.25s	
	_delay_ms(250);
	read_max31855();			
	}
// ----------------------------------------------------------------------------------------------------------------
#define Cx_min 0x01
#define Cx_max 0x03
#define Cx_step 0x0A // 
#define temp_min 0xFF38 // -200 .C
#define temp_max 0x546 // 1350 .C
#define hist_min 0x00 // 0 .C
#define hist_max 0x64 // 100 .C
#define activ_min 0x00 // 0.1s 
#define activ_max 0x3C // 60s
#define ALARM_FLAG_EE 0x32 // 50
int16_t Cx_data[5];
uint8_t Cx=0x01; // program num
uint8_t pass=0x00;
void alx_save()
	{
	if(blink_time_ & 0x80)
		{
		pass=(!pass) ? 0x01:pass;
		if(pass==1) 
			{
			if(!(alarm_flag & 0x80))  display=0xC63194; // -----
				else  
					{
					if(ALx_data[0]<0)
						{
						bin2display(ALx_data[0]*-1);
						display+=0xC00000;
						}
					else bin2display(ALx_data[0]);
					display+=0x0A;
					}
			}			
			else
				{
				alarm_flag^=0x03; // 
				pass=0;
				}
		}
		else
			{
			if(pass==1) pass=0x02;
			display=0xB5AD6B; // NNNNN N->NONE
			}	
	}
void set_alarm(uint8_t key)
	{
	blink_time();	
	if(!(alarm_flag & 0x02))
		{
		uint8_t ALx;
		ALx=((alarm_flag & 0x1C)>>2)/2+1;
		if(!(alarm_flag & 0x80))
			{ // alarm is OFF
			display=ALx;
			display=display*0x8000+0xF03171; // Cx-NA , N->NONE
			}
		if(key)
			{
			if(key==PROG && !(alarm_flag & 0x80)) alarm_flag =0x00 ;
				else 
					{
					if((((alarm_flag & 0x1C)>>2) ^ 0x07) == key>>3)
						{ // alarm ON || OFF
						if(alarm_flag & 0x80)
							{ // turn OFF alarm
							alarm_flag=0x03;
							eeprom_write_byte((uint8_t*)ALARM_FLAG_EE , 0x00);	
							alarm_out_off();
							}
							else
								{ // turn ON alarm
								alarm_flag+=0x80; // 0x80 ->AL ON,
								eeprom_write_byte((uint8_t*)ALARM_FLAG_EE , alarm_flag);
								eeprom_read_block ((void*) ALx_data , (const void*) ((ALx -1) * Cx_step) , Cx_step) ;	
								alarm_flag+=0x02; //  0x02 -> alx_save()								
								}
						PORTC &=0x01; // display off
						blink_time_=0x01; // reset blink time
						}
						else alarm_flag^=0x01;
					}					
			}	
		}
		else alx_save();		
	}
void cx_save()
	{
	if(!(menu_flag & 0x20))
		{
		PORTC &=0x01; // display off 
		menu_flag=0x3F;
		blink_time_=0x01; // reset blink time
		eeprom_update_block((const void*) Cx_data,(void*) ((Cx-1) * Cx_step) ,Cx_step);
		}
	if(blink_time_ & 0x80)
		{
		pass=(!pass) ? 0x01:pass;
		if(pass==1) display=0xC63194; // -----	
			else
			{
			menu_flag=0; // menu out
			pass=0; 
			}			 
		}
		else
			{
			if(pass==1) pass=0x02;	
			display=0xB5AD6B; // NNNNN N->NONE	
			}
	}
void set_act_time(uint8_t key)
	{
	if(!(menu_flag & 0x10))
		{
		if(key)
			{
			if(key==PROG) menu_flag =0x07 ;
				else if (key==UP)
					{
					Cx_data[2]++;
					if(Cx_data[2]==(activ_max+1)) Cx_data[2]=activ_min;
					}
					else if(key==DOWN)
						{
						Cx_data[2]--;
						if(Cx_data[2]==(activ_min-1)) Cx_data[2]=activ_max;
						}
						else menu_flag=0x1F; // SET
			}
		bin2display(Cx_data[2]);
		display+=0xB58000;
		display+=(blink_time_ & 0x80) ? 0x0B:0x11;
		}
		else cx_save();
	}
	
void set_hist(uint8_t key )
	{
	if(!(menu_flag & 0x08))
		{
		if(key)
			{
			if(key==PROG) menu_flag =0x03 ;
				else if (key==UP)
					{
					Cx_data[1]++;
					if(Cx_data[1]==(hist_max+1)) Cx_data[1]=hist_min;
					}
					else if(key==DOWN)
						{
						Cx_data[1]--;
						if(Cx_data[1]==(hist_min-1)) Cx_data[1]=hist_max;
						}
						else menu_flag=0x0F; // SET
			}
		bin2display(Cx_data[1]);
		display+=0xB00000;
		display+=(blink_time_ & 0x80) ? 0x0B:0x10;
		}
		else set_act_time(key);		
	}
	
void set_temp(uint8_t key )
	{
	if(!(menu_flag & 0x04))
		{
		if(key)
			{
			if(key==PROG)
				{
				menu_flag =0x01 ; // one step back
				up_down_time=0x00; // off UP DOWN speed
				}
				else if (key==UP)
					{
					Cx_data[0]++;
					if(Cx_data[0]==(temp_max+1)) Cx_data[0]=temp_min;
					}
					else if(key==DOWN)
						{
						Cx_data[0]--;
						if(Cx_data[0]==(temp_min-1)) Cx_data[0]=temp_max;
						}
						else menu_flag=0x07; // SET
			}
		if(Cx_data[0]<0)
			{
			bin2display(Cx_data[0]*-1);
			display+=0xC00000;
			}
			else bin2display(Cx_data[0]); 
		display+=(blink_time_ & 0x80) ? 0x0B:0x0A;
		}
		else set_hist(key);		
	}
void set_prog(uint8_t key)
	{
	blink_time();
	if(!(menu_flag & 0x02))
		{
		if(key)
			{
			if(key==PROG) menu_flag =0 ;
				else if (key==UP)
					{
					Cx++;
					if(Cx==(Cx_max+1)) Cx=Cx_min;	
					}	
					else if(key==DOWN)
						{
						Cx--;
						if(Cx==(Cx_min-1)) Cx=Cx_max;
						}
						else
							{ // SET
							menu_flag=0x03;
							up_down_time=0x01; // enable speed UP DOWN 
							eeprom_read_block ((void*) Cx_data , (const void*) ((Cx -1) * Cx_step) , Cx_step) ;	
							}	
			}
		display=Cx;
		display=display*0x8000 + 0xF02D6B; // CxNNN  N-NONE		
		}	
		else set_temp(key); 
	}
void menu()
	{
	uint8_t key=scan_key();
	
	if(menu_flag) set_prog(key);
		else if(alarm_flag & 0x03)	set_alarm(key);		
			else if(key)
				{
				if(key==PROG && (!(alarm_flag & 0x80))) menu_flag = 0x01 ;
					else 
						{
						if(!(error_flag))
							{
							if(alarm_flag & 0x80)
								{
								alarm_flag+=0x01;
								key_flag=0; // reset key press	
								}
								else alarm_flag=(key>>1)^0x1F;
							}													
						}						 						
				blink_time_ = 0x01; // reset blink time
				}
	}
// ----------------------------------------------------------------------------------------------------------------
#define AL_ACTIV_TIME 0x190;
uint16_t activ_time = AL_ACTIV_TIME // 2.5ms*400= 1s
void alarm()
	{
	if(alarm_flag & 0x80)
		{
		if(!(error_flag))
			{				
			if(!(alarm_flag & 0x40))
				{ // 
				activ_time=ALx_data[2]*AL_ACTIV_TIME;
				alarm_flag^=0x40;
				if(temp<ALx_data[0]) 
					{
					alarm_out_on();
					alarm_flag^=0x20;
					}				
					else alarm_out_off();
				}
			if(alarm_flag & 0x20)
				{
				if(temp>=ALx_data[0])
					{
					if(!(activ_time))
						{
						alarm_flag^=0x20;
						alarm_out_off();	
						}
						else activ_time--;	
					}
					else activ_time=ALx_data[2]*AL_ACTIV_TIME;	
				}
				else
					{
					if(temp<=(ALx_data[0]-ALx_data[1])) // (temp-hist)
						{
						if(!(activ_time))
							{
							alarm_flag^=0x20;
							alarm_out_on();
							}
							else activ_time--;	
						}
						else activ_time=ALx_data[2]*AL_ACTIV_TIME;	
				}
			}
			else
				{
				alarm_flag=0x00;
				alarm_out_off();
				}
		}
	}
	
void int_alarm()
	{
	uint8_t ALx;
	
	alarm_flag=eeprom_read_byte((const uint8_t*) ALARM_FLAG_EE);
	ALx=((alarm_flag & 0x1C)>>2)/2+1;
	if(alarm_flag) eeprom_read_block ((void*) ALx_data , (const void*) ((ALx -1) * Cx_step) , Cx_step) ;
	}
// ----------------------------------------------------------------------------------------------------------------
	
ISR(TIMER0_OVF_vect ) 
    { // ~2.5ms		
	TCNT0=0xEB;
	read_max31855();
	menu();	
	alarm();
	reset();
	wrt_display();	
	}
int main (void)
    {
    DDRC = 0b00111111;
    PORTC = 0b00000000;
    DDRB = 0b00000011;
    PORTB = 0b00111100;
    DDRD = 0b11111011;
    PORTD = 0b00000100;
	_delay_ms(100);
	EEARH = 0x00;
	TCCR0 = (1 << CS00) | (1 << CS02);
	TIMSK = (1<<TOIE0);
	int_max31855();
	int_alarm();
    TCNT0=0xEB;
	sei();
    while(1)
        {
			
						
        }
    }
	
// END

 

Post a comment
0
Comments | Add yours
  • No comments found
Free visitor tracking, live stats, counter, conversions for Joomla, Wordpress, Drupal, Magento and Prestashop