使用stm32f103驱动lcd1602

news/2025/2/5 6:48:37/

1. 项目需求

  • 使用上位机发送ASCII字符,在LCD1602上能够实时显示

2. 使用到的软件和硬件

  • 野火指南者开发板 在这里插入图片描述- LCD1602液晶屏
    在这里插入图片描述
  • 杜邦线
  • DAP仿真器
  • KEIL5

3. 连线说明在这里插入图片描述

4. 代码

  1. LCD驱动代码
    头文件:
    #ifndef __LCD_H
    #define __LCD_H#include "stm32f10x.h"typedef unsigned char uint_8;
    typedef unsigned int  uint_16;// 控制端引脚
    #define CON_GPIO           GPIOC
    #define LCD_CON_RCC_FUNC   RCC_APB2PeriphClockCmd
    #define CON_GPIO_CLK   		 RCC_APB2Periph_GPIOC
    #define CON_RS_PIN     		 GPIO_Pin_8
    #define CON_RW_PIN     		 GPIO_Pin_9
    #define CON_E_PIN      		 GPIO_Pin_10// 数据传输端引脚
    #define DATA_GPIO          GPIOB
    #define LCD_DATA_RCC_FUNC  RCC_APB2PeriphClockCmd
    #define DATA_GPIO_CLK  		 RCC_APB2Periph_GPIOB
    #define DATA0_PIN      		 GPIO_Pin_8
    #define DATA1_PIN      		 GPIO_Pin_9
    #define DATA2_PIN      		 GPIO_Pin_10
    #define DATA3_PIN      		 GPIO_Pin_11
    #define DATA4_PIN      		 GPIO_Pin_12
    #define DATA5_PIN      		 GPIO_Pin_13
    #define DATA6_PIN      		 GPIO_Pin_14
    #define DATA7_PIN      		 GPIO_Pin_15// 常用指令
    #define CLEAR                0x01   // 清屏
    #define CURSOR_RESET         0x10   // 光标归位
    #define AFTER_CL             0x04   // 写入数据后,光标左移,显示屏不移动
    #define AFTER_CL_SR          0x05   // 写入数据后,光标左移,显示屏整体向右移动
    #define AFTER_CR           	 0x06   // 写入数据后,光标右移,显示屏不移动
    #define AFTER_CR_SR          0x07   // 写入数据后,光标右移,显示屏整体向右移动
    #define CLOSE_CURSOR         0x0C   // 无光标
    #define SHOW_CURSOR_TWINKLE  0x0f   // 光标闪烁
    #define SHOW_CURSOR          0x0e   // 光标不闪烁
    #define CURSOR_LEFT          0x10   // 光标左移一格
    #define CURSOR_RIGHT         0x14   // 光标右移一格
    #define SCREEN_LEFT          0x18   // 显示屏上字符全部左移一格,光标不动
    #define SCREEN_RIGHT         0x1C   // 显示屏上所有字符右移一格,光标不动#define SHOW_ONE_5X7         0x30   // 显示一行,5X7点阵 (默认数据总线为8位)
    #define SHOW_ONE_5X10        0x34   // 显示一行,5X10
    #define SHOW_TWO_5X7         0x38   // 显示两行,5X7
    #define SHOW_TWO_5X10        0x3C   // 显示两行,5X10void LCD_Init(void);
    void LCD_WriteData(uint_8 data);
    void LCD_WriteCon(uint_8 data);#endif
    源文件
    #include "lcd.h"static void LCD_Desplay(uint_16 x)
    {while(x--);
    }static void GPIO_InitConifg()
    {GPIO_InitTypeDef GPIO_Structure;// 开启时钟LCD_CON_RCC_FUNC(CON_GPIO_CLK, ENABLE);LCD_DATA_RCC_FUNC(DATA_GPIO_CLK, ENABLE);// 控制端GPIO_Structure.GPIO_Pin = CON_RS_PIN;GPIO_Structure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(CON_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = CON_RW_PIN;GPIO_Init(CON_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = CON_E_PIN;GPIO_Init(CON_GPIO, &GPIO_Structure);// 输出端GPIO_Structure.GPIO_Pin = DATA0_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA1_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA2_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA3_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA4_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA5_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA6_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);GPIO_Structure.GPIO_Pin = DATA7_PIN;GPIO_Init(DATA_GPIO, &GPIO_Structure);
    }void LCD_Init(void)
    {GPIO_InitConifg();LCD_WriteCon(CLOSE_CURSOR);         // 设置光标闪烁LCD_WriteCon(SHOW_TWO_5X7);         // 一行,5X7LCD_WriteCon(AFTER_CR);             // 光标左移,屏幕不移动LCD_WriteCon(CLEAR);                // 清屏
    }// 发送数据
    void LCD_WriteData(uint_8 data)
    {GPIO_ResetBits(CON_GPIO, CON_E_PIN);// 10, 写入数据GPIO_SetBits(CON_GPIO, CON_RS_PIN);GPIO_ResetBits(CON_GPIO, CON_RW_PIN);// 写入数据GPIO_Write(DATA_GPIO, data<<8);LCD_Desplay(0xffff);// 写入使能GPIO_SetBits(CON_GPIO, CON_E_PIN);LCD_Desplay(0xffff);GPIO_ResetBits(CON_GPIO, CON_E_PIN);
    }// 发送指令
    void LCD_WriteCon(uint_8 data)
    {GPIO_ResetBits(CON_GPIO, CON_E_PIN);// 00, 写入命令GPIO_ResetBits(CON_GPIO, CON_RS_PIN);GPIO_ResetBits(CON_GPIO, CON_RW_PIN);// 写入数据GPIO_Write(DATA_GPIO, data<<8);LCD_Desplay(0xffff);// 写入使能GPIO_SetBits(CON_GPIO, CON_E_PIN);LCD_Desplay(0xffff);GPIO_ResetBits(CON_GPIO, CON_E_PIN);
    }	
  2. 串口驱动代码(移植于指南者例程)
    头文件
     #ifndef __USART_H_#define __USART_H_#include "stm32f10x.h"#include "stdio.h"#define DEBUG1 1#define DEBUG_USART_BAUDRATE 115200// 串口对应的DMA请求通道#define  USART_TX_DMA_CHANNEL     DMA1_Channel5// 外设寄存器地址#define  USART_DR_ADDRESS        (USART1_BASE+0x04)// 一次发送的数据量#define  RECEIVEBUFF_SIZE            5000#ifdef DEBUG1// 串口 1-USART1#define DEBUG_USARTx USART1#define DEBUG_USART_CLK RCC_APB2Periph_USART1#define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd// USART GPIO 引脚宏定义#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd#define DEBUG_USART_TX_GPIO_PORT GPIOA#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9#define DEBUG_USART_RX_GPIO_PORT GPIOA#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10#define DEBUG_USART_IRQ USART1_IRQn#define DEBUG_USART_IRQHandler USART1_IRQHandler#elif DEBUG2// 串口2#define DEBUG_USARTx USART2#define DEBUG_USART_CLK RCC_APB1Periph_USART2#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd// USART GPIO 引脚宏定义#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd#define DEBUG_USART_TX_GPIO_PORT GPIOA#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_2#define DEBUG_USART_RX_GPIO_PORT GPIOA#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_3#define DEBUG_USART_IRQ USART2_IRQn#define DEBUG_USART_IRQHandler USART2_IRQHandler#elif DEBUG3// 串口3#define DEBUG_USARTx USART3#define DEBUG_USART_CLK RCC_APB1Periph_USART3#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd// USART GPIO 引脚宏定义#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOB)#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd#define DEBUG_USART_TX_GPIO_PORT GPIOB#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_10#define DEBUG_USART_RX_GPIO_PORT GPIOB#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_11#define DEBUG_USART_IRQ USART3_IRQn#define DEBUG_USART_IRQHandler USART3_IRQHandler#elif DEBUG4// 串口4#define DEBUG_USARTx USART4#define DEBUG_USART_CLK RCC_APB1Periph_USART4#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd// USART GPIO 引脚宏定义#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOC)#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd#define DEBUG_USART_TX_GPIO_PORT GPIOC#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_10#define DEBUG_USART_RX_GPIO_PORT GPIOC#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_11#define DEBUG_USART_IRQ USART4_IRQn#define DEBUG_USART_IRQHandler USART4_IRQHandler#elif DEBUG5// 串口5#define DEBUG_USARTx USART5#define DEBUG_USART_CLK RCC_APB1Periph_USART5#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd// USART GPIO 引脚宏定义#define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOC)#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd#define DEBUG_USART_TX_GPIO_PORT GPIOC#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_12#define DEBUG_USART_RX_GPIO_PORT GPIOD#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_2#define DEBUG_USART_IRQ USART5_IRQn#define DEBUG_USART_IRQHandler USART5_IRQHandler// 打开串口GPIOD的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);#endifstatic void NVIC_Configuration(void);void DEBUG_Config(void);void Usart_SendByte(USART_TypeDef* pUSARTX, char data);void Usart_SendString( USART_TypeDef * pUSARTx, char *str);int fputc(int ch, FILE *f);int fgetc(FILE *f);#endif
    
    源文件
    	#include "usart.h"__IO unsigned char ReceiveBuff[RECEIVEBUFF_SIZE];static void NVIC_Configuration(void)
    {NVIC_InitTypeDef NVIC_InitStructure;/* 嵌套向量中断控制器组选择 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);/* 配置 USART 为中断源 */NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;/* 抢断优先级为 1 */NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;/* 子优先级为 1 */NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;/* 使能中断 */NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/* 初始化配置 NVIC */NVIC_Init(&NVIC_InitStructure);
    }// 初始化UART-DMA
    static void DMA_Configuration()
    {DMA_InitTypeDef DMA_InitStructure;// 开启DMA时钟RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);// 设置DMA源地址:串口数据寄存器地址*/DMA_InitStructure.DMA_PeripheralBaseAddr = USART_DR_ADDRESS;// 内存地址(要传输的变量的指针)DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ReceiveBuff;// 方向:从外设到内存	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;// 传输大小	DMA_InitStructure.DMA_BufferSize = RECEIVEBUFF_SIZE;// 外设地址不增	    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;// 内存地址自增DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;// 外设数据单位	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;// 内存数据单位DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;	 // DMA模式,一次或者循环模式//		DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	// 优先级:中	DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; // 禁止内存到内存的传输DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;// 配置DMA通道		   DMA_Init(USART_TX_DMA_CHANNEL, &DMA_InitStructure);		// 使能DMADMA_Cmd (USART_TX_DMA_CHANNEL, ENABLE);
    }void DEBUG_Config(void)
    {GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;// 打开串口 GPIO 的时钟DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);// 打开串口外设的时钟DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);// 将 USART Tx 的 GPIO 配置为推挽复用模式GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);// 将 USART Rx 的 GPIO 配置为浮空输入模式GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);// 配置串口的工作参数// 配置波特率USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;// 配置 针数据字长USART_InitStructure.USART_WordLength = USART_WordLength_8b;// 配置停止位USART_InitStructure.USART_StopBits = USART_StopBits_1;// 配置校验位USART_InitStructure.USART_Parity = USART_Parity_No ;// 配置硬件流控制USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// 配置工作模式,收发一起USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;// 完成串口的初始化配置USART_Init(DEBUG_USARTx, &USART_InitStructure);// 串口中断优先级配置NVIC_Configuration();// 使能串口接收中断USART_ITConfig(DEBUG_USARTx, USART_IT_IDLE, ENABLE);// 使能串口USART_Cmd(DEBUG_USARTx, ENABLE);// 串口DMA配置DMA_Configuration();/* USART1 向 DMA发出RX请求使能 */USART_DMACmd(DEBUG_USARTx, USART_DMAReq_Rx, ENABLE);
    }void Usart_SendByte(USART_TypeDef* pUSARTx, char data)
    {USART_SendData(pUSARTx, data);while(USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
    }void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
    {unsigned int k=0;do {Usart_SendByte( pUSARTx, *(str + k) );k++;} while (*(str + k)!='\0');/* 等待发送完成 */while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {}
    }//重定向fputc函数
    int fputc(int ch, FILE *f)
    {Usart_SendByte(DEBUG_USARTx, (unsigned char)ch);while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);return (ch);
    }int fgetc(FILE *f)
    {while(USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);return (int) USART_ReceiveData(DEBUG_USARTx);
    }
    
  3. 主函数
    #include "stm32f10x.h"
    #include "usart.h"
    #include "lcd.h"
    #include <string.h>extern __IO unsigned char ReceiveBuff[RECEIVEBUFF_SIZE];
    unsigned char data[] = "xiaodong, Hello World!";
    char index = 0;void delay(unsigned int a)
    {while(a--);
    }int main(void)
    {int i = 0;//LED_init();DEBUG_Config();LCD_Init();//	for (i=0;i<strlen((char *)data);i++) {
    //		if (i==16) {
    //			printf("正在换行\n");
    //			LCD_WriteCon(0xC0);
    //		}
    //		LCD_WriteData(data[i]);
    //	}//printf("sdf");while(1);}void DEBUG_USART_IRQHandler(void)
    {int i = 0;int t = 0;if (USART_GetITStatus(DEBUG_USARTx,USART_IT_IDLE) == SET) {DMA_Cmd(USART_TX_DMA_CHANNEL,DISABLE);                         //关闭DMA传输t = DMA_GetCurrDataCounter(USART_TX_DMA_CHANNEL);              //获取剩余的数据数量//Usart_SendArray(DEBUG_USARTx,ReceiveBuff,RECEIVEBUFF_SIZE-t);  //向电脑返回数据(接收数据数量 = SENDBUFF_SIZE - 剩余未传输的数据数量)// 显示数据printf("数据长度: %d\n", RECEIVEBUFF_SIZE-t);for (i=0;i<RECEIVEBUFF_SIZE-t;i++) {if (index % 32 == 0 && index != 0) {LCD_WriteCon(0x80);index = 0;} else if (index % 16 == 0 && index != 0) {LCD_WriteCon(0xC0);}LCD_WriteData(ReceiveBuff[i]);//printf("%c", ReceiveBuff[i]);index++;}DMA_SetCurrDataCounter(USART_TX_DMA_CHANNEL,RECEIVEBUFF_SIZE); //重新设置传输的数据数量DMA_Cmd(USART_TX_DMA_CHANNEL,ENABLE);                          //开启DMA传输USART_ReceiveData(DEBUG_USARTx);                              //读取一次数据,不然会一直进中断USART_ClearFlag(DEBUG_USARTx,USART_IT_IDLE);}
    }

5. 效果

在这里插入图片描述
在这里插入图片描述


http://www.ppmy.cn/news/894765.html

相关文章

Arduino—— SSD1306 OLED IIC

Zimo3InstallFULL.zip-电信其他资源-CSDN下载https://download.csdn.net/download/u012308586/12476953 这是下载链接&#xff0c;上传时CSDN自动设置5个积分&#xff0c;没有积分的话请私信我并留下邮箱&#xff0c;同时把这个地址也发给我 https://download.csdn.net/downloa…

STM32f103 驱动之I2C

目录 一、简介。 &#xff08;1&#xff09;数据有效性 &#xff08;2&#xff09;开始信号和结束信号 &#xff08;3&#xff09;应答信号 &#xff08;4&#xff09;传输时序 &#xff08;5&#xff09;字节写模式时序 &#xff08;6&#xff09;页写模式时序 &#xff…

STM32F103和DS1302时钟

STM32F103和DS1302时钟 DS1302模块讲解源文件演示源文件下载链接 最近在写了一些关于STM32F103C8T6对于模块的时候方面的代码的整合&#xff0c;想把之前用到的代码全部都整合成一个一个的例程来&#xff0c;以后要用直接拖进来改头文件的引脚口就好了。现在也开启第一章关于DS…

STM32利用I2C驱动SSD1306代码

前言&#xff1a; 之前购买了一款SSD1306驱动的0.96inchOLED显示屏幕&#xff0c;采用ESP8266使用u8g2库成功驱动。如今想自己摸索一下如何利用I2C驱动SSD1306. I2C协议 I2C开始 SCL为高电平期间&#xff0c;SDA由高到低 void IIC_START()//IIC_SCL高电平时候 IIC_SDA拉低 {I…

GD32E103/F303系列替换STM32F103

注&#xff1a;本文档仅针对GD32E103/F303系列替代STM32F103系列 版权&#xff1a;威尔健科技有限公司 联系方式&#xff1a;18816824119&#xff08;微信同号&#xff09; 本人&#xff1a;GD技术支持 明&#xff1a;GD32E103/GD32F10x/GD32F30x都是和STM32F10x系列是完全P…

stm32F103驱动lcd1602

接线 GPIOG0-7&#xff1a;D0-D7 RS&#xff1a;GPIOD13 RW&#xff1a;GPIOD14 EN&#xff1a;GPIOD15 程序 lcd.h #ifndef _lcd_H #define _lcd_H #include "stm32f10x.h" #include "SysTick.h"#define RS GPIO_Pin_13 #define RW GPIO_Pin_14 #d…

STM32F103-LCD1602驱动

STM32驱动LCD1602&#xff0c;不是很难&#xff0c;主要注意GPIO_Write(GPIOD,(GPIO_ReadOutputData(GPIOD) & 0xff00) | cmd);对电平的读取是整个驱动的核心&#xff0c;其他均与51驱动一致。 lcd.h文件 #ifndef __LCD_H__ #define __LCD_H__ #include "stm3…

stm32f103

配置:PLLCLK 32 参考电路图stlink与正点原子的接口连的时候,注意板子上接口实际正反是反的 蓝牙模块 一 蓝牙的AT指令模式 注意EN要接3.3v/EN什么都不接,长按蓝牙按钮的同时然后再上电. 慢闪是AT模式,快闪是透传模式. 指令集: AT //返回OK ATNAME? //返回蓝牙模块的名字…