您的位置 首页 元件

STM32 LCD1602驱动程序

#ifndefLCD1602_STM32_H#defineLCD1602_STM32_H#defineLCD_RS_1GPIOE->BSRR=GPIO_Pin_0//PE.0–(LCD)RS#

#ifndef LCD1602_STM32_H

#define LCD1602_STM32_H

#define LCD_RS_1 GPIOE->BSRR=GPIO_Pin_0 //PE.0–(LCD)RS
#define LCD_RS_0 GPIOE->BRR =GPIO_Pin_0
#define LCD_RW_1 GPIOE->BSRR=GPIO_Pin_1//PE.1–(LCD)RW
#define LCD_RW_0 GPIOE->BRR =GPIO_Pin_1
#define LCD_EN_1 GPIOE->BSRR=GPIO_Pin_2 //PE.2–(LCD)E
#define LCD_EN_0 GPIOE->BRR =GPIO_Pin_2
#define DATAOUT GPIOD->ODR //PD[0..7]–(LCD)D0~D7

#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif

extern void delay_nms(unsigned long n);
extern void delay_nus(unsigned long n);

uint8_t LCD_busy(void); //读LCD繁忙状况,直到LCD1602不忙学校
void Wait_Leisure(void);//一向等候到LCD1602闲暇
void LCD_WriteInitcmd(uchar cmd);//写入LCD初始化时的指令,不能够检测忙状况
void LCD_Writecmd(uchar cmd);//写指令到LCD1602,指令数据占一个字节
void LCD_Writedata(uchar dat);//写一字节数据到LCD1602
void LCD_pos(uchar pos);//设定显现方位 00h~27h,40h~47h
void LCD_Setpos(uchar row,uchar col);//依据习气设定显现方位
void LCD_DispChar(char ch);//显现一个字符
void LCD_Setpos_DispChar(uchar row,uchar col,char ch);//在指定方位显现一个字符
void LCD_DispString(char str[]);//使LCD1602显现一个字符串,显现方位需提早设定
void LCD_Setpos_DispString(uchar row,uchar col,char str[]);//使LCD1602从指定方位开端显现一个字符串
void LCD_Dispnum(uint32_t num);//显现一个不超越8位的整数,显现方位需提早设置
void LCD_Setpos_Dispnum(uchar row,uchar col,uint32_t num);//在指定方位显现一个不超越8位的整数
void LCD_DispDecimal(uint32_t num,uchar dot);//显现一个有用位不超越8位的浮点数,显现方位需求提早设定
//在指定方位显现一个有用位不超越8位的浮点数
void LCD_Setpos_DispDecimal(uchar row,uchar col,uint32_t num,uchar dot);
//显现日历,显现日期与时刻
void LCD_DispDateTime(uint32_t year,uchar month,uchar day,uchar hour,uchar min,uchar sec);
//显现秒表,显现时,分,秒,10毫秒,准确到10ms
void LCD_DispStopWatch(uchar hour,uchar min,uchar sec,uchar tenms);
//显现频率计,动态主动调整频率显现
void LCD_DispFreq(uint32_t freq);
void LCD_ShiftLeft(void);//屏幕全体左移一格,用于翻滚显现
void LCD_ShiftRight(void);//屏幕全体右移一格,用于翻滚显现
void LCD_Clear(void);//清屏,铲除显现
void LCD_Return(void);//使光标还回原点方位
void LCD_Close(void);//关显现
void LCD_Open(void);//开显现
void LCD_FlickerChar(uchar row,uchar col);//使指定方位字符业绩,不显现光标
void LCD_CloseFlicker(void);//封闭字符业绩
void LCD_FlickerScreen(void);//屏幕秒业绩一次

void LCD_Init(void);

#endif

#include “stm32f10x.h”
#include “LCD1602.h”
#ifndef LCD1602_STM32_C
#define LCD1602_STM32_C

uint8_t LCD_busy(void)
{
LCD_RS_0;
delay_nus(1);
LCD_RW_1;
delay_nus(1);
do
{
LCD_EN_0;
delay_nus(200);
LCD_EN_1;
delay_nus(200);
}
while(GPIOD->IDR & 0x80);
LCD_EN_0;
return (uint8_t)0;
}

void Wait_Leisure(void)
{
LCD_busy();
}

void LCD_WriteInitcmd(uchar cmd)
{
LCD_RS_0;
delay_nus(1);
LCD_RW_0;
delay_nus(1);
DATAOUT = cmd;
LCD_EN_0;
delay_nus(300);
LCD_EN_1;
delay_nus(300);
LCD_EN_0;
delay_nms(2);
}

void LCD_Writecmd(uchar cmd)
{
while(LCD_busy());
LCD_RS_0; //对同一个寄存器的两次写入,中心延时一会
delay_nus(1);
LCD_RW_0;
delay_nus(1);
LCD_EN_0;
delay_nus(300);//发生脉冲
DATAOUT = cmd;
LCD_EN_1;
delay_nus(300);//必要的延时
LCD_EN_0; //下降沿,LCD1602开端作业
}

void LCD_Writedata(uchar dat)
{
while(LCD_busy());//等候LCD1602闲暇
LCD_RS_1;
delay_nus(1);
LCD_RW_0;
delay_nus(1);
DATAOUT = dat;
LCD_EN_1;//先拉高
delay_nus(300);//很重要的延时,经调试,延时300us以上才能够
LCD_EN_0; //下降沿,开端写入有用数据
}

void LCD_pos(uchar pos)
{
LCD_Writecmd(pos | 0x80);
}

void LCD_Setpos(uchar row,uchar col)
{
if(row==1) LCD_Writecmd(col | 0x80);
else LCD_Writecmd(col | 0xC0);
}

void LCD_DispChar(char ch)
{
LCD_Writedata(ch);
}

void LCD_Setpos_DispChar(uchar row,uchar col,char ch)
{
LCD_Setpos(row,col);
LCD_Writedata(ch);
}

void LCD_DispString(char str[])
{
uchar i=0;
while(str[i] != \0)
{
LCD_Writedata(str[i]);
++i;
}
}

void LCD_Setpos_DispString(uchar row,uchar col,char str[])
{
LCD_Setpos(row,col);
LCD_DispString(str);
}

void LCD_Dispnum(uint32_t num)
{
uint i=0,j,k=0,wei,q;
char str[9];
if(num>=10000000)wei=8;
else if(num>=1000000)wei=7;
else if(num>=100000)wei=6;
else if(num>=10000)wei=5;
else if(num>=1000) wei=4;
else if(num>=100)wei=3;
else if(num>=10) wei=2;
else wei=1;
for(i=wei;i>0;i–)
{ q=1;
j=1; //i=1时,q=1,得到个位
for(;j str[k++]=num/q +0;
num %= q;
}
str[k] = \0; //增加字符串完毕标志
LCD_DispString(str);//显现字符串
}

void LCD_Setpos_Dispnum(uchar row,uchar col,uint32_t num)
{
LCD_Setpos(row,col);
LCD_Dispnum(num);
}

void LCD_DispDecimal(uint32_t num,uchar dot)
{
uint i=0,j,k=0,wei,q;
char str[10];
if(num>=10000000)wei=8;
else if(num>=1000000)wei=7;
else if(num>=100000)wei=6;
else if(num>=10000)wei=5;
else if(num>=1000) wei=4;
else if(num>=100)wei=3;
else if(num>=10) wei=2;
else wei=1;
for(i=wei;i>0;i–)
{ q=1;
j=1; //i=1时,q=1,得到个位
for(;j str[k++]=num/q +0;
num %= q;
}
str[k] = \0; //增加字符串完毕标志
for(i=8;i>0;i–)
{ if((str[i]>=0)&&(str[i]<=9)) break;
}
str[i+2]=\0; //增加字符串完毕符
for(j=0;j {
str[i+1]=str[i];
}
str[i+1]=.; //刺进小数点
LCD_DispString(str);//显现浮点小数
}

void LCD_Setpos_DispDecimal(uchar row,uchar col,uint32_t num,uchar dot)
{
LCD_Setpos(row,col);
LCD_DispDecimal(num,dot);
}

void LCD_DispDateTime(uint32_t year,uchar month,uchar day,uchar hour,uchar min,uchar sec)
{
LCD_Setpos(1,0);
LCD_DispString(“Date:”);
LCD_Dispnum((uint32_t)year);
LCD_DispChar(-);
LCD_Dispnum((uint32_t)month);
LCD_DispChar(-);
LCD_Dispnum((uint32_t)day);
LCD_Setpos(1,15);
LCD_DispChar(*); //榜首行完毕符显现
LCD_Setpos(2,0);
LCD_DispString(“Time:”);
LCD_Dispnum((uint32_t)hour);
LCD_DispChar(:);
LCD_Dispnum((uint32_t)min);
LCD_DispChar(:);
LCD_Dispnum((uint32_t)sec);
LCD_Setpos(2,15);
LCD_DispChar(*); //第二行完毕符显现
}

void LCD_DispStopWatch(uchar hour,uchar min,uchar sec,uchar tenms)
{
LCD_Setpos(1,0);
LCD_DispString(“Current Time:”);
LCD_Setpos(1,15);
LCD_DispChar(*); //榜首行完毕符显现
LCD_Setpos(2,2);
LCD_Dispnum((uint32_t)hour);
LCD_DispChar(:);
LCD_Dispnum((uint32_t)min);
LCD_DispChar(:);
LCD_Dispnum((uint32_t)sec);
LCD_DispChar(:);
LCD_Dispnum((uint32_t)tenms);
LCD_Setpos(2,15);
LCD_DispChar(*); //第二行完毕符显现
}

void LCD_DispFreq(uint32_t freq)
{
LCD_Setpos(1,0);
LCD_DispString(“Current Freq:”);
LCD_Setpos(2,1); //显现方位
if(freq>=1000000)
{
LCD_DispDecimal(freq,6);
LCD_DispString(“MHz”);
}
else if(freq>=1000)
{
LCD_DispDecimal(freq,3);
LCD_DispString(“KHz”);
}
else { LCD_Dispnum(freq);
LCD_DispString(“Hz”);
}
LCD_Setpos(2,14);
LCD_DispString(“OK”);
}
//屏幕全体左移一格,用于翻滚显现
void LCD_ShiftLeft()
{
LCD_Writecmd(0x18);
}
//屏幕全体右移一格,用于翻滚显现
void LCD_ShiftRight(void)
{
LCD_Writecmd(0x1C);
}
//清屏,铲除显现
void LCD_Clear(void)
{
LCD_Writecmd(0x01);
}
//使光标还回原点方位
void LCD_Return(void)
{
LCD_Writecmd(0x02);
}
//关显现
void LCD_Close(void)
{
LCD_Writecmd(0x08);
}
//开显现
void LCD_Open(void)
{
LCD_Writecmd(0x0C);
}

void LCD_FlickerChar(uchar row,uchar col)
{
LCD_Writecmd(0x0D);
LCD_Setpos(row,col);
}
//封闭字符业绩
void LCD_CloseFlicker(void)
{
LCD_Writecmd(0x0C);
}
//屏幕秒业绩一次
void LCD_FlickerScreen(void)
{
LCD_Writecmd(0x08);//关显现
delay_nms(500);
LCD_Writecmd(0x0C);//开显现
delay_nms(500);
}

void LCD_Init(void)
{
delay_nms(200); //延时20ms
LCD_WriteInitcmd(0x38); //16*2显现,5*7点阵,8位数据
delay_nms(10);
LCD_WriteInitcmd(0x38); //16*2显现,5*7点阵,8位数据
delay_nms(5);
LCD_WriteInitcmd(0x38); //16*2显现,5*7点阵,8位数据
delay_nms(5);
LCD_WriteInitcmd(0x08); //先关显现,后开显现
delay_nms(5);
LCD_WriteInitcmd(0x06); //主动右移光标,0x04为左移光标
delay_nms(5);
LCD_WriteInitcmd(0x01); //铲除LCD的显现内容
delay_nms(6);
LCD_WriteInitcmd(0x0c); //显现开,关光标;0x08为关显现
delay_nms(5);
}

#endif //避免屡次编译

#include “stm32f10x.h”

#include “LCD1602.h”

#define PE00 (uint32_t *)0x40230180

//时钟装备函数 8MHz*9=72MHz
void RCC_Configuration()
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);//使能HSE
if(RCC_WaitForHSEStartUp()==SUCCESS)
{
RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK=SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource()!=0x08);
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC|\
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
}

//延时n us
void delay_nus(unsigned long n)
{
unsigned long j;
while(n–)
{ j=8;
while(j–);
}
}

//延时n ms
void delay_nms(unsigned long n)
{
while(n–)
delay_nus(1100);
}
//GPIO装备函数
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOD, &GPIO_InitStructure); //PD口OD输出
GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //PE.0~2 OD输出
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
///////////////////////////////////////////
int main()
{
//uint32_t i=0;
char str[]={“happy!”};
RCC_Configuration();
GPIO_Configuration();
LCD_Init();
LCD_Setpos_DispString(1,3,str);
LCD_DispFreq(123456);
LCD_FlickerChar(2,3);
LCD_FlickerScreen();
LCD_FlickerScreen();
LCD_FlickerScreen();
delay_nms(2000);
LCD_CloseFlicker();
while(1)
{
};
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/xinpin/yuanjian/264447.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部