[技术问答] 请问NUC123硬件SPI0无法驱动OLED(SH1106)

[复制链接]
 楼主| 风来吴山 发表于 2020-5-28 16:23 | 显示全部楼层 |阅读模式
时钟初始化
  1.     /* Select HCLK as the clock source of SPI0 */
  2.     CLK_SetModuleClock(SPI0_MODULE, CLK_CLKSEL1_SPI0_S_HCLK, MODULE_NoMsk);
  3.     /* Enable SPI0 peripheral clock */
  4.     CLK_EnableModuleClock(SPI0_MODULE);
PIN初始化,没有使用PC2(MISO)
  1. /* Setup SPI0 multi-function pins */
  2.     SYS->GPC_MFP &= ~(SYS_GPC_MFP_PC0_Msk | SYS_GPC_MFP_PC1_Msk | SYS_GPC_MFP_PC3_Msk);        // SYS_GPC_MFP_PC2_Msk
  3.     SYS->GPC_MFP |= SYS_GPC_MFP_PC0_SPI0_SS0 | SYS_GPC_MFP_PC1_SPI0_CLK | SYS_GPC_MFP_PC3_SPI0_MOSI0;        // SYS_GPC_MFP_PC2_SPI0_MISO0
  4.     SYS->ALT_MFP &= ~(SYS_ALT_MFP_PC0_Msk | SYS_ALT_MFP_PC1_Msk | SYS_ALT_MFP_PC3_Msk);        // SYS_ALT_MFP_PC2_Msk
  5.     SYS->ALT_MFP |= SYS_ALT_MFP_PC0_SPI0_SS0 | SYS_ALT_MFP_PC1_SPI0_CLK | SYS_ALT_MFP_PC3_SPI0_MOSI0;        // SYS_ALT_MFP_PC2_SPI0_MISO0
SPI0配置
  1. void SPI0_Init(void)
  2. {
  3.         SPI_Open(SPI0, SPI_MASTER, SPI_MODE_0, 0, 9000000);
  4.         SPI_EnableAutoSS(SPI0, SPI_SS0, SPI_SS_ACTIVE_LOW);
  5. }
OLED读写
  1. #ifdef SOFT_SPI
  2. void OLED_WR_Byte(u8 dat,u8 cmd)
  3. {
  4.         u8 i;
  5.         if(cmd)
  6.           OLED_DC_Set();
  7.         else
  8.           OLED_DC_Clr();
  9.         OLED_CS_Clr();
  10.         for(i = 0; i < 8; i++)
  11.         {
  12.                 OLED_SCL_Clr();
  13.                 if(dat & 0x80)
  14.                    OLED_SDA_Set();
  15.                 else
  16.                    OLED_SDA_Clr();
  17.                 OLED_SCL_Set();
  18.                 dat <<= 1;
  19.         }
  20.         OLED_CS_Set();
  21.         OLED_DC_Set();
  22. }
  23. #else
  24. void OLED_WR_Byte(u8 dat, u8 cmd)
  25. {
  26.         if(cmd)
  27.           OLED_DC_Set();
  28.         else
  29.           OLED_DC_Clr();
  30.         SPI_WRITE_TX0(SPI0, dat);
  31.         OLED_DC_Set();
  32. }
  33. #endif
main函数
  1. #ifdef SOFT_SPI
  2.     SPI0_Init_Soft();
  3. #else
  4.     SPI0_Init();
  5. #endif
  6.         delay_ms(100);
  7.         OLED_Init();
  8. UART_SetTimeoutCnt(UART0, 40);
  9.         UART0->FCR |= (3 << 4);                // 设置UART0的串口FIFO为14字节
  10.         UART_EnableInt(UART0, (UART_IER_RDA_IEN_Msk | UART_IER_RTO_IEN_Msk));
  11.     printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);
  12.     printf("\n\nUART Sample Program\n");
  13.         t1.IDString = (uint8_t*)"LCC1 V0.0.1";
  14.         printf("please input data:\n");
  15.         delay_ms(500);
  16.         AD5764_Init();
  17.         while(1)
  18.     {
  19.                 OLED_Refresh();
  20.         OLED_ShowString(0, 1, t1.IDString, 16, 1);
  21.     }

如果我使用软件模拟SPI,屏幕可以点亮且正常显示,一旦使用硬件SPI0,则不行,起初我以为是SPI的模式、bit数不对,但SPI_MODE_0到SPI_MODE_3,bit数8和32都试过了,还是点不亮,求做过的大佬指点一下吧。急急急。
 楼主| 风来吴山 发表于 2020-5-28 16:24 | 显示全部楼层
SPI_Open(SPI0, SPI_MASTER, SPI_MODE_0, 8, 9000000);
这里更正一下
 楼主| 风来吴山 发表于 2020-5-28 17:06 | 显示全部楼层
解决了,是OLED_WR_Byte函数写的有问题,正确的写法如下:
  1. void OLED_WR_Byte(u8 dat, u8 cmd)
  2. {
  3.         int timeout = 25000;
  4.         if(cmd)
  5.           OLED_DC_Set();
  6.         else
  7.           OLED_DC_Clr();
  8.         SPI_WRITE_TX0(SPI0, dat);
  9.         SPI_TRIGGER(SPI0);
  10.         while (SPI_IS_BUSY(SPI0))
  11.         {
  12.                 if(!timeout--){}
  13.         }
  14.         OLED_DC_Set();
  15. }
jiekou001 发表于 2020-5-28 19:06 | 显示全部楼层
感谢楼主分享宝贵经验。
jerow 发表于 2020-5-28 22:22 | 显示全部楼层
感谢分享,一般来说,不要怀疑硬件的问题,都是操作底层函数导致的。
捉虫天师 发表于 2020-5-29 11:32 | 显示全部楼层
硬件一般不会有问题,分享的不错。
598330983 发表于 2020-5-29 20:47 | 显示全部楼层
太棒了,学习学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

40

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

7

主题

40

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部