20x4字符液晶的函数

发布者:乐呵的挑最新更新时间:2016-10-29 来源: eefocus关键字:20x4字符液晶  函数 手机看文章 扫描二维码
随时随地手机看文章
使用芯片ATmega8515l,,8M晶振,,在1602的基础上修改过来的

#include

#define lcd_data_port PORTA
#define lcd_data_ddr DDRA
#define lcd_busy_pin PINA
#define lcd_busy_ddr DDRA
#define lcd_control_port PORTC
#define lcd_control_ddr DDRC

#define lcd_RS 0x01 
//PORTC0
#define lcd_RW 0x02 
//PORTC1
#define lcd_EN 0x04 
//PORTC2
#define busy 0x80   
//LCD_DB7

/*----------------------------------函数声明----------------------------------*/
//IO口相关
void io_init(void);

//LCD相关
void lcd_init(void);
void lcd_write_command(unsigned char command,unsigned char wait_en);
void lcd_write_data(unsigned char char_data);
void wait_enable(void);
void display_a_char(unsigned char position,unsigned char char_data);
void display_a_string(unsigned char position,unsigned char *ptr);
void display_a_number(unsigned char position,int i);
int ntentimes(unsigned char n);

//全局变量
unsigned char str0[]="Hello,word!";

void main(void)
{

 unsigned int i=518;
 io_init();
 lcd_init();
 display_a_char(0,'a');
 display_a_string(20,str0);
 display_a_number(40,i);

 }

 

//液晶初始化
void lcd_init(void)
 {  
    delay_nms(30);
    lcd_data_port=0xff;
    lcd_data_ddr=0xff;
    lcd_control_port=0x00;
    lcd_control_ddr=0x07;
    lcd_write_command(0x38,0);//显示模式设置三次(此时不管lcd空闲与否)
    delay_nms(1);
    lcd_write_command(0x38,0);
    delay_nms(1);
    lcd_write_command(0x38,0);
    delay_nms(1);
    
    lcd_write_command(0x38,1);//显示模式设置(从此之后均需lcd空闲)
    lcd_write_command(0x08,1);//显示关闭
    lcd_write_command(0x01,1);//显示清屏
    lcd_write_command(0x06,1);//显示光标移动设置
    lcd_write_command(0x0c,1);//显示开及光标设置
    delay_nus(30);
    lcd_write_command(0x01,1);//显示清屏
 }


//写指令函数: E=高脉冲 RS=0 RW=0//command为指令,wait_en指定是否要检测LCD忙信号
void lcd_write_command(unsigned char command,unsigned char wait_en)
 {
    if(wait_en)wait_enable();//若wait_en为1,则要检测LCD忙信号,等待其空闲
    lcd_control_port&=~lcd_RS;//RS=0
    lcd_control_port&=~lcd_RW;//RW=0
    lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
    lcd_data_ddr=0xff;
    lcd_data_port=command;
    lcd_control_port|=lcd_EN;//E=1
    lcd_data_port=command;
    lcd_control_port&=~lcd_EN;//重设E=0
 }


//写数据函数: E =高脉冲 RS=1 RW=0
void lcd_write_data(unsigned char char_data)
 {
    wait_enable();//等待LCD空闲
    lcd_control_port|=lcd_RS;//RS=1数据
    lcd_control_port&=~lcd_RW;//RW=0写
    lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
    lcd_data_ddr=0xff;
    lcd_data_port=char_data;
    lcd_control_port|=lcd_EN;//E=1
    lcd_data_port=char_data;
    lcd_control_port&=~lcd_EN;//重设E=0
 }


//正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 空闲,1 忙。
//检测忙信号,等待LCD空闲函数
void wait_enable(void)
 {
    lcd_busy_ddr&=~busy;//设置busy口为输入
    lcd_control_port&=~lcd_RS;//RS=0
    lcd_control_port|=lcd_RW;//RW=1
    lcd_control_port&=~lcd_EN;//E=0,下面给LCD一个高脉冲
    NOP();
    lcd_control_port|=lcd_EN;//E=1
    while(lcd_busy_pin&busy);//等待LCD_DB7为0
    lcd_control_port&=~lcd_EN;//重设E=0
    lcd_busy_ddr|=busy;//设置busy口为输出
 }

void display_a_char(unsigned char position,unsigned char char_data)//参数position指定位置0~79,char_data为要显示的字符
 {
    unsigned char position_tem;
    if(position<20) //第一行时,地址为0x80到0x93,输入的数值加上0x80, 就是当前的地址值;
     position_tem=position+0x80;
    else if(position<40)//第二行的地址为0xc0到0xd3,当为第二行时position>20,此时地址值应为position+0xc0-0x20即position+0xac;
     position_tem=position+0xac; 
    else if(position<60)//第三行的地址为0x94到0xa7,当为第三行时position>40,此时地址值应为position+0x94-0x40即position+0x6c;
     position_tem=position+0x6c;
    else//第四行的地址为0xd4到0xe7,当为第三行时position>60,此时地址值应为position+0xd4-0x60即position+0x98;
     position_tem=position+0x98; 
    lcd_write_command(position_tem,1);
    lcd_write_data(char_data);
 }

//指定位置显示任意大小字符串
void display_a_string(unsigned char position,unsigned char *ptr)
 {
    unsigned char position_tem,i=0,i_tem=0;
    lcd_data_port=0xff;
    lcd_data_ddr=0xff;
    lcd_control_port=0x07;
    lcd_control_ddr=0x07;
    for(i=0;*(ptr+i)!=0;i++)
    i_tem++;
    position_tem=position;
    for(i=0;i     display_a_char(position_tem++,*(ptr+i));
 }
//指定位置显示一个整数
void display_a_number(unsigned char position,int num)
 {
  int j;
  unsigned char i,x;
  if(num>=10000)i=5;
  else if(num<10000&&num>=1000)i=4;
  else if(num<1000&&num>=100)i=3;
  else if(num<100&&num>=10)i=2;
  else if(num<10&&num>=0)i=1;
  else if(num<=-10000)i=15;
  else if(num>-10000&&num<=-1000)i=14;
  else if(num>-1000&&num<=-100)i=13;
  else if(num>-100&&num<=-10)i=12;
  else i=11;
  if(i<10)
   {for(;i>0;i--)
     {
      j=ntentimes(i-1);
      x=num/j;
      display_a_char(position,x+0x30);
      num=num%j;
      position++;
     }
   }
  else
   {
    i-=10;
    display_a_char(position,'-');
    position++;
    for(;i>0;i--)
     {
      j=ntentimes(i);
      x=num/j;
      display_a_char(position,x+0x30);
      num=num%j;
      position++;
     }
   }
 }
//n的10次方转换
int ntentimes(unsigned char n)
 {int m=1;
  for(;n>0;n--)
   {m*=10;}
  return(m);
 }
/*------------------------------------延时函数--------------------------------*/
void delay_ns(unsigned int n)
{
    unsigned int i,j;
    for(i=0;i      {for(j=1000;j>0;j--)
      delay_1ms();
      }
}
//n ms延时函数
void delay_nms(unsigned int n)
{
    unsigned int i;
    n-=n/1000;
    for(;n!=0;n--){for(i=1328;i!=0;i--) ; }
}
//1ms延时函数
void delay_1ms(void)
{
    unsigned int i;
    for(i=1328;i!=0;i--);
}
//n us延时函数
void delay_nus(int n)
 {while(n--);}
/*-----------------------------------端口初始化-------------------------------*/
void io_init(void)
 {DDRA=0xff;
  PORTA=0x00;
  DDRB=0x00;
  PORTB=0xff;
  DDRC=0x07;
  PORTC=0x07;
  DDRD=0xff;
  PORTD=0xf0;
  DDRE=0x07;
  PORTE=0x00;
  }

关键字:20x4字符液晶  函数 引用地址:20x4字符液晶的函数

上一篇:AVR单片机控制的电动自行车驱动系统
下一篇:AVR单片机I/O口、定时器和按键编程总结

推荐阅读最新更新时间:2024-03-16 15:18

生成任意波形的更好方法
多年来,函数和任意波形发生器——通常被测试工程师称为 ARB 发生器——传统上建立在一种通用技术之上:直接数字合成 (DDS)。DDS 以合理的价格为几代函数发生器提供了高质量的性能。然而,新技术使仪器能够在提高信号保真度的同时利用 DDS 方法,使这些仪器比以往更适用于更多应用。 Rigol 为其 DG1000Z 系列开发的 SiFi 和是德科技的 TrueForm 等 ARB 技术专为提高波形发生器的信号保真度而设计。基于这些技术的仪器将任意信号的真正点对点波形生成与重新设计的输出硬件相结合,以创建具有前所未有的灵活性和准确性的任意波形。此外,深存储器的可用性可以在更长时间内模拟精确的任意信号,而不会失去保真度。 了解
[测试测量]
生成任意波形的更好方法
STM32开发中常用库函数
  1.GPIO初始化函数   用法:   voidGPIO_Configuration(void)   {   GPIO_InitTypeDefGPIO_InitStructure;//GPIO状态恢复默认参数   GPIO_InitStructure.GPIO_Pin=GPIO_Pin_标号|GPIO_Pin_标号;   //管脚位置定义,标号可以是NONE、ALL、0至15。   GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//最高输出速度为50MHz   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出   GPIO_
[单片机]
STM32串口的设置和库函数的介绍
串口设置的一般步骤可以总结为如下几个: 1) 串口时钟使能, GPIO时钟使能 2) 串口复位 3)GPIO 端口模式设置 4) 串口参数初始化 5) 开启中断并且初始化 NVIC(如果需要开启中断才这个步骤) (如果需要开启中断才这个步骤) 6) 使能串口 使能串口 7) 编写中断处理函数 下面,我们就简单介绍这几个与串口基本配置直接相关的固件库函数。这些函数和 定义主要分布在 stm32f10x_usart.h ,stm32f10x_usart.c 文件中。 1.串口时钟使能。串口是挂载在APB2上的,所以使能函数为: RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1) 2.串
[单片机]
S7-200 PLC的数学函数指令
S7-200PLC 的数学函数指令有平方根指令,自然对数指令、指数指令、正弦指令、余弦指令和正切指令。平方根指令是将一个双字长(32位)的实数IN开平方,得到32位的实数结果送到OUT;自然对数指令是讲一个双字长(32位)的实数IN取自然对数,得到32位的实数结果送到OUT;指数指令是将一个双字长(32位)的实数IN取以e为底的指数,得到32位的实数结果送到OUT;正弦、余弦和正切指令是将一个弧度值IN分别求正弦、余弦和正切,得到32位的实数结果送到OUT。以上运算输入/输出数据都为实数,结果大于32位二进制数表示的范围时产生溢出。 1.程序设计
[嵌入式]
S7-200 PLC的数学<font color='red'>函数</font>指令
STM32多串口printf函数
1.配置usart2的串口配置,gpio,rcc enable,跟上面类似 2.勾选usb micro lib,跟上面类似 3.添加头文件#include stdarg.h ,编写USART2的printf函数 (1)hal库 /* USART1专用的printf函数 在usart.c中添加下列函数,还要添加申明头文件#include stdarg.h , #include stdio.h //支持printf函数 USART1_printf(“abcd”)用USART2发送字符abcd */ //hal库自定义串口printf函数 void printf2(char * fmt,…) { char buffer ; uint
[单片机]
对于STM32F4库函数中GPIO_PinAFConfig()函数的解读
最近在学STM32F4芯片,想用寄存器操作,在学到IO端口复用AF(Alternative Function)时,发现对于 GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF)函数无法理解.而后拿纸算了算,恍然大悟,写下这篇笔记来记录和分享. 先贴上代码: void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) { uint32_t temp = 0x00; uint32_t temp_2 =
[单片机]
对于STM32F4库<font color='red'>函数</font>中GPIO_PinAFConfig()<font color='red'>函数</font>的解读
stm32 _hal_time中断中的定时器回调函数
当触发中断时会调用对应的中断函数 例如定时器2中断: TIM2_IRQHandler(void) HAL 库中对中断的类型进行了分类处理,每一种类型的中断方式对应一个回调函数; 例如定时器有五种中断方式,对应着五个回调函数: Timer Period elapsed callback HAL_TIM_PeriodElapsedCallback() Timer Output Compare callback HAL_TIM_OC_DelayElapsedCallback() Timer Input capture callback HAL_TIM_IC_CaptureCallback() Timer Trigger
[单片机]
uC/OS-II在ARM系统上的移植与实现
0  引言   在开发嵌入式系统时,一般选择基于ARM 和uC/ OS - II 的嵌入式开发平台,因为ARM 微处理器具有处理速度快、超低功耗、价格低廉、应用前景广泛等优点 . 将uC/ OS - II 移植到ARM 系统之后,可以充分结合两者的优势. 如果一个程序在一个环境里能工作,我们经常希望能将它移植到另一个编译系统、处理器或者操作系统上,这就是移植技术.移植技术可以使一种特定的技术在更加广泛的范围使用,使软件使用更加灵活,不局限于某一条件.uC/OS - II 是由Jean J . Labrosse 先生编写的完整的可移植、固化、裁剪的占先式实时多任务内核.uC/ OS - II 的源代码完全开放,这是其他商业实时内核无
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved