#智能小车(四)OLED初始化

GPIO初始化

/**
 * @Brief: 初始化I2C对应的接口引脚
 * @Note:
 * @Parm: void
 * @Retval: void
 */
void IIC_Init(void)
{
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructer;
	GPIO_InitStructer.GPIO_Pin=GPIO_Pin_14|GPIO_Pin_15;/*PF14:SCL    PF15:SDA*/
	GPIO_InitStructer.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStructer.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStructer.GPIO_PuPd=GPIO_PuPd_NOPULL;
	GPIO_InitStructer.GPIO_Speed=GPIO_High_Speed;
	GPIO_Init(GPIOF,&GPIO_InitStructer);
}
void i2c_scanf_addr(void)/* 遍历地址1-127 */
{
    uint8_t i2c_count = 0;
    for (int i = 1; i < 128; i++)
    {
        if (!IIC_Start())
        {
            printf("External IIC Start Error:%d\n", i);
            return;
        }
        IIC_Send_Byte(i << 1);
        if (!IIC_Wait_Ack())
        {
            if (i == 127)
            {
                printf("External IIC Scanf End, Count=%d\n", i2c_count);
            }
            continue;
        }
        IIC_Stop();
        i2c_count++;
        printf("External IIC Found address:0x%2x\n", i);
        g_addr[i] = i;
    }
}

/**
 * @Brief: 产生IIC起始信号
 * @Note:
 * @Parm: void
 * @Retval: void
 */
int IIC_Start(void)
{ 
    SDA_OUT(); //sda线输出 /* 开始信号SLC=H SDA 由H到L */
    IIC_SDA = 1;
    if (!READ_SDA)
        return 0;
    IIC_SCL = 1;
    Delay_For_Pin(1);
    IIC_SDA = 0; //START:when CLK is high,DATA change form high to low
    if (READ_SDA)
        return 0;
    Delay_For_Pin(2);
    IIC_SCL = 0; //钳住I2C总线,准备发送或接收数据
    return 1;
}
/**
 * @Brief: 产生IIC停止信号
 * @Note:
 * @Parm: void
 * @Retval: void
 */
void IIC_Stop(void)  /* 停止信号SCL为H SDA 由L变H */
{
    SDA_OUT(); //sda线输出
    IIC_SCL = 0;
    IIC_SDA = 0; //STOP:when CLK is high DATA change form low to high
    Delay_For_Pin(2);
    IIC_SCL = 1;
    Delay_For_Pin(1);
    IIC_SDA = 1; //发送I2C总线结束信号
    Delay_For_Pin(2);
}

/**
 * @Brief: 等待应答信号到来
 * @Note:
 * @Parm:
 * @Retval: 1:接收应答失败 | 0:接收应答成功
 */
int IIC_Wait_Ack(void)
{
    uint8_t ucErrTime = 0;
    SDA_IN(); //SDA设置为输入
    IIC_SDA = 1;
    Delay_For_Pin(1);
    IIC_SCL = 1;
    Delay_For_Pin(1);
    while (READ_SDA)
    {
        ucErrTime++;
        if (ucErrTime > 50)
        {
            IIC_Stop();
            return 0;
        }
        Delay_For_Pin(1);
    }
    IIC_SCL = 0; //时钟输出0
    return 1;
}

/**
 * @Brief: 产生ACK应答
 * @Note:
 * @Parm: void
 * @Retval: void
 */
void IIC_Ack(void) /* ACK  主机SCL为H 读取SDA为低  */
{
    IIC_SCL = 0;
    SDA_OUT();
    IIC_SDA = 0;
    Delay_For_Pin(1);
    IIC_SCL = 1;
    Delay_For_Pin(1);
    IIC_SCL = 0;
}

/**
 * @Brief: 产生NACK应答
 * @Note:
 * @Parm: void
 * @Retval: void
 */
void IIC_NAck(void)/* NACK 主机SCL 为H  读取SDA为高 */
{
    IIC_SCL = 0;
    SDA_OUT();
    IIC_SDA = 1;
    Delay_For_Pin(1);
    IIC_SCL = 1;
    Delay_For_Pin(1);
    IIC_SCL = 0;
}

/**
 * @Brief: IIC发送一个字节
 * @Note:
 * @Parm: void
 * @Retval: void
 */
void IIC_Send_Byte(uint8_t txd)/* SCL = H SDA 数据有效 SCL=L SDA数据交换 */
{
    uint8_t t;
    SDA_OUT();
    IIC_SCL = 0; //拉低时钟开始数据传输
    for (t = 0; t < 8; t++)
    {
        IIC_SDA = (txd & 0x80) >> 7;/*MSB高位传输 */
        txd <<= 1;
        Delay_For_Pin(1);
        IIC_SCL = 1;
        Delay_For_Pin(1);
        IIC_SCL = 0;
        Delay_For_Pin(1);
    }
}

uint8_t SSD1306_Init(void)
{
    /* A little delay */
    uint32_t p = 2500;
    while (p > 0)
        p--;

    /* Init LCD */
    SSD1306_WRITECOMMAND(0xae);		      // display off
    SSD1306_WRITECOMMAND(0xa6);          // Set Normal Display (default)
    SSD1306_WRITECOMMAND(0xAE);        	// DISPLAYOFF
    SSD1306_WRITECOMMAND(0xD5);        	// SETDISPLAYCLOCKDIV
    SSD1306_WRITECOMMAND(0x80);        	// the suggested ratio 0x80
    SSD1306_WRITECOMMAND(0xA8);        	// SSD1306_SETMULTIPLEX
    SSD1306_WRITECOMMAND(0x1F);
    SSD1306_WRITECOMMAND(0xD3);        	// SETDISPLAYOFFSET
    SSD1306_WRITECOMMAND(0x00);         	// no offset
    SSD1306_WRITECOMMAND(0x40 | 0x0);  	// SETSTARTLINE
    SSD1306_WRITECOMMAND(0x8D);        	// CHARGEPUMP
    SSD1306_WRITECOMMAND(0x14);          // 0x014 enable, 0x010 disable
    SSD1306_WRITECOMMAND(0x20);          // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5),
    SSD1306_WRITECOMMAND(0x02);          // 0x12 //128x32 OLED: 0x002,  128x32 OLED 0x012
    SSD1306_WRITECOMMAND(0xa1);          // segment remap a0/a1
    SSD1306_WRITECOMMAND(0xc8);          // c0: scan dir normal, c8: reverse
    SSD1306_WRITECOMMAND(0xda);
    SSD1306_WRITECOMMAND(0x02);          // com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5)
    SSD1306_WRITECOMMAND(0x81);
    SSD1306_WRITECOMMAND(0xcf);          // [2] set contrast control
    SSD1306_WRITECOMMAND(0xd9);
    SSD1306_WRITECOMMAND(0xf1);          // [2] pre-charge period 0x022/f1
    SSD1306_WRITECOMMAND(0xdb);
    SSD1306_WRITECOMMAND(0x40);          // vcomh deselect level
    SSD1306_WRITECOMMAND(0x2e);          // Disable scroll
    SSD1306_WRITECOMMAND(0xa4);          // output ram to display
    SSD1306_WRITECOMMAND(0xa6);          // none inverted normal display mode
    SSD1306_WRITECOMMAND(0xaf);          // display on
    
    /* Clear screen */
    SSD1306_Fill(SSD1306_COLOR_BLACK);

    /* Update screen */
    SSD1306_UpdateScreen();

    /* Set default values */
    SSD1306.CurrentX = 0;
    SSD1306.CurrentY = 0;

    /* Initialized OK */
    SSD1306.Initialized = 1;

    /* Return OK */
    return 1;
}

你可能感兴趣的:(智能小车项目,单片机)