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

📄 rc24g.c

📁 M8控制cc2500,usb无线接口
💻 C
📖 第 1 页 / 共 2 页
字号:
	PCICR |= _BV(PCIE1);
	PCMSK1 |= _BV(PCINT13);
	
    DDRB &= ~_BV(PB0);             			// 设置ICP1口为输入		
	
}

void Beep_ON()
{

	OCR0A = 128;
	TCCR0A = _BV(COM0A1) | _BV(COM0A0) | _BV(WGM02) | _BV(WGM00);
	TCCR0B = _BV(CS01);

}

void Beep_OFF()
{

	TCCR0A = 0x00;
	TCCR0B = 0x00;
	
	PORTD &= ~_BV(PD6);
	
}


//-----------------------------------------------------------------------------
// 解码时标
//
// XTAL = 8,000,000 Hz (timer input frequency), prescaler = 8
// ppmLength (uS) = Timer / TCNT_CYCLES, where TCNT_CYCLES=8
//
// Timer = 20000 uS (PPM帧长度)
//         3000 uS (同步信号长度)
//         700 uS (通道最小值脉宽长度)
//         1500 uS (通道中值脉宽长度)
//         2200 uS (通道最大值脉宽长度)


//-----------------------------------------------------------------------------
//
// 初始化PPM解码
//
void inDecoderInit(void)
{

    TCCR1A  = 0;            						// 16位计数器1,为主频的1分频
    TCCR1B  = _BV(ICES1) | _BV(CS11);				// 普通计数模式, 上升沿触发	
	TCCR1C	= 0;
    TIFR1  |= _BV(ICF1);           				 	// 重置捕获中断标志
    TIMSK1 |= _BV(ICIE1);           				// 使能捕获中断

}

//
// 停止PPM解码中断
//
void inDecoderStop(void)
{
    TIMSK1 &= ~_BV(ICIE1);          // 关闭捕获中断
    TIFR1  |= _BV(ICF1);            // 重置捕获中断标志
}

//
// 边沿信号捕获中断
//
SIGNAL(SIG_INPUT_CAPTURE1)
{
    static uint16_t ppmData[MAX_CHANNELS];  // 临时通道数据缓冲
    static unsigned char ppmChannel;        // PPM通道计数
    static uint16_t timerLast;              // 最近捕获的定时器值
    uint16_t timer;                         // 当前捕获的定时器值
    uint16_t timerDiff;                     // 上述两者之差
    uint16_t ppmLength;                     // 以uS为单位表示的PPM脉冲长度值

	unsigned char i;

    // 计算脉冲长度
    timer     = ICR1;
    timerDiff = timer - timerLast;
    timerLast = timer;
	ppmLength = timerDiff;

    // 如果发现同步信号则开始处理整个PPM信号帧,
    // 否则简单地把通道信号长度保存到临时缓冲中
    if (ppmLength < 6000)
    {
        // 捕获到下一个通道信号
        if (ppmChannel < MAX_CHANNELS) ppmData[ppmChannel] = ppmLength;
        ppmChannel++;

    }
    else
    {
        // 帧结束
 
        // 将临时通道数据缓冲的值拷贝出来
        if (ppmChannel)
        {
            // 只关心到设定的最大通道值
            if (ppmChannel > MAX_CHANNELS) ppmChannel = MAX_CHANNELS;

            // 拷贝每个通道值
            for (i = 0; i < ppmChannel; i++)
            {
                // 关中断保证操作的原子性
                cli();
                channelData[i] = ppmData[i];
                sei();
            }

            // 设置新数据标志为非零值 (数值=实际通道数)
            newDataFound = ppmChannel;
			
            // 准备解码下一个PPM帧
            ppmChannel = 0;
        }

     }
}

SIGNAL(SIG_PIN_CHANGE1) 
{ 
	
	if (isSetting == SETTING) {
		
		if ((PINC & _BV(PC5)) == 0) {
	 
			isSetting = SAVESETTING;

		}

	}

}

int main()
{

	uint8_t c, pc, crc;

	uint32_t tmp;

	// 关闭看门狗
	wdt_disable();

	cli();

	// 关闭模拟比较器
	ACSR |= _BV(ACD);
	
	// IO口初始化
	IO_Init();
	
	// 重置新数据标志
	newDataFound = 0;
	
	isSetting = 0;				
	
	// 初始化解码过程	
	inDecoderInit();                

	// 等待电源稳定,再进行E2PROM操作
	for (c = 0; c < 10; c++)
		_delay_ms(10);

	// 读设置值
	for (c = 0; c < MAX_CHANNELS; c++){

		eeprom_busy_wait();
		Min[c] = eeprom_read_word((uint16_t*)(2*c));
		eeprom_busy_wait();
		Max[c] = eeprom_read_word((uint16_t*)(2*c + 2*MAX_CHANNELS));

	}
	
	eeprom_busy_wait();
	crc = eeprom_read_byte((uint8_t*)(4*MAX_CHANNELS));

	if (crc != crc8_ibutton((uint8_t *)Min, MAX_CHANNELS)) {
		
		isSetting = SETTING;

	} else {

		eeprom_busy_wait();
		crc = eeprom_read_byte((uint8_t*)(4*MAX_CHANNELS + 1));
		if (crc != crc8_ibutton((uint8_t *)Max, MAX_CHANNELS)) {
			
			isSetting = SETTING;

		}
		

	}

	if (((PINC & _BV(PC5)) == 0) || (isSetting == SETTING)) {
		
		// 提示音,进入设置状态
		for (c = 0; c < 3; c++) {
		
			Beep_ON();
			_delay_ms(16);
			_delay_ms(16);
			Beep_OFF();
			
			for (pc = 0; pc < 24; pc ++) {
				_delay_ms(16);
				_delay_ms(16);
			}
		
		}

		isSetting = SETTING;

		for (c = 0; c < MAX_CHANNELS; c++) {

			Min[c] = 0xFFFF;
			Max[c] = 0x0000;
		
		}
			
	
	}

	// CC2500模块初始化
	SPI_Master_Init();
	
	CC2500_Init();

	sei();

	// 等待PPM信号发生电路开始工作
	while (newDataFound == 0);

	// 重置新数据标志		    
	newDataFound = 0;			
	

	if (isSetting == 0) {
	
		// 提示音,设备开始工作
		Beep_ON();
		_delay_ms(16);
		_delay_ms(16);
		Beep_OFF();
		
		// 设定开门狗周期为30mS		
		wdt_enable(WDTO_30MS);			
	
	}

	sei();

	pc = 0;

	while(1){

		wdt_reset();                // 喂狗
		
		while (newDataFound == 0);
	    
		newDataFound = 0;			// 重置新数据标志

		
		if (isSetting == SETTING) {
			
			for (c = 0; c < MAX_CHANNELS; c++) {
				
				if (channelData[c] > Max[c]) 
					Max[c] = channelData[c];
				
				if (channelData[c] < Min[c])
					Min[c] = channelData[c];
			
			}	


		} else if (isSetting == SAVESETTING) {

			isSetting = 0;
				
			for (c = 0; c < MAX_CHANNELS; c++) {
				eeprom_busy_wait();
				eeprom_write_word((uint16_t*)(2*c), Min[c]);

				Max[c] = Max[c] - Min[c];			
				eeprom_busy_wait();
				eeprom_write_word((uint16_t*)(2*c + 2*MAX_CHANNELS), Max[c]);
		
			}

			// 写入crc校验字节, 先写Min数组crc字节,后写Max数组crc字节
			crc = crc8_ibutton((uint8_t *)Min, MAX_CHANNELS);
			eeprom_busy_wait();
			eeprom_write_byte((uint8_t*)(4*MAX_CHANNELS), crc);
			
			crc = crc8_ibutton((uint8_t *)Max, MAX_CHANNELS);
			eeprom_busy_wait();
			eeprom_write_byte((uint8_t*)(4*MAX_CHANNELS + 1), crc);
			 

			// 设定开门狗周期为30mS		
			wdt_enable(WDTO_30MS);			


		} else	{
		
			// 处理数据,将四通道数据,每通道10位数据组成一个数据帧
			// 数据帧,CRC8检验码
		
			// 数据帧处理 
			package[MAX_CHANNELS] = 0;
			
			for (c = 0; c < MAX_CHANNELS; c++) {
			
				if (channelData[c] < Min[c]) {
					
					Max[c] = Max[c] + Min[c] - channelData[c];
					Min[c] = channelData[c];
					tmp = 0;
				
				} else if (channelData[c] > (Min[c] + Max[c])) {
					
					Max[c] = channelData[c] - Min[c];
					tmp = 1023;

				} else {

					tmp = (uint32_t)(channelData[c] - Min[c]) * 1023;
					tmp = tmp / Max[c];
				
				}

				package[c] = tmp >> 2;
				package[MAX_CHANNELS] += (tmp & 0x0003) << (2*c);
		
			}			

			// 数据累计记数器
			package[PACKAGE_LEN - 1] = pc;	

			// 发送数据包,3次
			halRfSendPacket((uint8_t *) package, PACKAGE_LEN);
			_delay_ms(3);
			halRfSendPacket((uint8_t *) package, PACKAGE_LEN);
			_delay_ms(3);
			halRfSendPacket((uint8_t *) package, PACKAGE_LEN);

			// 数据包累计记数器
			if (pc < 255)
				pc ++;
			else 
				pc = 0;	
		
		}

	
	}


}

⌨️ 快捷键说明

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