📄 210.c
字号:
#include <iot13v.h>
#include <macros.h>
#define uchar unsigned char
#define unit unsigned int
#define ulong unsigned long
#define xtal 8
int mark=1500;
unsigned int ai,aa;
unsigned char crc,i,j,flag=0,flagh=0,flagl,acount=0,bcount=0,PINBS;
unsigned char DECODER_CODE1,DECODER_CODE0;
unsigned char data[3];
unsigned char dataf[3];
//PB3是控制输出端口!
#define RF_ON PORTB |= (1 << PB2) //打开输出
#define RF_OFF PORTB &= ~(1 << PB2) //关闭输出
#define EN_ON PORTB |= (1 << PB1) //打开输出
#define EN_OFF PORTB &= ~(1 << PB1) //关闭输出
#define DOOR_IN PINTB =BIT(0)
//端口初始化
void port_init(void)
{
PORTB = 0x29; //输入设置有上拉电阻,输出预设低电平
DDRB = 0x0e; //PB4输出,PB3输入
}
//转换初始化
void adc_init(void)
{
ADCSRA=0x00; //
ADCMUX = 0x42; //片内作为模拟参考电压 选择ADC2通道
ACSR = (1 << ACD);//禁用模拟比较器
//使能ADC,终端允许,自由模式,时钟CLK/8
//0x86允许转换ADEN,ADSC,时钟128分频 75KHz@9.6MHz system clock
ADCSRA = (1 << ADEN) | 0x07;//| ( 1 << ADATE )
}
/*//看门狗初始化
void watchdog_init(void)
{
WDR(); //this prevents a timout on enabling
WDTCR=(1<<WDCE)|(1<<WDE);
WDTCR=(0<<WDE);
}*/
/* EEPROM 写入 */
void EEPROM_write(unsigned char uiaddress,unsigned char ucdata)
{
WDR();
while(EECR&(1<<EEWE)); /*等待上一次写操作结束*/
EEAR=uiaddress; /*设置地址寄存器*/
EEDR=ucdata;
EECR|=(1<<EEMWE);
EECR|=(1<<EEWE); /*置位EEMWE 置位EEWE以启动写操作*/
}
/* EEPROM 读取 */
unsigned char EEPROM_read(unsigned char uiaddress)
{
while(EECR&(1<<EEWE)); /*等待上一次写操作结束*/
EEAR=uiaddress; /*设置地址寄存器*/
EECR|=(1<<EERE); /*置位EEMWE 置位EEWE以启动读操作*/
return EEDR; /*自数据存贮器返回数据*/
}
/* 微秒级延时程序 */
void del(int time)
{
do
{
time--;
}
while (time>1);
}
/* 毫秒级延时程序 */
void delay_1ms(void)
{ unsigned int i1;
for(i1=1;i1<(unsigned int)(xtal*143-2);i1++)
;
}
void delay(unsigned int n)
{
unsigned int i2=0;
while(i2<n)
{delay_1ms();
i2++; WDR();
}
}
//从AD口读入一个值
unsigned int GetADC(void)
{
unsigned int adc_value;
DDRB|=(1<<PB3);
PORTB&=~(1<<PB3);
ADC = 0;
ADCSRA |= (1 << ADSC); //启动AD转换
del(10);
while(!(ADCSRA&(BIT(ADIF))));////ADIF=4, 表示若ADCSR的第5位置为1,则中断AD转换
//loop_until_bit_is_set(ADCSRA, ADIF);//等待AD转换结束
ADCSRA |= (1 << ADIF); //写1清除标志位
adc_value = ADC; //读转换结果
DDRB&=~(1<<PB3);
PORTB|=(1<<PB3);
return adc_value;
}
/******************************************
CRC3校验函数
输 入: ptr需要进行校验的数据包
len需要校验的数据包字节数
输 出: 校验码;
调 用: 无;
被调用: 从机协议打包函数;
功 能: 将一给定的数据包进行CRC3校验给调用者返回校验码
******************************************/
unsigned char CRC3(unsigned char *data, unsigned char len)
{
unsigned char i;
unsigned char j;
j = 0;
crc=0;
while(len)
{
/*多项式除法*/
if(*data & (0x80>>j)) //如果该位为1
crc |= 0x01; //则在余数尾部添1否则添0
if(crc >= 0x8)
crc ^= 11;
crc <<= 1;
j++;
if(len==1)
{
if(j == 7)
{
j = 0;
data++;
len--;
}
}
else
{
if(j == 8)
{
j = 0;
data++;
len--;
}
}
}
return(crc);
}
//地址计算
void addr_f(void)
{
unsigned char i;
unsigned char j; //data[0]data[1]地址
data[0]=EEPROM_read(0);
data[1]=EEPROM_read(1); //EEPORM内地址,最大FFFF
data[2]=0;
if(GetADC()<579) data[2]|=0x80; //2.5/(3.3/13.3)/(1.1/1024)=579
if(PINBS) data[2]|=0x40;
data[2]+=CRC3(data,3);
}
//要发送的数据1
void data_1(void)
{
RF_OFF;
del(700);
RF_ON;
del(350);
}
//要发送的数据0
void data_0(void)
{
RF_OFF;
del(350);
RF_ON;
del(700);
}
//发送数据
void rf (unsigned char *dataf)
{
unsigned char i;
unsigned char j;
RF_ON; //起始位
del(350);
for(i=0;i<3;i++)
{ for(j=0;j<8;j++)
{
if(*dataf & (0x80>>j)) //如果该位为1
data_1();
else data_0();
}
dataf++;
}
RF_OFF;
}
#pragma interrupt_handler PCINT0_ovf_isr:03
void PCINT0_ovf_isr(void) //中断程序
{
NOP();
}
//主函数!不用解释了
void main()
{
unsigned char i;
//以下初始化硬件
port_init(); //端口初始化
adc_init();
// watchdog_init();//初始化看门狗
SEI(); //re-enable interrupts
GetADC();
delay(10);
while(1)
{
if((!(PINB&0x08))||(!(PINB&0x01)))
{
WDR();
EN_ON;
addr_f();
for(i=0;i<50;i++)
{
dataf[0]=data[0];
dataf[1]=data[1];
dataf[2]=data[2];
rf(dataf);
delay(3);
}
EN_OFF;
}
GIMSK|=(1<<PCIE);
PCMSK|=(1<<PCINT0);
PCMSK|=(1<<PCINT3);
ADCSRA=0;
MCUCR |= BIT(SM1);
MCUCR |= BIT(SE);
asm("sleep\n"); //进入睡眠状态
NOP();
MCUCR=0;
delay(2);
if(!(PINB&0x08)) PINBS=1;
else PINBS=0;
GIMSK=0;
adc_init();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -