久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

avr MEGA16單片機控制DS1302時鐘芯片1602液晶顯示

作者:肖邦   來源:本站原創   點擊數:  更新時間:2014年03月08日   【字體:
/*
 
          程序名(program name) :  時鐘芯片控制程序;

 
          概述 :  基于本程序的開發板是本人自主研發的YF-A1 AVR MEGA16單片機芯片開發板,信號
     輔助硬件工具有一部8通道的24兆赫茲的邏輯分析儀和一部萬用表,通俗的講,此程序就
              是開發板的操作系統,以MEGA16A為中央控制芯片,來控制DS1302時鐘芯片,使其時間數據
 顯示在1602液晶屏上;
     我用業余時間大概寫了三天左右....得以完善,這次我寫的比較順利,錯誤只有兩點,
              一是將寫好的程序下載入芯片后,時間不走,錯誤在于寫錯了時序,用邏輯分析儀捕捉信號
              后,修正,KO! 二是時間可以走,但是跑秒區并非從0走到59,問題在于顯示時,直接顯示
 BCD碼,并未將BCD碼轉換為十進制數,修正后OK!
                   此程序還用到了定時器模塊,定時每100毫秒讀一次時間數據,并顯示在液晶屏上;

 

 
            心得:    此次又突破了以往的程序量,這是我寫的目前最大的一個程序,由于AVR芯片IO口
    控制比較復雜,所以程序語句比較多,但是此程序還有精簡的空間,IO口的初始化很重
要!
 

 

 
                 finish time:   2014年3月7日13:16:14
                        作者: 肖邦;
                          QQ: 14-545-07665 ;
                         TEL:  SORRY 保密;
       地址:  新疆昌吉回族自治州昌吉市; 
                        夢想:  將 托尼*斯塔克成為現實;

 
*/

 

 
#include <avr/io.h>
#include <avr/interrupt.h>//此頭文件用于中斷服務,本程序中可以省略;

 
typedef unsigned char uint8;
typedef unsigned int uint16;

 
void init_io(void) //====初始化所有io口;
{
   DDRA=0XFF;
   PORTA=0XFF;

 
   DDRB=0XFF;
   PORTB=0X00;

 
   DDRC=0XFF;
   PORTC=0X00;

 
   DDRD=0XFF;
   PORTD=0X00;
}

 
//================IO口的位操作==================

 
void rs(uint8 a)    //指令/數據位/ ===========DS1302時鐘位;
{
  if(a) { PORTB|=1<<3; }

 
  else  { PORTB&=~(1<<3); }
}

 
void rw(uint8 a)  //讀/寫位/   ================DS1302數據位;
{
  if(a) { PORTB|=1<<4; }

 
  else  { PORTB&=~(1<<4); }
}

 
void e(uint8 a)    //1602傳輸時能位;
{
  if(a) { PORTB|=1<<5; }

 
  else  { PORTB&=~(1<<5); }
}

 

 
void ds(uint8 a)    //=========================DS1302傳輸使能位;
{
  if(a) { PORTC|=1<<4; }

 
  else  { PORTC&=~(1<<4); }
}

 

 
//==============================================

 

 
/*/======================================================
   模塊名:  1602LCD液晶屏函數 
     功能:  負責將視覺需要的數據顯示在屏幕上;
     
*///=====================================================
void pa7(uint8 a)  //繁忙檢測位=================
{
  if(a) { DDRA|=0X80; PORTA|=0X80 ;} //輸出高電平狀態;
  else  { DDRA&=~(0X80); PORTA|=0X80; }//輸入內部有上拉電阻;
}

 
void busy(void)    //繁忙檢測函數
{
   pa7(0);  // PA7引腳輸入狀態內部有上拉;
   do
   {
    e(0);
    rs(0);
    rw(1);
    e(1);   //注意!此處和讀寫數據指令不同,要置1傳輸使能位,再讀取,讀取完成后再清零此位;
   }

 
   while(PINA&0X80);//讀取PA7引腳是否是0;如果是0,表示液晶屏處于空閑狀態,可以進行操作;
   e(0);

 
   pa7(1);   //PA7引腳輸出狀態,輸出1;
}

 
void pa(uint8 a) //====向PA口裝載數據;
{

 
  PORTA=a;

 
}
void lcd_dat(uint8 dat)//=========寫數據==============
{
   busy();  //繁忙檢測;
    rs(1);  //數據;
    rw(0);  //寫入;
e(1);   //傳輸開始;
    pa(dat);  //裝載數據;
    e(0) ;   //傳輸結束;
  
}

 
void lcd_cmd(uint8 cmd)  //=============寫指令=============
{
   busy();  //繁忙檢測;
    rs(0);  //指令;
    rw(0);  //寫入;
e(1);   //傳輸開始;
    pa(cmd);  //裝載數據;
    e(0);    //傳輸結束;
  
}

 
void init_lcd()  //初始化液晶屏指令;
{
   lcd_cmd(0x3c);  //顯示數據,8位數據, 兩行,5X10顯示;
   lcd_cmd(0x0c);  //整屏顯示光標不閃,字符不閃.
   lcd_cmd(0x06);  //寫入一個數據時地址加一,整屏不移動;
   lcd_cmd(0x01);  //清屏指令;

 
}

 
void play(uint8 add,uint8 dat)//=======最終顯示函數===================
{
  lcd_cmd(add);
  lcd_dat(dat);

 
}

 
void delay1(uint8 j,uint8 i)//====可編程延時函數========
{
   uint16 a=0,s=10000;
   
    s=s*j;

 
    while(i--)
{
 for(a=0;a<s;a++);
    }

 
}

 

 
void buzz(void)    //蜂鳴器=============
{

 
  PORTC|=0X80;
  delay1(3,4);
  PORTC&=~(0X80);

 
}

 
//==========================================================

 

 

 

 
//==================DS1302模塊===========

 
void reset_1302()
{
   ds(0);
   rs(0);
   rw(0);

 
}
void delay2(void)      //用于DS1302小延時函數;
{
  uint8 j=0;
  for(j=0;j<200;j++);

 

 
}

 
void ds_write(uint8 dat)   //DS1302寫數據函數;
{
   uint8 j=0;

 
   for(j=0;j<8;j++)
     {
    rw(dat&0x01);
         
rs(0);
rs(1);
dat>>=1;
}
   
    
  
}

 
uint8 ds_read(void) // DS1302讀取函數;
{
    uint8 j=0,temp=0;

 
    DDRB&=~(1<<4); //rw引腳輸入狀態;
    PORTB|=1<<4;   //內部有上拉電阻;
     rs(0);

 

 
    for(j=0;j<8;j++)
{         
        temp>>=1;

 

 
   if((PINB&0X10)==0X10)//如果PB4口讀到1;
 {   
     temp|=0x80;//裝載數據;
 }
 
 
      rs(1);       //下降沿有效;
 delay2();    //時鐘脈寬延時;
      rs(0);        
}
 
    DDRB|=1<<4; //  rw引腳輸出狀態;
    PORTB|=1<<4;   //rw引腳輸出1;
        rs(0);
rw(0);

 
return (temp);

 

 
}

 
void w_1302(uint8 addr,uint8 dat) //寫一個地址,寫一個數據;
{
   ds_write(addr);
   ds_write(dat);

 
}

 

 
void ds_wp(uint8 j)  //j==1:不能夠寫入數據,j==0:可以寫入數據;
{  
   reset_1302(); //初始化時鐘,數據,片選線;
   ds(1);
   w_1302(0x8e,j?0x80:0);  //三目運算;
   ds(0);
}

 

 
void set_time(uint8 * dat)   //設置時間;
 { 
  uint8 r=0 ,t=0, ad=0x80;
   for(r=0;r<7;r++)    //BCD碼的轉換.
     {
  t=dat[r]%10;
  dat[r]=dat[r]/10;
  dat[r]=(dat[r]*16)+t;
 
}
      ds_wp(0);//可以寫入數據;
      for(r=0;r<7;r++)
  {     
     reset_1302();  //初始化1302;
        ds(1);    //傳輸使能開;
        ds_write(ad); //寫入"寫"操作地址;
        ds_write(dat[r]);//寫入時間數據;
ds(0);
         ad+=2;//地址加2;
       }
       ds_wp(1);//禁止寫入數據;  

 
}

 
void read_time(uint8 * dat)
{
   uint8 j=0,addr=0x81 ;

 
   for(j=0;j<7;j++)
    {
      reset_1302();
 ds(1);          //傳輸使能開;
      ds_write(addr);  //發送讀取地址;
 dat[j]=ds_read(); //接收讀到的數據;
 ds(0);          //傳輸使能關;

 
 addr+=2;   //讀取地址加2;
}

 
}

 
void timer0(void)  //定時器模塊函數;
{

 
  TCNT0=22;  //每5毫秒溢出一次;
  TCCR0=0X04;  //256分頻;

 

 
}

 

 
int main(void)
{
    uint8 j=0;
   uint8 sj[]={20,23,13,7,3,5,14};
   init_io();  //初始化所有io口;
   init_lcd();  //初始化1602液晶屏;

 
   play(0x82,'2');
   delay1(3,2);

 
  play(0x83,'0');
  delay1(3,2);
 
    play(0x86,'-');                    
   delay1(3,2);

 
     play(0x89,'-');             
   delay1(3,2);

 
    play(0x8d,'(');              
   delay1(3,2);

 
   play(0x8f,')');
   delay1(3,2);

 
   play(0xc4,':');
   delay1(3,2);

 
    play(0xc7,':');
   delay1(3,2);
    
   buzz();   //蜂鳴器叫;
   delay1(3,2);

 
  set_time(sj);  //設置時間;
  timer0();  //運行定時器;

 

 

 

 

 
 while(1)
  {  
    if(TIFR&0X01)  //定時器溢出了;
 j++;
      TCNT0=22;
 TIFR|=0X01;//溢出位置一清零;

 
     }

 
     if(j==20)
 {
    j=0;

 
      read_time(sj);
       
      play(0xc9,sj[0]%16+'0'); //秒個位;
 play(0xc8,sj[0]/16+'0'); //秒十位;

 
      play(0xc6,sj[1]%16+'0'); //分個位;
 play(0xc5,sj[1]/16+'0'); //分十位;

 
 play(0xc3,sj[2]%16+'0'); //時個位;
 play(0xc2,sj[2]/16+'0'); //時十位;

 
                               
 play(0x8b,sj[3]%16+'0'); //號個位;
 play(0x8a,sj[3]/16+'0'); //號十位;

 
 play(0x88,sj[4]%16+'0'); //月個位;
 play(0x87,sj[4]/16+'0'); //月十位;

 

 
      play(0x8e,sj[5]+'0'); //星期;

 

 
      play(0x85,sj[6]%16+'0'); //秒個位;
 play(0x84,sj[6]/16+'0'); //秒十位;

 

 

 
      
   
 }

 

 

 
  }

 

 

 

 
 

 

 
}
關閉窗口

相關文章

主站蜘蛛池模板: 中文字幕亚洲一区 | 在线一区二区三区 | 亚洲精品乱码久久久久久9色 | 国产午夜精品一区二区三区嫩草 | 羞羞视频在线观看 | 人人澡人人射 | 久久久五月天 | www在线| 二区成人 | 国产精品久久久久久久久久久久 | 国产成人免费视频 | av成人在线观看 | 91精品久久久久 | 亚洲 欧美 日韩在线 | gogo肉体亚洲高清在线视 | 蜜桃综合在线 | 我我色综合 | 国产精品免费一区二区三区四区 | 成人免费视频在线观看 | 国产高清一区二区三区 | 女人牲交视频一级毛片 | 日本三级全黄三级三级三级口周 | 久久99久久99 | 日韩欧美中文 | 婷婷精品 | 国产一级免费视频 | 日韩精品一区二区三区高清免费 | 精品视频久久久久久 | 亚洲国产精品第一区二区 | 懂色av一区二区三区在线播放 | av免费网址 | 亚洲国产黄色av | 天天草狠狠干 | 日韩三级在线 | 99re视频在线观看 | 日韩有码一区二区三区 | 午夜视频在线观看网址 | 在线观看电影av | 久久久久国产一区二区三区四区 | 免费成人毛片 | 国产一区二区三区四区三区四 |