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

📄 avr_vpwm.c

📁 AVR脉宽调整的程序
💻 C
字号:
/*------------------------------------------------------------------------ avrstep.c - Stepper motor test.   Create a custom(Virtual)PWM stepper motor controller using   an AVR AT90S2313 microcontroller.  The technique will require   the full attention of the microprocessor, any interrupt activity   would throw off the timing.  We work around this by not using   the any interrupts and try to configure the code to work in   a known timing loop.   Four other signals are used to step a stepper motor in a unipolar   fashion.  Logic in timer interrupt steps steppers slow for a while,   then at a fast rate.   Example 1 of 4 stepper winding interface elements:                                 +Vm                +12V             |                300 ohm          Motor Coil         +5v    pullup           |          |10k  |_____________||-   AVR    |     |             ||-   Micro  |   |/                 |   MC1A-------|                  V              |\                |                V   Want: A tight loop which offers a decent virtual pulse width   modulation for controlling the power delivered to the motor.   For starters we will drive the stepper motor using a timer,   but the intent would be to couple the micro to another micro   which would coordinate the step timing.   Secondary, we would like some way to easily bump up or down   the PWM timing.  Two input pins will be used to implement a   bump up, bump down PWM timing.   Results: TBD.Layout:   ; Board socket IO;       rxd  |1   __  16| +5v;       txd  |2       15| ;       pd2  |3       14| ;       pd3  |4       13| pb3,; pd4(485en) |5       12| pb2, MC1A;   pd5(led) |6       11| pb1, MC1B;            |7       10| pb0, MC2A;        Gnd |8        9| pd6, MC2B; AVR2313 IO;           /Reset  |1   __  20| Vcc; a        rxd,pd0  |2       19| pb7,sck   (input, bump up); b        txd,pd1  |3       18| pb6,miso  ;        xtal2,out  |4       17| pb5,mosi  (input, bump down);         xtal1,in  |5       16| pb4       (led-main brd); c       int0,pd2  |6       15| pb3,oc1   (Motor Coil1-A);         int1,pd3  |7       14| pb2       (Motor Coil1-B); (485en)   t0,pd4  |8       13| pb1,ain1  (Motor Coil2-A); (led)     t1,pd5  |9       12| pb0,ain0  (Motor Coil2-B);              Gnd  |10      11| pd6,icp;                    ----------; Copyright 2001 Karl Bongers|------------------------------------------------------------------------*/  #include <io.h>#include <interrupt.h>#include <sig-avr.h>#define INTR_ENABLE() sei()#define INTR_DISABLE() cli()#define MISO_BITNUM  6    //  ; pin18, MISO (our output)#define MISO_BIT  (1 << MISO_BITNUM)#define MOSI_BITNUM  5    //  ; pin17, MISO#define MOSI_BIT  (1 << MOSI_BITNUM)#define SCK_BITNUM  7    //  ; pin19, SCK#define SCK_BIT  (1 << SCK_BITNUM)#define LED_BITNUM  4    //  ; pin9, LED, pd5#define LED_BIT  (1 << LED_BITNUM)//  ; where DDBx=0 PORTBx=0 ---> Tri State//  ;       DDBx=0 PORTBx=1 ---> Will source current if ext. pulled low//  ;       DDBx=1 PORTBx=0 ---> push pull zero output//  ;       DDBx=1 PORTBx=1 ---> push pull one output#define SetLed() { sbi(PORTB, LED_BITNUM); }#define ClrLed() { cbi(PORTB, LED_BITNUM); }#define SetMc1A() { sbi(PORTB, 3); }#define ClrMc1A() { cbi(PORTB, 3); }#define SetMc1B() { sbi(PORTB, 2); }#define ClrMc1B() { cbi(PORTB, 2); }#define SetMc2A() { sbi(PORTB, 1); }#define ClrMc2A() { cbi(PORTB, 1); }#define SetMc2B() { sbi(PORTB, 0); }#define ClrMc2B() { cbi(PORTB, 0); }#define ClrMcAll() {outp(0, PORTB); }#define SetMc1Ap() {outp(8, PORTB); }#define SetMc1Bp() {outp(4, PORTB); }#define SetMc2Ap() {outp(2, PORTB); }#define SetMc2Bp() {outp(1, PORTB); }#define SetMcAll() {outp(0x0f, PORTB); }#define ClrMc1Ap() {outp(0x07, PORTB); }#define ClrMc1Bp() {outp(0x0b, PORTB); }#define ClrMc2Ap() {outp(0x0d, PORTB); }#define ClrMc2Bp() {outp(0x0e, PORTB); }  // Clear MISO output to 0 volts.#define ClrMiso() { cbi(PORTB, MISO_BITNUM); }#define SetMiso() { sbi(PORTB, MISO_BITNUM); }#define GetMosi() (inp(PINB) & MOSI_BIT)#define GetSck() (inp(PINB) & SCK_BIT)#define delay_1us() delay(1)#define delay_2us() delay(4)#define delay_4us() delay(9)#define delay_8us() delay(18)#define delay_10us() delay(25)#define delay_20us() delay(50)#define delay_40us() delay(105)#define delay_60us() delay(165)#define delay_80us() delay(215)#define delay_90us() delay(248)#define delay_180us() bdelay(2)#define delay_250us() bdelay(3)#define delay_370us() bdelay(4)#define delay_600us() bdelay(6)#define delay_740us() bdelay(8)#define delay_1ms() bdelay(10)#define delay_10ms() bdelay(120)#define delay_20ms() bdelay(240)#define u08 unsigned char#define u16 unsigned short#define word unsigned short#define byte unsigned shortu08 testtimer;volatile u08 timer0_cnt;volatile u08 stepi;  // stepper motor sequenceu08 time_base, max_base, pwm_base;/*---------------------------------------------------------------------------- tim0_ovf -  timer0 overflow interrupt handler   with timer0 prescaler = CK/1024(TCCR0=5)   and our 8 bit counter overflowing every 256 ticks, we   have clock_ticks = 256 * 1024 = 262144 ticks,   so at 10Mhz, we interrupt every 26.21ms|----------------------------------------------------------------------------*/SIGNAL(SIG_OVERFLOW0)//void tim0_ovf(void){  ++timer0_cnt;  if (timer0_cnt == 0xff)    timer0_cnt = 0;  // this causes the stepper motor to go fast for a while then  // slow for a while.  We turn the LED on and off as a visual  // indicator.  if ((timer0_cnt < 0x80) || ((timer0_cnt & 0x0f) == 0)) {    ++stepi;    if (stepi >= 4)      stepi=0;  }}/*---------------------------------------------------------------------------- delay -|----------------------------------------------------------------------------*/void delay(u08 delay_time){ u08 register i;  // this inner loop is about 4 cycle times in length.  // so if 10Mhz, delay_time=4=1us; 40=10us; 80=20us; 160=40us; 200=50us  // so if  5Mhz, delay_time=4=2us; 40=20us; 80=40us; 160=80us; 200=100us  for (i=0; i<delay_time; i++)  {  }}/*---------------------------------------------------------------------------- bdelay -|----------------------------------------------------------------------------*/void bdelay(u08 delay_time){ u08 register i;  for (i=0; i<delay_time; i++)  {    delay(0xff);  }}/*---------------------------------------------------------------------------- main -|----------------------------------------------------------------------------*/int main(void){ u08 register i;  outp(LED_BIT | MISO_BIT | 0x0f, DDRB); // setup output bits(rest are inputs)  outp(MOSI_BIT | SCK_BIT | 0x0f, PORTB); // set SCK & MOSI weak pullups active.  outp((1<<6), DDRD); //set 0,1,2,3 to output, rest to all input  outp(0, PORTD); // hi Z inputs.  outp(1, TCCR1B); // timer1, control reg B(no prescaler, start clock)  // do some initial blinking of the LED to show signs of life  for (i=0;i<20;i++)  {    bdelay(250);    bdelay(250);    if (i & 1)         {SetLed(); }    else {ClrLed(); }  }  ClrLed();  // lets get our timer interrupts going    // timer0 prescaler = CK/1024  outp(5, TCCR0);  outp( (1<<TOIE0), TIMSK);  // timer0 overflow interrupt enable, r/w  time_base = 0;  max_base = 40;  // 20=100khz @ 11.592Mhz AVR2313  pwm_base = 20;  INTR_ENABLE();  for (;;)  {    ++time_base;    if (time_base >= max_base) {      time_base = 0;      switch(stepi) {        case 0:          ClrMc1Ap();        break;        case 1:          ClrMc2Ap();        break;        case 2:          ClrMc1Bp();        break;        case 3:          ClrMc2Bp();        break;      }    }    else if (time_base == pwm_base) {      SetMcAll();      if (GetMosi() == 0) {        SetLed();        if (max_base < 255)          ++max_base;        else {          max_base = 20;          pwm_base = 2;        }        while (GetMosi() == 0)  // debounce          ;        ClrLed();      }      if (GetSck() == 0) {        SetLed();        if (pwm_base < max_base)          ++pwm_base;        else          pwm_base = 0;        while (GetSck() == 0)  // debounce          ;        ClrLed();      }    }  }}

⌨️ 快捷键说明

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