LCD1602
每行显示16个字符 一共2行
DB0--PB5
DB1--PB6
DB2--PB7
DB3--PB8
DB4--PB9
DB5--PC0
DB6--PC1
DB7--PC2
控制
使能PB4---------------- --[1--延时--0完成使能]
数据/命令选择 PC6 --- [1-数据 0-命令]
读/写选择     PA11------ [1-读   0-写]

分析一个数据过来比如11001010
那么分配一下
DB0--PB5--0
DB1--PB6--1
DB2--PB7--0
DB3--PB8--1
DB4--PB9--0
DB5--PC0--0
DB6--PC1--1
DB7--PC2--1
代码如何写呢?一个数据过来 需要分割2部分5BIT去PB 3BIT去PC
void Lcd1602_SendByte(unsigned char byte)
{
    unsigned short value = 0;
    
    value = GPIO_ReadOutputData(GPIOB);                    //读取GPIOB的数据
    value &= ~(0x001F << 5);                            //清除bit5~8
    value |= ((unsigned short)byte & 0x001F) << 5;        //将要写入的数据取低5位并左移5位
    GPIO_Write(GPIOB, value);                            //写入GPIOB
    
    value = GPIO_ReadOutputData(GPIOC);                    //读取GPIOC的数据
    value &= ~(0x0007 << 0);                            //清除bit0~2
    value |= ((unsigned short)byte & 0x00E0) >> 5;        //将要写入的数据取高3位并右移5位
    GPIO_Write(GPIOC, value);                            //写入GPIOC

DelayUs(10);
}
可以看到用了value整体处理 而不是一个一个去控制,因为设计好了,你看
先    value = GPIO_ReadOutputData(GPIOB);    //读取GPIOB的数据它包含了PB的全部引脚比如PB3它现在是高电平在亮灯的话那么PB3就是1 一起读出来是unsigned short
在    value &= ~(0x001F << 5);            //清除bit5~8 因为我们用的是PB56789 把我们控制的操作 不会干扰PB3的LED
在  value |= ((unsigned short)byte & 0x001F) << 5;        //其实这句话才体现了不会干扰PB3的LED 其他位置不变 在约定的地方|进去了byte参数的部分
在    GPIO_Write(GPIOB, value);                            //完成目标控制 并且不干扰别的管脚

可以看到这个依赖硬件的设计 管脚尽量靠在一起 操作方便

开始流程:
初始化--全部设置为output--开始初始化程序--    
    Lcd1602_WriteCom(0x38);
    DelayXms(5);
    Lcd1602_WriteCom(0x38);
    DelayXms(5);
    Lcd1602_WriteCom(0x38);
    Lcd1602_WriteCom_Busy(0x38);
    Lcd1602_WriteCom_Busy(0x08);
    Lcd1602_WriteCom_Busy(0x01);
    Lcd1602_WriteCom_Busy(0x06);
    Lcd1602_WriteCom_Busy(0x0c);
    --开始显示

关键函数Lcd1602_SendByte开始分析

GPIO的库函数控制 做个小测试吧

+++++++++++++++++++mcube+++在开始+++

https://www.cnblogs.com/will-king0308/p/8656077.html

8个数据

pa0 1 2 3 4 5 6 7-----D0 1 2 3 4 5 6 7

这样直接连接

另外3个需要编程的

pB7---rs

pb6--rw

pb5-e

供电

1---背光走3.3VSTM32板子

2---LCD上电用USB GNB+5V 3.3V 因为5V是开机的 3.3v是三号脚对比的

最后上图 是比较好看的

开始逻辑 8+3 全部的编程IO都是基础的GPIO_Mode_Out_PP

+++++++++++++++++麒麟座OK+++++++++

可以直接运行

如果麒麟座第一次烧录以后 此后STLINK无法连接 无法KEIL烧录 用3。3V拉一下R7也就是BOOT0

目前BOOT 0 1 都是GND的 你板子下电 usbhub一起供电关闭

短接R7和3.3V 上电 就可以烧录了

第一步 提供US延时 利用tim

void MX_TIM2_Init(void)
{htim2.Instance = TIM2;htim2.Init.Prescaler = 72-1;htim2.Init.CounterMode = TIM_COUNTERMODE_UP;htim2.Init.Period = 1000-1;
void TIM2_Delay(int us)
{uint16_t differ=us;if(differ>999)return;HAL_TIM_Base_Start(&htim2);__HAL_TIM_SET_COUNTER(&htim2,0);while(__HAL_TIM_GET_COUNTER(&htim2) < differ);HAL_TIM_Base_Stop(&htim2);
}

第二部IO对应有问题 下面是OK的

#define RS_H   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
#define RS_L   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);#define RW_H   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
#define RW_L   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);#define EN_H   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
#define EN_L   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);

全部代码

/* USER CODE BEGIN Header */
/********************************************************************************* @file           : main.c* @brief          : Main program body******************************************************************************* @attention** <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.* All rights reserved.</center></h2>** This software component is licensed by ST under BSD 3-Clause license,* the "License"; You may not use this file except in compliance with the* License. You may obtain a copy of the License at:*                        opensource.org/licenses/BSD-3-Clause********************************************************************************/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void TIM2_Delay(int us)
{uint16_t differ=us;if(differ>999)return;HAL_TIM_Base_Start(&htim2);__HAL_TIM_SET_COUNTER(&htim2,0);while(__HAL_TIM_GET_COUNTER(&htim2) < differ);HAL_TIM_Base_Stop(&htim2);
}
/* USER CODE END 0 */
#define RS_H   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
#define RS_L   HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_RESET);#define RW_H   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET);
#define RW_L   HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET);#define EN_H   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_SET);
#define EN_L   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, GPIO_PIN_RESET);uint32_t GReadGPIOOutput(GPIO_TypeDef* GPIOx)
{return GPIOx->ODR;}void GWriteGPIOOutput(GPIO_TypeDef* GPIOx,uint32_t value)
{GPIOx->ODR = value;}void Lcd1602_SendByte(unsigned char byte)
{unsigned short value = 0;value = GReadGPIOOutput(GPIOB);                 //读取GPIOB的数据value &= ~(0x001F << 5);                         //清除bit5~8value |= ((unsigned short)byte & 0x001F) << 5;     //将要写入的数据取低5位并左移5位GWriteGPIOOutput(GPIOB, value);                           //写入GPIOBvalue = GReadGPIOOutput(GPIOC);                   //读取GPIOC的数据value &= ~(0x0007 << 0);                         //清除bit0~2value |= ((unsigned short)byte & 0x00E0) >> 5;     //将要写入的数据取高3位并右移5位GWriteGPIOOutput(GPIOC, value);                           //写入GPIOC    TIM2_Delay(10);
}void Lcd1602_WriteCom(unsigned char byte)
{RS_L;RW_L;Lcd1602_SendByte(byte);EN_H;TIM2_Delay(20); EN_L;TIM2_Delay(5);
}void Lcd1602_WriteCom_Busy(unsigned char byte)
{HAL_Delay(2); RS_L;RW_L;Lcd1602_SendByte(byte);EN_H;TIM2_Delay(20); EN_L;TIM2_Delay(5);
}
void Lcd1602_WriteData(unsigned char byte)
{RS_H;RW_L;Lcd1602_SendByte(byte);EN_H;TIM2_Delay(20); EN_L;TIM2_Delay(5);
}
void Lcd1602_Init(void)
{HAL_Delay(15);Lcd1602_WriteCom(0x38);HAL_Delay(5);Lcd1602_WriteCom(0x38);HAL_Delay(5);Lcd1602_WriteCom(0x38);Lcd1602_WriteCom_Busy(0x38);Lcd1602_WriteCom_Busy(0x08);Lcd1602_WriteCom_Busy(0x01);Lcd1602_WriteCom_Busy(0x06);Lcd1602_WriteCom_Busy(0x0c);EN_L;
}void lcd_char_write(unsigned int x_pos,unsigned int y_pos,unsigned char lcd_dat) /*LCD1602 字符写入*/
{x_pos &= 0x0f; y_pos &= 0x01; if(y_pos==1) x_pos += 0x40;x_pos += 0x80;Lcd1602_WriteCom_Busy(x_pos);Lcd1602_WriteData(lcd_dat);
}#include <stdarg.h>
void Lcd1602_DisString(unsigned char pos, char *fmt,...)
{unsigned char LcdPrintfBuf[33];unsigned char count = 0;unsigned char remain = 0;                 //一行剩余空间va_list ap;unsigned char *pStr = LcdPrintfBuf;va_start(ap,fmt);vsprintf((char *)LcdPrintfBuf, fmt, ap);va_end(ap);remain = 0x8f - pos;                        //这里解决bug,以前只管写16次,这次要根据开始的位置来计算Lcd1602_WriteCom_Busy(pos);while(*pStr != 0){Lcd1602_WriteData(*pStr++);if(++count > remain && pos <= 0x8f){count = 0;Lcd1602_WriteCom_Busy(0xC0);HAL_Delay(1);}}}/*** @brief  The application entry point.* @retval int*/unsigned char temp_table[] ={"TempNow:    .  C"};
unsigned char temp_set_table[]={"MMX:70C IN:     "};
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM2_Init();/* USER CODE BEGIN 2 */
Lcd1602_Init();//       Lcd1602_DisString(0x80, "OneNET-IOT");
//              Lcd1602_DisString(0xC0, "China Mobile");
for(int i=0;i<16;i++)
lcd_char_write(i,0,temp_table[i]);
for(int j=0;j<16;j++)
lcd_char_write(j,1,temp_set_table[j]);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */
//HAL_Delay(200);
for(int i=0;i<1000;i++)      TIM2_Delay(200);
HAL_GPIO_TogglePin(LED2_GPIO_Port,LED2_Pin);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT *//************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

麒麟座的使用

1---STLINK直接 连接103的 这个要转接一下

也就是用麒麟座需要自己多一个线

2--每次KEIL烧录失败 你需要板子下电 短句R7-3.3V然后上电 烧录 完毕以后 在下电上电run

LCD1602开始--麒麟座OK相关推荐

  1. 和12岁小同志搞创客开发:如何驱动LCD1602液晶显示屏?

     目录 1.简介和驱动原理 2.实践 机缘巧合在网上认识一位12岁小同志,从零开始系统辅导其创客开发思维和技巧. 项目专栏:https://blog.csdn.net/m0_38106923/cate ...

  2. STC89C52单片机 LCD1602液晶显示屏

    LCD1602显示 VVcat #include <reg52.h>typedef unsigned char uchar; typedef unsigned int uint;sbit ...

  3. LCD1602液晶显示模块的单片机驱动深入详解之硬件篇

    (本文以HD44780主控芯片的LCD1602为蓝本进行描述,其中的截图也来自HD44780数据手册,用户可自行搜索其datasheet,有部分整理网上的,但绝对要比你看到的要深入得多) 一.接口 L ...

  4. lcd和服务器同时显示温度,为什么LCD1602不能同时显示温度和时间?

    程序目标:1602第一行显示温度,第二行显示时间.温度用DS18b20,时间用DS1302. 目前存在问题:用1602单独显示温度和时间都没得问题.合在一起显示就出现温度值为0,时间可以正常显示. 初 ...

  5. 【Arduino】利用FDC2214加LCD1602电容计测量A4纸张数量

    /** 名称:2019年全国电赛F题* 功能:极板电容测量A4纸张数量*/ #include <LiquidCrystal.h> const int rs = 7, en = 6, d4 ...

  6. Ardino基础教程 21_最简单最快控制LCD1602

    实验二十一:最简单最快控制LCD1602 实验接线图 下面个摇杆模块,不用接先不忙管. #include <LiquidCrystal.h> LiquidCrystal lcd(12, 1 ...

  7. C语言 | 基于MPU605(六轴传感器)的I2C实现LCD1602显示(代码类)

    博主github:https://github.com/MichaelBeechan 博主CSDN:https://blog.csdn.net/u011344545 基于MPU605(六轴传感器)的I ...

  8. 脉冲宽度测量程序 c51 c语言,基于C51单片机和LCD1602显示的超声波测距仪C语言程序...

    ; stringBuf=stringBuf[length-i-1]; stringBuf[length-i-1]=t; } stringBuf[length]='\0'; return length; ...

  9. 机智云代码移植_一步一步移植麒麟座例程到机智云GoKit V2.1

    本帖最后由 hiyle 于 2016-12-14 15:53 编辑 由于麒麟座开发版申请很慢,而很多朋友之前都有机智云的GoKit的开发版,我们可以利用起来学习OneNET的接入. 例程:麒麟座One ...

最新文章

  1. 功能测试常用6种方法_建筑管道常用的8种连接方法
  2. k8s 使用Nginx Ingress实现灰度发布和蓝绿发布
  3. php5.3中的safe_mod与magic_quotes_gpc
  4. 【Tools】MarkDown教程(一)-MarkDown简介
  5. 一.Spring框架基础
  6. Python手册 3.7
  7. Lightbox 效果
  8. hibernate 序列_Hibernate身份,序列和表(序列)生成器
  9. 原生js系列之DOM工厂模式
  10. 促销海报设计的套路你知道么? 看这里!
  11. Atitit 网络技术体系图 目录 1. 的三网融合是 1 1.1. 电话网、有线电视网 1 1.2. 计算机网 1 2. 计算机网 1 2.1. 互联网 1 2.2. 局域网 1 3. 第1章 计
  12. VS2010 asp.net development server 无法展示svg图片
  13. [转]深入Linux网络核心堆栈
  14. 数据库(SQL)学习——基础篇一:初识数据库
  15. npstion实现通过手机扫描二维码向电脑录入信息
  16. 基于51单片机的PC机控制系统
  17. [ STM32F103 ] 数据手册 —— CAN解析
  18. OpenGL编程(四)改变窗口大小时保持图形的原形
  19. 斧劈互联网(一):企业邮箱那点事儿
  20. LiteOS 软件定时器

热门文章

  1. D. Serval and Rooted Tree
  2. 用户输入一个列表和两个整数作为下标,然后使用切片获取并输出列表中结余两个下标之间的元素组成的子列表。例如,用户输入 [1,2,3,4,5,6]和2,5,程序输出[3,4,5]。
  3. 基于f2从零实现移动端可视化编辑器
  4. Android ---创建APP数据库
  5. 爪哇语:??????? 字面量,分类和存储库
  6. 完成“LPS node 与Crazyflie在TWR协议下的成功双向测距”实现心路历程总结
  7. phpcms extention.func.php数据的使用
  8. java计算机毕业设计南通大学福利发放管理系统源码+系统+数据库+lw文档+mybatis+运行部署
  9. 杭电多校联赛2017年总结
  10. Linux Shell脚本中压缩包解压到目标目录下