| 本帖最后由 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为开漏
 
 另外发现如果时钟主频过高则导致OLED显示会出现异常,降低系统主频到51Mhz内即可解决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);
}
那个设置函数只能设置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, 下载次数: 1) 
 
 
 
 
 
 |