📄 water_caravr16.c
字号:
#include "iom16v.h"
#define uchar unsigned char
#define uint unsigned int
//I/O定义
#define hw38k 7 //PD7 O 38kOUT
#define key0 2 //PD2 I
#define key1 3 //PD3 I
#define key2 2 //PB2 I
#define cup 4 //PA4 I
#define dis_sck 5 //PA5 O
#define dis_cs 6 //PA6 O
#define dis_data 7 //PA7 O
#define mota 6 //PC6 O
#define motb 5 //PC5 O
#define ctra 4 //PC4 O
#define ctrb 3 //PC3 O
#define bell 6 //PD6 O
#define low_loc 2 //PA2 I
#define high_loc 3 //PA3 I
#define temp 0 //PA0 I
//变量 常量定义
#define wr_device_add 0x64 //时钟器件地址写命令
#define rd_device_add 0x65 //器件地址读命令
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_DATA_ACK 0x28
#define MR_SLA_ACK 0x40
#define MR_DATA_ACK 0x50
#define MR_DATA_NAK 0x58
#define Start() (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))
#define Stop() (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN))
#define Wait() {while(!(TWCR&(1<<TWINT)));}
#define TestAck() (TWSR&0xf8)
#define SetAck() (TWCR|=(1<<TWEA))
#define SetNoAck() (TWCR&=~(1<<TWEA))
#define Twi() (TWCR=(1<<TWINT)|(1<<TWEN))
#define Write8Bit(x) {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}
uchar key0_status=0x00; //按钮状态
uchar key1_status=0x00;
uchar key2_status=0x00;
uchar temp_value=0x00; //温度值
uchar data_temp,data_temp1, data_temp2;
const uchar default_time[14]={'2','0','0','6','0','6','0','6','0','6','0','6','0','6'};
uchar now_time[12];
uchar now_time_hex[6];
uchar timer_set;
uchar hw_commd_h; //红外通讯命令
uchar hw_commd_l;
uchar hw_rx_tx;
uchar hw_crc;
uchar hw_data_buffer[20]; //操作命令
///子程序
/* UART初始化, 红外接口 */
void uart_init(void)
{
UCSRB = 0xd8; //接收发送使能和中断允许
UBRRL = 23 ; //9600
UBRRH = 0x00 ; //
UCSRC = 0x86 ; //
}
/* 延时us 子程序 */
void delay_us(int time) //us delay
{
do
{
time--;
}
while (time>1);
}
/*延时ms子程序 ms delay */
void delay_ms(unsigned int time)
{
while(time!=0)
{
WDR();
delay_us(500);
time--;
}
}
//iic 初始化
void iic_init(void)
{
TWSR=00;
TWBR=0x16; //50K
}
//I/O口方向初始化
void io_init(void)
{
DDRA=0xe0;
DDRB=0x00;
DDRC=0x79;
DDRD=0xc2;
}
//红外
void USART0_Transmit( unsigned char data )
{
/* 等待发送缓冲器为空*/
do
{
WDR();
}
while ( !( UCSRA & (1<<UDRE)) );
/* 将数据放入缓冲器,发送数据*/
UDR = data;
}
//关闭看门狗
void WDT_off(void)
{
/* 置位WDCE 和WDE */
WDTCR = (1<<WDCE) | (1<<WDE);
/* 关闭WDT */
WDTCR = 0x00;
}
/******************************************
I2C总线写一个字节
返回0:写成功
返回非0:写失败
*******************************************/
unsigned char i2c_Write(unsigned char Wdata,unsigned int RomAddress)
{
Start();//I2C启动
Wait();
if(TestAck()!=START) return 1;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK) return 1;//ACK
Write8Bit(RomAddress);//写地址
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Write8Bit(Wdata);//写数据
Wait();
if(TestAck()!=MT_DATA_ACK) return 1;//ACK
Stop();//I2C停止
WDR();
delay_ms(10);//延时等待
return 0;
}
/******************************************
I2C总线读一个字节
如果读失败也返回0
*******************************************/
unsigned char i2c_Read(unsigned int RomAddress)
{
unsigned char temp;
Start();//I2C启动
Wait();
if (TestAck()!=START) return 0;//ACK
Write8Bit(wr_device_add);//写I2C从器件地址和写方式
Wait();
if (TestAck()!=MT_SLA_ACK) return 0;//ACK
// P--;
Write8Bit(RomAddress);//写地址
Wait();
if (TestAck()!=MT_DATA_ACK) return 0;
Start();//I2C重新启动
Wait();
if (TestAck()!=RE_START) return 0;
Write8Bit(rd_device_add);//写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK) return 0;//ACK
Twi();//启动主I2C读方式
Wait();
if(TestAck()!=MR_DATA_NAK) return 0;//ACK
temp=TWDR;//读取I2C接收数据
Stop();//I2C停止
WDR();
return temp;
}
//外部中断0服务程序,开关控制部分
#pragma interrupt_handler EXT_INT0_ISR: iv_INT0
void EXT_INT0_ISR (void) //INT0 中断
{
uchar temp;
temp=SREG;
delay_ms(10);
if(key0_status==0x00)
{
portc &=~(1<<mota);
portc |=(1<<motb);
portc |=(1<<ctra);
key0_status=0x11;
}
else
{
portc &=~(1<<motb);
portc |=(1<<mota);
portc &=~(1<<ctra);
key0_status=0x00;
}
SREG=temp;
}
//外部中断1服务程序,设置响应
#pragma interrupt_handler EXT_INT1_ISR: iv_INT1
void EXT_INT1_ISR (void) //INT1 中断
{
uchar temp;
temp=SREG;
set_sub();
SREG=temp;
}
//外部中断2服务程序,模式响应
#pragma interrupt_handler EXT_INT2_ISR: iv_INT2
void EXT_INT2_ISR (void) //INT2 中断
{
uchar temp;
temp=SREG;
if(key2_status==0x00)
{
portc &=~(1<<ctrb);
key2_status=0x11;
}
else
{
portc |=(1<<ctrb);
key2_status=0x00;
}
SREG=temp;
}
//测试,定时器2中断,用于产生38K的红外载波信号(用PWM更精确)
#pragma interrupt_handler timer2_ovf_isr:iv_TIMER2_OVF
void timer2_ovf_isr(void) //us定时中断
{
PORTD ^= (1<<hw38k);
}
//主程序
void main(void)
{
uchar i, j;
io_init();
uart_init();
twi_init();
MCUCR=0x0f; //INT0 ,INT1 上升沿
GICR =0xe0; //INT0,INT1,INT2 中断使能
MCUCSR=0x40; //INT2
ADMUX=0x40; //ADC 控制(水温)
TCNT2 = 0x96; //计数初值
TIFR |= (1<<TOV2) ; //TOV2 clr
TCCR2 = 0x01 ; //
TIMSK = 0x40;
SREG=0x80; //INT allow
//
EEPROM_read(0x10); //读出时钟设置状态
while(timer_set) //等待时钟设置
{
for(i=0;i<5;i++)
{
portd |=(1<<bell); //蜂鸣提醒设置
delay_ms(800);
portd &=~(1<<bell);
delay_ms(200);
//
}
wait_time_set();
}
while(1)
{
if(UCSRA & (1<<RXC))
{
j=UDR;
comm_deal();
}
else
{
}
//
switch(mode_bit)
{
case 0: add_water(); //上水
break;
case 1: heat_control(); //加热
break;
case 2: cold_control(); //制冷
break;
case 3: get_control(); //接水
break;
case 4: out_control(); //排水
break;
default: portc &=~(1<<motb);
portc |=(1<<mota);
portc &=~(1<<ctra);
key0_status=0x00;
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -