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

📄 main.c

📁 软USB核的电力开关PowerSwitch
💻 C
字号:
/* Name: main.c * Project: PowerSwitch based on AVR USB driver * Author: Christian Starkjohann * Creation Date: 2005-01-16 * Tabsize: 4 * Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH * License: Proprietary, free under certain conditions. See Documentation. * This Revision: $Id: main.c 20 2005-02-20 16:39:43Z cs $ */#include <avr/io.h>#include <avr/signal.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/wdt.h>#include "usbdrv.h"#include "oddebug.h"/*This module implements an 8 bit parallel output controlled via USB. It isintended to switch the power supply to computers and/or other electronicdevices.Application examples:- Rebooting computers located at the provider's site- Remote switch on/off of rarely used computers- Rebooting other electronic equipment which is left unattended- Control room heating from remote*/#ifndef TEST_DRIVER_SIZE	/* define this to check out size of pure driver */#define	EEPROM_LOCATION	37static uchar	actionTimers[8];/* This is the AT90S2313 version of the routine. Change for others. */static void	outputByte(uchar b){	PORTB = (PORTB & ~0xfc) | (b & 0xfc);	PORTD = (PORTD & ~0x30) | ((b << 4) & 0x30);}static void	eepromWrite(unsigned char addr, unsigned char val){	while(EECR & (1 << EEWE));	EEARL = addr;	EEDR = val;	cli();	EECR |= 1 << EEMWE;	EECR |= 1 << EEWE;	/* must follow within a couple of cycles -- therefore cli() */	sei();}static uchar	eepromRead(uchar addr){	while(EECR & (1 << EEWE));	EEARL = addr;	EECR |= 1 << EERE;	return EEDR;}static uchar	computeTemporaryChanges(void){uchar	i, status = 0, mask = 1;	for(i=0;i<8;i++){		if(actionTimers[i])			status |= mask;		mask <<= 1;	}	return status;}static void	computeOutputStatus(void){uchar	status = eepromRead(EEPROM_LOCATION) ^ computeTemporaryChanges();	outputByte(status);}/* we poll for the timer overflow interrupt because we don't want to write * an assembler routine. If the compiler creates an interrupt signal * function, we can't re-enable interrupts before registers are pushed. */static void	timerInterrupt(void){static uchar	prescaler;uchar			i;	if(!prescaler--){		prescaler = 8;	/* rate = 12M / 1024 * 256 * 9 */		for(i=0;i<8;i++){			if(actionTimers[i])				actionTimers[i]--;		}		computeOutputStatus();	}}uchar	usbVendorSetup(uchar data[8], uchar *replyBuf){uchar	status = eepromRead(EEPROM_LOCATION);	if(data[1] == 0){		/* ECHO */		replyBuf[0] = data[2];		replyBuf[1] = data[3];		return 2;	}	if(data[1] == 1){		/* GET_STATUS -> result = 2 bytes */		replyBuf[0] = status;		replyBuf[1] = computeTemporaryChanges();		return 2;	}	if(data[1] == 2 || data[1] == 3){	/* SWITCH_ON or SWITCH_OFF, index = bit number */		uchar bit = data[4] & 7;		uchar mask = 1 << bit;		uchar needChange, isOn = status & mask;		if(data[1] == 2){	/* SWITCH_ON */			status |= mask;			needChange = !isOn;		}else{				/* SWITCH_OFF */			status &= ~mask;			needChange = isOn;		}		if(data[2] == 0){		/* duration == 0 -> permanent switch */			actionTimers[bit] = 0;			eepromWrite(EEPROM_LOCATION, status);		}else if(needChange){	/* temporary switch: value = duration in 200ms units */			actionTimers[bit] = data[2];		}	}	computeOutputStatus();	return 0;}int	main(void){uchar	i, j;	WDTCR = 0xd;		/* set watchdog to 512k cycles (~1s) */	odDebugInit();	DDRD = ~(1 << 2);	/* all outputs except PD2 = INT0 */	PORTD = 0;	PORTB = 0;			/* no pullups on USB pins */	DDRB = ~0;			/* output SE0 for USB reset */	computeOutputStatus();	/* set output status before we do the delay */	j = 0;	while(--j){			/* USB Reset by device only required on Watchdog Reset */		i = 0;		while(--i);		/* delay >10ms for USB reset */	}	DDRB = ~USBMASK;	/* all outputs except USB data */	TCCR0 = 5;			/* set prescaler to 1/1024 */	usbInit();	sei();	for(;;){	/* main event loop */		wdt_reset();		usbPoll();		if(TIFR & (1 << TOV0)){			TIFR |= 1 << TOV0;	/* clear pending flag */			timerInterrupt();		}	}	return 0;}#else	/* TEST_DRIVER_SIZE *//* This is the minimum do-nothing function to determine driver size. The * resulting binary will consist of the C startup code, space for interrupt * vectors and our minimal initialization. The C startup code and vectors * (together ca. 70 bytes of flash) can not directly be considered a part * of this driver. The driver is therefore ca. 70 bytes smaller than the * resulting binary due to this overhead. The driver also contains strings * of arbitrary length. You can save another ca. 50 bytes if you don't * include a textual product and vendor description. */uchar	usbVendorSetup(uchar data[8], uchar *replyBuf){	return 0;}int	main(void){	PORTD = 0;	PORTB = 0;			/* no pullups on USB pins */	DDRD = ~(1 << 2);	/* all outputs except PD2 = INT0 */	DDRB = ~USBMASK;	/* all outputs except USB data */	usbInit();	sei();	for(;;){	/* main event loop */		usbPoll();	}	return 0;}#endif	/* TEST_DRIVER_SIZE */

⌨️ 快捷键说明

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