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

📄 main.c

📁 同为电脑遥控器
💻 C
字号:
//redKontroll version 1.0  fredrikolofsson.com//GNU GPL v2 - See the OBDEV license for further details.  (http://www.obdev.at/avrusb/)#include <avr/io.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <avr/wdt.h>#include <util/delay.h>#include "usbdrv.h"static void hardwareInit(void) {		//--set pins to output	DDRB= 0b00110000;						//output pins for shiftin	DDRD= 0b00000101;						//output pins for usb		//--internal pull-ups for inputs	PORTD= 0b11111010;	PORTB= 0b00001111;		//--setup adc	//ADCSRA |= (1<<ADPS0);					//prescale 2	//ADCSRA |= (1<<ADPS1);					//prescale 4	ADCSRA |= (1<<ADPS2);					//prescale 16	//ADCSRA |= ((1<<ADPS2)|(1<<ADPS0));	//prescale 32	ADCSRA |= (1<<ADEN);					//enable adc		//--reset usb	uchar i= 20;	while(i) {								//300ms		_delay_ms(15);		i--;	}	DDRD= 0;}static uchar reportBuffer[8];				/* buffer for HID reports */static uchar idleRate;						/* in 4 ms units */uchar changed= 0;uchar shiftIn(void);uchar encoderIn(uchar currPin, uchar lastPin, uchar a, uchar b);PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { //USB report descriptor	0x05, 0x01,        // USAGE_PAGE (Generic Desktop)	0x09, 0x04,        // USAGE (Joystick)	0xa1, 0x01,        // COLLECTION (Application)		0x09, 0x30,        // USAGE (shift)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x31,        // USAGE (enc0)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x32,        // USAGE (enc1)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x33,        // USAGE (enc2)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x34,        // USAGE (enc3)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x35,        // USAGE (enc4)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x36,        // USAGE (pot0)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0x09, 0x37,        // USAGE (pot1)	0x15, 0x00,        // LOGICAL_MINIMUM (0)	0x26, 0xff, 0x00,  // LOGICAL_MAXIMUM (255)	0x75, 0x08,        // REPORT_SIZE (8)	0x95, 0x01,        // REPORT_COUNT (1)	0x81, 0x02,        // INPUT (Data,Var,Abs)		0xc0               // END_COLLECTION};static void buildReport(uchar shift, uchar enc0, uchar enc1, uchar enc2, uchar enc3, uchar enc4, uchar pot0, uchar pot1) {	reportBuffer[0]= shift;	reportBuffer[1]= enc0;	reportBuffer[2]= enc1;	reportBuffer[3]= enc2;	reportBuffer[4]= enc3;	reportBuffer[5]= enc4;	reportBuffer[6]= pot0;	reportBuffer[7]= pot1;}uchar usbFunctionSetup(uchar data[8]) {	usbRequest_t *rq = (void *)data;    usbMsgPtr = reportBuffer;    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */        if(rq->bRequest == USBRQ_HID_GET_REPORT){  /* wValue: ReportType (highbyte), ReportID (lowbyte) */            /* we only have one report type, so don't look at wValue */            buildReport(0, 0, 0, 0, 0, 0, 0, 0);            return sizeof(reportBuffer);        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){            usbMsgPtr = &idleRate;            return 1;        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){            idleRate = rq->wValue.bytes[1];        }    }else{        /* no vendor specific requests implemented */    }	return 0;}int main(void) {		uchar shift= 0, lastShift= 0;	uchar lastPINB= PINB&0b00001111;	uchar lastPIND= PIND&0b11111010;	uchar enc0= 0, enc1= 0, enc2= 0, enc3= 0, enc4= 0, encTemp;	uchar pot0= 0, pot1= 0;		wdt_enable(WDTO_2S);	hardwareInit();	usbInit();	sei();		//--main loop	while(1) {				wdt_reset();		usbPoll();				//--read digital inputs		shift= shiftIn();		if(shift!=lastShift) {			changed= 1;			lastShift= shift;		}				//--read encoders		encTemp= encoderIn(PIND&0b11111010, lastPIND, 1, 3);		if(encTemp==1) {			enc0--;			changed= 2;			lastPIND= PIND&0b11111010;		} else if(encTemp==2) {			enc0++;			changed= 2;			lastPIND= PIND&0b11111010;		}		encTemp= encoderIn(PIND&0b11111010, lastPIND, 4, 5);		if(encTemp==1) {			enc1--;			changed= 2;			lastPIND= PIND&0b11111010;		} else if(encTemp==2) {			enc1++;			changed= 2;			lastPIND= PIND&0b11111010;		}		encTemp= encoderIn(PIND&0b11111010, lastPIND, 6, 7);		if(encTemp==1) {			enc2--;			changed= 2;			lastPIND= PIND&0b11111010;		} else if(encTemp==2) {			enc2++;			changed= 2;			lastPIND= PIND&0b11111010;		}		encTemp= encoderIn(PINB&0b00001111, lastPINB, 0, 1);		if(encTemp==1) {			enc3--;			changed= 3;			lastPINB= PINB&0b00001111;		} else if(encTemp==2) {			enc3++;			changed= 3;			lastPINB= PINB&0b00001111;		}		encTemp= encoderIn(PINB&0b00001111, lastPINB, 2, 3);		if(encTemp==1) {			enc4--;			changed= 3;			lastPINB= PINB&0b00001111;		} else if(encTemp==2) {			enc4++;			changed= 3;			lastPINB= PINB&0b00001111;		}				//--read softpots		ADMUX= 0b11000010;			//select adc channel 2		ADCSRA |= (1<<ADSC);		//start conversion		while((ADCSRA&64)==64);		//wait for ADSC bit to go low		pot0= ADCL>>2;				//skip 2 lowest bits		pot0 |= (ADCH<<6);		if(reportBuffer[6]!=pot0) {			changed= 4;		}		ADMUX= 0b11000001;			//select adc channel 1		ADCSRA |= (1<<ADSC);		//start conversion		while((ADCSRA&64)==64);		//wait for ADSC bit to go low		pot1= ADCL>>2;				//skip 2 lowest bits		pot1 |= (ADCH<<6);		if(reportBuffer[7]!=pot1) {			changed= 4;		}				//--send report		if(usbInterruptIsReady()&&(changed>0)) {			buildReport(shift, enc0, enc1, enc2, enc3, enc4, pot0, pot1);			usbSetInterrupt(reportBuffer, sizeof(reportBuffer));			changed= 0;		}	}	return 0;}uchar encoderIn(uchar currPin, uchar lastPin, uchar a, uchar b) {	if((lastPin&(1<<a))!=(1<<a) && ((currPin&(1<<a))==(1<<a))) {		if((currPin&(1<<b))!=(1<<b)) {			return 2;		}		return 1;	} else if((lastPin&(1<<a))==(1<<a) && ((currPin&(1<<a))!=(1<<a))) {		if((currPin&(1<<b))==(1<<b)) {			return 2;		}		return 1;	}	return 0;}uchar shiftIn(void) {	char i;	uchar data= 0;	PORTB |= (1<<5);					//set latch pin to collect parallel data	_delay_us(20);	PORTB &= ~(1<<5);					//clear latch pin to transmit	for(i= 7; i>=0; i--) {		PORTB &= ~(1<<4);				//clear clock pin		if((PINC&(1<<0)) == (1<<0)) {			data |= (1<<i);		}		PORTB |= (1<<4);				//set clock pin	}	return data;}

⌨️ 快捷键说明

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