close

ST_logo_20130425.png

16x2 LCD 可以顯示兩行訊息,每行16 個字元,可以顯示英文字母,希臘字母,標點符號以及數學符號,其他功能包括訊息捲動(往左和往右捲動),顯示游標和LED背光等

1. 實驗材料

STM32F103C8T6開發板*1

20181027_181027_0001.jpg

16x2 LCD*1

408766.jpg

J-link*1

20181027_181027_0002.jpg

USB A to B(當供電源使用)*1

229169.jpg

線材*1

402985.jpg

2. 電路接線圖

1.JPG

408767.jpg

3. 程式撰寫

在STM32F103_Configuration下新增i2c1_config.c,

/*
程式名稱:I2C1配置初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void I2C1_ConfigInit(void){ 
    I2C_InitTypeDef I2C_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);    
 
        I2C_InitStructure.I2C_ClockSpeed = 100000; 
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; 
    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);        
}


/*
程式名稱:I2C1 Start
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void I2C1_Start(uint8_t address, uint8_t direction){

    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
 
    I2C_GenerateSTART(I2C1, ENABLE);

    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
 
    I2C_Send7bitAddress(I2C1, address, direction);
 
    if(direction == I2C_Direction_Transmitter){
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
    } else if(direction == I2C_Direction_Receiver){
        while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
    }
}

/*
程式名稱:I2C1 Write
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void I2C1_Write(uint8_t data){
    I2C_SendData(I2C1, data);
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}

/*
程式名稱:I2C1 Read Ack
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
uint8_t I2C1_Read_Ack(void){
    uint8_t data;
    
    I2C_AcknowledgeConfig(I2C1, ENABLE);
    while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    data = I2C_ReceiveData(I2C1);
    return data;
}

/*
程式名稱:I2C1 Read Nack
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
uint8_t I2C1_Read_Nack(void){
    uint8_t data;

    I2C_AcknowledgeConfig(I2C1, DISABLE);
    I2C_GenerateSTOP(I2C1, ENABLE);
    while( !I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) );
    data = I2C_ReceiveData(I2C1);
    return data;
}

/*
程式名稱:I2C1 Stop
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void I2C1_Stop(void){
    I2C_GenerateSTOP(I2C1, ENABLE);
        while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));
}

在STM32F103_Configuration下新增i2c1_config.h,

#ifndef __I2C1_CONFIG_H
#define __I2C1_CONFIG_H

#include "main.h"

/* I2C1配置初始化 */
void I2C1_ConfigInit(void);
/* I2C1 Start */
void I2C1_Start(uint8_t address, uint8_t direction);
/* I2C1 Write */
void I2C1_Write(uint8_t data);
/* I2C1 Read Ack */
uint8_t I2C1_Read_Ack(void);
/* I2C1 Read Nack */
uint8_t I2C1_Read_Nack(void);
/* I2C1 Stop */
void I2C1_Stop(void);

#endif 

在ExtDevices_Configuration下新增lcd1206.c,

#include "lcd1206.h"

/*
程式名稱:LCD 1206初始化
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_Init(void){

    /* I2C1配置初始化 */
    I2C1_ConfigInit();
    delay_ms(150);
     
    LCD1206_CommandWrite(0x02);    
    //16 *2顯示,5 *7點陣,4位數據口    
  LCD1206_CommandWrite(0x28);   
  //開顯示,光標關閉    
  LCD1206_CommandWrite(0x0C); 
    LCD1206_CommandWrite(0x80);  
}

/*
程式名稱:LCD 1206 命令寫入
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_CommandWrite(uint8_t cmd){
  uint8_t data_u=0, data_l=0;
    uint8_t data_t[4];
    
    data_u = cmd&0xF0;
    data_l = (cmd<<4)&0xF0;
    data_t[0] = data_u | 0x0C;//en=1, rs=0
    data_t[1] = data_u | 0x08;//en=0, rs=0
    data_t[2] = data_l | 0x0C;//en=1, rs=0
    data_t[3] = data_l | 0x08;//en=0, rs=0 
    
    LCD1206_ByteWrite(0x4E, data_t);
}

/*
程式名稱:LCD 1206 資料寫入
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_DataWrite(uint8_t data){
  uint8_t data_u=0, data_l=0;
    uint8_t data_t[4];
    
    data_u = data&0xF0;
    data_l = (data<<4)&0xF0;
    data_t[0] = data_u | 0x0D;//en=1, rs=1 
    data_t[1] = data_u | 0x09;//en=0, rs=1
    data_t[2] = data_l | 0x0D;//en=1, rs=1 
    data_t[3] = data_l | 0x09; //en=0, rs=1
    
    LCD1206_ByteWrite(0x4E, data_t);
}

/*
程式名稱:LCD 1206 光標設定
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_SetCursor(uint8_t x, uint8_t y){
    uint8_t addr=0;
    
    if (y == 0){
        addr = 0x00 + x;
    }else{
        addr = 0x40 + x;
    }
    
    LCD1206_CommandWrite(addr | 0x80);    
}

/*
程式名稱:LCD 1206 字串顯示
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_String(uint8_t *str, uint16_t length){
    uint16_t i=0;
    
    for(i=0; i<length; i++){
        LCD1206_DataWrite(*(str + i));
    }
}

/*
程式名稱:LCD 1206 清除
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_Clear(void){
    LCD1206_CommandWrite(0x01);    
}

/*
程式名稱:LCD 1206 Byte寫入
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/10/27
程式修改日期:N/A
程式說明:

*/
void LCD1206_ByteWrite(uint8_t address, uint8_t *writeData){
    uint8_t i=0;
    
    I2C1_Start(address, I2C_Direction_Transmitter);
    for(i=0; i<4; i++){
        I2C1_Write(*(writeData + i));
    }
    I2C1_Stop();    
}

在ExtDevices_Configuration下新增lcd1206.h,

#ifndef __lcd1206_H
#define __lcd1206_H

#include "main.h"

/* LCD 1206初始化 */
void LCD1206_Init(void);
/* LCD 1206 命令寫入 */
void LCD1206_CommandWrite(uint8_t cmd);
/* LCD 1206 資料寫入 */
void LCD1206_DataWrite(uint8_t data);
/* LCD 1206 光標設定 */
void LCD1206_SetCursor(uint8_t x, uint8_t y);
/* LCD 1206 字串顯示 */
void LCD1206_String(uint8_t *str, uint16_t length);
/* LCD 1206 清除 */
void LCD1206_Clear(void);
/* LCD 1206 Byte寫入 */
void LCD1206_ByteWrite(uint8_t address, uint8_t *writeData);

#endif 

在main.c

#include "main.h"

/*
程式名稱:主程式
程式版本:V1.0
程式撰寫者:Michael Jheng(鄭智遠)
程式撰寫日期:2018/1/6
程式修改日期:N/A
程式說明:

*/
int main(void){

    /* 開發板全域變數初始化 */
    BSP_VariableInit();
    /* 開發板整體系統初始化 */
    BSP_Init();
    

    LCD1206_SetCursor(0, 0);
    LCD1206_String("Hello, World!", 13);

    
  /* Infinite loop */
  for(;;){
        
        if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13)==0){
            GPIO_SetBits(GPIOC, GPIO_Pin_13);
        }else{
            GPIO_ResetBits(GPIOC, GPIO_Pin_13);
        }
        delay_ms(500);
        
  }
}

5. 實驗結果

231999.jpg

arrow
arrow

    鄭智遠 發表在 痞客邦 留言(0) 人氣()