OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4406|回复: 4

用stm32f103以IIC通信方式控制oled显示字符

[复制链接]

1

主题

1

帖子

0

精华

新手入门

积分
3
金钱
3
注册时间
2022-5-8
在线时间
0 小时
发表于 2022-5-8 20:18:48 | 显示全部楼层 |阅读模式
1金钱
用STM32F103显示字符,只有oled模块,编译过了,仿真时屏幕黑屏,想求助一下怎解决

#include "stm32f10x.h"
#include <stdio.h>
#include "oled.h"
int main(void)
{
        OLED_Init();                //OLED初始化
        while(1)
        {
                        OLED_ShowChinese(0,0,3,16,1);//温
                        OLED_ShowChinese(16,0,4,16,1);//度
                        OLED_ShowChar(32,0,':',16,1);//oled显示字符
                        OLED_ShowChinese(0,16,5,16,1);//湿
                        OLED_ShowChinese(16,16,4,16,1);//度
                        OLED_ShowChar(32,16,':',16,1);//oled显示字符
                        OLED_Refresh_Gram();       
        }
       
}
#include "OLED_Font.h"
#include "oled.h"

u8 OLED_GRAM[128][8];       
/*引脚初始化*/
void OLED_I2C_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;  
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
       
        OLED_W_SCL(1);
        OLED_W_SDA(1);
}

/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void OLED_I2C_Start(void)
{
        OLED_W_SDA(1);
        OLED_W_SCL(1);
        OLED_W_SDA(0);
        OLED_W_SCL(0);
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void OLED_I2C_Stop(void)
{
        OLED_W_SDA(0);
        OLED_W_SCL(1);
        OLED_W_SDA(1);
}

/**
  * @brief  I2C发送一个字节
  * @param  Byte 要发送的一个字节
  * @retval 无
  */
void OLED_I2C_SendByte(uint8_t Byte)
{
        uint8_t i;
        for (i = 0; i < 8; i++)
        {
                OLED_W_SDA(Byte & (0x80 >> i));
                OLED_W_SCL(1);
                OLED_W_SCL(0);
        }
        OLED_W_SCL(1);        //额外的一个时钟,不处理应答信号
        OLED_W_SCL(0);
}

/**
  * @brief  OLED写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void OLED_WriteCommand(uint8_t Command)
{
        OLED_I2C_Start();
        OLED_I2C_SendByte(0x78);                //从机地址
        OLED_I2C_SendByte(0x00);                //写命令
        OLED_I2C_SendByte(Command);
        OLED_I2C_Stop();
}

/**
  * @brief  OLED写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void OLED_WriteData(uint8_t Data)
{
        OLED_I2C_Start();
        OLED_I2C_SendByte(0x78);                //从机地址
        OLED_I2C_SendByte(0x40);                //写数据
        OLED_I2C_SendByte(Data);
        OLED_I2C_Stop();
}

//更新显存到OLED         
void OLED_Refresh_Gram(void)
{
        u8 i,n;                    
        for(i=0;i<8;i++)  
        {  
                        OLED_WriteCommand(0xB0+i);                                        //设置Y位置
                        OLED_WriteCommand(0x10);        //设置X位置高4位
                        OLED_WriteCommand(0x00);                        //设置X位置低4位
                for(n=0;n<128;n++)
                {
                        OLED_WriteData(OLED_GRAM[n]);
                }
        }   
}

//画点
//x:0~127
//y:0~63
//t:1 填充 0,清空                                  
void OLED_DrawPoint(u8 x,u8 y,u8 t)
{
        u8 pos,bx,temp=0;
        if(x>127||y>63)
        {
                return;//超出范围了.
        }
        pos=7-y/8;
        bx=y%8;
        temp=1<<(7-bx);
        if(t)
        {
                OLED_GRAM[x][pos]|=temp;
        }
        else OLED_GRAM[x][pos]&=~temp;            
}

//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示                                 
//size:选择字体 12/16/24
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
{                                  
        u8 temp,t,t1;
        u8 y0=y;
        u8 csize=(size/8+((size%8)?1:0))*(size/2);                //得到字体一个字符对应点阵集所占的字节数
        chr=chr-' ';//得到偏移后的值                 
    for(t=0;t<csize;t++)
    {   
                if(size==12)temp=asc2_1206[chr][t];                  //调用1206字体
                else if(size==16)temp=asc2_1608[chr][t];        //调用1608字体
                else if(size==24)temp=asc2_2412[chr][t];        //调用2412字体
                else return;                                                                //没有的字库
        for(t1=0;t1<8;t1++)
                {
                        if(temp&0x80)OLED_DrawPoint(x,y,mode);
                        else OLED_DrawPoint(x,y,!mode);
                        temp<<=1;
                        y++;
                        if((y-y0)==size)
                        {
                                y=y0;
                                x++;
                                break;
                        }
                }           
    }         
}
//m^n函数
u32 mypow(u8 m,u8 n)
{
        u32 result=1;         
        while(n--)result*=m;   
        return result;
}       

//显示2个数字
//x,y :起点坐标         
//len :数字的位数
//size:字体大小
//mode:模式        0,填充模式;1,叠加模式
//num:数值(0~4294967295);                           
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size)
{                
        u8 t,temp;
        u8 enshow=0;                                                  
        for(t=0;t<len;t++)
        {
                temp=(num/mypow(10,len-t-1))%10;
                if(enshow==0&&t<(len-1))
                {
                        if(temp==0)
                        {
                                OLED_ShowChar(x+(size/2)*t,y,' ',size,1);
                                continue;
                        }else enshow=1;
                          
                }
                 OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1);
        }
}
//显示字符串
//x,y:起点坐标  
//size:字体大小
//*p:字符串起始地址
void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size)
{       
    while((*p<='~')&&(*p>=' '))//判断是不是非法字符!
    {      
        if(x>(128-(size/2))){x=0;y+=size;}
        if(y>(64-size)){y=x=0;OLED_Clear();}
        OLED_ShowChar(x,y,*p,size,1);         
        x+=size/2;
        p++;
    }  
       
}          

//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!          
void OLED_Clear(void)  
{  
        u8 i,n;  
        for(i=0;i<8;i++)
        {
                for(n=0;n<128;n++)
                {
                        OLED_GRAM[n]=0X00;  
                }
        }
        OLED_Refresh_Gram();//更新显示
}

//显示汉字
//x,y:起点坐标
//num:字库中位数
//size:字体高度
//mode:模式        0,填充模式;1,叠加模式
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size,u8 mode)
{                                  
        u8 temp,t,t1;
        u8 y0=y;
        u8 csize=32;                //得到字体一个字符对应点阵集所占的字节数         
    for(t=0;t<csize;t++)
    {   
                if(size==16)temp=Oled_Chinese[num][t];        //调用1608字体
                else return;                                                                //没有的字库
        for(t1=0;t1<8;t1++)
                {
                        if(temp&0x80)OLED_DrawPoint(x,y,mode);
                        else OLED_DrawPoint(x,y,!mode);
                        temp<<=1;
                        y++;
                        if((y-y0)==size)
                        {
                                y=y0;
                                x++;
                                break;
                        }
                }           
    }         
}

/**
  * @brief  OLED初始化
  * @param  无
  * @retval 无
  */
void OLED_Init(void)
{
        uint32_t i, j;
       
        for (i = 0; i < 1000; i++)                        //上电延时
        {
                for (j = 0; j < 1000; j++);
        }
       
        OLED_I2C_Init();                        //端口初始化
       
        OLED_WriteCommand(0xAE);        //关闭显示
       
        OLED_WriteCommand(0xD5);        //设置显示时钟分频比/振荡器频率
        OLED_WriteCommand(0x80);
       
        OLED_WriteCommand(0xA8);        //设置多路复用率
        OLED_WriteCommand(0x3F);
       
        OLED_WriteCommand(0xD3);        //设置显示偏移
        OLED_WriteCommand(0x00);
       
        OLED_WriteCommand(0x40);        //设置显示开始行
       
        OLED_WriteCommand(0xA1);        //设置左右方向,0xA1正常 0xA0左右反置
       
        OLED_WriteCommand(0xC0);        //设置上下方向,0xC8正常 0xC0上下反置

        OLED_WriteCommand(0xDA);        //设置COM引脚硬件配置
        OLED_WriteCommand(0x12);
       
        OLED_WriteCommand(0x81);        //设置对比度控制
        OLED_WriteCommand(0xCF);

        OLED_WriteCommand(0xD9);        //设置预充电周期
        OLED_WriteCommand(0xF1);

        OLED_WriteCommand(0xDB);        //设置VCOMH取消选择级别
        OLED_WriteCommand(0x30);

        OLED_WriteCommand(0xA4);        //设置整个显示打开/关闭

        OLED_WriteCommand(0xA6);        //设置正常/倒转显示

        OLED_WriteCommand(0x8D);        //设置充电泵
        OLED_WriteCommand(0x14);

        OLED_WriteCommand(0xAF);        //开启显示
               
        OLED_Clear();                                //OLED清屏
}
头文件
#ifndef __OLED_H
#define __OLED_H
#include "stm32f10x.h"

/*引脚配置*/
#define OLED_W_SCL(x)                GPIO_WriteBit(GPIOB, GPIO_Pin_6, (BitAction)(x))
#define OLED_W_SDA(x)                GPIO_WriteBit(GPIOB, GPIO_Pin_7, (BitAction)(x))

void OLED_Init(void);//OLED初始化
void OLED_Clear(void);//清屏
void OLED_Refresh_Gram(void);//更新显存到OLED
void OLED_WriteData(uint8_t Data);//OLED写数据
void OLED_WriteCommand(uint8_t Command);//OLED写命令
void OLED_DrawPoint(u8 x,u8 y,u8 t);//画点
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode);//oled显示字符
void OLED_ShowString(u8 x,u8 y,const u8 *p,u8 size);//oled显示字符串
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size);//oled显示数字
u32 mypow(u8 m,u8 n);//m^n函数
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size,u8 mode);//oled显示中文
#endif



黑屏6.png
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2022-5-9 23:57:06 | 显示全部楼层
建议用硬件测试。。。
回复

使用道具 举报

11

主题

2103

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4584
金钱
4584
注册时间
2015-1-10
在线时间
573 小时
发表于 2022-5-10 17:15:32 | 显示全部楼层
操作总线的时候没有一点延时?你的OLED总线响应这么快呢?
回复

使用道具 举报

0

主题

12

帖子

0

精华

新手入门

积分
16
金钱
16
注册时间
2024-5-27
在线时间
4 小时
发表于 2024-5-29 17:13:08 | 显示全部楼层
11111111111111111
回复

使用道具 举报

0

主题

9

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2024-7-8
在线时间
7 小时
发表于 2024-7-25 14:13:43 | 显示全部楼层
111111111
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 06:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表