由于寄存器内容错误

时间:2021-07-31 13:06:10

标签: c++ c arduino avr inline-assembly

我目前正在尝试使用 Arduino Mega 2560 和修改后的 UTFT 库来驱动 SSD1289 显示器。通过用汇编程序 (Source) 替换一些函数来加速库。然后将该库修改为与 Arduino (Source) 兼容。 代码编译良好并正确上传到 Arduino。遗憾的是,显示器无法初始化(屏幕保持白色)。

这里是库的初始化命令:

00 LCD_Write_COM_DATA(0x00,0x0001);
01 LCD_Write_COM_DATA(0x03,0xA8A4);
02 LCD_Write_COM_DATA(0x0C,0x0000);
03 LCD_Write_COM_DATA(0x0D,0x080C);
04 LCD_Write_COM_DATA(0x0E,0x2B00);
05 LCD_Write_COM_DATA(0x1E,0x00B7);
06 LCD_Write_COM_DATA(0x01,0x2B3F);
07 LCD_Write_COM_DATA(0x02,0x0600);
08 LCD_Write_COM_DATA(0x10,0x0000);
09 LCD_Write_COM_DATA(0x11,0x6070);
10 LCD_Write_COM_DATA(0x05,0x0000);
11 LCD_Write_COM_DATA(0x06,0x0000);
12 LCD_Write_COM_DATA(0x16,0xEF1C);
13 LCD_Write_COM_DATA(0x17,0x0003);
14 LCD_Write_COM_DATA(0x07,0x0233);
15 LCD_Write_COM_DATA(0x0B,0x0000);
16 LCD_Write_COM_DATA(0x0F,0x0000);
17 LCD_Write_COM_DATA(0x41,0x0000);
18 LCD_Write_COM_DATA(0x42,0x0000);
19 LCD_Write_COM_DATA(0x48,0x0000);
20 LCD_Write_COM_DATA(0x49,0x013F);
21 LCD_Write_COM_DATA(0x4A,0x0000);
22 LCD_Write_COM_DATA(0x4B,0x0000);
23 LCD_Write_COM_DATA(0x44,0xEF00);
24 LCD_Write_COM_DATA(0x45,0x0000);
25 LCD_Write_COM_DATA(0x46,0x013F);
26 LCD_Write_COM_DATA(0x30,0x0707);
27 LCD_Write_COM_DATA(0x31,0x0204);
28 LCD_Write_COM_DATA(0x32,0x0204);
29 LCD_Write_COM_DATA(0x33,0x0502);
30 LCD_Write_COM_DATA(0x34,0x0507);
31 LCD_Write_COM_DATA(0x35,0x0204);
32 LCD_Write_COM_DATA(0x36,0x0204);
33 LCD_Write_COM_DATA(0x37,0x0502);
34 LCD_Write_COM_DATA(0x3A,0x0302);
35 LCD_Write_COM_DATA(0x3B,0x0302);
36 LCD_Write_COM_DATA(0x23,0x0000);
37 LCD_Write_COM_DATA(0x24,0x0000);
38 LCD_Write_COM_DATA(0x25,0x8000);
39 LCD_Write_COM_DATA(0x4f,0x0000);
40 LCD_Write_COM_DATA(0x4e,0x0000);
41 LCD_Write_COM(0x22);

LCD_Write_COM_DATA 头文件中的函数声明:

void LCD_Write_COM_DATA(uint8_t com, uint16_t v) asm("LCD_Write_COM_DATA");

汇编函数 LCD_Write_COM_DATA:

.global LCD_Write_COM_DATA
LCD_Write_COM_DATA:
    
    BUS_START_REG
    clr r1
    out DPLIO, r24
    out DPHIO, r1
    TOGGLE_WR

    BUS_START_DATA  
    out DPLIO, r22
    out DPHIO, r23
    TOGGLE_WR

    ret

我没有任何汇编经验。如果我理解正确,函数参数 com 被写入 R24(R25 保持 0x00,因为 com 只有 8 位)而 v 被写入 R22 和 R23。在 AVR Studio 中模拟此代码时,这似乎在第 35 行之前都能正常工作。但在执行第 35 行后,寄存器似乎发生了移位。 这里我注释了寄存器的内容:

32 LCD_Write_COM_DATA(0x36,0x0204); //R24=0x36, R23=0x02, R22=0x04
33 LCD_Write_COM_DATA(0x37,0x0502); //R24=0x37, R23=0x05, R22=0x02
34 LCD_Write_COM_DATA(0x3A,0x0302); //R24=0x3A, R23=0x03, R22=0x02
35 LCD_Write_COM_DATA(0x3B,0x0302); //R24=0x3B, R23=0x00, R22=0x00
36 LCD_Write_COM_DATA(0x23,0x0000); //R24=0x24, R23=0x00, R22=0x00
37 LCD_Write_COM_DATA(0x24,0x0000); //R24=0x25, R23=0x80, R22=0x00
38 LCD_Write_COM_DATA(0x25,0x8000); //R24=0x4F, R23=0x00, R22=0x00
39 LCD_Write_COM_DATA(0x4f,0x0000); //R24=0x22, R23=0x00, R22=0x00
40 LCD_Write_COM_DATA(0x4e,0x0000); //R24=0x22, R23=0x00, R22=0x00

谁能向我解释这种行为? 这似乎是显示器未初始化的原因之一。 我创建了一个草图,我手动传递 LCD_Write_COM_DATA 参数并添加了一些 nop 以获得正确的时间。使用此功能可以正确初始化显示:

void LCD_Write_COM_DATA(char com1,int dat1)
{
     asm volatile(
                  "cbi %[port1], %[pin1]\n"
                  "clr r1\n"
                  "out %[DPLIO],%[DLOWc]\n"
                  "out %[DPHIO], r1\n"
                  "cbi %[port2], %[pin2]\n"
                  "nop\n"
                  "nop\n"
                  "nop\n"
                  "nop\n"
                  "nop\n"
                  "sbi %[port2], %[pin2]\n"
                  "sbi %[port1], %[pin1]\n"
                  "out %[DPLIO], %[DLOWd]\n"
                  "out %[DPHIO], %[DHIGHd]\n"
                  "cbi %[port2], %[pin2]\n"
                  "nop\n"
                  "nop\n"
                  "nop\n"
                  "nop\n"
                  "nop\n"
                  "sbi %[port2], %[pin2]\n"
                  ::[port1] "I" (_SFR_IO_ADDR(RS_PORT)),
                  [pin1] "I" (RS_PIN),
                  [DPLIO] "I" (_SFR_IO_ADDR(DATA_PORT_LOW)),
                  [DPHIO] "I" (_SFR_IO_ADDR(DATA_PORT_HIGH)),
                  [port2] "I" (_SFR_IO_ADDR(WR_PORT)),
                  [pin2] "I" (WR_PIN),
                  [DLOWc] "r" (com1),
                  [DLOWd] "r" (dat1),
                  [DHIGHd] "r" (dat1>>8)
                  );
}

我需要修改头文件并手动传递参数吗?

0 个答案:

没有答案
相关问题