打印
[DemoCode下载]

最新M471K系列单片机开发板测评:驱动OLED

[复制链接]
1912|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 gaoyang9992006 于 2021-8-13 16:10 编辑

#申请原创# @21小跑堂

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

GND   VCC  SCL  SDA


经过观察,开发板的NU4接口可以为其供电,并提供IO功能,通过IO实现模拟IIC
如下图所示,7-10四个接口,VREF因为连接到了VDD,所以可以提供电能给OLED的VCC供电
又后面的IIC数据线跟OLED的相反,因此我们这里使用GPIO模拟实现

接下来移植oled的驱动
在main.c包含oled.h
在oled.h中粘贴:
#include "NuMicro.h"
结合上面选择的端口在oled.h中设置映射端口
#define SCL_PORT         (PC)
#define SCL_PIN          (BIT0)

#define SDA_PORT         (PC)
#define SDA_PIN          (BIT1)

                        


//-----------------OLED端口定义----------------

#define OLED_SCL_Clr() PC0=0
#define OLED_SCL_Set() PC0=1

#define OLED_SDA_Clr() PC1=0
#define OLED_SDA_Set() PC1=1

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

void SYS_Init(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

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

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

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

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

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

    /* Enable UART clock */
    CLK_EnableModuleClock(UART0_MODULE);

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

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

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

    /* Lock protected registers */
    SYS_LockReg();
}

/*----------------------------------------------------------------------*/
/* Init UART0                                                           */
/*----------------------------------------------------------------------*/
void UART0_Init(void)
{
    /* Reset UART0 */
    SYS_ResetModule(UART0_RST);

    /* Configure UART0 and set UART0 baud rate */
    UART_Open(UART0, 115200);
}

void led_init(void)
{
        GPIO_SetMode(PB, BIT14, GPIO_MODE_OUTPUT);
        PB14 = 1;
}

void led_blink(int i)
{
        while(i--)
                CLK_SysTickDelay(100000);
                PB14 ^=1;
}
//初始化按键的端口为输入模式
void button_init(void)
{
        GPIO_SetMode(PH, BIT4, GPIO_MODE_INPUT);
}
//通过按键改变一个数字从10到1的变化,用于控制LED闪烁的频率。
void get_button(int *i)
{
        if(PH4==0)
        {
                CLK_SysTickDelay(1000);
                if(PH4==0)
                {
                        while(PH4==0);
                        (*i)--;
                        if(*i<=0) *i=10;
                        printf("i=%d                T=%.2f s \n",*i,(float)*i/5);
                }
        }
}

void oled_gpio_init(void)
{
        GPIO_SetMode(SCL_PORT,SCL_PIN,GPIO_MODE_OPEN_DRAIN);
        GPIO_SetMode(SDA_PORT,SDA_PIN,GPIO_MODE_OPEN_DRAIN);
        CLK_SysTickDelay(1000);
}


int32_t main(void)
{
int t=10;
int i=0;

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

        /* Init UART0 for printf */
        UART0_Init();

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

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

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


        while(1)
        {
                led_blink(t);
                get_button(&t);               
                OLED_ShowNum(8*14,2,t,2,16);
        }
}

该例程结合了我上一个GPIO输入输出和串口的例子,在原来的基础上增加实现了在OLED上显示文字,以及显示按键按下后,控制速度的变量。
01_OLED.rar (14.97 KB)





使用特权

评论回复
沙发
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的驱动库移植确实很容易,不需要过多的配置。

使用特权

评论回复
5
643757107| | 2023-1-12 16:40 | 只看该作者
单片机控制OLED用硬件的I2C更好吧。

使用特权

评论回复
6
dongnanxibei| | 2023-9-27 19:49 | 只看该作者
使用的IO模拟,如果用硬件的应该更快。

使用特权

评论回复
7
huahuagg| | 2023-9-27 20:27 | 只看该作者
这个模块太好驱动了。

使用特权

评论回复
8
小灵通2018| | 2023-9-27 21:52 | 只看该作者
不知道用DMA可以驱动不。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:西安公路研究院南京院
简介:主要工作从事监控网络与通信网络设计,以及从事基于嵌入式的通信与控制设备研发。擅长单片机嵌入式系统物联网设备开发,音频功放电路开发。

1961

主题

15932

帖子

208

粉丝