|
移动物体 物体是一个4像素乘4像素的正方形,从左到右重复移动。
在从一个像素到右边的目标移动之间存在30ms的延迟。该范围捕获显示传输到OLED控制器的数据包;如上所述,数据包(即,用于更新整个屏幕的数据字节)大约为6毫秒宽,现在我们在数据包之间有30毫秒。
以下代码摘录为您提供了整个main()函数。移动物体功能处于无限循环中。 - int main (void)
- {
- //clock configuration and initialization
- sysclk_init();
-
- /*Disable the watchdog timer and configure/initialize
- port pins connected to various components incorporated
- into the SAM4S Xplained development platform, e.g., the
- NAND flash, the OLED interface, the LEDs, the SW0 pushbutton.*/
- board_init();
- //initialize SPI and the OLED controller
- ssd1306_init();
-
- /*These two statements configure the OLED module for
- "horizontal addressing mode."*/
- ssd1306_write_command(SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE);
- ssd1306_write_command(0x00);
-
- Configure_Pushbutton2();
-
- /*This function clears all the pixels in the array; it does not
- update the OLED display.*/
- Clear_OLED_Array();
-
- Update_OLED_Display();
-
- /*These variables hold the row and column address
- corresponding to the top-left pixel of the
- 4-pixel-by-4-pixel square target. The row address
- is set to 14 because we want the target to be in the
- middle of the display, and the column address is set
- to 0 so that the target starts from the left-hand
- edge of the screen.*/
- TargetRow = 14;
- TargetColumn = 0;
-
- while (1)
- {
- //form the 4-pixel-by-4-pixel square target
- Set_OLED_Pixel(TargetRow, TargetColumn);
- Set_OLED_Pixel(TargetRow, TargetColumn+1);
- Set_OLED_Pixel(TargetRow, TargetColumn+2);
- Set_OLED_Pixel(TargetRow, TargetColumn+3);
- Set_OLED_Pixel(TargetRow+1, TargetColumn);
- Set_OLED_Pixel(TargetRow+1, TargetColumn+1);
- Set_OLED_Pixel(TargetRow+1, TargetColumn+2);
- Set_OLED_Pixel(TargetRow+1, TargetColumn+3);
- Set_OLED_Pixel(TargetRow+2, TargetColumn);
- Set_OLED_Pixel(TargetRow+2, TargetColumn+1);
- Set_OLED_Pixel(TargetRow+2, TargetColumn+2);
- Set_OLED_Pixel(TargetRow+2, TargetColumn+3);
- Set_OLED_Pixel(TargetRow+3, TargetColumn);
- Set_OLED_Pixel(TargetRow+3, TargetColumn+1);
- Set_OLED_Pixel(TargetRow+3, TargetColumn+2);
- Set_OLED_Pixel(TargetRow+3, TargetColumn+3);
-
- Update_OLED_Display();
-
- delay_ms(30);
-
- //clear the previous target
- Clear_OLED_Pixel(TargetRow, TargetColumn);
- Clear_OLED_Pixel(TargetRow, TargetColumn+1);
- Clear_OLED_Pixel(TargetRow, TargetColumn+2);
- Clear_OLED_Pixel(TargetRow, TargetColumn+3);
- Clear_OLED_Pixel(TargetRow+1, TargetColumn);
- Clear_OLED_Pixel(TargetRow+1, TargetColumn+1);
- Clear_OLED_Pixel(TargetRow+1, TargetColumn+2);
- Clear_OLED_Pixel(TargetRow+1, TargetColumn+3);
- Clear_OLED_Pixel(TargetRow+2, TargetColumn);
- Clear_OLED_Pixel(TargetRow+2, TargetColumn+1);
- Clear_OLED_Pixel(TargetRow+2, TargetColumn+2);
- Clear_OLED_Pixel(TargetRow+2, TargetColumn+3);
- Clear_OLED_Pixel(TargetRow+3, TargetColumn);
- Clear_OLED_Pixel(TargetRow+3, TargetColumn+1);
- Clear_OLED_Pixel(TargetRow+3, TargetColumn+2);
- Clear_OLED_Pixel(TargetRow+3, TargetColumn+3);
-
- /*Move the target one pixel to the right. If the
- right edge of the target has reached the last
- display column, return the target to the left-hand
- edge of the screen.*/
- TargetColumn++;
- if ( (TargetColumn+3) == OLED_WIDTH_PIXELS)
- {
- TargetColumn = 0;
- }
- }
- }
复制代码
射击激光
按下按钮2即可激活激光器。我们需要启用连接到按钮2的端口引脚并配置其中断(按钮功能是中断驱动的)。 - static void Configure_Pushbutton2(void)
- {
- /*Enable the clock for PIOC, which is one of the parallel
- input/output controllers. The pushbutton 2 signal is connected
- to a pin included in PIOC.*/
- pmc_enable_periph_clk(ID_PIOC);
-
- /*Configure the integrated debounce functionality for the pin
- connected to pushbutton 2.*/
- pio_set_debounce_filter(PIOC, PIN_PUSHBUTTON_2_MASK, 10);
-
- /*This assigns an interrupt handler function for the pushbutton 2
- interrupt. The third parameter consists of attributes used in the
- process of configuring the interrupt. In this case the attributes
- parameter indicates that the pin's internal pull-up is active, that
- the pin's debounce filter is active, and that the interrupt fires on
- the falling edge.*/
- pio_handler_set(PIOC, ID_PIOC, PIN_PUSHBUTTON_2_MASK, PIN_PUSHBUTTON_2_ATTR, PushButton2_InterruptHandler);
-
- //enable PIOC interrupts in the NVIC (nested vectored interrupt controller)
- NVIC_EnableIRQ((IRQn_Type) ID_PIOC);
-
- //15 is the lowest priority, 0 is the highest priority
- pio_handler_set_priority(PIOC, (IRQn_Type) ID_PIOC, 0);
-
- /*Enable the pushbutton 2 interrupt source. Note that it is necessary
- to both "enable the interrupt" and "enable the interrupt in the NVIC."*/
- pio_enable_interrupt(PIOC, PIN_PUSHBUTTON_2_MASK);
- }
复制代码
激光器显示为垂直线,其从屏幕的底部中心快速向上延伸(即,行= 31,列= 63)。 如果激光击中目标,则程序产生“碎片效应”,即正方形消失并被四个向外扩展的像素(从正方形的每个角落一个)取代。 我意识到这不符合质量守恒,考虑到原始目标总共有16个像素; 我们假设其他12个像素被汽化成不可见的小颗粒。
这是按钮2中断处理程序,包括所有的激光函数。
- static void PushButton2_InterruptHandler(uint32_t id, uint32_t mask)
- {
- /*Confirm that the source of the interrupt is pushbutton 2. This seems
- unnecessary to me, but it is included in Atmel's example code.*/
- if ((id == ID_PIOC) && (mask == PIN_PUSHBUTTON_2_MASK))
- {
- /*Disable the pushbutton 2 interrupt to prevent spurious
- interrupts caused by switch bounce. I probed the pushbutton
- signal, and it looks like the spurious transitions occur at the end
- of the signal's active-low state, so disabling the interrupt as
- soon as we enter the interrupt handler effectively suppresses
- the spurious interrupt requests. For some reason I was not able
- to completely resolve this problem by means of the pin's integrated
- debounce filter.*/
- pio_disable_interrupt(PIOC, PIN_PUSHBUTTON_2_MASK);
-
- //these next 8 groups of statements create the laser beam
- Set_OLED_Pixel(31, 63);
- Set_OLED_Pixel(30, 63);
- Set_OLED_Pixel(29, 63);
- Set_OLED_Pixel(28, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(27, 63);
- Set_OLED_Pixel(26, 63);
- Set_OLED_Pixel(25, 63);
- Set_OLED_Pixel(24, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(23, 63);
- Set_OLED_Pixel(22, 63);
- Set_OLED_Pixel(21, 63);
- Set_OLED_Pixel(20, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(19, 63);
- Set_OLED_Pixel(18, 63);
- Set_OLED_Pixel(17, 63);
- Set_OLED_Pixel(16, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(15, 63);
- Set_OLED_Pixel(14, 63);
- Set_OLED_Pixel(13, 63);
- Set_OLED_Pixel(12, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(11, 63);
- Set_OLED_Pixel(10, 63);
- Set_OLED_Pixel(9, 63);
- Set_OLED_Pixel(8, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(7, 63);
- Set_OLED_Pixel(6, 63);
- Set_OLED_Pixel(5, 63);
- Set_OLED_Pixel(4, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- Set_OLED_Pixel(3, 63);
- Set_OLED_Pixel(2, 63);
- Set_OLED_Pixel(1, 63);
- Set_OLED_Pixel(0, 63);
- Update_OLED_Display();
- delay_ms(10);
-
- /*Does the target currently include the laser-beam column?
- If so, clear the OLED array to remove the target and the laser,
- then create the debris effect. After that, clear the OLED screen
- and return the target to its starting position.*/
- if (TargetColumn >= 60 && TargetColumn <= 63)
- {
- Clear_OLED_Array();
-
- Set_OLED_Pixel(TargetRow-1, TargetColumn-1);
- Set_OLED_Pixel(TargetRow-1, TargetColumn+4);
- Set_OLED_Pixel(TargetRow+4, TargetColumn-1);
- Set_OLED_Pixel(TargetRow+4, TargetColumn+4);
- Update_OLED_Display();
- delay_ms(200);
-
- Clear_OLED_Pixel(TargetRow-1, TargetColumn-1);
- Clear_OLED_Pixel(TargetRow-1, TargetColumn+4);
- Clear_OLED_Pixel(TargetRow+4, TargetColumn-1);
- Clear_OLED_Pixel(TargetRow+4, TargetColumn+4);
-
- Set_OLED_Pixel(TargetRow-2, TargetColumn-2);
- Set_OLED_Pixel(TargetRow-2, TargetColumn+5);
- Set_OLED_Pixel(TargetRow+5, TargetColumn-2);
- Set_OLED_Pixel(TargetRow+5, TargetColumn+5);
- Update_OLED_Display();
- delay_ms(200);
-
- Clear_OLED_Pixel(TargetRow-2, TargetColumn-2);
- Clear_OLED_Pixel(TargetRow-2, TargetColumn+5);
- Clear_OLED_Pixel(TargetRow+5, TargetColumn-2);
- Clear_OLED_Pixel(TargetRow+5, TargetColumn+5);
- Set_OLED_Pixel(TargetRow-3, TargetColumn-3);
- Set_OLED_Pixel(TargetRow-3, TargetColumn+6);
- Set_OLED_Pixel(TargetRow+6, TargetColumn-3);
- Set_OLED_Pixel(TargetRow+6, TargetColumn+6);
- Update_OLED_Display();
- delay_ms(200);
-
- Clear_OLED_Pixel(TargetRow-3, TargetColumn-3);
- Clear_OLED_Pixel(TargetRow-3, TargetColumn+6);
- Clear_OLED_Pixel(TargetRow+6, TargetColumn-3);
- Clear_OLED_Pixel(TargetRow+6, TargetColumn+6);
-
- Set_OLED_Pixel(TargetRow-4, TargetColumn-4);
- Set_OLED_Pixel(TargetRow-4, TargetColumn+7);
- Set_OLED_Pixel(TargetRow+7, TargetColumn-4);
- Set_OLED_Pixel(TargetRow+7, TargetColumn+7);
- Update_OLED_Display();
- delay_ms(200);
-
- Clear_OLED_Pixel(TargetRow-4, TargetColumn-4);
- Clear_OLED_Pixel(TargetRow-4, TargetColumn+7);
- Clear_OLED_Pixel(TargetRow+7, TargetColumn-4);
- Clear_OLED_Pixel(TargetRow+7, TargetColumn+7);
-
- Set_OLED_Pixel(TargetRow-5, TargetColumn-5);
- Set_OLED_Pixel(TargetRow-5, TargetColumn+8);
- Set_OLED_Pixel(TargetRow+8, TargetColumn-5);
- Set_OLED_Pixel(TargetRow+8, TargetColumn+8);
- Update_OLED_Display();
- delay_ms(200);
-
- Clear_OLED_Pixel(TargetRow-5, TargetColumn-5);
- Clear_OLED_Pixel(TargetRow-5, TargetColumn+8);
- Clear_OLED_Pixel(TargetRow+8, TargetColumn-5);
- Clear_OLED_Pixel(TargetRow+8, TargetColumn+8);
-
- Set_OLED_Pixel(TargetRow-6, TargetColumn-6);
- Set_OLED_Pixel(TargetRow-6, TargetColumn+9);
- Set_OLED_Pixel(TargetRow+9, TargetColumn-6);
- Set_OLED_Pixel(TargetRow+9, TargetColumn+9);
- Update_OLED_Display();
- delay_ms(200);
-
- Clear_OLED_Pixel(TargetRow-6, TargetColumn-6);
- Clear_OLED_Pixel(TargetRow-6, TargetColumn+9);
- Clear_OLED_Pixel(TargetRow+9, TargetColumn-6);
- Clear_OLED_Pixel(TargetRow+9, TargetColumn+9);
-
- Set_OLED_Pixel(TargetRow-7, TargetColumn-7);
- Set_OLED_Pixel(TargetRow-7, TargetColumn+10);
- Set_OLED_Pixel(TargetRow+10, TargetColumn-7);
- Set_OLED_Pixel(TargetRow+10, TargetColumn+10);
- Update_OLED_Display();
- delay_ms(500);
-
- Clear_OLED_Array();
- Update_OLED_Display();
- delay_ms(1000);
-
- TargetColumn = 0;
- }
-
- /*If the laser beam missed the target, clear the laser beam pixels.
- Nothing else needs to be done; the target will continue moving
- when execution returns to the infinite loop in main().*/
- else
- {
- OLED_Pixels[0][63] = 0;
- OLED_Pixels[1][63] = 0;
- OLED_Pixels[2][63] = 0;
- OLED_Pixels[3][63] = 0;
- }
-
- //reenable the pushbutton 2 interrupt
- pio_enable_interrupt(PIOC, PIN_PUSHBUTTON_2_MASK);
- }
- }
复制代码
|