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

📄 main.c

📁 利用ATtiny45晶片自行開發製做遊戲控制器
💻 C
字号:
/* Name: main.c * Project: Thermostat based on AVR USB driver * Author: Christian Starkjohann * Creation Date: 2006-04-23 * Tabsize: 4 * Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH * License: Proprietary, free under certain conditions. See Documentation. * This Revision: $Id: main.c 362 2007-06-25 14:38:21Z cs $ */#include <avr/io.h>#include <avr/wdt.h>#include <avr/eeprom.h>#include <avr/interrupt.h>#include <avr/pgmspace.h>#include <util/delay.h>#include "usbdrv.h"#include "oddebug.h"/*Pin assignment:PB0, PB2 = USB data lines*/#define BIT_LED 4#define BIT_KEY 1#define UTIL_BIN4(x)        (uchar)((0##x & 01000)/64 + (0##x & 0100)/16 + (0##x & 010)/4 + (0##x & 1))#define UTIL_BIN8(hi, lo)   (uchar)(UTIL_BIN4(hi) * 16 + UTIL_BIN4(lo))#ifndef NULL#define NULL    ((void *)0)#endif/* ------------------------------------------------------------------------- */static uchar    reportBuffer[1];    /* buffer for HID reports */static uchar    idleRate;           /* in 4 ms units */static uchar    FlagKey;/* ------------------------------------------------------------------------- */PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)    0x15, 0x00,                    // LOGICAL_MINIMUM (0)    0x09, 0x04,                    // USAGE (Joystick)    0xa1, 0x01,                    // COLLECTION (Application)    0x05, 0x09,                    //   USAGE_PAGE (Button)    0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)    0x29, 0x08,                    //   USAGE_MAXIMUM (Button 8)    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)    0x75, 0x01,                    //   REPORT_SIZE (1)    0x95, 0x08,                    //   REPORT_COUNT (8)    0x55, 0x00,                    //   UNIT_EXPONENT (0)    0x65, 0x00,                    //   UNIT (None)    0x81, 0x02,                    //   INPUT (Data,Var,Abs)    0xc0                           // END_COLLECTION};/* ------------------------------------------------------------------------- */static void timerPoll(void){static uchar timerCnt;static uchar i;    if(TIFR & (1 << TOV1)){        TIFR = (1 << TOV1); /* clear overflow */        if(++timerCnt >= 63){       /* ~ 1 second interval */		    timerCnt = 0;			if (!FlagKey) {				FlagKey = 1;								if (++i > 3)					i=0;				switch (i) {					case 0:						reportBuffer[0] = 1;    /* no modifiers */												break;					case 1:						reportBuffer[0] = 2;    /* no modifiers */												break;					case 2:						reportBuffer[0] = 8;    /* no modifiers */												break;					case 3:						reportBuffer[0] = 64;    /* no modifiers */												break;				}						}			        }    }}/* ------------------------------------------------------------------------- */static void timerInit(void){    TCCR1 = 0x0b;           /* select clock: 16.5M/1k -> overflow rate = 16.5M/256k = 62.94 Hz */}/* ------------------------------------------------------------------------- *//* ------------------------ interface to USB driver ------------------------ *//* ------------------------------------------------------------------------- */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 */            reportBuffer[0] = 0;    /* no modifiers */			            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;}/* ------------------------------------------------------------------------- *//* --------------------------------- main ---------------------------------- *//* ------------------------------------------------------------------------- */int main(void){uchar    i;/* Calibrate the RC oscillator to 8.25 MHz. The core clock of 16.5 MHz is * derived from the 66 MHz peripheral clock by dividing. We assume that the * EEPROM contains a calibration value in location 0. If no calibration value * has been stored during programming, we offset Atmel's 8 MHz calibration * value according to the clock vs OSCCAL diagram in the data sheet. This * seems to be sufficiently precise (<= 1%). */    uchar calibrationValue = eeprom_read_byte(0);    if(calibrationValue != 0xff){        OSCCAL = calibrationValue;  /* a calibration value is supplied */    }else{        /* we have no calibration value, assume 8 MHz calibration and adjust from there */        if(OSCCAL < 125){            OSCCAL += 3;    /* should be 3.5 */        }else if(OSCCAL >= 128){            OSCCAL += 7;    /* should be 7 */        }else{  /* must be between 125 and 128 */            OSCCAL = 127;   /* maximum possible avoiding discontinuity */        }    }    odDebugInit();    DDRB = (1 << USB_CFG_DMINUS_BIT) | (1 << USB_CFG_DPLUS_BIT);    PORTB = 0;          /* indicate USB disconnect to host */    for(i=0;i<20;i++){  /* 300 ms disconnect, also allows our oscillator to stabilize */        _delay_ms(15);    }    DDRB = 1 << BIT_LED;    /* output for LED */    PORTB = 1 << BIT_KEY;   /* pull-up on key input */    wdt_enable(WDTO_1S);    timerInit();    usbInit();    sei();    for(;;){    /* main event loop */        wdt_reset();        usbPoll();        if(usbInterruptIsReady() ){ /* we can send another key */                     usbSetInterrupt(reportBuffer, sizeof(reportBuffer));            FlagKey = 0;        }        timerPoll();    }    return 0;}

⌨️ 快捷键说明

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