· 

AVR128DB28のタイマー

 

AVR128DB28のタイマーをローレベルに動かしてみる

 
AVR128DB28のタイマーはちょっと前(https://sunday-engineer.jimdofree.com/2024/08/12/avr128db28%E3%81%A7arduino-5/)にいじってみたけど、もちっとローレベルな動かし方でやってみる。やっぱり8ビットマイコンはこういう動かし方だよね的な。
で、実は参考になるサイトが少なすぎるのと、Atmega328Pで最初何をみてやってたのか思い出せずにちょっと苦労した。
で、結局、こんなところによい参考があった。
で、いろいろ要らなそうな記述やら消したり、ピンへの出力は自前でやるってことでその辺を変更したりして、こうなる。
  1. /*========================================================================
  2. study6.ino
  3. 2024.10.14 Sunday Engineer
  4. SWD access tool study
  5. Board: "AVR DB-series (Optiboot)"
  6. Board: "AVR128DB28"
  7. Clock Speed: "16 MHz crystal"
  8. millis()/micros() timer: "TCB2 (recommended)"
  9. BOD level if enabled (Bootload burn req'd): "1.9V"
  10. BOD Mode Active/Sleeping (Bootload burn req'd): "Disabled/Disabled"
  11. WDT Timeout (Bootload burn req'd): "Disabled (recommended)"
  12. WDT "window" (Bootload burn req'd): "No delay before window "opens""
  13. Reset pin function (Bootload burn req'd): "PF6: Reset (default boot entry on reset pin & SW resets, 1 sec timeout)
  14. Startup Time: "64ms"
  15. Bootloader Serial Port (Bootload burn req'd): "USART0 (alt): TX PA4, RX PA5"
  16. Bootloader Entry Condition (Bootload burn req'd): "Default (see documentation)"
  17. MultiVoltage I/O (MVIO) (Bootload burn req'd): "Enabled (burn bootloader req'd)"
  18. attachInterrupt() Version: "On all pins, with new implementation."
  19. printf(): "Default (doesn't print floats, 1.4k flash use)"
  20. Wire (Wire.h/I2C) Library mode: "1x Wire, Master or Slave (least Flash & RAM)"
  21. How to set FLMAP: "Use last FLMAP section, lock FLMAP, provide PROGMEM_MAPPED"
  22. ========================================================================*/
  23. /*
  24. F_PER=16000000Hz
  25. CLKSEL=111(=DIV1024)
  26. F_TIM=15625Hz
  27. T_TIM=64us
  28. */
  29. uint16_t per_set=15625;
  30. void setup() {
  31.   pinMode(LED_BUILTIN, OUTPUT);
  32.   digitalWrite(LED_BUILTIN,HIGH);
  33.   takeOverTCA0();
  34.   TCA0.SINGLE.CTRLB = 0x10;
  35.   TCA0.SINGLE.PER = per_set;
  36.   TCA0.SINGLE.CMP0 = (per_set>>1);
  37.   TCA0.SINGLE.INTCTRL = 0x11;
  38.   TCA0.SINGLE.CTRLA = 0x0F;
  39. }
  40. void loop() {
  41. }
  42. ISR(TCA0_OVF_vect) {
  43.   TCA0.SINGLE.INTFLAGS = 0x01;
  44.   digitalWrite(LED_BUILTIN,HIGH);
  45. }
  46. ISR(TCA0_CMP0_vect){
  47.   TCA0.SINGLE.INTFLAGS = 0x10;
  48.   digitalWrite(LED_BUILTIN,LOW);
  49. }
(Arduinoでの設定をメモとしてコード先頭に記述している。決して賑やかしではない。)で、実行してみると。
はい。よくできました。ここで、限界に挑戦してみる。
で、こんなもんで限界。
  1. uint16_t per_set=64;
  2. void setup() {
  3.     PORTC.DIR|=0x01;
  4.     VPORTC.DIR|=0x01;
  5.     VPORTC.OUT=0x01;
  6.     takeOverTCA0();
  7.     TCA0.SINGLE.CTRLB = 0x10;
  8.     TCA0.SINGLE.PER = per_set;
  9.     TCA0.SINGLE.CMP0 = (per_set>>1);
  10.     TCA0.SINGLE.INTCTRL = 0x11;
  11.     TCA0.SINGLE.CTRLA = 0x01;
  12. }
  13. void loop() {
  14. }
  15. ISR(TCA0_OVF_vect) {
  16.     TCA0.SINGLE.INTFLAGS = 0x01;
  17.     VPORTC.OUT|=0x01;
  18. }
  19. ISR(TCA0_CMP0_vect){
  20.     TCA0.SINGLE.INTFLAGS = 0x10;
  21.     VPORTC.OUT&=~0x01;
  22. }
 
4usなので250kHz。
まぁ、コードでトグルしてたんじゃこんなもんよな、、、
ちなみに今回の目的はARMのSWDにアクセスするスタンドアロンツールを作るためなんやけど、SWDってSPIとほぼ同じなので、SPIモジュールでやればもっと早くできる。が、SWDは微妙なビット数の時があるので、こまるんよね。SPIペリフェラルって、どのマイコンも、なんでビット数をもちっと柔軟にできんのかな、、、