[DemoCode下载] 最新M471K系列单片机开发板测评:驱动OLED

[复制链接]
 楼主| gaoyang9992006 发表于 2021-8-13 11:58 | 显示全部楼层 |阅读模式
本帖最后由 gaoyang9992006 于 2021-8-13 16:10 编辑

#申请原创# @21小跑堂

--------------------------------------------------------------------
OLED是0.91寸的,IIC接口接口顺序为

GND   VCC  SCL  SDA

187706115edbcdfd48.png
经过观察,开发板的NU4接口可以为其供电,并提供IO功能,通过IO实现模拟IIC
如下图所示,7-10四个接口,VREF因为连接到了VDD,所以可以提供电能给OLED的VCC供电
又后面的IIC数据线跟OLED的相反,因此我们这里使用GPIO模拟实现
499006115e884c05fd.png
接下来移植oled的驱动
在main.c包含oled.h
在oled.h中粘贴:
#include "NuMicro.h"
结合上面选择的端口在oled.h中设置映射端口
  1. #define SCL_PORT         (PC)
  2. #define SCL_PIN          (BIT0)

  3. #define SDA_PORT         (PC)
  4. #define SDA_PIN          (BIT1)

  5.                         


  6. //-----------------OLED端口定义----------------

  7. #define OLED_SCL_Clr() PC0=0
  8. #define OLED_SCL_Set() PC0=1

  9. #define OLED_SDA_Clr() PC1=0
  10. #define OLED_SDA_Set() PC1=1

初始化GPIO为开漏
  1. void oled_gpio_init(void)
  2. {
  3.         GPIO_SetMode(SCL_PORT,SCL_PIN,GPIO_MODE_OPEN_DRAIN);
  4.         GPIO_SetMode(SDA_PORT,SDA_PIN,GPIO_MODE_OPEN_DRAIN);
  5.         CLK_SysTickDelay(1000);
  6. }
另外发现如果时钟主频过高则导致OLED显示会出现异常,降低系统主频到51Mhz内即可解决
那个设置函数只能设置51MHz和120MHz。
main.c的内容为
  1. #include "stdio.h"
  2. #include "NuMicro.h"
  3. #include "oled.h"

  4. void SYS_Init(void)
  5. {
  6.     /* Unlock protected registers */
  7.     SYS_UnlockReg();

  8.     /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
  9.     PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

  10.     /* Enable HIRC clock (Internal RC 48 MHz) */
  11.     CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);

  12.     /* Wait for HIRC clock ready */
  13.     CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);

  14.     /* Set core clock as 50MHz from PLL */
  15.     CLK_SetCoreClock(FREQ_50MHZ);

  16.     /* Set PCLK0/PCLK1 to HCLK/2 */
  17.     CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);

  18.     /* Enable UART clock */
  19.     CLK_EnableModuleClock(UART0_MODULE);

  20.     /* Select UART clock source from HIRC */
  21.     CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));

  22.     /* Update System Core Clock */
  23.     /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
  24.     SystemCoreClockUpdate();

  25.     /*----------------------------------------------------------------------*/
  26.     /* Init I/O Multi-function                                              */
  27.     /*----------------------------------------------------------------------*/
  28.     /* Set GPB multi-function pins for UART0 RXD and TXD */
  29.     SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) |
  30.                     (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

  31.     /* Lock protected registers */
  32.     SYS_LockReg();
  33. }

  34. /*----------------------------------------------------------------------*/
  35. /* Init UART0                                                           */
  36. /*----------------------------------------------------------------------*/
  37. void UART0_Init(void)
  38. {
  39.     /* Reset UART0 */
  40.     SYS_ResetModule(UART0_RST);

  41.     /* Configure UART0 and set UART0 baud rate */
  42.     UART_Open(UART0, 115200);
  43. }

  44. void led_init(void)
  45. {
  46.         GPIO_SetMode(PB, BIT14, GPIO_MODE_OUTPUT);
  47.         PB14 = 1;
  48. }

  49. void led_blink(int i)
  50. {
  51.         while(i--)
  52.                 CLK_SysTickDelay(100000);
  53.                 PB14 ^=1;
  54. }
  55. //初始化按键的端口为输入模式
  56. void button_init(void)
  57. {
  58.         GPIO_SetMode(PH, BIT4, GPIO_MODE_INPUT);
  59. }
  60. //通过按键改变一个数字从10到1的变化,用于控制LED闪烁的频率。
  61. void get_button(int *i)
  62. {
  63.         if(PH4==0)
  64.         {
  65.                 CLK_SysTickDelay(1000);
  66.                 if(PH4==0)
  67.                 {
  68.                         while(PH4==0);
  69.                         (*i)--;
  70.                         if(*i<=0) *i=10;
  71.                         printf("i=%d                T=%.2f s \n",*i,(float)*i/5);
  72.                 }
  73.         }
  74. }

  75. void oled_gpio_init(void)
  76. {
  77.         GPIO_SetMode(SCL_PORT,SCL_PIN,GPIO_MODE_OPEN_DRAIN);
  78.         GPIO_SetMode(SDA_PORT,SDA_PIN,GPIO_MODE_OPEN_DRAIN);
  79.         CLK_SysTickDelay(1000);
  80. }


  81. int32_t main(void)
  82. {
  83. int t=10;
  84. int i=0;

  85.         /* Init System, IP clock and multi-function I/O. */
  86.         SYS_Init();

  87.         /* Init UART0 for printf */
  88.         UART0_Init();

  89.         printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);

  90.         printf("+-------------------------------------------------+\n");
  91.         printf("|    PB.14(Output) and PCH.4(Input) Sample Code     |\n");
  92.         printf("+-------------------------------------------------+\n\n");
  93.         
  94.         led_init();
  95.         button_init();
  96.         oled_gpio_init();
  97.         
  98.         OLED_Init();//初始化OLED
  99.         CLK_SysTickDelay(1000);
  100.         OLED_ColorTurn(0);//0正常显示,1 反色显示
  101.         OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
  102.         CLK_SysTickDelay(1000);
  103.         
  104.         for(i=0;i<8;i++)
  105.                 OLED_ShowChinese(i*16,0,i,16);      //第一个是列坐标,字符是16×16,第二个是行开始的坐标,单位是8。第三个是写入第几个字符的数组编号
  106.         for(i=0;i<8;i++)
  107.                 OLED_ShowChinese(i*16,2,i+8,16);

  108.                 OLED_ShowString(0,2,"NuMaKer-471KI---",16);


  109.         while(1)
  110.         {
  111.                 led_blink(t);
  112.                 get_button(&t);               
  113.                 OLED_ShowNum(8*14,2,t,2,16);
  114.         }
  115. }
696886115ec0a937c6.png
该例程结合了我上一个GPIO输入输出和串口的例子,在原来的基础上增加实现了在OLED上显示文字,以及显示按键按下后,控制速度的变量。
01_OLED.rar (14.97 KB, 下载次数: 1)





redone 发表于 2021-8-13 13:18 | 显示全部楼层
我当年也是有这个小屏的,找不到了
 楼主| gaoyang9992006 发表于 2021-8-13 16:03 | 显示全部楼层
redone 发表于 2021-8-13 13:18
我当年也是有这个小屏的,找不到了

这是华大开发板上提供的那个小屏,用的SSD1306驱动器。发现IO模拟IIC主频高了就不行了。
jiekou001 发表于 2023-1-12 16:04 | 显示全部楼层
利用GPIO的驱动库移植确实很容易,不需要过多的配置。
643757107 发表于 2023-1-12 16:40 | 显示全部楼层
单片机控制OLED用硬件的I2C更好吧。
dongnanxibei 发表于 2023-9-27 19:49 | 显示全部楼层
使用的IO模拟,如果用硬件的应该更快。
huahuagg 发表于 2023-9-27 20:27 | 显示全部楼层
这个模块太好驱动了。
小灵通2018 发表于 2023-9-27 21:52 | 显示全部楼层
不知道用DMA可以驱动不。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2045

主题

16350

帖子

222

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