⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsmexa_1.c

📁 AVR MCU application to control valves and pumps
💻 C
📖 第 1 页 / 共 3 页
字号:
// Project: AVR MCU application to control valves and pumps
// Chip type:ATmega32L
// Crystal: 8.0000Mhz



#include <iom16v.h>
#include <macros.h>
#include <slavr.h>
#include <eeprom.h>

//#define PD7 24LC64_WP
//#define PD5 RF_OUT
//#define PD6 RF_EN

#define I2C_START 0x08
#define I2C_RESTART 0x10
#define I2C_MTA_ACK 0x18
#define I2C_MTD_ACK 0x28
#define I2C_MRA_ACK 0x40
#define I2C_MRD_ACK 0x50
#define EEPROM_W 0xa0
#define EEPROM_R 0xa1

#define ADC_VREF_TYPE 0x00
#define ADC_NUM 0x08

//#define PB0 DS1302_SCLK 
//#define PB1 DS1302_IO 
//#define PB2 DS1302_RST 

#define RDS1302_YEAR 0x8d
#define WDS1302_YEAR 0x8c
#define RDS1302_MONTH 0x89
#define WDS1302_MONTH 0x88
#define RDS1302_WEEKDAY 0x8b
#define WDS1302_WEEKDAY 0x8a
#define RDS1302_DATE 0x87
#define WDS1302_DATE 0x86
#define RDS1302_HOUR 0x85
#define WDS1302_HOUR 0x84
#define RDS1302_MINUTE 0x83
#define WDS1302_MINUTE 0x82
#define RDS1302_SECOND 0x81
#define WDS1302_SECOND 0x80

#define PROGRAM1_OFFSET1 0x1
#define PROGRAM1_OFFSET2 0x1
#define PROGRAM1_OFFSET3 0x1
#define PROGRAM1_OFFSET4 0x1
#define PROGRAM1_OFFSET5 0x1
#define PROGRAM1_OFFSET6 0x1
#define PROGRAM1_OFFSET7 0x1
#define PROGRAM1_OFFSET8 0x1

#define PROGRAM0_OFFSET1 0x1
#define PROGRAM0_OFFSET2 0x1
#define PROGRAM0_OFFSET3 0x1
#define PROGRAM0_OFFSET4 0x1
#define PROGRAM0_OFFSET5 0x1
#define PROGRAM0_OFFSET6 0x1
#define PROGRAM0_OFFSET7 0x1
#define PROGRAM0_OFFSET8 0x1
#define PROGRAM_OFFSET1 0x1
#define PROGRAM_OFFSET2 0x1

#define RENT_OFFSET1 0x1
#define RENT_OFFSET2 0x1
#define RENT_OFFSET3 0x1
#define RENT_OFFSET4 0x1
#define RENT_OFFSET5 0x1
#define RENT_OFFSET6 0x1
#define RENT_OFFSET7 0x1
#define RENT_OFFSET8 0x1
#define RENT_OFFSET9 0x1
#define RENT_OFFSET10 0x1
#define RENT_OFFSET11 0x1
#define RENT_OFFSET12 0x1
#define RENT_OFFSET13 0x1

#define CLOSE_OFFSET1 0x1
#define CLOSE_OFFSET2 0x1
#define CLOSE_OFFSET3 0x1

#define OPEN_OFFSET1 0x1
#define OPEN_OFFSET2 0x1
#define OPEN_OFFSET3 0x1

#define DEL_OFFSET 0x1

#define HALT_OFFSET 0x1

#define START_OFFSET 0x1

#define DEL_OFFSET 0x1

#define ADD_OFFSET1 0x1
#define ADD_OFFSET2 0x1
#define ADD_OFFSET3 0x1
#define ADD_OFFSET4 0x1

#define PSW_OFFSET 0x1
#define RENP_OFFSET1 0x1
#define RENP_OFFSET2 0x1


#define VALVE_OPEN1 0x02
#define VALVE_OPEN2 0x08
#define VALVE_CLOSE1 0x01
#define VALVE_CLOSE2 0x06

#define UNICODE_0 0x0030//0
#define UNICODE_1 0x0031//1
#define UNICODE_2 0x0032//2
#define UNICODE_3 0x0033//3
#define UNICODE_4 0x0034//4
#define UNICODE_5 0x0035//5
#define UNICODE_6 0x0036//6
#define UNICODE_7 0x0037//7
#define UNICODE_8 0x0038//8
#define UNICODE_9 0x0039//9
#define UNICODE_X 0x0058//X
#define UNICODE_STAR 0x002a//*
#define UNICODE_WELL 0xff03//#
#define UNICODE_QUESTION 0xff1f//?
#define UNICODE_COMMA 0xff0c//,
#define UNICODE_SEMICOLON 0xff1b//;
#define UNICODE_FULLSTOP 0x3002//。
#define UNICODE_CAO 0x64cd//操
#define UNICODE_ZUO 0x4f5c//作
#define UNICODE_WAN 0x5b8c//完
#define UNICODE_CHENG 0x6210//成
#define UNICODE_FA 0x9600//阀
#define UNICODE_BENG 0x6cf5//泵
#define UNICODE_ZHOU 0x5468//周
#define UNICODE_RI 0x65e5//日
#define UNICODE_YI 0x4e00//一
#define UNICODE_ER 0x4e8C//二
#define UNICODE_SAN 0x4e09//三
#define UNICODE_SI 0x56db//四
#define UNICODE_WU 0x4e94//五
#define UNICODE_LIU 0x516d//六
#define UNICODE_GUAN 0x5173//关
#define UNICODE_BI 0x95ed//闭
#define UNICODE_CHENG1 0x7a0b//程
#define UNICODE_XU 0x7e8f//序
#define UNICODE_KAI 0x5f00//开
#define UNICODE_QI 0x542f//启
#define UNICODE_LI 0x7acb//立
#define UNICODE_JI 0x5373//即
#define UNICODE_YUN 0x8fd0//运
#define UNICODE_XING 0x884c//行
#define UNICODE_ZENG 0x589e//增
#define UNICODE_BU 0x8865//补
#define UNICODE_QING 0x6e05//清
#define UNICODE_CHU 0x9664//除
#define UNICODE_QUAN 0x5168//全
#define UNICODE_GENG 0x66f4//更
#define UNICODE_GAI 0x6539//改
#define UNICODE_XIN 0x65b0//新
#define UNICODE_QUE 0x786e//确
#define UNICODE_REN 0x8ba4//认
#define UNICODE_MI 0x5bc6//密
#define UNICODE_MA 0x7801//码
#define UNICODE_CUO 0x9519//错
#define UNICODE_WU1 0x8bef//误
#define UNICODE_WEI 0x672a//未
#define UNICODE_BI1 0x6bd5//毕
#define UNICODE_XIAN 0x73b0//现
#define UNICODE_ZAI 0x5728//在
#define UNICODE_SHI 0x65f6//时
#define UNICODE_JIAN 0x95f4//间
#define UNICODE_NIAN 0x5e74//年
#define UNICODE_YUE 0x6708//月
#define UNICODE_SHI 0x65f6//时
#define UNICODE_MIAO 0x79d2//秒




//Structure of sensor: water_result is for data of ADC, water_threshold decides the action of valves
//valve_open and pump_open show IDs of valves and pumps with sensors
struct sensor_structure
{
	int water_result[8][5];
	int water_threshold;
	unsigned char attend_valve[8];
}sensor;

//Structure of valve: address means ID and action means operation of valve
struct valve_structure
{
	int address;
	int action;
}valve;

//Structure of time: year, month, weekday, date, hour, minute, second
//time_now is result of reading DS1302, time_order is time of program order sent
struct time_structure
{
	unsigned char second;
	unsigned char minute;
	unsigned char hour;
	unsigned char date;
	unsigned char month;
	unsigned char weekday;
	unsigned char year;
}time_now,time_order;

int rec_order[65];//Buffer of received order
int rf_counter1;//Counter for pulses of a order to open/close a valve
int rf_counter2;//Counter for pulses of a bit
int rf_time;//The lasted time to open a valve or pump
unsigned char rf_flag;//Denote if rf sending of a valve complete
unsigned char address_offset;//Used to be the counter of valve
unsigned char valve_totalold;//Used to remember valve_total
unsigned char valve_total;//Used to be total number of valves operated
unsigned char program0_total;//Used for Add_Program order
unsigned char program1_total;//Used for Add_Program order
unsigned char valve_closetime[64][4];//Used to store closetime for valve
unsigned char valve_statusnow;//Used to check status of valve
unsigned char program_num;//Denote the program
unsigned char rf_type;//Denote the parts of program in rf pulses' sending
unsigned char adc_mux;//Denote the channel of ADC
unsigned char password[4];//Denote the 4 passwords
unsigned char password_input[4];//Buffer of password
unsigned char password_flag1;
unsigned char password_flag2;
unsigned char bit_status;//1 or 0
unsigned char valve_status[8];//The status of switches,1 for open and 0 for close
unsigned char bug[2][18];
unsigned char device_flag;
//Structure of program: day means: in program0, days interval; in program1, weekday
//time1 is the first hour:minute to open valves and pumps
//time2 is the second hour:minute to open valves and pumps
//valve[0][] means ID of valves or pumps
//valve[1][] means lasting time of valves and pumps
struct program_structure
{
	unsigned char day;//When program1,weekday:retain,sunday,saturday,friday,thursday,wednesday,tuesday,monday
	unsigned char time1[4];
	unsigned char time2[4];
	int valve[2][64];
};
struct program_structure program[2];//Denote the program structure in SRAM

#pragma data:eeprom
int discard=0x0000;
unsigned char bak_bug[2][18]={{1,9,7,7,0,4,0,4,1,9,7,4,1,0,1,0,3,1},{1,9,7,4,1,0,1,0,3,1,1,9,7,4,0,4,0,4}};
unsigned char bak_device_flag;
unsigned char bak_password;
struct program_structure bak_program[2];
#pragma data:data



//Function
//Ports initialisation: direction and status
void port_init(void)
{
	PORTA = 0xFF;
	DDRA  = 0x00;
	PORTB = 0xFF;
	DDRB  = 0x01;
	PORTC = 0xFF; //m103 output only
	DDRC  = 0x00;
	PORTD = 0xFF;
	DDRD  = 0x00;
}

//Timer1 initialisation: create pulses of 90us interval for a bit to rf output
void timer1_init(void)
{
	TIMSK=0x80;
	TCCR1B=0x00;
	OCR1AH=0x00;
	OCR1AL=0x00;
	OCR1BH=0x00;
	OCR1BL=0x00;
	TCCR1A=0x00;
}

//Watchdog initialisation
//prescale: 16K cycles
void watchdog_init(void)
{
	WDR(); //this prevents a timout on enabling
	WDTCR = 0x08; //WATCHDOG ENABLED - dont forget to issue WDRs
}

// TWI initialisation
// bit rate:1
void twi_init(void)
{
	TWCR= 0X00; //disable twi
	TWBR= 0x01; //set bit rate
	TWSR= 0x00; //set prescale
	TWAR= 0x02; //set slave address
	TWCR= 0x44; //enable twi
}

void uart0_init(void)
{
	UCSRB = 0x00; //disable while setting baud rate
	UCSRA = 0x00;
	UCSRC = 0x00;
	UBRRL = 0x33; //set baud rate lo
	UBRRH = 0x00; //set baud rate hi
	UCSRB = 0x98;
}


//Write a byte(8bits) to DS1302
void DS1302input_byte(unsigned char ucdat)
{
	unsigned char i;
	DDRB |= 0x02;//Set DS1302_IO as output
	for(i=8;i>0;i--)
	{
		if (ucdat & 0x01)
		{
			PORTB |= 0x02;
		}
		else
		{
			PORTB &= 0xfd;
		}
		PORTB |= 0x01;//DS1302_SCLK=1
		asm("nop");
		PORTB &= 0xfe;//DS1302_SCLK=0
		ucdat>>=1;
	}
}

//Read a byte(8bits) from DS1302
unsigned char DS1302output_byte(void)
{
	unsigned char i;
	unsigned char ucdat=0;
	DDRB &= 0xfd;//Clear DS1302_IO as input
	for(i=8;i>0;i--)
	{
		ucdat>>=1;
		if(PORTB & 0x02)
		{
			ucdat |=0x80;
		}
		PORTB |= 0x01;//DS1302_SCLK=1
		asm("nop");
		PORTB &= 0xfe;//DS1302_SCLK=0
	}
	return(ucdat);
}

//Write a byte to DS1302, address is destination and ucdat is content
void write_DS1302(unsigned char address,unsigned char ucdat)
{
	PORTB &= 0xfb;//DS1302_RST=0
	PORTB &= 0xfe;//DS1302_SCLK=0
	PORTB |= 0x04;//DS1302_RST=1
	DS1302input_byte(address);
	DS1302input_byte(ucdat);
	PORTB |= 0x01;//DS1302_SCLK=1
	PORTB &= 0xfb;//DS1302_RST=0
}

//Read a byte from DS1302, address is destination of data required
unsigned char read_DS1302(unsigned char address)
{
	unsigned char ucdat;
	PORTB &= 0xfb;//DS1302_RST=0
	PORTB &= 0xfe;//DA1302_SCLK=0;
	PORTB |= 0x04;//DS1302_RST=1
	DS1302input_byte(address);
	ucdat=DS1302output_byte();
	PORTB |= 0x01;//DS1302_SCLK=1
	PORTB &= 0xfb;//DS1302_RST=0
	return(ucdat);
}

//Set the time in DS1302, address is offset of content, p_DS1302 is pointer of content, n is the number of content written
void set_DS1302(unsigned char address,unsigned char *p_DS1302,unsigned char n)
{
	write_DS1302(0x8e,0x00);
	for(n=n;n>0;n--)
	{
		write_DS1302(address,*p_DS1302);
		p_DS1302++;
		address+=2;
	}
	write_DS1302(0x8e,0x80);
}

//Get the format of time:second, minute, hour, date, month, weekday, year, the function is unused
unsigned char get_DS1302(unsigned char address,unsigned char *p_DS1302,unsigned char n)
{
	for(n=n;n>0;n--)
	{
		*p_DS1302=read_DS1302(address);
		address+=2;
		p_DS1302++;
	}
	return(*p_DS1302);
}

//DS1302 initialisation
void DS1302_init(void)
{
	DDRB |= 0x02;//Set DS1302_IO as output
	PORTB &= 0xfe;//DS1302_SCLK=0
	PORTB &= 0xfb;//DS1302_RST=0
	write_DS1302(0x8e,0x00);
	write_DS1302(0x90,0x00);
}

void init_devices(void)
{
 //stop errant interrupts until set up
	CLI(); //disable all interrupts
	port_init();
	watchdog_init();
	twi_init();
	uart0_init();
	adc_init();
	time1_init();
	DS1302_init();


	MCUCR = 0x00;
	GICR  = 0x00;
	TIMSK = 0x00; //timer interrupt sources
	SEI(); //re-enable interrupts
 //all peripherals are now initialised
}

//Check the satus of valve
void check_valve(unsigned char valve_num)
{
	unsigned char a,b;
	a=valve_num>>3;
	b=valve_num-(8*a);
	if ((valve_status[a] & (0x01<<b))==0)
	{
		valve_statusnow=0;
	}
	else
	{
		valve_statusnow=1;
	}
}

//Set the bit of valve[]
void set_valve(unsigned char valve_num)
{
	unsigned char a,b;
	a=valve_num>>3;
	b=valve_num-(8*a);
	valve_status[a] |=(0x01<<b);
}

//Clear the bit of valve[]
void clr_valve(unsigned char valve_num)
{
	unsigned char a,b;
	a=valve_num>>3;
	b=valve_num-(8*a);
	valve_status[a] &=~(0x01<<b);
}

//Dealling with accidents in rf output
void rf_error(void)
{
}
//Set a bit: 1
void rf_1(void)
{
	if (rf_counter2<16)
	{
		if (rf_counter2<12)
		{
			bit_status=1;
		}
		else 
		{
			bit_status=0;
		}
		rf_counter1+=1;
		rf_counter2+=1;
		if (rf_counter2==16)
		{
			rf_counter2=0;
		}
	}
}

//Set a bit: 0
void rf_0(void)
{
	if (rf_counter2<16)
	{
		if (rf_counter2<4)
		{
			bit_status=0;
		}
		else 
		{
			bit_status=1;
		}
		rf_counter1+=1;
		rf_counter2+=1;
		if (rf_counter2==16)
		{
			rf_counter2=0;
		}
	}
}

//Set a bit decided by parameter
void rf_bit(int a)
{
	if (a==1)
	{
		rf_1();
	}
	else 
	{
		rf_0();
	}
}

//Set bits to get synchronizating with rf
void rf_syn(void)
{
	if (rf_counter1<128)
	{
		if (rf_counter1<4)
		{
			bit_status=1;
		}
		else 
		{
			bit_status=0;
		}
		rf_counter1+=1;
	}
	else 
	{	switch ((rf_counter1-128)>>4)
		{
			case 0: rf_1();break;
			case 1: rf_0();break;
			case 2: rf_1();break;
			case 3: rf_0();break;
			case 4: rf_1();break;
			case 5: rf_0();break;
			case 6: rf_1();break;
			case 7: rf_1();break;
			default: rf_error();
		}
	}
	if (rf_counter1==256)
	{
		rf_type=2;
	}	
}

//Set bits of ID of valves or pumps
void rf_address(void)
{
	switch (((rf_counter1-256)>>4))
	{
		case 0: rf_bit(((valve.address>>11))&0x01);break;
		case 1: rf_bit(((valve.address>>10))&0x01);break;
		case 2: rf_bit(((valve.address>>9))&0x01);break;
		case 3: rf_bit(((valve.address>>8))&0x01);break;
		case 4: rf_bit(((valve.address>>7))&0x01);break;
		case 5: rf_bit(((valve.address>>6))&0x01);break;
		case 6: rf_bit(((valve.address>>5))&0x01);break;
		case 7: rf_bit(((valve.address>>4))&0x01);break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -