本帖最后由 bushiniu 于 2012-12-28 22:31 编辑
感谢野火的开发板,在努力学习中,手上1602很多还想发挥余热,写了个驱动,欢迎批评指正
————————————————以下为驱动文件————————Lcd1602.c——————————
/****************************************************************
LCD1602模块 STM32 通用驱动 集成1602 显示变量函数
不同引脚定义,只需要修改”各端口定义“部分
By bushiniu 2012.12
****************************************************************/
/**********************使用方法**********************************
主程序中调用:
#include "Lcd1602.h" //包含LCD驱动头文件
Lcd_Init(); //LCD初始化
函数说明在头文件中
*****************************************************************/
#include "Lcd1602.h"
#include "SysTick.h"
/********************各端口定义*********************************/
#define GPIO_EN GPIOC // 使能端口组
#define GPIO_EN_PIN GPIO_Pin_7 // 使能端口号
#define RCC_GPIO_EN RCC_APB2Periph_GPIOC // 使能时钟组
#define GPIO_RW GPIOC // 读/写选择端口组
#define GPIO_RW_PIN GPIO_Pin_6 // 读/写选择端口号
#define RCC_GPIO_RW RCC_APB2Periph_GPIOC // 读/写时钟组
#define GPIO_RS GPIOB // 数据/命令端口组
#define GPIO_RS_PIN GPIO_Pin_5 // 数据/命令端口号
#define RCC_GPIO_RS RCC_APB2Periph_GPIOB // 数据/命令时钟组
#define GPIO_DATA_0 GPIOB // 数据线0_端口组
#define GPIO_DATA_0_PIN GPIO_Pin_8 // 数据线0_端口号
#define GPIO_DATA_1 GPIOB // 数据线1_端口组
#define GPIO_DATA_1_PIN GPIO_Pin_9 // 数据线1_端口号
#define GPIO_DATA_2 GPIOB // 数据线2_端口组
#define GPIO_DATA_2_PIN GPIO_Pin_10 // 数据线2_端口号
#define GPIO_DATA_3 GPIOB // 数据线3_端口组
#define GPIO_DATA_3_PIN GPIO_Pin_11 // 数据线3_端口号
#define GPIO_DATA_4 GPIOB // 数据线4_端口组
#define GPIO_DATA_4_PIN GPIO_Pin_12 // 数据线4_端口号
#define GPIO_DATA_5 GPIOB // 数据线5_端口组
#define GPIO_DATA_5_PIN GPIO_Pin_13 // 数据线5_端口号
#define GPIO_DATA_6 GPIOB // 数据线6_端口组
#define GPIO_DATA_6_PIN GPIO_Pin_14 // 数据线6_端口号
#define GPIO_DATA_7 GPIOB // 数据线7_端口组
#define GPIO_DATA_7_PIN GPIO_Pin_15 // 数据线7_端口号
#define RCC_GPIO_DATA RCC_APB2Periph_GPIOB // 数据线时钟组
/******************************************************************/
/***********************基本指令***********************************/
#define SET_EN GPIO_SetBits(GPIO_EN, GPIO_EN_PIN) //EN 使能 输出1
#define CLE_EN GPIO_ResetBits(GPIO_EN, GPIO_EN_PIN) // 输出0
#define SET_RW GPIO_SetBits(GPIO_RW, GPIO_RW_PIN) //RW 读写 输出1
#define CLE_RW GPIO_ResetBits(GPIO_RW, GPIO_RW_PIN) // 输出0
#define SET_RS GPIO_SetBits(GPIO_RS, GPIO_RS_PIN) //RS 指令 输出1
#define CLE_RS GPIO_ResetBits(GPIO_RS, GPIO_RS_PIN) // 输出0
/******************************************************************/
/************************端口初始化*******************************/
void Lcd_GPIO_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //声明结构体
/********Data端口设置*************/
RCC_APB2PeriphClockCmd(RCC_GPIO_DATA, ENABLE); //打开端口B时钟
GPIO_InitStructure.GPIO_Pin = GPIO_DATA_0_PIN|GPIO_DATA_1_PIN|GPIO_DATA_2_PIN|GPIO_DATA_3_PIN|GPIO_DATA_4_PIN|GPIO_DATA_5_PIN|GPIO_DATA_6_PIN|GPIO_DATA_7_PIN; // DB8~DB15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //标准输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIO_DATA_0, &GPIO_InitStructure); //初始化端口
/********使能端口设置**********/
RCC_APB2PeriphClockCmd(RCC_GPIO_EN, ENABLE); //打开端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_EN_PIN; // 使能端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //标准输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIO_EN, &GPIO_InitStructure);
/********读/写端口设置**********/
RCC_APB2PeriphClockCmd(RCC_GPIO_RW, ENABLE); //打开端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_RW_PIN; // 使能端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //标准输出模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIO_RW, &GPIO_InitStructure);
/********指令/数据端口设置**********/
RCC_APB2PeriphClockCmd(RCC_GPIO_RS, ENABLE); //打开端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_RS_PIN; // 使能端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽复用输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIO_RS, &GPIO_InitStructure);
}
/******************************************************************/
void Lcd_Init( void ) //初始化
{
Lcd_GPIO_init();
Delay_us(1500); //延时15ms
Lcd_Write_Command( 0x38,0); // 写指令38H 不检测忙信号
Delay_us(500); //延时5ms
Lcd_Write_Command( 0x38,0); // 写指令38H 不检测忙信号
Delay_us(500); //延时5ms
Lcd_Write_Command( 0x38,0); // 写指令38H 不检测忙信号
//以后每次写指令、读/写数据操作之前需检测忙信号
Lcd_Write_Command( 0x38,1); //显示模式设置
Lcd_Write_Command( 0x08,1); //显示关闭
Lcd_Write_Command( 0x01,1); //显示清屏
Lcd_Write_Command( 0x06,1); //显示光标移动设置
Lcd_Write_Command( 0x0C,1); //显示开、光标不显示
}
/******************************************************/
void Lcd_En_Toggle(void) //发使能脉冲
{
SET_EN; //使能1
Delay_us(5); //延时160us
CLE_EN;
}
void Lcd_Busy(void)//判断忙
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_GPIO_DATA, ENABLE); //打开DATA端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_DATA_0_PIN|GPIO_DATA_1_PIN|GPIO_DATA_2_PIN|GPIO_DATA_3_PIN|GPIO_DATA_4_PIN|GPIO_DATA_5_PIN|GPIO_DATA_6_PIN|GPIO_DATA_7_PIN; // DB8~DB15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //输入模式 = 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIO_DATA_7, &GPIO_InitStructure); //打开忙检测端口
CLE_RS; //RS = 0
//Delay_us(1); //延时10us
SET_RW; //RW = 1
//Delay_us(1); //延时10us
SET_EN; //EN = 1
//Delay_us(2); //延时20us
while (GPIO_ReadInputDataBit(GPIO_DATA_7,GPIO_DATA_7_PIN)); //循环等待忙检测端口 = 0
CLE_EN; //EN = 0
//恢复端口为输出状态
RCC_APB2PeriphClockCmd(RCC_GPIO_DATA, ENABLE); //打开DATA端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_DATA_0_PIN|GPIO_DATA_1_PIN|GPIO_DATA_2_PIN|GPIO_DATA_3_PIN|GPIO_DATA_4_PIN|GPIO_DATA_5_PIN|GPIO_DATA_6_PIN|GPIO_DATA_7_PIN; // DB8~DB15
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度
GPIO_Init(GPIO_DATA_7, &GPIO_InitStructure);
}
void Gpio_data(unsigned char x) //端口置入数据
{
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_0_PIN); //DB0
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_1_PIN); //DB1
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_2_PIN); //DB2
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_3_PIN); //DB3
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_4_PIN); //DB4
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_5_PIN); //DB5
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_6_PIN); //DB6
GPIO_ResetBits(GPIO_DATA_0, GPIO_DATA_7_PIN); //DB7
if(x&0X01)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_0_PIN);//DB0
if(x&0X02)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_1_PIN);//DB1
if(x&0X04)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_2_PIN);//DB2
if(x&0X08)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_3_PIN);//DB3
if(x&0X10)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_4_PIN);//DB4
if(x&0X20)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_5_PIN);//DB5
if(x&0X40)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_6_PIN);//DB6
if(x&0X80)GPIO_SetBits(GPIO_DATA_0, GPIO_DATA_7_PIN);//DB7
}
//向液晶里面写入指令 时序:RS=L,RW=L,Data0-Data7=指令码,E=高脉冲
void Lcd_Write_Command(unsigned char x,char Busy)
{
if(Busy) Lcd_Busy();
//Delay_us(1); //延时10us
CLE_RS; //RS = 0
//Delay_us(1); //延时10us
CLE_RW; //RW = 0
//Delay_us(4); //延时40us
Gpio_data(x); //端口置入数据
//Delay_us(4); //延时40us
Lcd_En_Toggle(); //发使能脉冲
//Delay_us(1); //延时100us
Lcd_Busy(); //测忙
}
//向液晶里面写入数据 时序:RS=H,RW=L,Data0-Data7=指令码,E=高脉冲
void Lcd_Write_Data( unsigned char x) //向液晶里面写入数据
{
Lcd_Busy(); //测忙
//Delay_us(1); //延时10us
SET_RS; //RS = 1
//Delay_us(1); //延时10us
CLE_RW; //RW = 0
//Delay_us(4); //延时40us
Gpio_data(x);
//Delay_us(4); //延时40us
Lcd_En_Toggle(); //发使能脉冲
//Delay_us(1); //延时100us
Lcd_Busy(); //测忙
}
void Lcd_SetXY(unsigned char x,unsigned char y) //字符初始位置设定,x表示列,y表示行
{
unsigned char addr;
if(y==0)
addr=0x80+x;
else if(y==1)
addr=0xC0+x;
Lcd_Write_Command(addr,1) ;
}
/******************************************************/
void Lcd_Puts(unsigned char x,unsigned char y, unsigned char *string) //向1602写一个字符串
{
//unsigned char i=0;
Lcd_SetXY(x,y);
while(*string)
{
Lcd_Write_Data(*string);
string++;
}
}
unsigned char strTemp2[2];
unsigned char strTemp3[3];
unsigned char strTemp4[4];
unsigned char strTemp5[5];
unsigned char strTemp6[6];
unsigned char strTemp7[7];
unsigned char *tr_2(unsigned int outData_2)
{
strTemp2[0]=(unsigned char)(((outData_2/10) % 10) + 0x30);
strTemp2[1]=(unsigned char)((outData_2%10) + 0x30);
return strTemp2;
}
unsigned char *tr_3(unsigned int outData3)
{
strTemp3[0]=(unsigned char)(((outData3/100) % 10) + 0x30);
strTemp3[1]=(unsigned char)(((outData3/10) % 10) + 0x30);
strTemp3[2]=(unsigned char)((outData3%10) + 0x30);
return strTemp3;
}
unsigned char *tr_4(unsigned int outData4)
{
strTemp4[0]=(unsigned char)(((outData4/1000)% 10) + 0x30);
strTemp4[1]=(unsigned char)(((outData4/100)% 10) + 0x30);
strTemp4[2]=(unsigned char)(((outData4/10)% 10) + 0x30);
strTemp4[3]=(unsigned char)((outData4%10) + 0x30);
return strTemp4;
}
unsigned char *tr_5(unsigned int outData5)
{
strTemp5[0]=(unsigned char)(((outData5/10000)% 10) + 0x30);
strTemp5[1]=(unsigned char)(((outData5/1000)% 10) + 0x30);
strTemp5[2]=(unsigned char)(((outData5/100)% 10) + 0x30);
strTemp5[3]=(unsigned char)(((outData5/10)% 10) + 0x30);
strTemp5[4]=(unsigned char)((outData5%10) + 0x30);
return strTemp5;
}
unsigned char *tr_6(unsigned int outData6)
{
strTemp6[0]=(unsigned char)(((outData6/100000)% 10) + 0x30);
strTemp6[1]=(unsigned char)(((outData6/10000)% 10) + 0x30);
strTemp6[2]=(unsigned char)(((outData6/1000)% 10) + 0x30);
strTemp6[3]=(unsigned char)(((outData6/100)% 10) + 0x30);
strTemp6[4]=(unsigned char)(((outData6/10)% 10) + 0x30);
strTemp6[5]=(unsigned char)((outData6%10) + 0x30);
return strTemp6;
}
unsigned char *tr_7(unsigned int outData7)
{
strTemp7[0]=(unsigned char)(((outData7/1000000)% 10) + 0x30);
strTemp7[1]=(unsigned char)(((outData7/100000)% 10) + 0x30);
strTemp7[2]=(unsigned char)(((outData7/10000)% 10) + 0x30);
strTemp7[3]=(unsigned char)(((outData7/1000)% 10) + 0x30);
strTemp7[4]=(unsigned char)(((outData7/100)% 10) + 0x30);
strTemp7[5]=(unsigned char)(((outData7/10)% 10) + 0x30);
strTemp7[6]=(unsigned char)((outData7%10) + 0x30);
return strTemp7;
}
/******************************************************/
程序如下:野火开发板的例程
/******************** (C) COPYRIGHT 2012 WildFire Team ***************************
* 文件名 :SysTick.c
* 描述 :SysTick 系统滴答时钟10us中断函数库,中断时间可自由配置,
* 常用的有 1us 10us 1ms 中断。
* 实验平台:野火STM32开发板
* 硬件连接:-----------------
* | |
* | 无 |
* | |
* -----------------
* 库版本 :ST3.5.0
* 作者 :wildfire team
* 论坛 :http://www.amobbs.com/forum-1008-1.html
* 淘宝 :http://firestm32.taobao.com
**********************************************************************************/
#include "SysTick.h"
static __IO u32 TimingDelay;
/*
* 函数名:SysTick_Init
* 描述 :启动系统滴答定时器 SysTick
* 输入 :无
* 输出 :无
* 调用 :外部调用
*/
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms 中断一次
* SystemFrequency / 10000 100us 中断一次
* SystemFrequency / 100000 10us 中断一次
* SystemFrequency / 1000000 1us 中断一次
*/
// if (SysTick_Config(SystemFrequency / 100000)) // ST3.0.0库版本
if (SysTick_Config(SystemCoreClock / 100000)) // ST3.5.0库版本
{
/* Capture error */
while (1);
}
// 关闭滴答定时器
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
/*
* 函数名:Delay_us
* 描述 :us延时程序,10us为一个单位
* 输入 :- nTime
* 输出 :无
* 调用 :Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
* :外部调用
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
// 使能滴答定时器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while(TimingDelay != 0);
}
/*
* 函数名:TimingDelay_Decrement
* 描述 :获取节拍程序
* 输入 :无
* 输出 :无
* 调用 :在 SysTick 中断函数 SysTick_Handler()调用
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
/******************* (C) COPYRIGHT 2012 WildFire Team *****END OF FILE************/
一周热门 更多>