📄 main.lst
字号:
537:main.c **** 538:main.c **** SIGNAL (SIG_INT0) { 830 .LM66: 831 /* prologue: frame size=0 */ 832 0368 1F92 push __zero_reg__ 833 036a 0F92 push __tmp_reg__ 834 036c 0FB6 in __tmp_reg__,__SREG__ 835 036e 0F92 push __tmp_reg__ 836 0370 1124 clr __zero_reg__ 837 0372 8F93 push r24 838 /* prologue end (size=6) */ 839 .L78: 539:main.c **** 540:main.c **** // Wait until button no longer pressed 541:main.c **** 542:main.c **** while (! (BUTTON_PIN & _BV(BUTTON))) { 841 .LM67: 842 0374 829B sbis 48-0x20,2 843 0376 FECF rjmp .L78 543:main.c **** } 544:main.c **** 545:main.c **** if (sensor_timer.bytes.high_byte == 0xFF) { 845 .LM68: 846 0378 8091 0000 lds r24,sensor_timer+1 847 037c 8F3F cpi r24,lo8(-1) 848 037e 29F4 brne .L81 546:main.c **** 547:main.c **** // so in this instance, we set the watchdog to reset us 548:main.c **** 549:main.c **** sensor_timer.bytes.high_byte = 0x00; 850 .LM69: 851 0380 1092 0000 sts sensor_timer+1,__zero_reg__ 550:main.c **** 551:main.c **** // Re-enable the watchdog timer, then loop until 552:main.c **** // it fires off. 553:main.c **** 554:main.c **** WDTCSR = _BV(WDE); 853 .LM70: 854 0384 88E0 ldi r24,lo8(8) 855 0386 81BD out 65-0x20,r24 856 .L82: 555:main.c **** for (;;); 858 .LM71: 859 0388 FFCF rjmp .L82 860 .L81: 556:main.c **** 557:main.c **** } else { 558:main.c **** 559:main.c **** // We want to shut everything down. Setting sensor_timer 560:main.c **** // to the pin value will cause both the communications 561:main.c **** // loop and the regular timeout loop in the main() to 562:main.c **** // give up, which results in the device going to sleep. 563:main.c **** 564:main.c **** sensor_timer.bytes.high_byte = 0xFF; 862 .LM72: 863 038a 8FEF ldi r24,lo8(-1) 864 038c 8093 0000 sts sensor_timer+1,r24 865 /* epilogue: frame size=0 */ 866 0390 8F91 pop r24 867 0392 0F90 pop __tmp_reg__ 868 0394 0FBE out __SREG__,__tmp_reg__ 869 0396 0F90 pop __tmp_reg__ 870 0398 1F90 pop __zero_reg__ 871 039a 1895 reti 872 /* epilogue end (size=6) */ 873 /* function __vector_1 size 26 (14) */ 875 .Lscope4: 878 .global __vector_2 880 __vector_2: 565:main.c **** 566:main.c **** } 567:main.c **** 568:main.c **** } 569:main.c **** 570:main.c **** // Interrupt 1 executes when the hall effect sensor fires 571:main.c **** 572:main.c **** // QUESTION: unlike the pixel output interrupt, this one 573:main.c **** // doesn't sei(). Why? 574:main.c **** 575:main.c **** SIGNAL (SIG_INT1) { 882 .LM73: 883 /* prologue: frame size=0 */ 884 039c 1F92 push __zero_reg__ 885 039e 0F92 push __tmp_reg__ 886 03a0 0FB6 in __tmp_reg__,__SREG__ 887 03a2 0F92 push __tmp_reg__ 888 03a4 1124 clr __zero_reg__ 889 03a6 2F93 push r18 890 03a8 3F93 push r19 891 03aa 4F93 push r20 892 03ac 5F93 push r21 893 03ae 6F93 push r22 894 03b0 7F93 push r23 895 03b2 8F93 push r24 896 03b4 9F93 push r25 897 03b6 AF93 push r26 898 03b8 BF93 push r27 899 03ba EF93 push r30 900 03bc FF93 push r31 901 /* prologue end (size=17) */ 576:main.c **** 577:main.c **** // make sure we don't get bitten by the watchdog 578:main.c **** 579:main.c **** asm("wdr"); 903 .LM74: 904 /* #APP */ 905 03be A895 wdr 580:main.c **** 581:main.c **** // *** PORTB |= 0x8; 582:main.c **** 583:main.c **** // The first issue we need to deal with when the hall-effect 584:main.c **** // sensor tells us it sees the magnet is to avoid doing any 585:main.c **** // processing if we get an interrupt too soon after the previous 586:main.c **** // interrupt. 587:main.c **** 588:main.c **** // hall_debounce is incremented by TIMER0, which fires every 3ms 589:main.c **** // or so. At the current setting of 4, this means that at least 590:main.c **** // 15ms must elapse per trigger, which translates to about 4000 591:main.c **** // rpm. 592:main.c **** 593:main.c **** if (hall_debounce > HALL_DEBOUNCE_THRESH) { 907 .LM75: 908 /* #NOAPP */ 909 03c0 8091 0000 lds r24,hall_debounce 910 03c4 8530 cpi r24,lo8(5) 911 03c6 08F4 brsh .+2 912 03c8 73C0 rjmp .L86 594:main.c **** 595:main.c **** 596:main.c **** // We know the number of ms since the last hall sensor trigger 597:main.c **** // and there are 128 radial 'pixels' per sweep so divide to get 598:main.c **** // the necessary ms between the pixel interrupts 599:main.c **** 600:main.c **** // QUESTION: 128 or 256? 601:main.c **** 602:main.c **** // Then we just make TIMER1 trigger at that rate! 603:main.c **** 604:main.c **** // Reset the Timer Count Register for TIMER1 to 0, so it will 605:main.c **** // begin counting up. 606:main.c **** 607:main.c **** TCNT1 = 0; 914 .LM76: 915 03ca 1DBC out (76)+1-0x20,__zero_reg__ 916 03cc 1CBC out 76-0x20,__zero_reg__ 608:main.c **** 609:main.c **** // sensor_timer contains the number of TIMER0 interrupts since 610:main.c **** // the last time we updated TIMER1. If it has a reasonable 611:main.c **** // value, then we use it to reset the TIMER1 clock. 612:main.c **** 613:main.c **** // if ((sensor_timer.bytes.low_byte < 0xFF) && (sensor_timer.bytes.low_byte > 0x03)) { 614:main.c **** if ((sensor_timer.bytes.high_byte == 0x00) || (sensor_timer.bytes.low_byte > 0x03)) { 918 .LM77: 919 03ce 8091 0000 lds r24,sensor_timer+1 920 03d2 8823 tst r24 921 03d4 29F0 breq .L88 922 03d6 8091 0000 lds r24,sensor_timer 923 03da 8430 cpi r24,lo8(4) 924 03dc 08F4 brsh .+2 925 03de 56C0 rjmp .L87 926 .L88: 615:main.c **** 616:main.c **** // TIMER1 works differently from TIMER0. It's a 16-bit timer 617:main.c **** // that apparently increments at the system clock rate. 618:main.c **** // 619:main.c **** // Because TIMER0 increments at 1/256 of the clock rate, and 620:main.c **** // fires the interrupt only when it overflows, sensor_timer 621:main.c **** // is incremented once ever 256*256 cycles. 622:main.c **** // 623:main.c **** // We want TIMER1 to fire off 256 times around the loop, so 624:main.c **** // we can display 256 lines of pixels. We do this by putting 625:main.c **** // sensor_timer into the high byte of TIMER1's comparator 626:main.c **** // value, and the residual of TIMER0 (what it's counted up 627:main.c **** // to since the last time sensor_timer was incremented) into 628:main.c **** // the low byte, effectively a fractional value! 629:main.c **** // 630:main.c **** // Since TIMER0 is incrementing at 1/256 of the rate of TIMER1, 631:main.c **** // this results in TIMER1 firing off 256 times per rotation, 632:main.c **** // with excellent time resolution. 633:main.c **** // 634:main.c **** // I was quite touched by the elegance of how this works out; 635:main.c **** // it may be able to handle the extreme RPMs of BrightSaber 636:main.c **** // without modification... 637:main.c **** 638:main.c **** // Set the TIMER1 comparator value. As a hack to Limor's hack, 639:main.c **** // reduce the timing a little bit so that the display doesn't 640:main.c **** // span the full 360 degrees, thus giving us a little more time 641:main.c **** // around hall-effect interrupt time to do things. An attempt 642:main.c **** // to get more speed, it doesn't seem to help - so back to the 643:main.c **** // old way of doing things. 644:main.c **** 645:main.c **** // OCR1A = ((sensor_timer << 8) | TCNT0) - (sensor_timer); 646:main.c **** 647:main.c **** // OCR1A = ((sensor_timer << 8) | TCNT0); 648:main.c **** 649:main.c **** OCR1AH = sensor_timer.bytes.low_byte; 928 .LM78: 929 03e0 8091 0000 lds r24,sensor_timer 930 03e4 8BBD out 75-0x20,r24 650:main.c **** OCR1AL = TCNT0; 932 .LM79: 933 03e6 82B7 in r24,82-0x20 934 03e8 8ABD out 74-0x20,r24 651:main.c **** 652:main.c **** // Clear the residual of TIMER0 653:main.c **** 654:main.c **** TCNT0 = 0; 936 .LM80: 937 03ea 12BE out 82-0x20,__zero_reg__ 655:main.c **** 656:main.c **** // The code for no scrolling is NUM_LINES = 0 657:main.c **** 658:main.c **** #if NUM_LINES > 0 659:main.c **** 660:main.c **** // Check the line timer; if it has reached a particular value 661:main.c **** // then increment line_shift. When that reaches 16, wrap it 662:main.c **** // and increment cur_line. This system lets us be a little 663:main.c **** // more flexible in our timing system, and permits long delays 664:main.c **** // in the scrolling. 665:main.c **** 666:main.c **** if (line_timer >= SCROLLSPEED) { 939 .LM81: 940 03ec 8091 0000 lds r24,line_timer 941 03f0 8031 cpi r24,lo8(16) 942 03f2 D0F0 brlo .L89 667:main.c **** 668:main.c **** line_timer = line_timer - SCROLLSPEED; // reset in a safe way that retains any residual 944 .LM82: 945 03f4 8091 0000 lds r24,line_timer 946 03f8 8051 subi r24,lo8(-(-16)) 947 03fa 8093 0000 sts line_timer,r24 669:main.c **** line_shift = (line_shift + 1) & 0x0f; // increment line_shift 949 .LM83: 950 03fe 8091 0000 lds r24,line_shift 951 0402 8F5F subi r24,lo8(-(1)) 952 0404 8F70 andi r24,lo8(15) 953 0406 8093 0000 sts line_shift,r24 670:main.c **** 671:main.c **** if (line_shift == 0x00) { 955 .LM84: 956 040a 9091 0000 lds r25,line_shift 957 040e 9923 tst r25 958 0410 59F4 brne .L89 672:main.c **** 673:main.c **** // Move down LINEINC lines in the line list, wrapping around 674:main.c **** // Made the mistake of using % which isn't a good thing 675:main.c **** // on a chip without mult/div... 676:main.c **** 677:main.c **** cur_line += LINEINC; 960 .LM85: 961 0412 8091 0000 lds r24,cur_line 962 0416 8F5F subi r24,lo8(-(1)) 963 0418 8093 0000 sts cur_line,r24 678:main.c **** 679:main.c **** if (cur_line >= NUM_LINES) { 965 .LM86: 966 041c 8091 0000 lds r24,cur_line 967 0420 8930 cpi r24,lo8(9) 968 0422 10F0 brlo .L89 680:main.c **** cur_line = 0; 970 .LM87: 971 0424 9093 0000 sts cur_line,r25 972 .L89: 973 .LBB2: 681:main.c **** } 682:main.c **** 683:main.c **** } 684:main.c **** 685:main.c **** } 686:main.c **** 687:main.c **** #else 688:main.c **** 689:main.c **** // we could do this just once when the app initializes, but 690:main.c **** // for now, let's do it here. Later we'll move it. 691:main.c **** 692:main.c **** cur_line = line_shift = 0; 693:main.c **** 694:main.c **** #endif 695:main.c **** 696:main.c **** // read in the code, and if need be, the pixel data 697:main.c **** 698:main.c **** cur_code = pgm_read_byte(&lines[cur_line]); 975 .LM88: 976 0428 8091 0000 lds r24,cur_line 977 042c E82F mov r30,r24 978 042e FF27 clr r31 979 0430 E050 subi r30,lo8(-(lines)) 980 0432 F040 sbci r31,hi8(-(lines)) 981 /* #APP */ 982 0434 C895 lpm 983 0436 802D mov r24, r0 984 985 /* #NOAPP */ 986
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -