[STM32]

用STM32F103C8驱动LCD1602

[复制链接]
4285|7
手机看帖
扫描二维码
随时随地手机跟帖
zhangjw258|  楼主 | 2018-10-29 19:52 | 显示全部楼层 |阅读模式
本帖最后由 zhangjw258 于 2018-10-29 19:52 编辑

先贴电路图:
4.png
再贴头文件1602.h:
#ifndef __1602_H
#define __1602_H
#include "stm32f10x.h"
// 端口A
#define E GPIO_Pin_11   //GPIOA
#define RS GPIO_Pin_12
#define RW GPIO_Pin_15
/* 常量定义 */
#define SETMODE 0x38   //16*2显示,5*7点阵,8位数据接口
#define DISOPEN 0x0C   //显示开,不显示光标,光标不闪烁
#define DISMODE 0x06   //读写字符后地址加1,屏显不移动
#define SETADDR 0x80   //设置数据地址指针初始值
#define CLEAR 0x01   //清屏,数据指针清零
#define RET  0x02   //回车,数据指针清零
void test_1602_GPIO_Config(void);
void Init1602(void);
void Write1602_One_Dat(uint16_t x, uint16_t y, uint16_t dat);
void Write1602_Str(uint8_t addr, uint8_t length, uint8_t *pbuf); //写一个数据串
#endif /* __1602_H */

然后贴上源文件1602.c:

#include "1602.h"
#include "systick.h"
void test_1602_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启1602相关的GPIO外设时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
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_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed  = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //开AFIO时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_15;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
/************************************************
功能:写命令
参数:写入命令
返回:无
************************************************/
void Write1602_Com(uint16_t com)
{
GPIO_ResetBits(GPIOA, E);
SysTick_Delay_ms(1);
GPIO_ResetBits(GPIOA, RS);
SysTick_Delay_ms(1);
GPIO_Write(GPIOB, (com << 8));  //端口赋值
SysTick_Delay_ms(1);
GPIO_SetBits(GPIOA, E);    //高脉冲
SysTick_Delay_ms(1);
GPIO_ResetBits(GPIOA, E);
}
/************************************************
功能:写数据
参数:写入数据
返回:无
************************************************/
void Write1602_Dat(uint16_t dat)
{
GPIO_ResetBits(GPIOA, E);
SysTick_Delay_ms(1);
GPIO_SetBits(GPIOA, RS);
SysTick_Delay_ms(1);
GPIO_Write(GPIOB, (dat << 8));  //端口赋值
SysTick_Delay_ms(1);
GPIO_SetBits(GPIOA, E);   //高脉冲
SysTick_Delay_ms(1);
GPIO_ResetBits(GPIOA, E);
}
/************************************************
功能:初始化1602
参数:无
返回:无
************************************************/
void Init1602(void)
{
Write1602_Com(SETMODE);  //模式设置
SysTick_Delay_ms(1);
Write1602_Com(DISOPEN);  //显示设置
SysTick_Delay_ms(1);
Write1602_Com(DISMODE);  //显示模式
SysTick_Delay_ms(1);
Write1602_Com(CLEAR);  //清屏
}
/************************************************
功能:写一个数据
参数:x = 列,y = 行,dat = 值
返回:无
注意:x取值0 -- 15,y取值0 -- 1
************************************************/
void Write1602_One_Dat(uint16_t x, uint16_t y, uint16_t dat)
{
x &= 0x0f;
y &= 0x01;
if(y)
  x |= 0x40;
x |= 0x80;
Write1602_Com(x);
SysTick_Delay_ms(1);
Write1602_Dat(dat);
}
/************************************************
功能:写一个数据串
参数:addr=起始地址(如0x80),length=串长度,
  pbuf=串指针
返回:无
************************************************/
void Write1602_Str(uint8_t addr, uint8_t length, uint8_t *pbuf)
{
uint8_t i;
Write1602_Com(addr);
for(i = 0; i < length; i++)
{
  Write1602_Dat(pbuf);
}
}
还有两个文件systick.h和systick.c:
#ifndef __SYSTICK_H
#define __SYSTICK_H
#include "stm32f10x.h"
#include "core_cm3.h"
void SysTick_Delay_us(uint32_t us);
void SysTick_Delay_ms(uint32_t ms);
#endif /* _SYSTICK_H */

#include "systick.h"
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72);
for(i = 0; i < us; i++)
{
  while(!((SysTick -> CTRL) & (1 << 16)));
}
SysTick -> CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_ms(uint32_t ms)
{
uint32_t i;
SysTick_Config(72000);
for(i = 0; i < ms; i++)
{
  while(!((SysTick -> CTRL) & (1 << 16)));
}
SysTick -> CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
最后是测试用的main.c文件:

#include "1602.h"
int main()
{
test_1602_GPIO_Config();
GPIO_ResetBits(GPIOA, RW);
Init1602();
Write1602_Str(0x80, 16, "Welcome to zhang");
while(1);
}
说明一下:

端口A的pin11,pin12,pin15分别接E,RS,RW
端口B的pin8~pin15接D0~D7
VDD接+5V

本以为有了51的经验,这个应该很容易,却不料也发现了这样或那样的问题.最主要的就是端口A的Pin15脚.
不过这也使我学习到了很多东西.试验结果当然是成功的.图懒得贴了.内容慢慢体会吧!


评论
一路向北lm 2018-11-5 12:13 回复TA
这个不难的,跟51一样,写时序和读时序出来就好啦 

相关帖子

ningling_21| | 2018-10-30 10:18 | 显示全部楼层
恭喜楼主

使用特权

评论回复
zh877| | 2018-11-2 10:55 | 显示全部楼层

自己动手,丰衣足食!

使用特权

评论回复
jazzyfox| | 2018-11-5 11:25 | 显示全部楼层
恭喜楼主喜提STM32+1602一只

使用特权

评论回复
tristeboy| | 2019-5-12 22:08 | 显示全部楼层
程序里出了这个错误解决不掉啊
..\HARDWARE\1602\1602.c(96): error:  #167: argument of type "uint8_t *" is incompatible with parameter of type "uint16_t"

使用特权

评论回复
QWE4562009| | 2019-8-27 17:11 | 显示全部楼层

这程序看起来怎么如此繁琐 复杂 段码屏就是麻烦

使用特权

评论回复
QWE4562009| | 2019-8-27 17:11 | 显示全部楼层

这程序看起来怎么如此繁琐 复杂 段码屏就是麻烦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

8

帖子

0

粉丝