msp430f5529标准库学习之4针oled使用

 引脚说明:

VCC:电源正极,接3.3V

GND:电源负极

SCL:时钟线

SDA:数据线

IIC部分:

这里使用的是P6.5,P.6进行IIC通信

IIC代码如下

#include "./I2C/i2c.h"

void i2c_init(void)
{
    GPIO_setAsOutputPin(I2C_SCL_GPIO_PORT,I2C_SCL_GPIO_PIN);//输出模式
    GPIO_setAsOutputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输出模式
}

//开始i2c传输
void i2c_star(void)
{
    GPIO_setAsOutputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输出模式
    I2C_SDA(1);
    I2C_SCL(1);
    __delay_cycles(2);
    I2C_SDA(0);
    __delay_cycles(2);
    I2C_SCL(0);
    __delay_cycles(2);
}

//停止i2c传输
void i2c_stop(void)
{
    GPIO_setAsOutputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输出模式
    I2C_SDA(0);      /* STOP信号: 当SCL为高时, SDA从低变成高, 表示停止信号 */
    __delay_cycles(2);
    I2C_SCL(1);
    __delay_cycles(2);
    I2C_SDA(1);      /* 发送I2C总线结束信号 */
    __delay_cycles(2);
}
         
 //等待应答。1,接收应答失败,0,接收应答成功
uint8_t i2c_wait_ack(void)
{
    uint8_t waittime = 0;
    uint8_t rack = 0;
    
    I2C_SDA(1);      /* 主机释放SDA线(此时外部器件可以拉低SDA线) */
    __delay_cycles(2);
    I2C_SCL(1);      /* SCL=1, 此时从机可以返回ACK */
    __delay_cycles(2);
    GPIO_setAsInputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输入模式
    while (GPIO_getInputPinValue(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN)) /* 等待应答 */
    {
        waittime++;

        if (waittime > 250)
        {
            UART_printf(USCI_A0_BASE, "waitout\r\n");
            i2c_stop();
            rack = 1;
            break;
        }

        __delay_cycles(2);
    }

    I2C_SCL(0);      /* SCL=0, 结束ACK检查 */
    __delay_cycles(2);
    return rack;
}

//ack应答
void i2c_ack(void)
{
    GPIO_setAsOutputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输出模式
    I2C_SDA(0);  /* SCL 0 -> 1  时SDA = 0,表示应答 */
    __delay_cycles(2);
    I2C_SCL(1);
    __delay_cycles(2);
    I2C_SCL(0);
    __delay_cycles(2);
    I2C_SDA(1);  /* 主机释放SDA线 */
    __delay_cycles(2);
}

//ack非应答
void i2c_nack(void)
{
    GPIO_setAsOutputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输出模式
    I2C_SDA(1);  /* SCL 0 -> 1  时 SDA = 1,表示不应答 */
    __delay_cycles(2);
    I2C_SCL(1);
    __delay_cycles(2);
    I2C_SCL(0);
    __delay_cycles(2);
}

//发送一个字节数据,高位先发
void i2c_write_byte(uint8_t dat)
{
    int i;
    uint8_t temp=0;
    GPIO_setAsOutputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输出模式
    for(i=7;i>=0;i--)
    {
        temp=(dat>>i) & 0x01;
        I2C_SDA(temp);
        __delay_cycles(2);
        I2C_SCL(1);
        __delay_cycles(2);
        I2C_SCL(0);
    }

    I2C_SDA(1);      /* 发送完成, 主机释放SDA线 */
}

//读一个字节数据,高位先读
uint8_t i2c_read_byte(uint8_t ack)
{
    uint8_t i;
    uint8_t dat=0;
    GPIO_setAsInputPin(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN);//输入模式
    for(i=0;i<8;i++)
    {
        dat<<=1;
        
        I2C_SCL(1);
        __delay_cycles(2);
        if(GPIO_getInputPinValue(I2C_SDA_GPIO_PORT,I2C_SDA_GPIO_PIN))
            dat ++;
        
        I2C_SCL(0);
        __delay_cycles(2);
    }
    
    if (!ack)
    {
        i2c_nack();  /* 发送nACK */
    }
    else
    {
        i2c_ack();   /* 发送ACK */
    }
    
    return dat;
}

Oled代码如下

#include "./OLED/oled.h"
#include "./I2C/i2c.h"
#include "./OLED/oledfont.h"

//OLED的显存, 每个字节表示8个像素, 128,表示有128列, 8表示有64行, 高位表示第行数.
static uint8_t g_oled_gram[128][8];

//写命令
void oled_write_cmd(uint8_t cmd)
{
    i2c_star();
    i2c_write_byte(0x78);//oled地址
    i2c_wait_ack();
    i2c_write_byte(0x00);//写命令命令
    i2c_wait_ack();
    i2c_write_byte(cmd);//写命令
    i2c_wait_ack();
    i2c_stop();
}

//写数据
void oled_write_data(uint8_t dat)
{
    i2c_star();
    i2c_write_byte(0x78);//oled地址
    i2c_wait_ack();
    i2c_write_byte(0x40);//写数据命令
    i2c_wait_ack();
    i2c_write_byte(dat);//写数据
    i2c_wait_ack();
    i2c_stop();
}

//全屏更新
void oled_all_refresh_gram(void)
{
    uint8_t i,j;
    oled_display_off();
    for(i=0;i<8;i++)//设置为8页
    {
        oled_write_cmd(0xb0 |i);//设置页
        oled_write_cmd(0x00);//设置列(低4bit)因为128列,至少要7bit
        oled_write_cmd(0x10);//设置列(高4bit)
        for(j=0;j<128;j++)
        {
            oled_write_data(g_oled_gram[j][i]);//写入数据
        }
    }
    oled_display_on();
}

//区域更新
void oled_area_refresh_gram(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2)
{
    uint8_t pos1,pos2,i,j;
    if (x1 > 127 || y1 > 63) return;  /* 超出范围了. */
    if (x2 > 127 || y2 > 63) return;  /* 超出范围了. */
    pos1=y1/8;
    pos2=y2/8;
    for(i=pos1;i<=pos2;i++)//设置为8页
    {
        oled_write_cmd(0xb0 |i);//设置页
        for(j=x1;j<=x2;j++)
        {
            oled_write_cmd(j&0xf);//设置列(低4bit)因为128列,至少要7bit
            oled_write_cmd((j>>4)|0x10);//设置列(高4bit)
            oled_write_data(g_oled_gram[j][i]);//写入数据
        }
    }
}

//全屏清屏
void oled_all_clear(void)
{
    uint8_t i, j;

    for (i = 0; i < 8; i++)
        for (j = 0; j < 128; j++)
            g_oled_gram[j][i] = 0X00;

    oled_all_refresh_gram();    /* 更新显示 */
}

//区域清屏
void oled_area_clear(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2)
{
    uint8_t pos1,pos2,i,j;
    if (x1 > 127 || y1 > 63) return;  /* 超出范围了. */
    if (x2 > 127 || y2 > 63) return;  /* 超出范围了. */
    pos1=y1/8;
    pos2=y2/8;
    //printf("x1=%d,y1=%d,x2=%d,y2=%d,pos1=%d,pos2=%d\r\n",x1,y1,x2,y2,pos1,pos2);
    for(i=pos1;i<=pos2;i++)//设置为8页
        for(j=x1;j<=x2;j++)
        {
            //printf("i=%d,j=%d\r\n",i,j);
            g_oled_gram[j][i] = 0X00;
        }
}


//全屏点亮
void oled_fill(void)
{
    uint8_t i, j;

    for (i = 0; i < 8; i++)
        for (j = 0; j < 128; j++)
            g_oled_gram[j][i] = 0XFF;

    oled_all_refresh_gram();    /* 更新显示 */
}

void oled_rect_fill(uint8_t y,uint8_t mode)
{
    uint8_t i;

    if(mode==1)
    {
        for (i = 0; i < 128; i++)
        {
             g_oled_gram[i][y*2] = 0XFF;
             g_oled_gram[i][y*2+1] = 0XFF;
        }
    }
    else
    {
        for (i = 0; i < 128; i++)
        {
             g_oled_gram[i][y*2] = 0X00;
             g_oled_gram[i][y*2+1] = 0X00;
        }
    }
}

//打开
void oled_display_on(void)
{
    oled_write_cmd(0X8D);   /* SET DCDC命令 */
    oled_write_cmd(0X14);   /* DCDC ON */
    oled_write_cmd(0XAF);   /* DISPLAY ON */
}

//关闭
void oled_display_off(void)
{
    oled_write_cmd(0X8D);   /* SET DCDC命令 */
    oled_write_cmd(0X10);   /* DCDC OFF */
    oled_write_cmd(0XAE);   /* DISPLAY OFF */
}

//oled初始化
void oled_init(void)
{
    i2c_init();//i2c初始化
    __delay_cycles(1000);//延时1ms,重要

    oled_write_cmd(0xAE);   /* 关闭显示 */
    oled_write_cmd(0xD5);   /* 设置时钟分频因子,震荡频率 */
    oled_write_cmd(0xf0);     /* [3:0],分频因子;[7:4],震荡频率 */
    oled_write_cmd(0xA8);   /* 设置驱动路数 */
    oled_write_cmd(0X3F);   /* 默认0X3F(1/64) */
    oled_write_cmd(0xD3);   /* 设置显示偏移 */
    oled_write_cmd(0X00);   /* 设置列(低4bit)*/
    oled_write_cmd(0x10);//设置列(高4bit)

    oled_write_cmd(0x40);   /* 设置显示开始行 [5:0],行数. */

    oled_write_cmd(0x8D);   /* 电荷泵设置 */
    oled_write_cmd(0x14);   /* bit2,开启/关闭 */
    oled_write_cmd(0x20);   /* 设置内存地址模式 */
    oled_write_cmd(0x02);   /* [1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; */
    oled_write_cmd(0xb0);   //开启地址0-7
    oled_write_cmd(0xA1);   /* 段重定义设置,bit0:0,0->0;1,0->127; */
    oled_write_cmd(0xC8);   /* 设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 */
    oled_write_cmd(0xDA);   /* 设置COM硬件引脚配置 */
    oled_write_cmd(0x12);   /* 128*64 */

    oled_write_cmd(0x81);   /* 对比度设置 */
    oled_write_cmd(0xEF);   /* 1~255;默认0X7F (亮度设置,越大越亮) */
    oled_write_cmd(0xD9);   /* 设置预充电周期 */
    oled_write_cmd(0x22);   //充电时间
    oled_write_cmd(0xf1);   /* [3:0],PHASE 1;[7:4],PHASE 2; */
    oled_write_cmd(0xDB);   /* 设置VCOMH 电压倍率 */
    oled_write_cmd(0x20);   //0x20,0.77xVcc

    oled_write_cmd(0xA4);   /* 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) */
    oled_write_cmd(0xA6);   /* 设置显示方式;bit0:1,反相显示;0,正常显示 */
    oled_write_cmd(0xAF);   /* 开启显示 */

    oled_all_clear();
}

//画点
void oled_draw_point(uint8_t x, uint8_t y, uint8_t dot)
{
    uint8_t pos, bx, temp = 0;

    if (x > 127 || y > 63) return;  /* 超出范围了. */

    pos = y / 8;        /* 计算GRAM里面的y坐标所在的字节, 每个字节可以存储8个行坐标 */

    bx = y % 8;         /* 取余数,方便计算y在对应字节里面的位置,及行(y)位置 */
    temp = 1 << bx;     /* 高位表示低行号, 得到y对应的bit位置,将该bit先置1 */

    if (dot)    /* 画实心点 */
    {
        g_oled_gram[x][pos] |= temp;
    }
    else        /* 画空点,即不显示 */
    {
        g_oled_gram[x][pos] &= ~temp;
    }
}

// 显示字符
void oled_show_char(uint8_t x, uint8_t y, uint8_t chr, uint8_t size, uint8_t mode)
{
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    uint8_t *pfont = 0;
    uint8_t csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); /* 得到字体一个字符对应点阵集所占的字节数 */
    chr = chr - ' ';         /* 得到偏移后的值,因为字库是从空格开始存储的,第一个字符是空格 */

    if (size == 12)          /* 调用1206字体 */
    {
        pfont = (uint8_t *)oled_asc2_1206[chr];
    }
    else if (size == 16)     /* 调用1608字体 */
    {
        pfont = (uint8_t *)oled_asc2_1608[chr];
    }
    else if (size == 24)     /* 调用2412字体 */
    {
        pfont = (uint8_t *)oled_asc2_2412[chr];
    }
    else                    /* 没有的字库 */
    {
        return;
    }

    for (t = 0; t < csize; t++)
    {
        temp = pfont[t];

        for (t1 = 0; t1 < 8; t1++)
        {
            if (temp & 0x80)oled_draw_point(x, y, mode);
            else oled_draw_point(x, y, !mode);

            temp <<= 1;
            y++;

            if ((y - y0) == size)
            {
                y = y0;
                x++;
                break;
            }
        }
    }
}


//平方函数, m^n
static uint32_t oled_pow(uint8_t m, uint8_t n)
{
    uint32_t result = 1;

    while (n--)
    {
        result *= m;
    }

    return result;
}

//显示len个数字
void oled_show_num(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size,uint8_t mode)
{
    uint8_t t, temp;
    uint8_t enshow = 0;

    for (t = 0; t < len; t++)   /* 按总显示位数循环 */
    {
        temp = (num / oled_pow(10, len - t - 1)) % 10;  /* 获取对应位的数字 */

        if (enshow == 0 && t < (len - 1))   /* 没有使能显示,且还有位要显示 */
        {
            if (temp == 0)
            {
                oled_show_char(x + (size / 2)*t, y, ' ', size, mode); /* 显示空格,站位 */
                continue;       /* 继续下个一位 */
            }
            else
            {
                enshow = 1;     /* 使能显示 */
            }
        }

        oled_show_char(x + (size / 2)*t, y, temp + '0', size, mode);    /* 显示字符 ,因为是通过两页写的所以size除2*/
    }
}

//显示数据
void oled_show_data(uint8_t x, uint8_t y, uint32_t integer,uint32_t decimal, uint8_t integer_len,uint8_t decimal_len, uint8_t size,uint8_t mode)
{
    oled_show_num(x,y,integer,integer_len,size,mode);
    oled_show_char(x+integer_len*8,y,'.',size,mode);
    oled_show_num(x+integer_len*8+8,y,decimal,decimal_len,size,mode);
}



//显示字符串
void oled_show_string(uint8_t x, uint8_t y, const char *p, uint8_t size,uint8_t mode)
{
    while ((*p <= '~') && (*p >= ' '))  /* 判断是不是非法字符! */
    {
        if (x > (128 - (size / 2)))     /* 宽度越界 */
        {
            x = 0;
            y += size;                  /* 换行 */
        }

        if (y > (64 - size))            /* 高度越界 */
        {
            y = x = 0;
            oled_all_clear();
        }

        oled_show_char(x, y, *p, size,mode);   /* 显示一个字符 */
        x += size / 2;      /* ASCII字符宽度为汉字宽度的一半 因为是通过两页写的所以size除2*/
        p++;
    }
}

//显示半个汉字
void oled_show_halfway_character(uint8_t x, uint8_t y,char *p,uint8_t size,uint8_t mode)
{
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    uint8_t *pfont = 0;
    uint8_t csize = (size / 8 + ((size % 8) ? 1 : 0)) * (size / 2); /* 得到字体一个字符对应点阵集所占的字节数 */

    pfont = (uint8_t *)p;
    for (t = 0; t < csize; t++)
    {
        temp = pfont[t];

        for (t1 = 0; t1 < 8; t1++)
        {
            if(mode==1)
            {
                if (temp & 0x80)oled_draw_point(x, y,1);
                else oled_draw_point(x, y,0);
            }
            else
            {
                if (temp & 0x80)oled_draw_point(x, y,0);
                else oled_draw_point(x, y,1);
            }
            temp <<= 1;
            y++;

            if ((y - y0) == size)
            {
                y = y0;
                x++;
                break;
            }
        }
    }
}

//显示多个汉字
void led_show_character(uint8_t x, uint8_t y,char *p,uint8_t size,uint8_t chara_len,uint8_t mode)
{
    uint8_t i=0;
    for(i=0;i<chara_len*2;i++)
    {
        oled_show_halfway_character(x+size/2*i,y,p,size,mode);
        p+=size;
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 要使用MSP430F5529控制OLED显示器,您需要遵循以下步骤: 1. 确保您已经连接了正确的硬件,包括MSP430F5529微控制器和OLED显示器。 2. 下载并安装MSP430F5529的开发环境,例如Code Composer Studio。 3. 在代码中包含OLED显示器的库文件,并初始化OLED显示器。 4. 编写代码来控制OLED显示器的输出,例如显示文本或图像。 5. 将代码上传到MSP430F5529微控制器,并将其连接到OLED显示器。 6. 测试代码并调试任何问题。 请注意,这只是一个概述,具体步骤可能因您使用的硬件和软件而有所不同。建议您查阅相关文档和教程,以确保正确地使用MSP430F5529控制OLED显示器。 ### 回答2: msp430f5529是一款低功耗的微控制器,可以非常方便地实现oled显示。实现oled显示的方法分为两种:硬件控制和软件控制。 硬件控制方法是使用msp430f5529的专用引脚控制oled的显示,需要使用专门的oled显示模块,通常使用SPI协议与单片机进行通信。在使用硬件控制方法时,需要连接SDO、SCK、CSB、DC、RST等引脚,并通过程序控制这些引脚的高低电平,从而达到控制oled显示的目的。 软件控制方法则是在msp430f5529使用软件控制oled的显示。软件控制方法可以使用通用IO口实现,通过编写驱动程序将需要显示的图像发送到oled显示屏上,从而完成oled的显示效果。软件控制方法相对硬件控制方法更加灵活,可以根据需要自定义显示的图像,并且不需要连接额外的显示模块,仅需要连接单片机oled屏幕的通信引脚即可。 无论是硬件控制还是软件控制oled显示,最后需要将msp430f5529连接到电源上,通过程序控制使用oled显示屏来输出需要的信息。通过oled显示屏,可以实现低功耗、高清晰度的信息显示,使得msp430f5529的应用更加广泛和优化。 ### 回答3: msp430f5529是一款功能强大的微控制器,可以通过oled显示屏幕来显示信息。OLED显示器采用有机化学发光材料,这种技术具有高亮度、对比度、颜色、反应时间和可见角度。它还具有低功率消耗和自发光特性,能大大节省能量。 首先,您需要准备一个MSP430F5529微控制器,一个OLED显示器和适配器。然后将适配器固定在OLED显示器的背面,并将MSP430F5529OLED适配器连接。MSP430F5529OLED适配器通过SPI通信协议进行通信。在此之前,您需要了解如何使用MSP430F5529的SPI模块。 接下来,您需要使用MSP430F5529的编程软件编写您的代码。在您的代码中,您需要将OLED显示器初始化,并使用SPI通信协议将其连接到MSP430F5529。然后,您可以使用各种命令和数据将信息发送到OLED显示器以在屏幕上显示文本、图像等。 当您的代码完成并且MSP430F5529OLED显示器正确连接时,您可以通过MSP430F5529发送命令和数据来控制OLED显示器。您可以在OLED显示器上显示文本,如“Hello world!”或“Welcome to MSP430F5529 OLED Display”,还可以将图像插入屏幕。您可以相应地设置字体大小、颜色以及其他选项来自定义您的显示选项。 因此,msp430f5529可以与oled之间进行通信,从而在OLED显示上显示文本和图像等内容,拓展了其应用范围,使得开发人员可以通过OLED显示器来显示自己想要的任何信息,如文本、传感器数据、图像等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值