📄 gsmexa_1.c
字号:
// 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 + -