这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 以STC15系列单片机驱动LCD1602

共2条 1/1 1 跳转至

以STC15系列单片机驱动LCD1602

专家
2023-10-21 15:26:15     打赏

  前面介绍了IIC LCD1602的相关知识。这次我们就是用STC15系列的单片机来实现驱动LCD1602显示。程序中使用了单片机的两个IO口用来模拟SCL和SDA来实现IIC功能。程序中接收来自从机的ACK时,没有判断是否正常接收。对程序就不另外说明了,看注释就应该能明白。另外要说明的是,这个测试是专门为了使用芯圣HC18M003测试IIC设备做的铺垫。


/**
 * IIC方式驱动LCD1602
 * 使用IAP15W4K58S4
 * LCD1602模块:  VCC  - 5V
 *  (PFC8547)     GND
 *                SCL - P3.2
 *                SDA - P3.3
 * PCF8574T      LCD1602
 * P7          DB7
 * P6          DB6
 * P5          DB5
 * P4          DB4
 * P3             控制背光灯
 * P0          RS
 * P1          RW
 * P2          CS
 *================================================================================
 * LCD1602的操作指令        P7  P6  P5  P4  P7  P6  P5  P4   P2(CS)  P1(RW)  P0(RS)      
 * 写指令: RS=0, RW=0, CS(E)上升沿
 * 写数据: RS=1, RW=0, CS(E)上升沿
 *
 * 显示模式设置           0   0   1   1   1   0   0   0     1      0        0      设置显示5*7点阵,8位数据接口
 * 显示开关             0   0   0   0   1   D   C   B     1      0        0      D=1开显示,D=0关显示
 *                                                                                  C=1显示光标,C=0关闭光标
 *                                                                                  B=1光标闪烁,B=0光标不闪烁
 *                  0   0   0   0    0   1   N    S                          N=1,读写后,自制自动加1;N=0,读写后,自制自动减1
 *                                                                                  S=1,写一个字符,整屏左移;S=0,不左移
 * 数据指针设置           80H + 地址码(0-27H(第一行),40H-67H(第二行))
 *
 *
 *
 *
 * LCD1602 四线驱动方式下,一个字节数据传输2回
 * 
 */
#include "stc15.h"
#include "string.h"
sbit SCL=P3^2;
sbit SDA=P3^3;
void delay_ms(unsigned int ms);
void delay_10us(unsigned int i);
/**********I2C init***********/
void I2cStart(void);
void I2cStop(void);
unsigned char I2cSendByte(unsigned char dat);
void send_pfc8574Byte(unsigned char dat);
void write_lcd1602_cmd(unsigned char cmd);
void write_lcd1602_data(unsigned char dat);
void lcd_init(void);
void write_cmd(unsigned char cmd);
void write_data(unsigned char DData);
void dispaly(unsigned char X, unsigned char Y, unsigned char DData);
void dispaly_character(unsigned char X, unsigned char Y, unsigned char* Arry);
void lcd1602_write_str(unsigned char addr, unsigned char num, unsigned char *dat);
//Y为显示指针的位置,即为各行的第几个位置,X选行
//col:0-15
//row:0-1
void lcd1602_GotoXY(unsigned char row, unsigned char col);
//向LCD写入字符串
void LCD1602_Display_NoXY(unsigned char *str);
unsigned char code arry[]="successfully!";
// 读写IIC显示板的地址
#define LCD_ADDR_W 0x4E
#define LCD_ADDR_R 0x4F
// 毫秒级延时
void delay_ms(unsigned int ms) {
    unsigned int i,j;
    for(j=0;j<ms;j++)
        for(i=0;i<1000;i++);
}
// 1o微秒单位的延时
void delay_10us(unsigned int i) { 
    unsigned char a,b,c;
  for(c=0;c<i;c++) {
      for(b=1;b>0;b--) {
      for(a=2;a>0;a--);
      }
  }
}
// 开始信号
void I2cStart(void) {
    SDA=1;
    delay_10us(5);
    SCL=1;
    delay_10us(5);
    SDA=0;
    delay_10us(5);
    SCL=0;
    delay_10us(5);
}
// 停止信号
void I2cStop(void) {
    SDA=0;
    delay_10us(5);
    SCL=1;
    delay_10us(5);
    SDA=1;
    delay_10us(5);
}
// MCU模拟IIC方式发出一字节
unsigned char I2cSendByte(unsigned char dat) {
   unsigned char a=0,b=0;
    
    for(a=0;a<8;a++) {
        SDA=dat>>7; 
        dat=dat<<1;
        delay_10us(5);
        SCL=1;
        delay_10us(5);
        SCL=0;
        delay_10us(5);
    }
   // 等待ACK
    SDA=1;
   // 等待从机使ACK=0
    delay_10us(5);
    SCL=1;
   delay_10us(5);
   // 等待SDA=0
    while(SDA) {
        b++;
        if(b>200) {
            SCL=0;
            delay_10us(5);
        // 超时
            return 0;
        }
    }
    // 收到SDA=0
    SCL=0;
    delay_10us(5);
   return 1;
}
// 发送一个字节给pfc8574
// 发送给LCD1602,要通过pfc8574实现,类似于74HC164那种串并转换处理
void send_pfc8574Byte(unsigned char dat) {
    I2cStart();
    I2cSendByte(LCD_ADDR_W);     // 写器件的物理地址,读时为0x4F                                     
    I2cSendByte(dat);
    I2cStop();
}
// 向LCD1602发送指令
void write_lcd1602_cmd(unsigned char cmd) {
    unsigned char cmd1, cmd2;
    cmd1=cmd|0x0f;
    
    send_pfc8574Byte(cmd1 & 0xfc);    // 11111100 : CS=1,RW=0, RS=0
    delay_10us(1);
    send_pfc8574Byte(cmd1 & 0xf8);    // 11111100 : CS=0,RW=0, RS=0
    
    cmd2=cmd<<4;
    cmd2=cmd2|0x0f;
    send_pfc8574Byte(cmd2 & 0xfc);    // 11111100 : CS=1,RW=0, RS=0
    delay_10us(1);
    send_pfc8574Byte(cmd2 & 0xf8);    // 11111100 : CS=0,RW=0, RS=0
}
// 向LCD1602发送数据
void write_lcd1602_data(unsigned char dat) {
    unsigned char dat1, dat2;
    dat1=dat|0x0f;
    
    send_pfc8574Byte(dat1 & 0xfd);    // 11111100 : CS=1,RW=0, RS=1
    delay_10us(1);
    send_pfc8574Byte(dat1 & 0xf9);    // 11111100 : CS=0,RW=0, RS=1
    
    dat2=dat<<4;
    dat2=dat2|0x0f;
    send_pfc8574Byte(dat2 & 0xfd);    // 11111100 : CS=1,RW=0, RS=1
    delay_10us(1);
    send_pfc8574Byte(dat2 & 0xf9);    // 11111100 : CS=0,RW=0, RS=1
}
// 初始化
void lcd_init(void) {
    write_lcd1602_cmd(0x33);    // 设置显示 4 (0x38:8)
    write_lcd1602_cmd(0x32);    // 设置4线控制
    write_lcd1602_cmd(0x28);    // 设置16*2, 5*7, 4线初始化
    write_lcd1602_cmd(0x06);    // 地址加1,数据不一定,地址移动
    write_lcd1602_cmd(0x0C);    // 不显示光标,光标不闪烁
    //write_lcd1602_cmd(0x0f);    //  显示光标,光标闪烁
    write_lcd1602_cmd(0x01);    // 清屏
    write_lcd1602_cmd(0x80);    // 起始地址
    delay_ms(5);
}
// 使LCD1602显示字符串
void lcd1602_write_str(unsigned char addr, unsigned char num, unsigned char *dat) {
    unsigned char i;
    write_lcd1602_cmd(addr);
    for (i=0;i<num; i++) {
        write_lcd1602_data(*dat++);
    }
}
//Y为显示指针的位置,即为各行的第几个位置,X选行
//col:0-15
//row:0-1
void lcd1602_GotoXY(unsigned char row, unsigned char col) {
    if(row == 0)
        write_lcd1602_cmd(0x80 + col);
    if(row == 1)
        write_lcd1602_cmd(0x80 + 0x40 + col);
}
//向LCD写入字符串
void LCD1602_Display_NoXY(unsigned char *str) {
    while(*str != '\0') {
        write_lcd1602_data(*str);
        str++;
    }
}
int main() {
    // 初始化LCD1602
    lcd_init();
    // 循环显示固定内容,仅仅是为了测试
    while(1) {
        // 定位显示位置为第一行、第一列
     lcd1602_GotoXY(0,0);
     write_lcd1602_data('B');
        
     // 定位显示位置为第二行、第一列
     lcd1602_GotoXY(1,0);
     LCD1602_Display_NoXY(arry);
     delay_ms(10);
    }
}

显示效果如下:

11.jpg




关键词: 菜鸟学单片机     STC15     IIC LCD1602    

院士
2023-10-21 17:28:39     打赏
2楼

学习了,谢谢分享。


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]