完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
使用74HC595芯片的目的其实很简单,就是为节省STM32的IO口。 如果不使用74HC595模块,我们将要使用D0-D7八个数据脚,还有RS,RW,EN控制引脚,也就是说要很多IO脚,这样就不便于STM32的其他功能或模块的扩展,是不可取的。而使用595模块就能很好的解决这个问题。 使用的单片机型号:STM32L052K8* 液晶显示的模块:RG1602A,其实和LCD1602是一样的。 接线,如下图(很重要): 你会发现只需要将74HC595的三个引脚接在STM32 上就可以了,但要提示一下,不是要求必须接PB1、PA5、PA7,其实是随便你怎么接,需要代码进行修改就行。 1.LCD1602的实现 ||*可以发现只使用了4位控制线实现数据传输 如何实现传输的呢? ——假如要传输一个字节的数据,需要先传输该字节的高四位,然后再传输该字节的低四位。 根据配置RS和EN来进行写数据或写命令。 关于LCD1602的管脚及功能信息在之前的博客也有涉及,大家可以看看我之前的博客。 2.74HC595实现串行并出 ||*数据的发送 这个在之前的博客也讲到过,可以查看之前的博客。一定要注意时序的关系。 关于IO口的初始化配置,如下: static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, SCLK_Pin|DATA_Pin, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(RCLK_GPIO_Port, RCLK_Pin, GPIO_PIN_RESET); /*Configure GPIO pins : SCLK_Pin DATA_Pin */ GPIO_InitStruct.Pin = SCLK_Pin|DATA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /*Configure GPIO pin : RCLK_Pin */ GPIO_InitStruct.Pin = RCLK_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(RCLK_GPIO_Port, &GPIO_InitStruct); } lcd1602.c #include "lcd1602.h" #include "stdio.h" #include "main.h" /**********************************/ /** 函数名称:void LCD1602_Send595OneByte(unsigned char dis_data) **/ /** 输入参数:unsigned char dis_data 需要输入的数据 */ /** 函数功能:将数据写进74HC595中*/ /** ****************************** **/ void LCD1602_Send595OneByte(unsigned char dis_data) { unsigned char i; unsigned char temp; temp = dis_data; for(i=0;i<8;i++) { HAL_GPIO_WritePin(SCLK_GPIO_Port,SCLK_Pin,GPIO_PIN_RESET); if(temp & 0X80) { HAL_GPIO_WritePin(DATA_GPIO_Port,DATA_Pin,GPIO_PIN_SET); } else { HAL_GPIO_WritePin(DATA_GPIO_Port,DATA_Pin,GPIO_PIN_RESET); } temp = temp<<1; HAL_GPIO_WritePin(SCLK_GPIO_Port,SCLK_Pin,GPIO_PIN_RESET); // 0 HAL_GPIO_WritePin(SCLK_GPIO_Port,SCLK_Pin,GPIO_PIN_SET); // 1 HAL_GPIO_WritePin(SCLK_GPIO_Port,SCLK_Pin,GPIO_PIN_RESET); // 0 } } /****************************************/ /**函数名称:void LCD1602_OUT(void) */ /**函数参数:无参 */ /**函数功能:寄存器数据输出显示 */ void LCD1602_OUT(void) { HAL_GPIO_WritePin(RCLK_GPIO_Port,RCLK_Pin,GPIO_PIN_RESET); HAL_GPIO_WritePin(RCLK_GPIO_Port,RCLK_Pin,GPIO_PIN_SET); HAL_GPIO_WritePin(RCLK_GPIO_Port,RCLK_Pin,GPIO_PIN_RESET); } /* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */ //液晶写指令 void LCD1602_Write_Command(uint8_t command) { LCD1602_Send595OneByte(0x02); //LCD1602_EN=1,LCD1602_RS=0,清高4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x02|(((command & 0xf0)>>4)<<2)); //LCD1602_EN=1,LCD1602_RS=0,写高4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x00|(((command & 0xf0)>>4)<<2)); //LCD1602_EN=0,LCD1602_RS=0,写高4位 LCD1602_OUT(); command = command << 4; //低4位移到高4位 LCD1602_Send595OneByte(0x02); //LCD1602_EN=1,LCD1602_RS=0,清高4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x02|(((command & 0xf0)>>4)<<2)); //LCD1602_EN=1,LCD1602_RS=0,写低4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x00|(((command & 0xf0)>>4)<<2)); //LCD1602_EN=0,LCD1602_RS=0,写低4位 LCD1602_OUT(); } //液晶写数据 void LCD1602_Write_Data(uint8_t RecData) { LCD1602_Send595OneByte(0x03); //LCD1602_EN=1,LCD1602_RS=1,清高4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x03|(((RecData & 0xf0)>>4)<<2)); //LCD1602_EN=1,LCD1602_RS=1,写高4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x01|(((RecData & 0xf0)>>4)<<2)); //LCD1602_EN=0,LCD1602_RS=1,写高4位 LCD1602_OUT(); RecData = RecData << 4; //低4位移到高4位 LCD1602_Send595OneByte(0x03); //LCD1602_EN=1,LCD1602_RS=1,清高4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x03|(((RecData & 0xf0)>>4)<<2)); //LCD1602_EN=1,LCD1602_RS=1,写低4位 LCD1602_OUT(); LCD1602_Send595OneByte(0x01|(((RecData & 0xf0)>>4)<<2)); //LCD1602_EN=0,LCD1602_RS=1,写低4位 LCD1602_OUT(); } /* 清屏 */ void LCD1602_ClearScreen(void) { LCD1602_Write_Command(0x01); } /* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */ void LCD1602_Set_Cursor(uint8_t x, uint8_t y) { uint8_t addr; if (y == 0) addr = 0x00 + x; else addr = 0x40 + x; LCD1602_Write_Command(addr | 0x80); } /* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */ void LCD1602_Show_Str(uint8_t x, uint8_t y, uint8_t *str) { LCD1602_Set_Cursor(x, y); while(*str != ' |