本帖最后由 付pj 于 2019-10-30 16:02 编辑
此内容由EEWORLD论坛网友付pj原创,如需转载或用于商业用途需征得作者同意并注明出处
初学stm32,然后想做一个LCD1602显示DHT11温度的作品,然后卡在显示字符这里,通过自己摸索,终于写出了代码,放在这里可以让像我这样的有一些参考,经调试是没有问题的。
开发板用的是正点原子的ministm32 v3.41。
注释掉的代码可以不用管,因为dht11的程序我还在调试中。
这个程序是用IAR写的,如果有报错请看一下配置有没有问题。
LCD1602.H头文件代码:
#ifndef __LCD1602_H_
#define __LCD1602_H_
#define RW_H GPIO_SetBits(GPIOA,GPIO_Pin_4)
#define RW_L GPIO_ResetBits(GPIOA,GPIO_Pin_4)
#define RS_H GPIO_SetBits(GPIOA,GPIO_Pin_5)
#define RS_L GPIO_ResetBits(GPIOA,GPIO_Pin_5)
#define EN_H GPIO_SetBits(GPIOA,GPIO_Pin_6)
#define EN_L GPIO_ResetBits(GPIOA,GPIO_Pin_6)
#define GPIO_WriteHigh(GPIOx,a) GPIOx->BSRR=(((uint8_t)(uint8_t)~(a))<<24)|(((uint32_t)(uint8_t)(a))<<8)
#define GPIO_WriteLow(GPIOx,a) GPIOx->BSRR=(((uint32_t)(uint8_t)~(a))<<16)|((uint32_t)(uint8_t)(a))
#define DATAOUT(x) GPIO_Write(GPIOB, x)
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
//void lcd1602_gpio_ENinput_init();
void lcd1602_gpio_ENoutput_init();
//void lcd1602_gpio_RSinput_init();
void lcd1602_gpio_RSoutput_init();
//void lcd1602_gpio_RWinput_init();
void lcd1602_gpio_RWoutput_init();
void lcd1602_write_cmd(u16 cmd);
void lcd1602_write_data(u16 data);
void lcd1602_gpio_shujuoutput_init();
void lcd1602_init();
void lcd1602_char(unsigned char *word);
//void lcd1602_gpio_shujuinput_init();
#endif
LCD1602.C代码:
#include "lcd1602.h"
#include "systick.h"
void lcd1602_gpio_RWoutput_init() //设置RW为输出模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/*void lcd1602_gpio_RWinput_init() //设置RW为输入模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
/* GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}*/
void lcd1602_gpio_RSoutput_init() //设置RS为输出模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/*void lcd1602_gpio_RSinput_init() //设置RS为输入模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
/* GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}*/
void lcd1602_gpio_ENoutput_init() //设置EN为输出模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
/*void lcd1602_gpio_ENinput_init() //设置EN为输入模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
/* GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}*/
void lcd1602_gpio_shujuoutput_init() //设置8个数据口为输出模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE );//初始化时钟,使能
/*初始化gpio*/
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
//GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.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_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/*void lcd1602_gpio_shujuinput_init() //设置8个数据口为输入模式
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE );//初始化时钟,使能
/*初始化gpio*/
/* GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
}*/
void lcd1602_write_cmd(u16 cmd) //写指令函数
{
RS_L;
RW_L;
GPIO_Write(GPIOB, cmd);
GPIO_WriteHigh(GPIOB,cmd);
EN_H;
DelayUs(5000);
EN_L;
}
void lcd1602_write_data(u16 data) //写数据函数
{
RS_H;
RW_L;
GPIO_WriteHigh(GPIOB,data);
EN_H;
DelayUs(5000);
EN_L;
}
void lcd1602_init() //1602配置初始化
{
lcd1602_write_cmd(0x34);
lcd1602_write_cmd(0x0c);
lcd1602_write_cmd(0x06);
lcd1602_write_cmd(0x01);
}
void lcd1602_char(unsigned char *word) //1602写字符串函数
{
while(*word)
{
lcd1602_write_data(*word);
word++;
}
}
本程序中的延时全部是用滴答定时器进行延时的
滴答定时器 systick.h头文件代码:
#ifndef _SYSTICK_H_
#define _SYSTICK_H_
#include "stm32f10x.h"
void SysTick_CLKSourceConfig(u32 SysTick_CLKSource);
void systick_init();
void DelayUs(__IO uint32_t timer);
#endif
滴答定时器 systick.c代码:
#include "systick.h"
__IO uint32_t TimerDelay; //定义可反复查询状态的变量
void systick_init() //配置SysTick时钟定时1ms
{
if( SysTick_Config(72)==1) //配置Systick重载值
{
while(1);
}
}
void TimerDelay_Decrement() //产生溢出函数
{
if(TimerDelay!=0)
{
TimerDelay--;
}
}
void SysTick_Handler() //Systick中断向量函数
{
TimerDelay_Decrement() ;
}
void DelayUs(__IO uint32_t timer) //延时设定函数
{
TimerDelay=timer;
while(TimerDelay!=0);
}
主程序代码:
#include "stm32f10x.h"
#include "lcd1602.h"
#include "systick.h"
#include "dht11.h"
//u8 temp_h_init ,temp_l_init ,damp_h_init ,damp_l_init ,check ,temp_h ,temp_l ,damp_h ,damp_l ,T_L ,T_H1 ,T_H2 ,D_L ,D_H1 ,D_H2;
void main()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);//设定时钟为SysTick,72M
systick_init();
lcd1602_gpio_RWoutput_init();
lcd1602_gpio_ENoutput_init();
lcd1602_gpio_RSoutput_init();
lcd1602_gpio_shujuoutput_init();
lcd1602_init();
while(1)
{
// dhtll_init();
// dht11_readbit();
lcd1602_write_cmd(0x80);
lcd1602_char("hello stm32");
//lcd1602_write_data(T_H1+'0');
//lcd1602_write_data(T_H2+'0');
}
}
注释掉的代码可以不用去管。
如果有什么问题欢迎留言。