專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

1602自定義字符顯示攝氏度符號(hào)(AVR版)

作者:佚名   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年10月23日   【字體:

LCD1602
的數(shù)據(jù)寫入及CGRAM的使用
1.當(dāng)使能端E1變?yōu)?/span>0時(shí),執(zhí)行寫指令,數(shù)據(jù)被寫入。
例如,欲寫入數(shù)據(jù)iDDRAM
void WDR(uchar i)
{
         CheckBusy();//檢忙
         LCD_RS=1;
         LCD_RW=0;
         LCD_EN=0;
         Delay();
         LCD_DATA=i;//數(shù)據(jù)輸出到定義端口
         Delay();   
         LCD_EN=1;
         Delay();
         LCD_EN=0;//這一步才開(kāi)始寫入到LCD
         Delay();
}
2.CGRAM
1602能存儲(chǔ)8個(gè)自定義字符,這8個(gè)自定義字符存儲(chǔ)空間的首地址分別是:0X40,0X48,0X50,0X58,0X60,0X68,0X70,0X78。
0x40來(lái)說(shuō),它的存儲(chǔ)空間如圖所示:
 
 

 
 
 
如果使用5*7字符的話,那么最左3位和最后一行的數(shù)據(jù)實(shí)際上是沒(méi)用的,通常置0。如果要自定義一個(gè)符號(hào),那么先填框,如圖(紅10):
 
 
這樣我們就得到每個(gè)地址需要寫入的數(shù)據(jù):
地址:數(shù)據(jù)
0x40:0x16
0x41:0x09
0x42:0x08
其他類推。將這8個(gè)數(shù)據(jù)寫入到對(duì)應(yīng)地址即可。
使用時(shí),先確定顯示的位置,例如0X80,然后向DDRAM寫入自定義字符的使用代碼。0X40-0X78對(duì)應(yīng)為0X00-0X07。
本例中,先寫入指令寄存器0X80確定顯示位置為第一行第一個(gè),然后寫入數(shù)據(jù)寄存器0X00,這樣就會(huì)在第一行第一個(gè)位置顯示出符號(hào)。
 

 
 

以下是源程序如果網(wǎng)頁(yè)格式導(dǎo)致部分字符丟失請(qǐng)下載c程序源文件:http://www.torrancerestoration.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()  //把設(shè)定字存入CGRAM
{
  uchar i;
  writecmd(0x40); //設(shè)置第一個(gè)字的起始地址
  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))    //寫數(shù)據(jù),從低位開(kāi)始
     {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)); //讀數(shù)據(jù),從低位開(kāi)始
    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;  //小數(shù)位
    uchar TZ;  //整數(shù)位
    init_1820();        //復(fù)位18b20
    write_1820(0xcc);   // 發(fā)出轉(zhuǎn)換命令
    write_1820(0x44);
     ;;;;;;
    init_1820();
    write_1820(0xcc);  //發(fā)出讀命令
    write_1820(0xbe);
    teml=read_1820();  //讀數(shù)據(jù)byte1
    temh=read_1820();  //byte2
    TX=teml&0x0f;
    temh=temh<<4;
    temh|=(teml&0xf0)>>4;
    TZ=temh;
    tempp=TZ*10+TX;
      
        return tempp;
}

 
關(guān)閉窗口

相關(guān)文章