一板网电子技术论坛

风筝
发表于: 2018-8-27 17:28:06 | 显示全部楼层

本篇文章主要提供了与代码开发、硬件配置和OLED接口相关的其他详细信息。


所需的硬件/软件

●    SAM4S Xplained Pro入门套件

●    Atmel Studio


一个简单的显示驱动程序

在上一篇文章的最后,我们成功创建了一个新项目,用于配置和初始化ATSAM4SD32C微控制器,然后在OLED显示屏上重复显示简单的文本消息。也许这个功能对你来说足够令人兴奋,但我并不十分满意。所以,让我们继续开发一款视频游戏,它包括一个移动的方形目标和一个按下按钮时激发的激光束。如果激光束击中目标,你就赢了。如果激光束未击中目标,则继续射击直至获胜。


我们需要的第一件事就是为视频游戏提供一个非常简单的显示驱动,这可以让我们很方便的在OLED屏幕内任何位置设置和清除像素点。此外,我们希望在微控制器中保持与屏幕当前状态相对应的存储器。这允许我们在不从OLED控制器读取数据的情况下检查像素的状态;这对我们特定的硬件配置尤为重要,因为我们通过SPI与OLED模块通信,OLED控制器的SPI接口(与其并行接口不同)不支持读操作。


页和列

首先,我们需要了解OLED像素的排列方式。请仔细查看SSD1306数据表中的以下两个图表。

OLEDT2_datasheet1.jpg

OLEDT2_datasheet2.jpg

所以我们这里有8页“垂直像素”和128列水平像素。每页包含8个垂直像素,使得总分辨率为64个垂直像素×128个水平像素。然而,显示器的物理尺寸是32个垂直像素×128个水平像素;因此,OLED控制器具有足够的8个垂直页面的像素存储器,但是一次只能显示4个页面。


我们通过SPI写一个字节来修改OLED显示。该字节控制对应于当前所选页面和列地址的8个垂直像素。第二个图表示页面中像素与写入字节内的位之间的关系 - 字节中的最低有效位对应于页面中的最高像素,最高有效位对应于最低像素。


单个像素与所有像素

可以只修改一页的一列;您可以通过设置列和页面地址然后写入单个数据字节来完成此操作。 ASF函数是ssd1306_set_page_address()和ssd1306_set_column_address(),后跟ssd1306_write_data()。不过,我更喜欢修改显示缓冲区中的像素,然后更新整个屏幕。我发现这种方法更加通用和直观。它可能看起来效率很低,但实际上并不太糟糕。其中一个原因是OLED的SPI接口支持相当高的时钟速率。以下示波器线显示SPI时钟信号,当前配置为以5 MHz运行(OLED控制器支持的最大值为10 MHz)。

OLEDT2_scope1.jpg

因此,写一个字节只需1.6μs。您会认为我们可以在约(1.6μs)×(128列)×(4页)≈0.8ms内更新整个屏幕,但实际上需要更长的时间,因为连续字节之间有大约10μs的死区时间。故意将此死区时间合并到ssd1306_write_data()函数中以适应SSD1306的延迟,尽管函数中的注释表明死区时间可能低至3μs,因此我不确定为什么Atmel选择了10μs 。如果你想加快速度,可以尝试减少ssd1306_write_data()中的延迟。无论如何,对于当前的延迟,它应该花费大约(11.6μs)×(128列)×(4页)≈5.9ms来更新整个屏幕,并且范围确认情况确实如此:

OLEDT2_scope2.jpg

因此,我们可以看到更新整个屏幕所需的时间并不过分,特别是如果您考虑即使在每秒30帧,我们在屏幕更新之间也会有33毫秒。



驱动程序代码

我使用以下二维数组作为显示缓冲区:

  1. //Preprocessor definitions
  2. #define OLED_HEIGHT_BYTES 32/8
  3. #define OLED_WIDTH_PIXELS 128

  4. //Global variables
  5. unsigned char OLED_Pixels[OLED_HEIGHT_BYTES][OLED_WIDTH_PIXELS];
复制代码

以下两个函数修改显示缓冲区中的单个像素:

  1. /*This function sets one OLED pixel identified by the Row and Column parameters.
  2. Keep in mind that the OLED array rows are addressed as bytes (of 8 pixels), whereas
  3. the Row parameter passed to this function is a pixel address.*/   
  4. static inline void Set_OLED_Pixel(unsigned char Row, unsigned char Column)
  5. {
  6.         if (Row < 8)
  7.         {
  8.                 OLED_Pixels[0][Column] |= (0x01 << Row);
  9.         }
  10.         
  11.         else if (Row < 16)
  12.         {
  13.                 OLED_Pixels[1][Column] |= (0x01 << (Row - 8));
  14.         }
  15.         
  16.         else if (Row < 24)
  17.         {
  18.                 OLED_Pixels[2][Column] |= (0x01 << (Row - 16));
  19.         }
  20.         
  21.         else if (Row < 32)
  22.         {
  23.                 OLED_Pixels[3][Column] |= (0x01 << (Row - 24));
  24.         }
  25. }

  26. /*This function clears one OLED pixel identified by the Row and Column parameters.
  27. Keep in mind that the OLED array rows are addressed as bytes (of 8 pixels), whereas
  28. the Row parameter passed to this function is a pixel address.*/
  29. static inline void Clear_OLED_Pixel(unsigned char Row, unsigned char Column)
  30. {
  31.         if (Row < 8)
  32.         {
  33.                 OLED_Pixels[0][Column] &= ~(0x01 << Row);
  34.         }
  35.         
  36.         else if (Row < 16)
  37.         {
  38.                 OLED_Pixels[1][Column] &= ~(0x01 << (Row - 8));
  39.         }
  40.         
  41.         else if (Row < 24)
  42.         {
  43.                 OLED_Pixels[2][Column] &= ~(0x01 << (Row - 16));
  44.         }
  45.         
  46.         else if (Row < 32)
  47.         {
  48.                 OLED_Pixels[3][Column] &= ~(0x01 << (Row - 24));
  49.         }
  50. }
复制代码

请注意,我将这些声明为“内联inline”函数,以便它们更快地执行。

这是我用来清除显示缓冲区中所有像素的函数:

  1. static void Clear_OLED_Array(void)
  2. {
  3.         unsigned char x, y;
  4.                
  5.         for (x = 0; x < OLED_HEIGHT_BYTES; x++)
  6.         {
  7.                 for (y = 0; y < OLED_WIDTH_PIXELS; y++)
  8.                 {
  9.                         OLED_Pixels[x][y] = 0;
  10.                 }
  11.         }
  12. }
复制代码

请注意,这三个函数实际上并不更新OLED屏幕;他们只是修改缓冲区。 通过将显示缓冲区的内容复制到OLED控制器中的内存来更新屏幕:

  1. static void Update_OLED_Display(void)
  2. {
  3.         unsigned char Row, Column;
  4.         
  5.         ssd1306_set_page_address(0);
  6.         ssd1306_set_column_address(0);
  7.         
  8.         for (Row = 0; Row < OLED_HEIGHT_BYTES; Row++)
  9.         {
  10.                 for (Column = 0; Column < OLED_WIDTH_PIXELS; Column++)
  11.                 {
  12.                         ssd1306_write_data(OLED_Pixels[Row][Column]);
  13.                 }
  14.         }
  15. }
复制代码

该函数根据以下模式将所有字节从显示缓冲区写入OLED控制器:第0页,第0列;第0页,第1栏;...第0页,第127栏;第1页,第0栏; ...;第1页,第127栏;第2页,第0栏; ...第2页,第127栏;第3页,第0栏; ...;第3页,第127列。请记住,这些字节是一个接一个地写入的,没有任何插入的内存地址信息。因此,我们需要确保OLED控制器正确识别这些数据。为此,我们将其配置为“水平寻址模式”:

OLEDT2_datasheet3.jpg


在此模式下操作时,OLED控制器将以与我们发送显示缓冲区内容的方式一致的方式自动更新其地址指针。


跳转到指定楼层
风筝
发表于: 2018-8-27 17:30:49 | 显示全部楼层

移动物体

物体是一个4像素乘4像素的正方形,从左到右重复移动。

在从一个像素到右边的目标移动之间存在30ms的延迟。该范围捕获显示传输到OLED控制器的数据包;如上所述,数据包(即,用于更新整个屏幕的数据字节)大约为6毫秒宽,现在我们在数据包之间有30毫秒。

OLEDT2_scope3_3.jpg


以下代码摘录为您提供了整个main()函数。移动物体功能处于无限循环中。

  1. int main (void)
  2. {        
  3.         //clock configuration and initialization
  4.         sysclk_init();
  5.         
  6.         /*Disable the watchdog timer and configure/initialize
  7.         port pins connected to various components incorporated
  8.         into the SAM4S Xplained development platform, e.g., the
  9.         NAND flash, the OLED interface, the LEDs, the SW0 pushbutton.*/  
  10.         board_init();

  11.         //initialize SPI and the OLED controller
  12.         ssd1306_init();
  13.         
  14.         /*These two statements configure the OLED module for
  15.         "horizontal addressing mode."*/
  16.         ssd1306_write_command(SSD1306_CMD_SET_MEMORY_ADDRESSING_MODE);
  17.         ssd1306_write_command(0x00);
  18.         
  19.         Configure_Pushbutton2();
  20.         
  21.         /*This function clears all the pixels in the array; it does not
  22.         update the OLED display.*/
  23.         Clear_OLED_Array();
  24.         
  25.         Update_OLED_Display();
  26.                
  27.         /*These variables hold the row and column address
  28.         corresponding to the top-left pixel of the
  29.         4-pixel-by-4-pixel square target. The row address
  30.         is set to 14 because we want the target to be in the
  31.         middle of the display, and the column address is set
  32.         to 0 so that the target starts from the left-hand
  33.         edge of the screen.*/
  34.         TargetRow = 14;
  35.         TargetColumn = 0;
  36.         
  37.         while (1)
  38.         {
  39.                 //form the 4-pixel-by-4-pixel square target
  40.                 Set_OLED_Pixel(TargetRow, TargetColumn);
  41.                 Set_OLED_Pixel(TargetRow, TargetColumn+1);
  42.                 Set_OLED_Pixel(TargetRow, TargetColumn+2);
  43.                 Set_OLED_Pixel(TargetRow, TargetColumn+3);
  44.                 Set_OLED_Pixel(TargetRow+1, TargetColumn);
  45.                 Set_OLED_Pixel(TargetRow+1, TargetColumn+1);
  46.                 Set_OLED_Pixel(TargetRow+1, TargetColumn+2);
  47.                 Set_OLED_Pixel(TargetRow+1, TargetColumn+3);
  48.                 Set_OLED_Pixel(TargetRow+2, TargetColumn);
  49.                 Set_OLED_Pixel(TargetRow+2, TargetColumn+1);
  50.                 Set_OLED_Pixel(TargetRow+2, TargetColumn+2);
  51.                 Set_OLED_Pixel(TargetRow+2, TargetColumn+3);
  52.                 Set_OLED_Pixel(TargetRow+3, TargetColumn);
  53.                 Set_OLED_Pixel(TargetRow+3, TargetColumn+1);
  54.                 Set_OLED_Pixel(TargetRow+3, TargetColumn+2);
  55.                 Set_OLED_Pixel(TargetRow+3, TargetColumn+3);
  56.                
  57.                 Update_OLED_Display();
  58.                
  59.                 delay_ms(30);
  60.                
  61.                 //clear the previous target
  62.                 Clear_OLED_Pixel(TargetRow, TargetColumn);
  63.                 Clear_OLED_Pixel(TargetRow, TargetColumn+1);
  64.                 Clear_OLED_Pixel(TargetRow, TargetColumn+2);
  65.                 Clear_OLED_Pixel(TargetRow, TargetColumn+3);
  66.                 Clear_OLED_Pixel(TargetRow+1, TargetColumn);
  67.                 Clear_OLED_Pixel(TargetRow+1, TargetColumn+1);
  68.                 Clear_OLED_Pixel(TargetRow+1, TargetColumn+2);
  69.                 Clear_OLED_Pixel(TargetRow+1, TargetColumn+3);
  70.                 Clear_OLED_Pixel(TargetRow+2, TargetColumn);
  71.                 Clear_OLED_Pixel(TargetRow+2, TargetColumn+1);
  72.                 Clear_OLED_Pixel(TargetRow+2, TargetColumn+2);
  73.                 Clear_OLED_Pixel(TargetRow+2, TargetColumn+3);
  74.                 Clear_OLED_Pixel(TargetRow+3, TargetColumn);
  75.                 Clear_OLED_Pixel(TargetRow+3, TargetColumn+1);
  76.                 Clear_OLED_Pixel(TargetRow+3, TargetColumn+2);
  77.                 Clear_OLED_Pixel(TargetRow+3, TargetColumn+3);
  78.                
  79.                 /*Move the target one pixel to the right. If the
  80.                 right edge of the target has reached the last
  81.                 display column, return the target to the left-hand
  82.                 edge of the screen.*/
  83.                 TargetColumn++;
  84.                 if ( (TargetColumn+3) == OLED_WIDTH_PIXELS)
  85.                 {
  86.                         TargetColumn = 0;
  87.                 }
  88.         }
  89. }
复制代码

射击激光

按下按钮2即可激活激光器。我们需要启用连接到按钮2的端口引脚并配置其中断(按钮功能是中断驱动的)。

  1. static void Configure_Pushbutton2(void)
  2. {
  3.         /*Enable the clock for PIOC, which is one of the parallel
  4.         input/output controllers. The pushbutton 2 signal is connected
  5.         to a pin included in PIOC.*/
  6.         pmc_enable_periph_clk(ID_PIOC);
  7.         
  8.         /*Configure the integrated debounce functionality for the pin
  9.         connected to pushbutton 2.*/
  10.         pio_set_debounce_filter(PIOC, PIN_PUSHBUTTON_2_MASK, 10);
  11.         
  12.         /*This assigns an interrupt handler function for the pushbutton 2
  13.         interrupt. The third parameter consists of attributes used in the
  14.         process of configuring the interrupt. In this case the attributes
  15.         parameter indicates that the pin's internal pull-up is active, that
  16.         the pin's debounce filter is active, and that the interrupt fires on
  17.         the falling edge.*/
  18.         pio_handler_set(PIOC, ID_PIOC, PIN_PUSHBUTTON_2_MASK, PIN_PUSHBUTTON_2_ATTR, PushButton2_InterruptHandler);
  19.         
  20.         //enable PIOC interrupts in the NVIC (nested vectored interrupt controller)
  21.         NVIC_EnableIRQ((IRQn_Type) ID_PIOC);
  22.         
  23.         //15 is the lowest priority, 0 is the highest priority
  24.         pio_handler_set_priority(PIOC, (IRQn_Type) ID_PIOC, 0);
  25.         
  26.         /*Enable the pushbutton 2 interrupt source. Note that it is necessary
  27.         to both "enable the interrupt" and "enable the interrupt in the NVIC."*/
  28.         pio_enable_interrupt(PIOC, PIN_PUSHBUTTON_2_MASK);
  29. }
复制代码

激光器显示为垂直线,其从屏幕的底部中心快速向上延伸(即,行= 31,列= 63)。 如果激光击中目标,则程序产生“碎片效应”,即正方形消失并被四个向外扩展的像素(从正方形的每个角落一个)取代。 我意识到这不符合质量守恒,考虑到原始目标总共有16个像素; 我们假设其他12个像素被汽化成不可见的小颗粒。


这是按钮2中断处理程序,包括所有的激光函数。

  1. static void PushButton2_InterruptHandler(uint32_t id, uint32_t mask)
  2. {        
  3.         /*Confirm that the source of the interrupt is pushbutton 2. This seems
  4.         unnecessary to me, but it is included in Atmel's example code.*/
  5.         if ((id == ID_PIOC) && (mask == PIN_PUSHBUTTON_2_MASK))
  6.         {
  7.                 /*Disable the pushbutton 2 interrupt to prevent spurious
  8.                 interrupts caused by switch bounce. I probed the pushbutton
  9.                 signal, and it looks like the spurious transitions occur at the end
  10.                 of the signal's active-low state, so disabling the interrupt as
  11.                 soon as we enter the interrupt handler effectively suppresses
  12.                 the spurious interrupt requests. For some reason I was not able
  13.                 to completely resolve this problem by means of the pin's integrated
  14.                 debounce filter.*/
  15.                 pio_disable_interrupt(PIOC, PIN_PUSHBUTTON_2_MASK);
  16.                
  17.                 //these next 8 groups of statements create the laser beam
  18.                 Set_OLED_Pixel(31, 63);
  19.                 Set_OLED_Pixel(30, 63);
  20.                 Set_OLED_Pixel(29, 63);
  21.                 Set_OLED_Pixel(28, 63);
  22.                 Update_OLED_Display();
  23.                 delay_ms(10);
  24.                
  25.                 Set_OLED_Pixel(27, 63);
  26.                 Set_OLED_Pixel(26, 63);
  27.                 Set_OLED_Pixel(25, 63);
  28.                 Set_OLED_Pixel(24, 63);
  29.                 Update_OLED_Display();
  30.                 delay_ms(10);
  31.                
  32.                 Set_OLED_Pixel(23, 63);
  33.                 Set_OLED_Pixel(22, 63);
  34.                 Set_OLED_Pixel(21, 63);
  35.                 Set_OLED_Pixel(20, 63);
  36.                 Update_OLED_Display();
  37.                 delay_ms(10);
  38.                                 
  39.                 Set_OLED_Pixel(19, 63);
  40.                 Set_OLED_Pixel(18, 63);
  41.                 Set_OLED_Pixel(17, 63);
  42.                 Set_OLED_Pixel(16, 63);
  43.                 Update_OLED_Display();
  44.                 delay_ms(10);
  45.                                                 
  46.                 Set_OLED_Pixel(15, 63);
  47.                 Set_OLED_Pixel(14, 63);
  48.                 Set_OLED_Pixel(13, 63);
  49.                 Set_OLED_Pixel(12, 63);
  50.                 Update_OLED_Display();
  51.                 delay_ms(10);
  52.                         
  53.                 Set_OLED_Pixel(11, 63);
  54.                 Set_OLED_Pixel(10, 63);
  55.                 Set_OLED_Pixel(9, 63);
  56.                 Set_OLED_Pixel(8, 63);
  57.                 Update_OLED_Display();
  58.                 delay_ms(10);
  59.                                                 
  60.                 Set_OLED_Pixel(7, 63);
  61.                 Set_OLED_Pixel(6, 63);
  62.                 Set_OLED_Pixel(5, 63);
  63.                 Set_OLED_Pixel(4, 63);
  64.                 Update_OLED_Display();
  65.                 delay_ms(10);
  66.                
  67.                 Set_OLED_Pixel(3, 63);
  68.                 Set_OLED_Pixel(2, 63);
  69.                 Set_OLED_Pixel(1, 63);
  70.                 Set_OLED_Pixel(0, 63);
  71.                 Update_OLED_Display();
  72.                 delay_ms(10);
  73.                
  74.                 /*Does the target currently include the laser-beam column?
  75.                 If so, clear the OLED array to remove the target and the laser,
  76.                 then create the debris effect. After that, clear the OLED screen
  77.                 and return the target to its starting position.*/
  78.                 if (TargetColumn >= 60 && TargetColumn <= 63)
  79.                 {
  80.                         Clear_OLED_Array();
  81.                         
  82.                         Set_OLED_Pixel(TargetRow-1, TargetColumn-1);
  83.                         Set_OLED_Pixel(TargetRow-1, TargetColumn+4);
  84.                         Set_OLED_Pixel(TargetRow+4, TargetColumn-1);
  85.                         Set_OLED_Pixel(TargetRow+4, TargetColumn+4);
  86.                         Update_OLED_Display();
  87.                         delay_ms(200);
  88.                         
  89.                         Clear_OLED_Pixel(TargetRow-1, TargetColumn-1);
  90.                         Clear_OLED_Pixel(TargetRow-1, TargetColumn+4);
  91.                         Clear_OLED_Pixel(TargetRow+4, TargetColumn-1);
  92.                         Clear_OLED_Pixel(TargetRow+4, TargetColumn+4);
  93.                         
  94.                         Set_OLED_Pixel(TargetRow-2, TargetColumn-2);
  95.                         Set_OLED_Pixel(TargetRow-2, TargetColumn+5);
  96.                         Set_OLED_Pixel(TargetRow+5, TargetColumn-2);
  97.                         Set_OLED_Pixel(TargetRow+5, TargetColumn+5);
  98.                         Update_OLED_Display();
  99.                         delay_ms(200);
  100.                         
  101.                         Clear_OLED_Pixel(TargetRow-2, TargetColumn-2);
  102.                         Clear_OLED_Pixel(TargetRow-2, TargetColumn+5);
  103.                         Clear_OLED_Pixel(TargetRow+5, TargetColumn-2);
  104.                         Clear_OLED_Pixel(TargetRow+5, TargetColumn+5);

  105.                         Set_OLED_Pixel(TargetRow-3, TargetColumn-3);
  106.                         Set_OLED_Pixel(TargetRow-3, TargetColumn+6);
  107.                         Set_OLED_Pixel(TargetRow+6, TargetColumn-3);
  108.                         Set_OLED_Pixel(TargetRow+6, TargetColumn+6);
  109.                         Update_OLED_Display();
  110.                         delay_ms(200);
  111.                         
  112.                         Clear_OLED_Pixel(TargetRow-3, TargetColumn-3);
  113.                         Clear_OLED_Pixel(TargetRow-3, TargetColumn+6);
  114.                         Clear_OLED_Pixel(TargetRow+6, TargetColumn-3);
  115.                         Clear_OLED_Pixel(TargetRow+6, TargetColumn+6);
  116.                
  117.                         Set_OLED_Pixel(TargetRow-4, TargetColumn-4);
  118.                         Set_OLED_Pixel(TargetRow-4, TargetColumn+7);
  119.                         Set_OLED_Pixel(TargetRow+7, TargetColumn-4);
  120.                         Set_OLED_Pixel(TargetRow+7, TargetColumn+7);
  121.                         Update_OLED_Display();
  122.                         delay_ms(200);
  123.                         
  124.                         Clear_OLED_Pixel(TargetRow-4, TargetColumn-4);
  125.                         Clear_OLED_Pixel(TargetRow-4, TargetColumn+7);
  126.                         Clear_OLED_Pixel(TargetRow+7, TargetColumn-4);
  127.                         Clear_OLED_Pixel(TargetRow+7, TargetColumn+7);
  128.                         
  129.                         Set_OLED_Pixel(TargetRow-5, TargetColumn-5);
  130.                         Set_OLED_Pixel(TargetRow-5, TargetColumn+8);
  131.                         Set_OLED_Pixel(TargetRow+8, TargetColumn-5);
  132.                         Set_OLED_Pixel(TargetRow+8, TargetColumn+8);
  133.                         Update_OLED_Display();
  134.                         delay_ms(200);
  135.                         
  136.                         Clear_OLED_Pixel(TargetRow-5, TargetColumn-5);
  137.                         Clear_OLED_Pixel(TargetRow-5, TargetColumn+8);
  138.                         Clear_OLED_Pixel(TargetRow+8, TargetColumn-5);
  139.                         Clear_OLED_Pixel(TargetRow+8, TargetColumn+8);
  140.                         
  141.                         Set_OLED_Pixel(TargetRow-6, TargetColumn-6);
  142.                         Set_OLED_Pixel(TargetRow-6, TargetColumn+9);
  143.                         Set_OLED_Pixel(TargetRow+9, TargetColumn-6);
  144.                         Set_OLED_Pixel(TargetRow+9, TargetColumn+9);
  145.                         Update_OLED_Display();
  146.                         delay_ms(200);
  147.                         
  148.                         Clear_OLED_Pixel(TargetRow-6, TargetColumn-6);
  149.                         Clear_OLED_Pixel(TargetRow-6, TargetColumn+9);
  150.                         Clear_OLED_Pixel(TargetRow+9, TargetColumn-6);
  151.                         Clear_OLED_Pixel(TargetRow+9, TargetColumn+9);
  152.                         
  153.                         Set_OLED_Pixel(TargetRow-7, TargetColumn-7);
  154.                         Set_OLED_Pixel(TargetRow-7, TargetColumn+10);
  155.                         Set_OLED_Pixel(TargetRow+10, TargetColumn-7);
  156.                         Set_OLED_Pixel(TargetRow+10, TargetColumn+10);
  157.                         Update_OLED_Display();
  158.                         delay_ms(500);
  159.                         
  160.                         Clear_OLED_Array();
  161.                         Update_OLED_Display();
  162.                         delay_ms(1000);
  163.                         
  164.                         TargetColumn = 0;
  165.                 }
  166.                
  167.                 /*If the laser beam missed the target, clear the laser beam pixels.
  168.                 Nothing else needs to be done; the target will continue moving
  169.                 when execution returns to the infinite loop in main().*/
  170.                 else
  171.                 {
  172.                         OLED_Pixels[0][63] = 0;
  173.                         OLED_Pixels[1][63] = 0;
  174.                         OLED_Pixels[2][63] = 0;
  175.                         OLED_Pixels[3][63] = 0;
  176.                 }
  177.                
  178.                 //reenable the pushbutton 2 interrupt
  179.                 pio_enable_interrupt(PIOC, PIN_PUSHBUTTON_2_MASK);
  180.         }
  181. }
复制代码

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 27 | 回复: 28



Archiver|手机版|小黑屋|

GMT+8, 2018-11-13 02:06 , Processed in 0.046875 second(s), 29 queries . Powered by Discuz! X3.4

YiBoard一板网 © 2015-2018 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表