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

📄 native_avr.c

📁 单片机上的java虚拟机 用winavr 编译
💻 C
字号:
////  NanoVM, a tiny java VM for the Atmel AVR family//  Copyright (C) 2005 by Till Harbaum <Till@Harbaum.org>////  This program is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the//  GNU General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA//////  native_avr.c//#include "types.h"#include "debug.h"#include "config.h"#include "error.h"#ifndef CTBOT#ifndef NIBO#ifdef AVR#include "vm.h"#include "native.h"#include "native_avr.h"#include "stack.h"#include "uart.h"#include <avr/io.h>#include <avr/interrupt.h>#if defined(ATMEGA128)volatile u08_t *ports[] = { &PORTA, &PORTB, &PORTC, &PORTD, &PORTE, &PORTF };volatile u08_t *ddrs[]  = { &DDRA,  &DDRB,  &DDRC,  &DDRD,  &DDRE,  &DDRF  };volatile u08_t *pins[]  = { &PINA,  &PINB,  &PINC,  &PIND,  &PINE,  &PINF  };#elif defined(ATMEGA32)volatile u08_t *ports[] = { &PORTA, &PORTB, &PORTC, &PORTD };volatile u08_t *ddrs[]  = { &DDRA,  &DDRB,  &DDRC,  &DDRD  };volatile u08_t *pins[]  = { &PINA,  &PINB,  &PINC,  &PIND  };#elif defined(ATMEGA8)volatile u08_t *ports[] = { NULL,  &PORTB, &PORTC, &PORTD  };volatile u08_t *ddrs[]  = { NULL,   &DDRB,  &DDRC,  &DDRD  };volatile u08_t *pins[]  = { NULL,   &PINB,  &PINC,  &PIND  };#elif defined(ATMEGA168)volatile u08_t *ports[] = { NULL,  &PORTB, &PORTC, &PORTD  };volatile u08_t *ddrs[]  = { NULL,   &DDRB,  &DDRC,  &DDRD  };volatile u08_t *pins[]  = { NULL,   &PINB,  &PINC,  &PIND  };#else#error "Unsupported AVR CPU!"#endifvolatile static nvm_int_t ticks;SIGNAL(SIG_OUTPUT_COMPARE1A) {  TCNT1 = 0;  ticks++;}void native_init(void) {  // init timer  TCCR1B = _BV(CS11);           // clk/8  OCR1A = (u16_t)(CLOCK/800u);  // 100 Hz is default#if defined(ATMEGA168)  TIMSK1 |= _BV(OCIE1A);         // interrupt on compare#else  TIMSK |= _BV(OCIE1A);         // interrupt on compare#endif}// the AVR classvoid native_avr_avr_invoke(u08_t mref) {  if(mref == NATIVE_METHOD_GETCLOCK) {    stack_push(CLOCK/1000);  } else    error(ERROR_NATIVE_UNKNOWN_METHOD);}// the port classvoid native_avr_port_invoke(u08_t mref) {  if(mref == NATIVE_METHOD_SETINPUT) {    u08_t bit  = stack_pop();    u08_t port = stack_pop();    DEBUGF("native setinput %bd/%bd\n", port, bit);    *ddrs[port] &= ~_BV(bit);  } else if(mref == NATIVE_METHOD_SETOUTPUT) {    u08_t bit  = stack_pop();    u08_t port = stack_pop();    DEBUGF("native setoutput %bd/%bd\n", port, bit);    *ddrs[port] |= _BV(bit);  } else if(mref == NATIVE_METHOD_SETBIT) {    u08_t bit  = stack_pop();    u08_t port = stack_pop();    DEBUGF("native setbit %bd/%bd\n", port, bit);    *ports[port] |= _BV(bit);  } else if(mref == NATIVE_METHOD_CLRBIT) {    u08_t bit  = stack_pop();    u08_t port = stack_pop();    DEBUGF("native clrbit %bd/%bd\n", port, bit);    *ports[port] &= ~_BV(bit);  } else    error(ERROR_NATIVE_UNKNOWN_METHOD);}// the timer class, based on AVR 16 bit timer 1void native_avr_timer_invoke(u08_t mref) {  if(mref == NATIVE_METHOD_SETSPEED) {    OCR1A = stack_pop_int();  // set reload value  } else if(mref == NATIVE_METHOD_GET) {    stack_push(ticks);  } else if(mref == NATIVE_METHOD_TWAIT) {    nvm_int_t wait = stack_pop_int();    ticks = 0;    while(ticks < wait);      // reset watchdog here if enabled  } else if(mref == NATIVE_METHOD_SETPRESCALER) {    TCCR1B = stack_pop_int();  } else    error(ERROR_NATIVE_UNKNOWN_METHOD);}// the Adc classvoid native_avr_adc_invoke(u08_t mref) {  if(mref == NATIVE_METHOD_ADC_SETPRESCALER) {    ADCSRA = _BV(ADEN) | (stack_pop_int() & 7);  // set prescaler value  } else if(mref == NATIVE_METHOD_ADC_SETREFERENCE) {    ADMUX = stack_pop_int() & 0xc0;              // set reference value  } else if(mref == NATIVE_METHOD_ADC_GETVALUE) {    // ADLAR = 0    ADMUX = (ADMUX & 0xc0) | (stack_pop_int() & 0x0f);    // do conversion    ADCSRA |= _BV(ADSC);                  // Start conversion    while(!(ADCSRA & _BV(ADIF)));         // wait for conversion complete    ADCSRA |= _BV(ADIF);                  // clear ADCIF    stack_push(ADCL + (ADCH << 8));  } else if(mref == NATIVE_METHOD_ADC_GETBYTE) {    // ADLAR = 1    ADMUX = (ADMUX & 0xc0) | _BV(ADLAR) | (stack_pop_int() & 0x0f);    // do conversion    ADCSRA |= _BV(ADSC);                  // Start conversion    while(!(ADCSRA & _BV(ADIF)));         // wait for conversion complete    ADCSRA |= _BV(ADIF);                  // clear ADCIF    stack_push(ADCH);  } else    error(ERROR_NATIVE_UNKNOWN_METHOD);}// the Pwm class#if (!defined(ATMEGA8) && !defined(ATMEGA168) && !defined(ATMEGA32))#error Please add PWM support for your CPU!#endifvoid native_avr_pwm_invoke(u08_t mref) {  if(mref == NATIVE_METHOD_PWM_SETPRESCALER) {    u08_t value = stack_pop();    u08_t port = stack_pop();   // top byte contains class ref    // implement pwm1    if(port == 1) {      // keep everything but prescaler#if defined(ATMEGA168)      TCCR2B = (TCCR2B & ~7) | (value & 7);#else      TCCR2 = (TCCR2 & ~7) | (value & 7);#endif    }  } else if(mref == NATIVE_METHOD_PWM_SETRATIO) {    u08_t value = stack_pop();    u08_t port = stack_pop();   // top byte contains class ref    // implement pwm1    if(port == 1) {      // setup of timer 2: keep prescaler, set fast pwm      // and clear OC2 on match, set OC2 on top#if defined(ATMEGA168)      TCCR2A = _BV(WGM21) | _BV(WGM20);      TCCR2B = (TCCR2B & 7) | _BV(COM2A1);#else      TCCR2 = (TCCR2 & 7) | _BV(WGM21) | _BV(WGM20) | _BV(COM21);#endif#if defined(ATMEGA8)      // the pwm output is on pin b.3 on the mega8      DDRB |= _BV(3);        // OC2 -> output#elif defined(ATMEGA168)      // the pwm output is on pin b.3 on the mega8      DDRB |= _BV(3);        // OC2 -> output#elif defined(ATMEGA32)      // the pwm output is on pin d.7 on the mega32      DDRD |= _BV(7);        // OC2 -> output#elif defined(ATMEGA128)      // the pwm output is on pin b.7 on the mega128      DDRB |= _BV(7);        // OC2 -> output#else#error Please add PWM support for your CPU!#endif#if defined(ATMEGA168)      OCR2A = value;#else      OCR2 = value;#endif    }  } else    error(ERROR_NATIVE_UNKNOWN_METHOD);}#endif#endif // !NIBO#endif // !CTBOT

⌨️ 快捷键说明

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