123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*
- **************************************************************************************************
- * 小浩电子科技
- * 文件名:stm32驱动1602程序源文件
- * 描 述:
- * 版本号:V2.0
- * 备 注:
- * 程序员:电子极客迷
- * 日 期:2018-04-22
- ***************************************************************************************************
- */
- #include "drive_lcd1602.h"
- #include "delay.h"
- #include "stm32f10x.h"
- #include "stm32f10x_gpio.h"
- #include "stm32f10x_rcc.h"
- #include <stdarg.h> // 标准头文件
- #include "stdio.h"
- #ifdef LCD602_Bin //
- /*以下为并口驱动程序*/
- ///********************************硬件接口定义*********************************/
- #define RS GPIO_Pin_7
- #define RW GPIO_Pin_6
- #define EN GPIO_Pin_5
- #define Control_GPIO GPIOA
- /********************************宏定义*********************************/
- #define LCD1602_RS(x) x ? GPIO_SetBits(Control_GPIO, RS): GPIO_ResetBits(Control_GPIO, RS)
- #define LCD1602_RW(x) x ? GPIO_SetBits(Control_GPIO, RW): GPIO_ResetBits(Control_GPIO, RW)
- #define LCD1602_EN(x) x ? GPIO_SetBits(Control_GPIO, EN): GPIO_ResetBits(Control_GPIO, EN)
- void LCDGPIO_Configuration(void);
- /*********************************************************************
- *名 称:LcdWaitReady()
- *描 述:等待液晶准备好
- *入口参数:无
- *出口参数:result
- *********************************************************************/
- u8 LcdWaitReady(void)
- { // 测试LCD忙碌状态
- u8 result;
- LCD1602_RS(0); //0;
- LCD1602_RW(1); //1;
- LCD1602_EN(1); //1;
- delay_us(50);
- result = (GPIO_ReadInputData(GPIOB) & 0x8000)>>8;
- LCD1602_EN(0); // 0;
- return result;
- }
- /*********************************************************************
- *名 称: LcdWriteCmd(u8 cmd)
- *描 述:写指令到LCD1602,指令数据占一个字节
- *入口参数:cmd,待写入指令
- *出口参数:无
- *********************************************************************/
- void LCD1602_Write_Cmd(unsigned char cmd)
- { // 写入指令数据到LCD
- //while(LcdWaitReady());
- delay_us(500);
- LCD1602_RS(0); // 0;
- LCD1602_RW(0); // 0;
- LCD1602_EN(0); // 0;
- delay_us(50);
- GPIOB->BSRR = cmd<<8 & 0xff00; //将数据送到P0口
- GPIOB->BRR = ((~cmd)<<8) & 0xff00;
- delay_us(50);
- LCD1602_EN(1); // 1;
- delay_us(50);
- LCD1602_EN(0); // 0;
- }
- /*********************************************************************
- *名 称: LcdWriteCmd(u8 cmd)
- *描 述:写数据到LCD1602,数据占一个字节
- *入口参数:dat,待写入数据
- *出口参数:无
- *********************************************************************/
- void LCD1602_Write_Dat(unsigned char dat)
- { //写入字符显示数据到LCD
- //while(LcdWaitReady());
- delay_us(500);
- LCD1602_RS(1); //= 1;
- LCD1602_RW(0); //= 0;
- LCD1602_EN(0); //= 0;
- GPIOB->BSRR = dat<<8 & 0xff00; ////P0 = dat
- GPIOB->BRR = ((~dat)<<8) & 0xff00;
- delay_us(50);
- LCD1602_EN(1);// = 1;
- delay_us(50);
- LCD1602_EN(0);// = 0;
- delay_us(50);
- }
- /*********************************************************************
- *名 称:InitLcd1602()
- *描 述:初始化1602液晶
- *入口参数:无
- *出口参数:无
- *********************************************************************/
- void Init_Lcd1602(void)
- {
- //LCD初始化设定
- LCDGPIO_Configuration();
- delay_ms(100);
- LCD1602_Write_Cmd(0x38); //16*2显示,5*7点阵,8位数据
- delay_ms(30);
- LCD1602_Write_Cmd(0x0c); //显示开,关光标
- delay_ms(30);
- LCD1602_Write_Cmd(0x06); //移动光标
- delay_ms(30);
- LCD1602_Write_Cmd(0x01); //清除LCD的显示内容
- delay_ms(30);
- }
- /*********************************************************************
- *名 称:LcdClearScreen()
- *描 述:清屏
- *入口参数:无
- *出口参数:无
- *********************************************************************/
- void LcdClearScreen(void)
- {
- LCD1602_Write_Cmd(0x01);
- }
- /*********************************************************************
- *名 称:LcdOpenCursor()
- *描 述:打开光标的闪烁效果
- *入口参数:无
- *出口参数:无
- *********************************************************************/
- void LcdOpenCursor(void)
- {
- LCD1602_Write_Cmd(0x0F);
- }
- /*********************************************************************
- *名 称:LcdCloseCursor()
- *描 述: 关闭光标显示
- *入口参数:无
- *出口参数:无
- *********************************************************************/
- void LcdCloseCursor(void)
- {
- LCD1602_Write_Cmd(0x0C);
- }
- void LCDGPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//RS RW EN 控制脚 时钟
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
- //所有GPIO为同一类型端口
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //输出的最大频率为50HZ
- GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB端口
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Init(Control_GPIO,&GPIO_InitStructure);
- }
- #else
- //1602指令/数据 引脚 rs
- #define LCD_RS_Set() GPIO_SetBits(GPIOB, GPIO_Pin_7)
- #define LCD_RS_Clr() GPIO_ResetBits(GPIOB, GPIO_Pin_7)
-
- //1602读写引脚 rw可以不用 直接接地
- #define LCD_RW_Set() GPIO_SetBits(GPIOB, GPIO_Pin_6)
- #define LCD_RW_Clr() GPIO_ResetBits(GPIOB, GPIO_Pin_6)
-
- //1602使能引脚 en
- #define LCD_EN_Set() GPIO_SetBits(GPIOB, GPIO_Pin_6)
- #define LCD_EN_Clr() GPIO_ResetBits(GPIOB, GPIO_Pin_6)
-
- //1602数据端口 PD4~7 //采用操作一组io写方法使用 不建议用
- #define DATAOUT(x) GPIO_Write(LCD_DATA_PORT, x)
- #define LCD_DATA_PORT GPIOB
- void LCDGPIO_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA,ENABLE);//打开时钟
- //dataIO GPIOA4~7 初始化
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(LCD_DATA_PORT, &GPIO_InitStructure);
- // RS RW E IO初始化
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_6|GPIO_Pin_5; //rw rs en
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
-
- /* 检测液晶忙不忙 */
- void LCD1602_Wait_Ready(void)
- {
- int8_t sta;
- DATAOUT(0xff); //PA端口全部置1
- LCD_RS_Clr(); //RS 0
- LCD_RW_Set(); //RW 1
- do
- {
- LCD_EN_Set(); //EN 1
- delay_ms(5); //延时5MS
- sta = GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15);//读取状态字
- LCD_EN_Clr(); //EN 0
- }while(sta & 0x80);//bit7等于1表示忙,重复检测到其为0停止
- }
- /*
- 向1602写入一字节命令,cmd-待写入命令
- //写入指令 RS-0 RW-0
- */
- void LCD1602_Write_Cmd(unsigned char cmd)
- {
- char ik=0;
- delay_ms(10); //不判忙信号 必须加入延时
- //LCD1602_Wait_Ready(); //判断忙不忙
- LCD_RS_Clr();
- for(ik=0;ik<2;ik++) //操作一位一位的写数据进去 建议用这种写法 不影响其他位
- {
- LCD_EN_Set();
- GPIO_ResetBits(GPIOB,GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);//数据口全部写低
- if(cmd&0x80) GPIO_SetBits(GPIOB,GPIO_Pin_15);
- if(cmd&0x40) GPIO_SetBits(GPIOB,GPIO_Pin_14);
- if(cmd&0x20) GPIO_SetBits(GPIOB,GPIO_Pin_13);
- if(cmd&0x10) GPIO_SetBits(GPIOB,GPIO_Pin_12);
- LCD_EN_Clr();
- cmd=cmd<<4;
- }
- }
-
- /* 向1602写入一字节数据*/
- void LCD1602_Write_Dat(unsigned char dat)
- {
- char ik=0;
- delay_ms(10); //不判忙信号 必须加入延时
- LCD_RS_Set(); //1
- for(ik=0;ik<2;ik++)
- {
- LCD_EN_Set();
- GPIO_ResetBits(GPIOB,GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
- if(dat&0x80) GPIO_SetBits(GPIOB,GPIO_Pin_15);
- if(dat&0x40) GPIO_SetBits(GPIOB,GPIO_Pin_14);
- if(dat&0x20) GPIO_SetBits(GPIOB,GPIO_Pin_13);
- if(dat&0x10) GPIO_SetBits(GPIOB,GPIO_Pin_12);
- LCD_EN_Clr();
- dat=dat<<4;
- }
- }
- /* 初始化液晶*/
- void Init_Lcd1602(void)
- {
- LCDGPIO_Configuration();//IO配置初始化
- LCD1602_Write_Cmd(0x28); //16*2显示,5*7点阵,4位数据口
- LCD1602_Write_Cmd(0x0C); //开显示,光标关闭
- LCD1602_Write_Cmd(0x06); //文字不动,地址自动+1
- LCD1602_Write_Cmd(0x01); //清屏
- }
- #endif
- /************ 写字符数据函数 *****************
- //功能:在lcd1602指定位置上显示字符;
- //参数
- //p: 指向待显示数据指针
- //x: X坐标
- //y: Y坐标
- */
- void WriteLcd1602_String(char x,char y,char *p)
- {
- if(y == 0)
- {
- LCD1602_Write_Cmd(0x80 + x);
- }
- else
- {
- LCD1602_Write_Cmd(0xC0 + x);
- }
- while(*p != 0)
- {
- LCD1602_Write_Dat(*p);
- p++;
- }
- }
- void L1602_printf(char x,char y,char *p,...)
- {
- char Lcdbuf[16];
- va_list ap;
- va_start(ap,p);
- vsprintf(Lcdbuf,p,ap);
- va_end(ap);
- WriteLcd1602_String(x,y,Lcdbuf);
- }
|