HDD и прерывания - доработка программы из статьи /node/220

Здравствуйте.
нужна помощь, пытаюсь запустить движок HDD.
взял за основу программу из статьи https://avrlab.com/node/220
однако у меня Arduino MEGA на проце 2560.

Внес изменения в программу - убрал работу по UART и на плате драйвера поставил 2 кнопки, которые завел на 4 и 5 разряды порта С.

кнопки работают, проверено на LED 4-го разряда порта B - пин13 ардуины со светодиодом.

нет ухода на прерывания, и еще, компилятор ругается на TIMSK, видимо оттого, что на 2560 их аж 5 штук, какой применить для правильной работы с имеющейся инициализацией прерываний. Также непонятно, где происходит привязка подпрограмм-обработчиков...

и все равно компилятор ругается на TIMSK и GIMSK наверно для atmega2560 там что то другое должно быть

  1. # include "avr/io.h"
  2. # include "avr/interrupt.h"
  3. # include "stdio.h"
  4.  
  5. #define nop() {asm("nop");}
  6.  
  7. char status,data;
  8. char state;
  9. unsigned int lvl=65530/4;
  10.  
  11. // кнопки на int0 и int1 20 и 21 контакты
  12. SIGNAL(SIG_INTERRUPT0)//обработка прерываний кнопки "+"
  13. {cli(); lvl++; //увеличение при нажатии на кнопку "+" на 1
  14. sei();}
  15.  
  16.  
  17. SIGNAL(SIG_INTERRUPT1)//обработка прерываний кнопки "-"
  18. {cli(); lvl--; //уменьшение при нажатии на кнопку "-" на 1
  19. sei(); }
  20.  
  21. // Timer1 output compare A interrupt service routine
  22. ISR(TIMER1_COMPA_vect)
  23. { switch (state)
  24. { case 0: PORTC=1; PORTB=0x00;break;
  25. case 1: PORTC=3; PORTB=0x80;break;
  26. case 2: PORTC=2; PORTB=0x00;break;
  27. case 3: PORTC=6; PORTB=0x80;break;
  28. case 4: PORTC=4; PORTB=0x00;break;
  29. case 5: PORTC=5; PORTB=0x80;break; }
  30.  
  31. if (state<5) state++;
  32. else state=0; }
  33.  
  34.  
  35. int main(void)
  36. { PORTC=0xF0;
  37. DDRC=0x0F;
  38. DDRB=0x80;
  39. PORTB=0x80;
  40.  
  41. GIMSK=0b11000000; //разрешаем прерывание int0 и int1
  42. MCUCR=0b00001111;// прерывание по возрастающему фронту - для кнопки 1 и 2
  43.  
  44. // Timer/Counter 1 initialization
  45. // Clock source: System Clock
  46. // Clock value: 8000,000 kHz
  47. // Mode: CTC top=OCR1A
  48. // OC1A output: Discon.
  49. // OC1B output: Discon.
  50. // Noise Canceler: Off
  51. // Input Capture on Falling Edge
  52. // Timer1 Overflow Interrupt: Off
  53. // Input Capture Interrupt: Off
  54. // Compare A Match Interrupt: On
  55. // Compare B Match Interrupt: Off
  56. TCCR1A=0x00;
  57. TCCR1B=0x09;
  58. TCNT1H=0x00;
  59. TCNT1L=0x00;
  60. ICR1H=0x00;
  61. ICR1L=0x00;
  62. OCR1AH=0xFF;
  63. OCR1AL=0xFF;
  64. OCR1BH=0x00;
  65. OCR1BL=0x00;
  66.  
  67. // Timer(s)/Counter(s) Interrupt(s) initialization
  68. TIMSK = 0x10;
  69.  
  70. // Global enable interrupts
  71. sei();
  72.  
  73. while (1)
  74. {
  75. // if ((PINC&0x20)==0x00) PORTB=0x80; else PORTB=0x00; //при нажатии кнопки зажигаем светодиод
  76. OCR1A=lvl; }; }

Посмотри документацию на свой

Посмотри документацию на свой МК у него судя по всему регистры TIMSK и GIMSK по другому называются, могут типа
TIMSK0 и GIMSK0 или TIMSK1 и GIMSK1 называться. Глянь, с 2560 не работал сам.

Так ты же не убрал привязку к

Так ты же не убрал привязку к работе от прерывания по приходу UART у тебя до сих пор в программе стоит обработчик прерывания по UART а не по кнопке.

перекинул кнопки

и все равно компилятор ругается на TIMSK и GIMSK наверно для atmega2560 там чтото другое должно быть

  1. # include "avr/io.h"
  2. # include "avr/interrupt.h"
  3. # include "stdio.h"
  4.  
  5. #define nop() {asm("nop");}
  6.  
  7. char status,data;
  8. char state;
  9. unsigned int lvl=65530/4;
  10.  
  11. // кнопки на int0 и int1 20 и 21 контакты
  12.  
  13. SIGNAL(SIG_INTERRUPT0)//обработка прерываний кнопки "+"
  14. {
  15. cli(); lvl++; //увеличение при нажатии на кнопку "+" на 1
  16. sei();
  17. }
  18.  
  19.  
  20. SIGNAL(SIG_INTERRUPT1)//обработка прерываний кнопки "-"
  21. {
  22. cli(); lvl--; //уменьшение при нажатии на кнопку "-" на 1
  23. sei();
  24. }
  25.  
  26. // Timer1 output compare A interrupt service routine
  27. ISR(TIMER1_COMPA_vect)
  28. {
  29.  
  30. switch (state)
  31. { case 0: PORTC=1; PORTB=0x00;break;
  32. case 1: PORTC=3; PORTB=0x80;break;
  33. case 2: PORTC=2; PORTB=0x00;break;
  34. case 3: PORTC=6; PORTB=0x80;break;
  35. case 4: PORTC=4; PORTB=0x00;break;
  36. case 5: PORTC=5; PORTB=0x80;break; }
  37.  
  38. if (state<5) state++;
  39. else state=0;
  40. }
  41.  
  42.  
  43. int main(void)
  44. { PORTC=0xF0;
  45. DDRC=0x0F;
  46. DDRB=0x80;
  47. PORTB=0x80;
  48.  
  49. GIMSK=0b11000000; //разрешаем прерывание int0 и int1
  50. MCUCR=0b00001111;// прерывание по возрастающему фронту - для кнопки 1 и 2
  51.  
  52. // Timer/Counter 1 initialization
  53. // Clock source: System Clock
  54. // Clock value: 8000,000 kHz
  55. // Mode: CTC top=OCR1A
  56. // OC1A output: Discon.
  57. // OC1B output: Discon.
  58. // Noise Canceler: Off
  59. // Input Capture on Falling Edge
  60. // Timer1 Overflow Interrupt: Off
  61. // Input Capture Interrupt: Off
  62. // Compare A Match Interrupt: On
  63. // Compare B Match Interrupt: Off
  64. TCCR1A=0x00;
  65. TCCR1B=0x09;
  66. TCNT1H=0x00;
  67. TCNT1L=0x00;
  68. ICR1H=0x00;
  69. ICR1L=0x00;
  70. OCR1AH=0xFF;
  71. OCR1AL=0xFF;
  72. OCR1BH=0x00;
  73. OCR1BL=0x00;
  74.  
  75. // Timer(s)/Counter(s) Interrupt(s) initialization
  76. TIMSK = 0x10;
  77.  
  78. // Global enable interrupts
  79. sei();
  80.  
  81. while (1)
  82. {
  83. // if ((PINC&0x20)==0x00) PORTB=0x80; else PORTB=0x00; //при нажатии кнопки зажигаем светодиод
  84. OCR1A=lvl; }; }

хм... то есть имя обработчика

хм... то есть имя обработчика это привязка к прерыванию...
ччерт а где про это почитать...
и собственно на кнопки не реагирует и пока фиг с ними, не могу понять, почему на 0-1-2 порты С не идут импульсы по другому прерыванию... видимо проблема с TIMSK ... подскажите какой номер на него вешать...

Ошибки кода: 1. В обработчике

Ошибки кода:
1. В обработчике не обязательно cli(); и sei(); ставить так как на время выполнение прерывания ЦПУ и так будет занят только обработкой прерывания.
2. Все что касается кнопки советую цеплять на внешнее прерывание, на порты int0 и int1.

http://avrlab.com/node/83 -

http://avrlab.com/node/83 - тут про работу с кнопками
http://avrlab.com/node/87 - тут про работу с прерываниями