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

Atmega16单片机实用程序

作者:韩冰   来源:本站原创   点击数:  更新时间:2013年11月29日   【字体:
/*********************************************************************
 MCU:        ATmega16
 外部晶振:  8MHz
 程序功能:  4*4鍵盤識別,LED七段數碼管顯示,密碼功能模塊,直流電機正反轉控制
             AD轉換模塊, 模擬比較器,外部中斷應用,12864液晶,C/T0
 硬件設計:  參考PROTUES硬件仿真電路
 調試:      所有程序主要功能都軟硬件仿真通過,實際使用時要根據需要加入可靠性。
 編譯環境:  ICC AVR 
 Design by:   wdw        
 ********************************************************************/
#include<iom16v.h>
#include<macros.h>
#include<math.h>                            
#define uchar unsigned char
#define uint unsigned int
#define   SET_1(a,b)   a|=bit(b)       //將寄存器a的第b位置1
#define   CLR_0(a,b)   a&=~bit(b)      //將寄存器a的第b位清0
#program date code:
   const date[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,//共陽數據;
                  0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};
#program duan code:
   const duan[]={0x20,0x10,0x08,0x04,0x02,0x01};              //段選;
char adchannel; 
int dispbuf[]={0,0,0,0,0,0,};                           //顯示緩存;
uchar securbuf[]={0,0,0,0,0,};                       //5位密碼緩存;
/********************************************************************
名稱:ms延時子函數
功能:延時指定的ms
*********************************************************************/
void delayms(int ms)
  {
    int i,j;
 for(i=ms;i>0;i--)
   {
    for(j=1722;j>0;j--);                              //8M时改为1141;
    }                                                 //12M时为1722;
   }
/*******************************************************************
名稱:us延時子程序
功能:延時指定的us
********************************************************************/
void delayus(uchar us)
    {
 
 for(us;us<0;us--);
       {
  
     }                    //12M时单位T为1.45US
       
 
  } 
/********************************************************************
单参数LED 显示
硬件连接:数据PORTC-----D7~D0
          段选PORTD-----D7~D4
*********************************************************************/ 
void LEDShow(long int shownum)
{
 uchar i,tmp,curnum;
 long int tmpnum;
  tmp = 0xfb;
  tmpnum = shownum;
  for(i=0;i<6;i++)                 //显示的位数为5
  { 
   curnum = tmpnum % 10;
   tmpnum = tmpnum / 10;
   PORTD = tmp;
   PORTC = date[curnum];
   delayus(1);
   tmp = (tmp << 1) + 0x01;    //补上移位造成的最右位为0;  
  }
}
/*******************************************************
名稱:七段LED共陽數碼管,在指定数位上显示指定的数,双参数
功能:在指定的位置上顯示制定的數;
硬件連接:PC口複用控制段選和位選,有2片573進行數據鎖存;
*******************************************************/  
void show(uchar dat,uchar num)                  //六位七段數碼管顯示程序OK;
       {
    PORTC=date[dat];
    PORTD|=BIT(0);
    PORTD&=~BIT(0);                          //送數據;
    delayus(2);
   
    PORTC=0X00;
    delayus(1);
       PORTC=duan[num];
    PORTD|=BIT(1);
    delayus(2);
    PORTD&=~BIT(1); 
    delayus(2); 
    }                                       //送選通信號;
/************************************************************
名稱:MCU端口初始化
功能:設置MCU端口初始方向為輸出初始狀態為低
*************************************************************/
void Gpioinit0()
      {
    DDRA=0XFF;
    PORTA=0X00;
    DDRB=0XFF;
    PORTB=0X00;
    DDRC=0XFF;
    PORTC=0X00;
    DDRD=0XFF;
    PORTD=0X00;  
    }
/***********************************************************
名稱:MCU端口初始化
功能:設置MCU端口初始為輸出初始狀態為高   
************************************************************/
void Gpioinit1()
     {
  DDRA=0Xff;
  PORTA=0XFF;
  DDRB=0xff;
  PORTB=0XFF;
  DDRC=0xff;
  PORTC=0XFF;
  DDRD=0xff;
  PORTD=0XFF;
  }  
/**************************************************
名稱:單端口測試
輸入:測試PC的任意端口號0~7
功能:週期改變一個端口的電平
**************************************************/ 
void IOtest(uchar num)
     {
  
   DDRC|=BIT(num);
  // while(1)
    //  {
     PORTC|=BIT(num);
     delayms(50);
     PORTC&=~BIT(num);
     delayms(50);
    // }
   }
/*************************************************
名稱:按鍵動作檢測子程序。
功能:檢測4*4鍵盤是否有鍵按下;
硬件連接:PB0~PB3為行;PB4~pb7為列;
*************************************************/ 
uchar key_press()
    {
  uchar key;
  DDRB=0XFF;
  PORTB=0X0F;
  DDRB=0XF0;
  delayms(2);                         //此處要加上適當延時否則讀不到端口信息;                           
  key=PINB;
  key&=0x0f;                          //按下返回1,否則為0;
 
  if(key==0x0f)
    {
     return 0;
     }
  else
     return 1;
    
     }
/***************************************************
 名稱:4*4矩陣按鍵掃描子程序
 功能:掃描一個4*4矩陣案件,比返回相應按鍵值;
 硬件連接:PB0~PB3為行;PB4~pb7為列;
***************************************************/ 
uchar keyscan()                                   //4*4鍵盤掃面程序,調試0K;
     {
   uchar keycode,keynum;
  do{
     }while(key_press()==0);                   //按鍵是否按下?
   asm("nop");
   asm("nop");
   while(key_press()==1)
     {
  DDRB=0XFF;                                //PB0~PB3為列,PB4~PB7為行;
  PORTB=0X0F;                               //列輸出高電平,行輸出低電平;
  DDRB=0XF0;             
  delayus(10);                               //延時2毫秒,讀列狀態;
  keycode=PINB;
  
  keycode&=0x0f;                            //讀列狀態,屏蔽行狀態;
  
  DDRB=0XFF;
  PORTB=0XF0;
  DDRB=0X0F;
  delayus(10);
  PINB&=0Xf0;                               //讀行狀態,屏蔽列狀態;
  
  keycode|=PINB;
  delayus(10);
      
    do{
    }while(key_press()==1);                //按鍵是否釋放;
   
  switch(keycode)
      {
    case 0xee:
        keynum=0;
     break;
       case 0xde:
        keynum=1;
     break;
       case 0xbe:
        keynum=2;
     break;
    case 0x7e:
        keynum=3;
     break;
    case 0xed:
        keynum=4;
     break;
    case 0xdd:
        keynum=5;
     break;
    case 0xbd:
        keynum=6;
     break;
    case 0x7d:
        keynum=7;
     break;
    case 0xeb:
        keynum=8;
     break;
    case 0xdb:
        keynum=9;
     break;
    case 0xbb:
        keynum=10;
     break;
    case 0x7b:
        keynum=11;
     break;
    case 0xe7:                      
        keynum=12;
     break;
    case 0xd7:
        keynum=13;
     break;
    case 0xb7:
        keynum=14;
     break;
    case 0x77:
        keynum=15;
     break;         
      
    default :
       keynum=16;
        break; 
   
    }  
  
   } 
  return keynum;
  
   } 

/************************************************************
 名稱:六位密碼輸入比對程序
 功能:輸入六位數並與存儲密碼比對,0K返回1,按錯或者順序錯返回0;
       原始密碼654321
**************************************************************/ 
uchar securtcom()                                    //6位密碼輸入比對程序0K;
    {
 uchar  keycount=0;
  while(key_press()==1);
  delayms(3);
  do{
      while(key_press()==1);
   delayms(1);
      while(key_press()==0);
    show(8,keycount);
   securbuf[keycount++]=keyscan();
   }while(keycount<6);
  if(securbuf[0]==6)                           //初始比對,密碼654321;
       {
      if(securbuf[1]==5)
       {
      if(securbuf[2]==4)
       {
         if(securbuf[3]==3)
        {
         if(securbuf[4]==2)
      {
       if(securbuf[5]==1);
       }
        }
      
       }  
     }
   return  1;                                    //密碼正確,返回1;
    }                       
       else
    return  0;                                    //密碼錯誤,返回0;
  } 
uchar serset()                                         //密碼設定子程序;                         
    {
 
   
 }
uchar speci_keypress(uchar presstimes)  //特殊按鍵F按下某一設定次數OK;
    {
 }
   
uchar key_longpress(uchar prst)        //按鍵長按子程序
      {
   
    }   
/**************************************************
名稱:  直流蜂鳴器控制 
功能:  控制蜂鳴器鳴響時間
硬件連接:PD5輸出控制信號
**************************************************/   
void dcbeep(uchar beeptime)            //直流蜂鳴器,調試OK;
     {uchar beep;
   DDRD|=BIT(5);
   PORTD&=~BIT(5);
   PORTD|=BIT(5);
   delayus(beeptime);
   PORTD&=~BIT(5);
   delayus(100-beeptime);
    
    }
/**********************************************************
名稱:直流電機全橋控制
功能:fbw=1.正轉;fbw=0,反轉;
硬件連接:PD6與PD7口組合輸出控制信號;
**********************************************************/   
void moto(uchar fbw)                 //直流電機正反轉程序,驅動全橋;
      {
    DDRD|=BIT(6);
    DDRD|=BIT(7);
    PORTD&=~BIT(6);
    PORTD&=~BIT(7);
    delayms(5);
    if(fbw==1)
      {
      
    PORTD|=BIT(6);
    delayms(500);
    PORTD&=~BIT(6);
    delayms(20);
  
    }
    else
       {
     }
   if(fbw==0)
     {
    PORTD|=BIT(7);
    delayms(500);
    PORTD&=~BIT(7);
    delayms(20);
    
      }     
   }
/*********************************************************
 名稱: AD單次轉換子程序;
 功能: 採樣AD通路0的電壓,該函數輸出為AD 轉換後的數據,
        查詢工作方式
*********************************************************/  
void ad_init()
   {
   ADMUX=0XC0;                //設置AD輸入通道為0通道,內部2.56V參考電壓;
   ADCSRA=0X80;               //使能ADC,清中斷標誌ADIF,查詢方式;
   DDRA&=~BIT(0);             //設置PA0口為輸入;
   PORTA&=~BIT(0);            //PA0口清零;
  
    }
int ad_conv()                                //單次轉換子程序,OK;
       {
     int addata;
  ADCSRA|=BIT(ADSC);                   //啟動一次轉換;
    
  while(!(ADCSRA&(BIT(ADIF))));    //查詢等待轉換結束標誌置位;
  ADCSRA&=~BIT(ADIF);
  addata=ADCL;
     addata=addata+ADCH*256;
  return addata;
   
    } 
int ad_aver()                             //轉換8次,做平均值濾波
     {
    int adaver,count;
    for(count=7;count>0;count--)
        {
      adaver=ad_conv();
   adaver+=adaver;
   delayms(1);
      }  
    adaver=adaver/8;
    delayms(1);  
    return adaver;
   }
/*********************************************************
名稱:AD採樣
功能:採樣AD0的電壓,內部2.56V參考電壓,中斷工作方式
**********************************************************/
void ad0_init()
    {
  ADMUX=0xc0; 
  adchannel=0;
  ADCSRA=0x98;
  DDRA&=~BIT(0);
  PORTA&=~BIT(0);
  SEI();
     }  
#pragma interrupt_handler process:15    //interrupt process program
void process()
     {
       int adcode=0;
    ADCSRA&=~BIT(ADIE);
    adcode=ADCL;
    adcode=(ADCH<<8)+adcode;      //get adc value
    /************************
                   中斷處理函數
          *************************/
    ADCSRA|=BIT(ADIE);
   }
/********************************************************
名稱:DAC0832 DA轉換
輸入:有效分度0~255
輸出:無
功能:對8為數字信號進行DA轉換,實際應用需調試
********************************************************/ 
#define cs_low  PORTD&=~BIT(0)
#define cs_high PORTD|=BIT(0)
#define wr1_low  PORTD&=~BIT(1)
#define wr1_high PORTD|=BIT(1)
#define ile_high  PORTD|=BIT(2)
#define ile_low   PORTD&=~BIT(2)
#define wr2_low   PORTD&=~BIT(3)
#define wr2_high  PORTD|=BIT(3)
#define xfer_low  PORTD&=~BIT(5)
#define xfer_high PORTD|=BIT(5)
void dac(int dadata)
     {
   Gpioinit1();
   DDRD=0xff;
   DDRC=0xff;
   ile_high;
   //delayus(1);
   cs_low;
   wr1_low;
   //delayus(1);
   PORTC=dadata;
   //delayus(1);
   wr1_high;
   cs_high;
  // delayus(1);
   wr2_low;
   xfer_low;
  // delayus(1);
   xfer_high;
  
   
   }
/*****************************************************
名稱: 數據拆分顯示函數
功能: 將四位數據分別顯示到對應的數碼管。
*****************************************************/           
void addisplay(int addat)                  //轉換數據顯示,運算OK;
       {
     int a;
  a=addat;
  show(a/1000,3);
  delayms(2);
  show((a/100)%10,2);
  delayms(2);
  show(((a/10)%10)/10,1);
  delayms(2);
     show(a%10,0);
  delayms(2);
    
   } 
/**********************************************************
名稱:SPI通信
功能:應用mega16自身SPI通信模塊與外設進行通信.查詢方式;
***********************************************************/  
void SPI_masterinit()
     {
   DDRB|=BIT(5)|BIT(7);               //設置MOSI與SCK為輸出
   DDRB&=~(BIT(4)&BIT(6));            //設置MISO與SS為輸入
   SPCR|=BIT(4)|BIT(3)|BIT(1)|BIT(0); //數據高位先發送,主機模式,空閒時鐘極性
                                      //為高,SCK起始沿採樣數據,128分頻
   SPCR|=BIT(6);                      //使能SPI          
   delayms(1);         
   }  
void SPI_mastertransdata(uchar data)
     {
  SPDR=data;
  while(!(SPSR&BIT(7)));
  } 
void SPI_slaveinit()
     {
  
   }
void SPI_slaverecive()
      {
    }
   
/*********************************************************
名稱:比較匹配模式,,中斷方式,調試OK
功能:AVR比較匹配模式應用,當AIN大於AIN1時,上升沿產生中斷
**********************************************************/   
void com_inti()                        
      {
     SEI();                         //開總中斷;
     DDRB&=((~BIT(2))&(~BIT(3)));   //設置PB2/3口為輸入;
  SFIOR&=~BIT(3);                //設置AIN1為模擬比較器反向輸入端;
  ACSR&=~BIT(7);                 //使能模擬比較器,注意此處為低電平有效;
  ACSR&=~BIT(6);                 //設置AIN0為正極輸入端;
  ACSR|=BIT(3);                  //使能模擬比較器中斷;
     ACSR|=(BIT(1)|BIT(0));         //比較器上升沿觸發中斷;
    }
   
#pragma interrupt_handler comp:17       //注意函數名後不加();
void comp()                            //模擬比較器中斷服務程序;
      {
    ACSR&=~BIT(3);
   /*************
    此處加中斷處理函數
   
    **************/
    ACSR|=BIT(3);
  
                      
    }
/**********************************************************
名稱:外部中斷INT0 調試OK
功能:低電平觸發INT0端口引起中斷,並響應相關中斷服務程序
**********************************************************/  
void int0_init()
      {
    DDRD&=~BIT(2);                         //PD2/INT0端口配置為輸入;
    MCUCR&=((~BIT(0))&(~BIT(0)));          //INT0觸發方式為低電平;
    GICR|=BIT(6);                          //使能外部中斷0;
    SEI();                                 //開總中斷;
   
    }
#pragma interrupt_handler int0:2
void int0()                                   //INT0中斷服務函數;
     {
    GICR&=~BIT(6);                         //關閉外部INT0;
  /************************
 
 
   此處加INT0中斷處理函數
         
 
  ************************/ 
    GICR|=BIT(6);                         //開啟外部INT0;
   }
/*********************************************************
名稱:外部中斷INT1,
功能:邊沿觸發INT0端口引起中斷,並響應相關中斷服務程序
**********************************************************/    
void int1_init()
     {
   DDRD&=~BIT(3);                        //將PD3口配置為輸入;
   PORTD&=~BIT(3);                       //pd3口初始值為0;
   MCUCR|=(BIT(3)|BIT(2));               //INT1上升沿觸發中斷;
   GICR|=BIT(7);                         //使能INT1中斷;
   SEI();                                //開總中斷;
   }
#pragma interrupt_handler int1:3
void int1()
     {
   GICR&=~BIT(7);                       //關閉INT1中斷;
   /*******************************
  
   此處加INT1中斷服務函數;
  
   *******************************/                                 
   GICR|=BIT(7);                        //開啟INT1中斷; 
                 
   } 
/**********************************************************       
/**********************************************************
名稱:12864(ks0108)顯示應用
功能:圖形液晶使用
**********************************************************/  
#define EN_CLR          PORTD&=~BIT(0)       //使能12864
#define EN_SET          PORTD|=BIT(0)        //關閉12864
#define RW_READ         PORTD|=BIT(1)        //讀操作
#define RW_WRITE        PORTD&=~BIT(1)       //寫操作
#define RS_COMM         PORTD&=~BIT(2)       //命令操作
#define RS_DATA         PORTD|=BIT(2)        //數據操作
#define RESET           PORTD&=~BIT(3)       //12864液晶複位
#define RESET_OVER      PORTD|=BIT(3)        //12864液晶結束複位;
#define CS1_EN          PORTD&=~BIT(4)       //使能CS1,選擇左半屏幕;
#define CS1_DIS         PORTD|=BIT(4)        //禁止CS1
#define CS2_EN          PORTD&=~BIT(5)       //使能CS2,選擇右半屏幕;
#define CS2_DIS         PORTD|=BIT(5)        //禁止CS2
#define basic_com       0x30                 //一次送8BIT數據,基本指令集;
#define explo_com       0xc4                 //擴展指令集
#define show_stitude    0x0f                 //顯示狀態,整體顯示,游標開,游標位置開
#define cleanscreen     0x01                 //顯示清零,AC歸零
#define cursor          0x07                 //写入/讀取时,游标右移,畫面左移
#define AC_0            0x03                 //AC归0,不改变DDRAM内容
const int char_0816[]={
                       0xe0,0x18,0x04,0x04,0x04,0x18,0xe0,0x00,
        0x07,0x18,0x20,0x20,0x20,0x18,0x07,0x00
                        };
/************************************************************
名稱:MCU端口初始化
功能:設置MCU端口初始方向以及狀態
*************************************************************/
void GPIO_INIT()
      {
    DDRA=0XFF;
    PORTA=0X00;
    DDRB=0XFF;
    PORTA=0X00;
    DDRC=0XFF;
    PORTA=0X00;
    DDRD=0XFF;
    PORTA=0X00;  
    }
/****************************************************************
名稱:輸入數據
功能:MCU將數據送到總線
*****************************************************************/   
void SET_DATA(uchar data)
     {
   delayus(3);
   PORTC=data;
   delayus(3);
   }
/****************************************************************
名稱:開關顯示控制
功能:開啟與關閉顯示操作,1為開顯示,0為關閉顯示
*****************************************************************/ 
void LCD_Command_Displayonoff(uchar onoff) 
      {
    RW_WRITE;
    RS_COMM;
    EN_CLR;
    SET_DATA(0x3e + onoff);     //onoff為1開顯示,為0關顯示;
    EN_SET;
    delayus(2);
    EN_CLR;
   }
/***************************************************************
名稱: LCD顯示起始行設定
功能:設置LCD顯示起始行位置,startline範圍0~63
***************************************************************/  
void LCD_Command_setstartline(uchar startline)
     {
  RW_WRITE;
  RS_COMM;
  EN_CLR;
  SET_DATA(0Xc0 + startline);    //12864行地址為0~63之間設定;
  EN_SET;
  delayus(2);
  EN_CLR;
  }
/***************************************************************
名稱:設置顯示行頁地址
功能:設置顯示行頁地址,12864為0~7
****************************************************************/ 
void LCD_Command_set_x(uchar x)
   {
     RW_WRITE;
  RS_COMM;
  EN_CLR;
  SET_DATA(0xB8+x);    //設置12864行頁地址  x範圍0~7;
  EN_SET;
  delayus(2);
  EN_CLR;
    }
/****************************************************************
名稱:設置顯示列地址
功能:設置顯示列地址y,範圍0~63;
*****************************************************************/
void LCD_Command_set_y(uchar column)
    {
  RW_WRITE;
  RS_COMM;
  EN_CLR;
  SET_DATA(0x40+column);    //設置顯示列地址y,範圍0~63;
  EN_SET;
  delayus(2);
  EN_CLR;
  }
/********************************************************************
名稱:LCD顯示數據寫入
功能:將顯示數據寫入12864液晶
*********************************************************************/
void LCD_Command_writebyte(uchar data)
    {
  RW_WRITE;
  RS_DATA;
  EN_CLR;
  SET_DATA(data);
  EN_SET;
  delayus(2);
  EN_CLR;
  } 
/*********************************************************************
名稱:LCD複位操作
功能:複位LCD
**********************************************************************/ 
void LCD_RESET()
     {
   RESET;
   NOP();
   NOP();
   NOP();
   RESET_OVER;
   } 
/************************************************************
名稱:清除指定範圍函數
功能:清除LCD屏幕指定範圍起始行~結束行的顯示內容
************************************************************/   
void LCD_CLEAR_LINE(uchar startline,uchar endline)
     {
   uchar i,j;
   for(i-startline;i<=endline;i++)
      {
    CS1_EN;
    CS2_EN;
    LCD_Command_set_x(i);
    LCD_Command_set_y(0);               //y地址每次操作後自動加1;
    for(j=0;j<64;j++)
       {
     LCD_Command_writebyte(0x00);
     }
    }
   } 
/*************************************************************
名稱:顯示初始化
功能:初始化LCD
*************************************************************/   
void LCD_init()
     {
   LCD_RESET();
   LCD_CLEAR_LINE(0,7);
   NOP();
   LCD_Command_Displayonoff(1);
   NOP();
   LCD_Command_setstartline(0);
   }
/**************************************************************
名稱:LCD_WRITE_DATA
輸入:x in [0,7] and y in [0,127]
輸出:無
功能:在LCD指定行列寫一個數據
**************************************************************/ 
void LCD_write_data(uchar x,uchar y,uchar data)
     {
   if(y<64)
     {
   CS1_EN;
   CS2_DIS;
   LCD_Command_set_x(x);
   LCD_Command_set_y(y);
   }
   else
   {
   CS1_DIS;
   CS2_EN;
   LCD_Command_set_x(x);
   LCD_Command_set_y(y-64);
   }
  LCD_Command_writebyte(data); 
  delayus(1);
  }
/*********************************************************
名稱:LCD_WRITE_DOT
輸入:x in [0,63] and y in [0,127]
輸出:無
功能:在指定像素位置描點,此函數為覆蓋式描點,原位置一個
      字節數據被覆蓋
*********************************************************/ 
void LCD_write_dot(uchar x,uchar y)
     {
   uchar x_address,y_address;
   uchar data=0;
   if((x<64)&&(y<128))
     {
   x_address=x>>3;
   y_address=y;
   LCD_write_data(x_address,y_address,data|(1<<(x%8)));
   }
  }
/**********************************************************
名稱:LCD_WRITE_CHAR
輸入:x in [0,3],y in [0,15], disp-顯示字符自模數組首地址
輸出:無
功能:在LCD指定顯示單元顯示一個字符,每個顯示單元默認為8*16
      點陣字體,對12864點陣LCD,x最多顯示4行,y最多顯示16個字
   符。
***********************************************************/ 
void LCD_write_char(uchar x,uchar y,const uchar *disp)
     {
   uchar i;
   uchar x_address;
   uchar y_address;
  if((x<4)&&(y<16))
      {
   for(i=0;i<8;i++)
       {
     x_address=x<<1;
     y_address=(y<<3)+i;
     LCD_write_data(x_address,y_address,*disp++);
     }
     for(i=0;i<8;i++)
        {
      x_address=(x<<1)+1;
      y_address=(y<<3)+i;
      LCD_write_data(x_address,y_address,*disp++);
      }  
    }
   }
/***********************************************************
名稱:LCD_write_word
輸入:x in [1,3],y in [1,14] disp-顯示字符字模組首地址
輸出:無
功能:在LCD指定顯示單元顯示一個中文字符,每個顯示單元默認為
      16*16點陣字體,對128*64點陣LCD,x最多顯示4行,y最多顯
   示16個字符,不允許顯示半個漢字
***********************************************************/
void LCD_write_word(int x,int y,const uchar *disp)
      {
   int i;
   int x_address;
   int y_address;
    if((x<4)&&(y<15))
      {
    for(i=0;i<16;i++)
       {
     x_address=x<<1;
     y_address=(y<<3)+i;
     LCD_write_data(x_address,y_address,*disp++);
     }
    }
      for(i=0;i<16;i++)
       {
     x_address=(x<<1)+1;
     y_address=(y<<3)+i;
     LCD_write_data(x_address,y_address,*disp++);
     } 
   }
/************************************************************
名稱:LCD_write_picture
輸入:x in [1,7] and y in [0,127],x1_length-縱向像素(8的整數倍),
      y1_length-橫向像素(不一定為8的整數倍)
輸出:無
功能:在指定區域顯示指定像素大小的圖片
************************************************************/ 
void LCD_write_picture(int x1,int y1,int x_length,int y_length,const int *pdata)
        {
   int x_address;
   int y_address;
   for(x_address=x1;x_address<=x1+(x_length>>3)-1;x_address++)
       {
     for(y_address=y1;y_address<y1+y_length;y_address++)
        {
      LCD_write_data(x_address,y_address,*pdata);
      }
    }
   }  
/**********************************************************
名稱: busy
輸入:無
輸出:忙狀態返回1,空閒狀態返回0;
功能:判別LCD控制器內部狀態,忙時返回1,閑時返回0
**********************************************************/  
uchar busy(void)
      {
   RS_COMM;
   RW_READ;
   if(BIT(7)==0)
      {
    return 0;
    }
    else
       return 1;  
    } 
/***************************************************************
名称:12864测试
功能:逐点扫描
****************************************************************/ 
void LCD_test()
     {
   uchar i,j;
  for(i=0;i<63;i++)
      {
   for(j=0;j<127;j++)
      {
     delayms(20);
     LCD_write_dot(i,j);
     delayms(100);
    }
    }
  }  
/**************************************************************
名称:axis()
输入:无
输出:无
功能:标定界面坐标
***************************************************************/ 
void  axis()
     {
   uchar a,b,y,x;
    for(a=0;a<63;a++)                 //y轴坐标及分位点;
       {
     LCD_write_data(a,29,0x01);
     }
  for(b=0;b<127;b+=5)              //x轴坐标及分位点;
      {
         LCD_write_data(30,b,0x04);
   
      }
   }
/**********************************************************   
/********************************************************
名称:定时器0初始化
輸入:
輸出:
描述:普通方式,中断工作方式,注意中斷響應程序中要重裝初值
*********************************************************/
void timer0_init()
      {
    SFIOR|=BIT(0);                        //复位预定比例分频器;
    TCCR0|=(BIT(2)|BIT(0));               //设定分频器为1024分频;
    //TCCR0|=BIT(0);                      //設定分頻器為無分頻;
    TCNT0=255;                            //装订计数初值
    TIMSK|=BIT(0);                        //开启T/C0中断;
    SEI();                                //开总中断;   
   
    DDRC|=BIT(0);
    PORTC|=BIT(0);      
    }
/************************************************************
中斷處理函數
************************************************************/ 
#pragma interrupt_handler time0_proc:10
void time0_proc()
      {
    TIMSK&=~BIT(0);                     //關閉中斷;
    TCNT0=255;                          //重新装订计数初值;
    PORTC^=BIT(0);
    TIMSK|=BIT(0);                      //開啟T0中斷
   }
  
/*************************************************************
名称:6位数码管按键位移显示
输入:无
输出:无
描述:按键输入时在LED上移位显示按键值,当按下f时,全部清零。
**************************************************************/
void keymovedis()
       {  
      uchar keyval1,keyval2,presstimes;
   while(1)
      {
     if(keyscan()==15)              //F的键值为15;
        {
       for(presstimes=0;presstimes<5;presstimes++)
          {
        dispbuf[presstimes]=date[0];
        show(0,presstimes);
           } 
      }
      else
         {
        for(presstimes=0;presstimes<5;presstimes++)
         {
      
       dispbuf[5-presstimes]=dispbuf[4-presstimes];
       dispbuf[0]=keyscan();
       show(dispbuf[presstimes],presstimes);
      
       }
      }  
    }
  
     }
/*********************************************************
主函數main().c,地球人都知道,不必廢話
**********************************************************/ 
void main()
    {
 
  while(1)
    {
    
  
     }
 
   
    
     }
 
关闭窗口

相关文章