---------------------------------------------
Code
#include <mega8.h>
#include <mega8_bits.h>
// Global variables.
unsigned char RunClockwise = 1; //!< Start with clockwise rotation.
unsigned char IPM_B4_PWM = 0xFF; //!< Control signals to IPM driver chip.
// Function prototypes.
void main(void);
void initialization(void);
void PWM2_initialize(void);
void ADC_setup(void);
//! Initialize I/O-ports, ADC and PWM output.
void initialization(void)
{
PORTB= ~0x3f; // 6 bits of PORTB to be high
DDRB = 0x3f; // set PORTB6 bits as output
ADC_setup(); // Initialize the ADC
PWM2_initialize(); // Initialize PWM2.
}
//! Initialize ADC to CPU/4 speed, channel 5, free running mode.
void ADC_setup(void)
{
ADCSRA = (1<<ADEN)|(1<<ADPS1)|(1<<ADATE)|(1<<ADSC); //Enable ADC, ADC clk = CK/4, free running.
// ADMUX = 0x05 | (1<<REFS0) | (1<<ADLAR); // Channel 5 with AVCC as ref.
ADMUX = 0x05 | (0<<REFS0) | (1<<ADLAR); // Channel 5 with AREF as ref.
}
//! Initialize PWM output OC2B from Timer/Counter2 at 20kHz base freq @ 8MHz CPU.
void PWM2_initialize(void)
{
TCCR2A = (1<<COM2B1)|(1<<COM2B0)| // Set OC2B (DIP pin 5) on Compare Match,
(0<<WGM21)|(1<<WGM20); // phase correct PWM & OCR2A as TOP.
TCCR2B = (1<<WGM22)|(0<<CS22)|(0<<CS21)|(1<<CS20);
OCR2A = 200; // 200 decimal TOP.
OCR2B = 100; // This starts PWM output at 50%
DDRD |= (1<<DDB3);
}
//! Pin Change Interrupt for PORTC (PCINT8..14).
interrupt [PORTB1] void Pin_Change_Int_Serv(void)
{
static unsigned char Hall_In;
Hall_In = PINC & 0x07;
if( RunClockwise ) {
// This is clockwise Switch statement.
// Based on Hall inputs select 1 of 6 patterns to
// send to IPM via main().
switch(Hall_In) {
case 1: IPM_B4_PWM = 0b101011; break;
case 5: IPM_B4_PWM = 0b110011; break;
case 4: IPM_B4_PWM = 0b110101; break;
case 6: IPM_B4_PWM = 0b011101; break;
case 2: IPM_B4_PWM = 0b011110; break;
case 3: IPM_B4_PWM = 0b101110; break;
// All outputs off if illegal Hall sensors.
default: IPM_B4_PWM = 0b111111;
}
} else {
// This is counter-clockwise Switch statement.
// Based on Hall inputs, select 1 of 6 patterns to
// send to IPM via main().
switch(Hall_In) {
case 6: IPM_B4_PWM = 0b011110; break;
case 4: IPM_B4_PWM = 0b011101; break;
case 5: IPM_B4_PWM = 0b110101; break;
case 1: IPM_B4_PWM = 0b110011; break;
case 3: IPM_B4_PWM = 0b101011; break;
case 2: IPM_B4_PWM = 0b101110; break;
// All outputs off if illegal Hall sensors.
default: IPM_B4_PWM = 0b111111;
}
}
}
//! Application starts here.
void main(void)
{
unsigned char speed;
initialization(); // Initialize Peripherals.
// Set up and Enable Interrupts
PCMSK1 = (1<<PCINT10) | (1<<PCINT9)| (1<<PCINT8);
PCICR = (1<<PCIE1);// Enable Pin Change Ints from port C.
// Start interrupts by forcing Hall Inputs to 0, then switching pins to inputs.
DDRC = 7; // 3 Hall Inputs pulled to 0 volts.
PORTC = 0;
PORTC = 1;
PORTC = 2;
PORTC = 4; // Start interrupts with forced pin change
DDRC = 0; // Port C switched back to all inputs.
SREG |= 0x80;// Enable Interrupts via SEI bit
PORTD |= (1<<PORTD0) | (1<<PORTD1); // Direction control input pullups, undocumented.
while(1) { // IPM_B4_PWM is updated via a Pin Change Interrupt
// Direction control, undocumented.
if( !(PIND & (1<<PORTD0)) ) RunClockwise = 1;
if( !(PIND & (1<<PORTD1)) ) RunClockwise = 0;
// Update speed setting from ADC reading.
speed = ADCH;
if( speed > 199 ) speed = 199;
OCR2B = speed;
// If OC2B is high, send inactive outputs to IPM.
if( PIND & (1 << PORTD3) ) {
PORTB = ~0xFF; // <== If motor driver has active high inputs.
// PORTB = 0xFF; // <== If motor driver has active low inputs.
} else {
PORTB = ~IPM_B4_PWM; // <== If motor driver has active high inputs.
// PORTB = IPM_B4_PWM; // <== If motor driver has active low inputs.
}
}
}
помогите адаптировать под мегу8,если получится а то на 48,таймеры "круче"