专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

1602自定义字符显示摄氏度符号(AVR版)

作者:佚名   来源:本站原创   点击数:  更新时间:2013年10月23日   【字体:

LCD1602
的数据写入及CGRAM的使用
1.当使能端E1变为0时,执行写指令,数据被写入。
例如,欲写入数据iDDRAM
void WDR(uchar i)
{
         CheckBusy();//检忙
         LCD_RS=1;
         LCD_RW=0;
         LCD_EN=0;
         Delay();
         LCD_DATA=i;//数据输出到定义端口
         Delay();   
         LCD_EN=1;
         Delay();
         LCD_EN=0;//这一步才开始写入到LCD
         Delay();
}
2.CGRAM
1602能存储8个自定义字符,这8个自定义字符存储空间的首地址分别是:0X40,0X48,0X50,0X58,0X60,0X68,0X70,0X78
0x40来说,它的存储空间如图所示:
 
 

 
 
 
如果使用5*7字符的话,那么最左3位和最后一行的数据实际上是没用的,通常置0。如果要自定义一个符号,那么先填框,如图(红10):
 
 
这样我们就得到每个地址需要写入的数据:
地址:数据
0x40:0x16
0x41:0x09
0x42:0x08
其他类推。将这8个数据写入到对应地址即可。
使用时,先确定显示的位置,例如0X80,然后向DDRAM写入自定义字符的使用代码。0X40-0X78对应为0X00-0X07
本例中,先写入指令寄存器0X80确定显示位置为第一行第一个,然后写入数据寄存器0X00,这样就会在第一行第一个位置显示出符号。
 

 
 

以下是源程序如果网页格式导致部分字符丢失请下载c程序源文件:http://www.51hei.com/f/avr1602c.rar
#include <iom16.h>
#include <intrinsics.h>
#define u8 uchar unsigned char
#define u16 uchar unsigned int
#define uchar unsigned char
#define uint unsigned int
uchar zi[]={0x16,0x09,0x08,0x08,0x08,0x09,0x06,0x00};  //自定义字符摄氏度

#include"1602.h"
#include"18b20.h"

void port_init()
{
  PORTA=0xff;
  DDRA=0xff;
  PORTB=0xff;
  DDRB=0xff;
  PORTC=0xff;
  DDRC=0xff;
  PORTD=0xff;
  DDRD=0x00;
}
void setzi()  //把设定字存入CGRAM
{
  uchar i;
  writecmd(0x40); //设置第一个字的起始地址
  for(i=0;i<8;i++)
  {
    writedata(zi[i]);
  } 
}

void show_temp(uint k)
{
  displayonechar(1,1,(k/100)+48);
  displayonechar(2,1,(k%100/10)+48);
  displayonechar(3,1,'.');
  displayonechar(4,1,(k%10)+48); 
}
void main()
{
 uint TT; //显示的温度值
 port_init();
 delay(1000);
 init1602();
 displaychar(0,0,"Set zi Test");
 setzi();
 displayonechar(5,1,0x00);    //0x00表示 0x40地址的值
  while(1)
 {
 TT=read_temper();
 show_temp(TT);
}
}
 
//---------------1602.h----------------
 
#define RS PORTB_Bit0
#define RW PORTB_Bit1
#define EN PORTB_Bit2
#define DATA PORTA
#define busy 0x80
void delay(uint k)
{
 uint i,j;
for(i=0;i<k;i++)
for(j=0;j<1140;j++);
 
}

void wait()
{
  uchar val;
  DATA=0xff;
  RS=0;
  RW=1;
  __no_operation();
  __no_operation();
  EN=1;
  __no_operation();
  __no_operation();
  DDRA=0x00;
  val=PINA;
  while(val&busy)
  {
    val=PINA;
  }
  EN=0;
  DDRA=0xff;
}

void writecmd(uchar cmd)
{
  wait();
  RS=0;
  RW=0;
  __no_operation();
  DATA=cmd;
  __no_operation();
  EN=1;
  __no_operation();
  __no_operation();
  EN=0;
}
void writedata(uchar data)
{
  wait();
  RS=1;
  RW=0;
 __no_operation();
 DATA=data;
 __no_operation();
 EN=1;
 __no_operation();
 __no_operation();
 EN=0;
}

 
void displayonechar(uchar x,uchar y,uchar dda)
{
  y&=0x01;
  x&=0x0f;
  if(y)x|=0x40;
  x|=0x80;
  writecmd(x);
  writedata(dda);
}
 
void displaychar(uchar x,uchar y,uchar *p)
{
  y&=0x01;
  x&=0x0f;
  while(*p!='\0')
  {
    if(x<=0x0f)
    {
      displayonechar(x,y,*p);
      p++;
      x++;
    }
  }
}

void init1602()
{
 delay(15);
writecmd(0x38);
delay(5);
writecmd(0x38);
delay(5);
writecmd(0x38);
writecmd(0x80);
writecmd(0x01);
writecmd(0x06);
writecmd(0x0c);
}
 
//--------------18B20.h------------

uchar teml,temh;
uchar sign;
uchar Flag_1820Error;
uint tempp; //温度值

/*********************************/
void delay_15us(void)  //15us左右
{
uchar x=27;
  while(x)
  {
    x--;
  }
}
/********************************/
void delay_60us(void)  //60us左右
{
uchar x=117;
  while(x)
  {
    x--;
  }
}

void init_1820(void)
{
   uchar i;
   uint j=0;
   PORTC|=(1<<7);  //"1"
   PORTC&=~(1<<7); //"0"
   for(i=0;i<8;i++)delay_60us();//480us以上
   PORTC|=(1<<7);  //"1"
   DDRC&=~(1<<7);  //"PINC7 is INPUT"
   delay_15us();     //15~60us
   delay_15us();
   Flag_1820Error=0; 
   while(PINC&(1<<7))
   { delay_60us();
     j++;
  if(j>=18000){Flag_1820Error=1;break;}
   }  
   DDRC|=(1<<7);   //PORTC7 is OUTPUT
   PORTC|=(1<<7);  //"1"
   for(i=0;i<4;i++)delay_60us(); //240us
}
/********************************/
void delay_5us(void)  //5us左右
{
uchar x=7;
  while(x)
  {
    x--;
  }
}
/********************************/
void write_1820(uchar x)
{   
   uchar m;
   for(m=0;m<8;m++)
   {
    if(x&(1<<m))    //写数据,从低位开始
     {PORTC&=~(1<<7);delay_5us(); //"0",5us
   PORTC|=(1<<7); //write"1"
   delay_15us(); //15~45us
   delay_15us();
   delay_15us();
  }
     else
     {PORTC&=~(1<<7);delay_15us();//"0",15us
   delay_15us(); //write"0"
   delay_15us(); //15~45us
   delay_15us();
      PORTC|=(1<<7);  //"1"
  }
   }
   PORTC|=(1<<7); //"1"
}
/*******************************/
uchar read_1820(void)
{    
   uchar temp,k,n;
   temp=0;
   for(n=0;n<8;n++)
   {
    PORTC&=~(1<<7);  //"0"
    delay_5us();     
    PORTC|=(1<<7);   //"1"
    delay_5us();
    DDRC&=~(1<<7);   //"PINC7 is INPUT"
    k=(PINC&(1<<7)); //读数据,从低位开始
    if(k)
     temp|=(1<<n);   //read"1"
    else
     temp&=~(1<<n);  //read"0"
    delay_15us();      //45us
 delay_15us();
 delay_15us();    
    DDRC|=(1<<7);    //PORTC7 is OUTPUT
   }
   return (temp);

/*************************************/
uint read_temper(void)
{
    uchar TX;  //小数位
    uchar TZ;  //整数位
    init_1820();        //复位18b20
    write_1820(0xcc);   // 发出转换命令
    write_1820(0x44);
     ;;;;;;
    init_1820();
    write_1820(0xcc);  //发出读命令
    write_1820(0xbe);
    teml=read_1820();  //读数据byte1
    temh=read_1820();  //byte2
    TX=teml&0x0f;
    temh=temh<<4;
    temh|=(teml&0xf0)>>4;
    TZ=temh;
    tempp=TZ*10+TX;
      
        return tempp;
}

 
关闭窗口

相关文章