From: AceVest Date: Fri, 15 Jun 2018 10:17:58 +0000 (+0800) Subject: atemga328p avr code X-Git-Url: http://zhaoyanbai.com/repos/zlib_tech.html?a=commitdiff_plain;h=141d762520383f612d45fbcdb3d79196817f90b6;p=acecode.git atemga328p avr code --- diff --git a/arduino/hardware/ace/avr/cores/avr/main.cpp b/arduino/hardware/ace/avr/cores/avr/main.cpp index 9bb79f0..fa5944d 100644 --- a/arduino/hardware/ace/avr/cores/avr/main.cpp +++ b/arduino/hardware/ace/avr/cores/avr/main.cpp @@ -7,11 +7,182 @@ * ------------------------------------------------------------------------ */ #include +#include +#include +#include + +#define __SFR_OFFSET 0x20 +#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr)) +#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET) +#define SREG _SFR_IO8(0x3F) +#define DDRB _SFR_IO8(0x04) +#define PORTB _SFR_IO8(0x05) +#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L ) +#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() ) +#define MICROSECONDS_PER_TIMER0_OVERFLOW (clockCyclesToMicroseconds(64 * 256)) +#define MILLIS_INC (MICROSECONDS_PER_TIMER0_OVERFLOW / 1000) +#define FRACT_INC ((MICROSECONDS_PER_TIMER0_OVERFLOW % 1000) >> 3) +#define FRACT_MAX (1000 >> 3) + +#define cli() __asm__ __volatile__ ("cli" ::: "memory") +#define sei() __asm__ __volatile__ ("sei" ::: "memory") +#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) + + +#define __INTR_ATTRS used, externally_visible +#ifdef __cplusplus +# define ISR(vector, ...) \ + extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \ + void vector (void) +#else +# define ISR(vector, ...) \ + void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \ + void vector (void) +#endif + +volatile unsigned long timer0_overflow_count = 0; +volatile unsigned long timer0_millis = 0; +static unsigned char timer0_fract = 0; + +ISR(TIMER0_OVF_vect) +{ + // copy these to local variables so they can be stored in registers + // (volatile variables must be read from memory on every access) + unsigned long m = timer0_millis; + unsigned char f = timer0_fract; + + m += MILLIS_INC; + f += FRACT_INC; + if (f >= FRACT_MAX) { + f -= FRACT_MAX; + m += 1; + } + + timer0_fract = f; + timer0_millis = m; + timer0_overflow_count++; +} + +static void __empty() { + // Empty +} +//void yield(void) __attribute__ ((weak, alias("__empty"))); +void yield(void) { } + +unsigned long micros() { + unsigned long m; + uint8_t oldSREG = SREG, t; + + cli(); + m = timer0_overflow_count; + + t = TCNT0; + if ((TIFR0 & _BV(TOV0)) && (t < 255)) { + m++; + } + SREG = oldSREG; + + return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); +} + +void delay(unsigned long ms) +{ + uint32_t start = micros(); + while (ms > 0) { + yield(); + while ( ms > 0 && (micros() - start) >= 1000) { + ms--; + start += 1000; + } + } +} + + + + + +void init() { + sei(); + + // on the ATmega168, timer 0 is also used for fast hardware pwm + // (using phase-correct PWM would mean that timer 0 overflowed half as often + // resulting in different millis() behavior on the ATmega8 and ATmega168) + sbi(TCCR0A, WGM01); + sbi(TCCR0A, WGM00); + + // set timer 0 prescale factor to 64 + sbi(TCCR0B, CS01); + sbi(TCCR0B, CS00); + + // enable timer 0 overflow interrupt + sbi(TIMSK0, TOIE0); + +#if 0 + // timers 1 and 2 are used for phase-correct hardware pwm + // this is better for motors as it ensures an even waveform + // note, however, that fast pwm mode can achieve a frequency of up + // 8 MHz (with a 16 MHz clock) at 50% duty cycle + TCCR1B = 0; + sbi(TCCR1B, CS11); +//#if F_CPU >= 8000000L + sbi(TCCR1B, CS10); +//#endif + // put timer 1 in 8-bit phase correct pwm mode + sbi(TCCR1A, WGM10); + + // set timer 2 prescale factor to 64 + sbi(TCCR2B, CS22); + // configure timer 2 for phase correct pwm (8-bit) + sbi(TCCR2A, WGM20); + +//#if F_CPU >= 16000000 // 16 MHz / 128 = 125 KHz + sbi(ADCSRA, ADPS2); + sbi(ADCSRA, ADPS1); + sbi(ADCSRA, ADPS0); +//#endif + sbi(ADCSRA, ADEN); + + // the bootloader connects pins 0 and 1 to the USART; disconnect them + // here so they can be used as normal digital i/o; they will be + // reconnected in Serial.begin() + UCSR0B = 0; +#endif +} + int main() { - setup(); - for(;;) { - loop(); - } - return 0; + init(); + + uint8_t pin = 5; + uint8_t bit = 1<