時隔一年,pcb版1.8寸數碼管時鐘2.0版出爐了,平時帶娃上班沒時間,所以久了點。(老版本沒上傳,這次上傳看看)
去年做的pcb時自己學protel99畫的,本想找淘寶的,pcb廠家說不帶畫,于是找帶畫的,可一個種帶畫收費800塊,覺得不難,所以一氣之下自己自學了。現在一年沒動,忘記好多,在3231芯片畫封裝的時候沒實物測量,直接上下兩排引腳距離寫錯了,本來9mm寫成5了,板子到手才發現,幸虧家里有熱風槍,所以把3231的引腳向里彎后用風槍焊,電烙鐵是不行了。所以PCB就不發出來了,有興趣的朋友可自己畫。
之前pcb版的秒用的是led,這次直接用數碼管的點表示秒。
之前的DS3231直接用5v電源供電,發現誤差大,這次添加3.3v穩壓管后正常。
之前數碼管使用MAX7219驅動4位共陰數碼管,雖然芯片有調光功能,但使用中發現經常死機不動或黑屏,現在直接使用PNP三極管驅動4位共陽數碼管+AD功能光控。
功能:
1、使用STC12C5A60S2 AD功能檢測環境光線控制數碼管亮暗。(60K太大覺得浪費的朋友可換小容量的芯片,我是本著價格差距不大,情愿容量大的想法所以用60s2)
2、有按鍵和紅外遙控功能(正面為了美觀。實測紅外接收頭在反面,遙控器在正面也能接收信號)
3、采用DS3231時鐘芯片,年誤差+-2min
4、時鐘芯片電池使用LIR系列可充電紐扣電池(這里用的LIR1220,可換LIR2032等更大容量電池)
5、由于給老年人使用,所以沒設鬧鐘功能,但引腳以連,可在程序里自行添加。
6、目前為止1.8寸是最大數碼管(5V驅動里),更大的數碼管需要>=12V電壓供電,芯片驅動,電路比較麻煩。所以這里使用1.8寸數碼管。
7、由于畫線路圖時數碼管標號A~DP對應的管腳寫反了,PCB文件沒細看就發廠商制版了,所以程序中數碼管顯示數組另外寫了,常用如下:
uchar code table[]= //共陽數碼管編碼0~F
{0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,
0xc6,0xc0,0x86,0x8e};
制作出來的實物圖如下:
IMG20180923160322.jpg (3.2 MB, 下載次數: 82)
下載附件
2018-9-23 16:08 上傳
IMG20180923160251.jpg (5.17 MB, 下載次數: 64)
下載附件
2018-9-23 16:08 上傳
IMG20180923155932.jpg (3.6 MB, 下載次數: 72)
下載附件
2018-9-23 16:08 上傳
IMG20180923160021.jpg (5.49 MB, 下載次數: 86)
下載附件
2018-9-23 16:08 上傳
IMG20180923160014.jpg (5.18 MB, 下載次數: 78)
下載附件
2018-9-23 16:08 上傳
IMG20180923155842.jpg (4.19 MB, 下載次數: 75)
下載附件
2018-9-23 16:08 上傳
電路原理圖如下:
0.png (128.03 KB, 下載次數: 74)
下載附件
2018-9-23 16:45 上傳
單片機源程序如下:
- /*****************************************************************************************************
- *******************************************頭文件與宏定義*********************************************
- *****************************************************************************************************/
- #include <STC12C5A60S2.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- /*****************************************************************************************************
- ***********************************************ADC定義************************************************
- *****************************************************************************************************/
- sfr ADC_LOW2 = 0xBE; //ADC低2位結果
- #define ADC_POWER 0x80 //ADC電源控制位
- #define ADC_FLAG 0x10 //ADC完成標志
- #define ADC_START 0x08 //ADC起始控制位
- #define ADC_SPEEDLL 0x00 //540個時鐘
- #define ADC_SPEEDL 0x20 //360個時鐘
- #define ADC_SPEEDH 0x40 //180個時鐘
- #define ADC_SPEEDHH 0x60 //90個時鐘
- /*****************************************************************************************************
- ********************************************紅外遙控定義**********************************************
- *****************************************************************************************************/
- #define Imax 14000
- #define Imin 8000
- #define Inum1 1450
- #define Inum3 3000
- #define Inum2 700
- uchar f;
- uchar IrOK;
- unsigned long m,Tc;
- uchar Im[4]={0x00,0x00,0x00,0x00};
- /*****************************************************************************************************
- **********************************************DS3231定義**********************************************
- *****************************************************************************************************/
- uchar RTC_Data[7];
- uchar RTC_Data1[7];
- uchar RTC_Set_ID;
- code uchar rtc_address[7]={0x00,0x01,0x02,0x04,0x05,0x03,0x06};
- /*****************************************************************************************************
- **********************************************標志位定義**********************************************
- *****************************************************************************************************/
- bit T0_Flag; //定時器0標志位
- bit laba_flag; //蜂鳴器標志位
- bit set_flag; //設置顯示標志位
- bit RTC_Save_Flag; //設置時間標志位
- bit gk; //光控標志位
- /*****************************************************************************************************
- **********************************************管腳定義************************************************
- *****************************************************************************************************/
- sbit IIC_SCL=P3^6; //DS3231_SCL
- sbit IIC_SDA=P3^5; //DS3231_SDA
- sbit hongwai=P3^3; //紅外接收數據輸入端
- sbit key1=P2^0; //設置鍵
- sbit key2=P2^1; //加鍵
- sbit key3=P2^2; //減鍵
- sbit key4=P2^3; //確定鍵
- //sbit key5=P2^4; //PWM鍵
- sbit key6=P2^5; //光控鍵
- sbit laba=P3^4; //喇叭輸出端
- sbit D1=P1^3; //數碼管位碼
- sbit D2=P1^2; //數碼管位碼
- sbit D3=P1^1; //數碼管位碼
- sbit D4=P1^0; //數碼管位碼
- int ld; //光控ADC用
- uint temp[3]; //光控ADC用
- uchar code table[]={0x03,0x9f,0x25,0x0d, //共陽數碼管不帶小數點
- 0x99,0x49,0x41,0x1f,
- 0x01,0x09,0x11,0xc1,
- 0x63,0x85,0x61,0x71};
- uchar code table1[]={0x02,0x9e,0x24,0x0c, //共陽數碼管帶小數點
- 0x98,0x48,0x40,0x1e,
- 0x00,0x08,0x10,0xc0,
- 0x62,0x84,0x60,0x70};
- /*****************************************************************************************************
- **********************************************延時函數************************************************
- *****************************************************************************************************/
- void Delay_xms(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<112;j++);
- }
- void Delayms(uint t)
- {
- uchar i;
- while(t--)
- for(i=0;i<123;i++);
- }
- /*****************************************************************************************************
- **********************************************顯示函數************************************************
- *****************************************************************************************************/
- void display()
- {
- D1=0;
- P0=table[RTC_Data[2]/10];
- Delayms(4);
- P0=0xff;
- D1=1;
- D2=0;
- if(RTC_Data[0]/1%2==0) P0=table[RTC_Data[2]%10];
- else P0=table1[RTC_Data[2]%10];
- Delayms(4);
- P0=0xff;
- D2=1;
- D3=0;
- if(RTC_Data[0]/1%2==0) P0=table[RTC_Data[1]/10];
- else P0=table1[RTC_Data[1]/10];
- Delayms(4);
- P0=0xff;
- D3=1;
- D4=0;
- P0=table[RTC_Data[1]%10];
- Delayms(4);
- P0=0xff;
- D4=1;
- }
- /*****************************************************************************************************
- **************************************顯示小時函數*****設置用*****************************************
- *****************************************************************************************************/
- void display_set_shi()
- {
- D1=0;
- P0=0x91;
- Delayms(2);
- P0=0xff;
- D1=1;
- D2=0;
- P0=0xff;
- Delayms(2);
- P0=0xff;
- D2=1;
- D3=0;
- P0=table[RTC_Data[2]/10];
- Delayms(2);
- P0=0xff;
- D3=1;
- D4=0;
- P0=table[RTC_Data[2]%10];
- Delayms(2);
- P0=0xff;
- D4=1;
- }
- /*****************************************************************************************************
- **************************************顯示分鐘函數*****設置用*****************************************
- *****************************************************************************************************/
- void display_set_fen()
- {
- D1=0;
- P0=table[15];
- Delayms(2);
- P0=0xff;
- D1=1;
- D2=0;
- P0=0xff;
- Delayms(2);
- P0=0xff;
- D2=1;
- D3=0;
- P0=table[RTC_Data[1]/10];
- Delayms(2);
- P0=0xff;
- D3=1;
- D4=0;
- P0=table[RTC_Data[1]%10];
- Delayms(2);
- P0=0xff;
- D4=1;
- }
- /*****************************************************************************************************
- ***************************************顯示秒函數*****設置用******************************************
- *****************************************************************************************************/
- void display_set_miao()
- {
- D1=0;
- P0=0x49;
- Delayms(2);
- P0=0xff;
- D1=1;
- D2=0;
- P0=0xff;
- Delayms(2);
- P0=0xff;
- D2=1;
- D3=0;
- P0=table[RTC_Data[0]/10];
- Delayms(2);
- P0=0xff;
- D3=1;
- D4=0;
- P0=table[RTC_Data[0]%10];
- Delayms(2);
- P0=0xff;
- D4=1;
- }
- /*****************************************************************************************************
- ********************************************鍵值處理函數**********************************************
- *****************************************************************************************************/
- void KeyDataProcess()
- {
- if(key1==0)// 設置
- {
- if(key1==0)
- {
- Delay_xms(20);
- while(!key1);
- laba_flag=1; //蜂鳴器響一聲
- set_flag=0;
- RTC_Set_ID++;
- if(RTC_Set_ID>=4)
- RTC_Set_ID=1;
- }
- }
- if(key2==0)//+
- {
- if(key2==0)
- {
- Delay_xms(20);
- while(!key2);
- laba_flag=1; //蜂鳴器響一聲
- set_flag=0;
- if(RTC_Set_ID==1)
- {
- RTC_Data[2]++;
- if(RTC_Data[2]>23)
- RTC_Data[2]=0;
- display_set_shi();
- }
- else if(RTC_Set_ID==2)
- {
- RTC_Data[1]++;
- if(RTC_Data[1]>59)
- RTC_Data[1]=0;
- display_set_fen();
- }
- else if(RTC_Set_ID==3)
- {
- RTC_Data[0]++;
- if(RTC_Data[0]>59)
- RTC_Data[0]=0;
- display_set_miao();
- }
- }
- }
- if(key3==0)//-
- {
- if(key3==0)
- {
- Delay_xms(20);
- while(!key3);
- laba_flag=1; //蜂鳴器響一聲
- set_flag=0;
- if(RTC_Set_ID==1)
- {
- RTC_Data[2]--;
- if(RTC_Data[2]==-1)
- RTC_Data[2]=23;
- display_set_shi();
- }
- else if(RTC_Set_ID==2)
- {
- RTC_Data[1]--;
- if(RTC_Data[1]==-1)
- RTC_Data[1]=59;
- display_set_fen();
- }
- else if(RTC_Set_ID==3)
- {
- RTC_Data[0]--;
- if(RTC_Data[0]==-1)
- RTC_Data[0]=59;
- display_set_miao();
- }
- }
- }
- if(key4==0)//ok
- {
- if(key4==0)
- {
- Delay_xms(20);
- while(!key4);
- laba_flag=1; //蜂鳴器響一聲
- set_flag=1;
- RTC_Save_Flag=1;
- }
- }
- if(key6==0)//gk
- {
- if(key6==0)
- {
- Delay_xms(20);
- while(!key6);
- laba_flag=1; //蜂鳴器響一聲
- set_flag=1;
- gk=!gk;
- }
- }
- //以下為紅外遙控部分
- if(IrOK==1) //設置鍵
- {
- if(Im[2]==0x0d)
- {
- laba_flag=1; //蜂鳴器響一聲
- set_flag=0;
- RTC_Set_ID++;
- if(RTC_Set_ID>=4)
- RTC_Set_ID=1;
- }
- else if(Im[2]==0x40)//遙控器+鍵
- {
- laba_flag=1; //蜂鳴器響一聲
- set_flag=0;
- if(RTC_Set_ID==1)
- {
- RTC_Data[2]++;
- if(RTC_Data[2]>23)
- RTC_Data[2]=0;
- display_set_shi();
- }
- else if(RTC_Set_ID==2)
- {
- RTC_Data[1]++;
- if(RTC_Data[1]>59)
- RTC_Data[1]=0;
- display_set_fen();
- }
- else if(RTC_Set_ID==3)
- {
- RTC_Data[0]++;
- if(RTC_Data[0]>59)
- RTC_Data[0]=0;
- display_set_miao();
- }
- }
- else if(Im[2]==0x19)//遙控器-鍵
- {
- laba_flag=1; //蜂鳴器響一聲
- set_flag=0;
- if(RTC_Set_ID==1)
- {
- RTC_Data[2]--;
- if(RTC_Data[2]==-1)
- RTC_Data[2]=23;
- display_set_shi();
- }
- else if(RTC_Set_ID==2)
- {
- RTC_Data[1]--;
- if(RTC_Data[1]==-1)
- RTC_Data[1]=59;
- display_set_fen();
- }
- else if(RTC_Set_ID==3)
- {
- RTC_Data[0]--;
- if(RTC_Data[0]==-1)
- RTC_Data[0]=59;
- display_set_miao();
- }
- }
- else if(Im[2]==0x15)//遙控器播放鍵
- {
- laba_flag=1; //蜂鳴器響一聲
- set_flag=1;
- RTC_Save_Flag=1;
- }
- else if(Im[2]==0x47)//遙控器MENU鍵
- {
- laba_flag=1; //蜂鳴器響一聲
- set_flag=1;
- gk=!gk;
- }
- IrOK=0;
- }
- }
- /*****************************************************************************************************
- *****************************************DS3231時鐘函數***********************************************
- *****************************************************************************************************/
- void delay_IIC()
- {
- _nop_();_nop_();_nop_();_nop_();//IIC總線限速延時函數。該函數是空函數,延時4個機器周期。
- }
- void IIC_Init() //IIC總線初始化函數
- {
- IIC_SDA=1;//釋放IIC總線的數據線。
- IIC_SCL=1;//釋放IIC總線的時鐘線。
- }
- void IIC_start() //IIC總線產生起始信號函數
- {
- IIC_SDA=1;//拉高數據線
- IIC_SCL=1;//拉高時鐘線
- delay_IIC();
- IIC_SDA=0;//在時鐘線為高電平時,拉低數據線,產生起始信號。
- delay_IIC();
- IIC_SCL=0;//拉低時鐘線
- }
- void IIC_stop()//IIC總線產生停止信號函數
- {
- IIC_SDA=0;//拉低數據線
- delay_IIC();
- IIC_SCL=1;//拉高時鐘線。
- delay_IIC();
- IIC_SDA=1;//時鐘時線為高電平時,拉高數據線,產生停止信號。
- delay_IIC();
- }
- bit IIC_Tack() //接收應答信號函數
- {
- bit ack;//定義一個位變量,來暫存應答狀態。
- IIC_SDA=1;//釋放數據總線,準備接收應答信號。
- delay_IIC();
- IIC_SCL=1;//拉高時鐘線。
- delay_IIC();
- ack=IIC_SDA;//讀取應答信號的狀態。
- delay_IIC();
- IIC_SCL=0;//拉低時鐘線。
- delay_IIC();
- return ack;//返回應答信號的狀態,0表示應答,1表示非應答。
- }
- void IIC_write_byte(uchar Data)//向IIC總線寫入一個字節的數據函數
- {
- uchar i;
- for(i=0;i<8;i++)//有8位數據
- {
- if(Data&0x80)
- IIC_SDA=1;//寫最高位的數據
- else
- IIC_SDA = 0;
- delay_IIC();
- IIC_SCL=1; //拉高時鐘線,將數寫入到設備中。
- delay_IIC();
- IIC_SCL=0;//拉低時鐘線,允許改變數據線的狀態
- delay_IIC();
- Data=Data<<1;//數據左移一位,把次高位放在最高位,為寫入次高位做準備
- }
- }
- uchar IIC_read_byte()//從IIC總線讀取一個字節的數據函數
- {
- uchar i;
- uchar Data; //定義一個緩沖寄存器。
- for(i=0;i<8;i++)//有8位數據
- {
- IIC_SCL=1;//拉高時鐘線,為讀取下一位數據做準備。
- delay_IIC();
- Data=Data<<1;//將緩沖字節的數據左移一位,準備讀取數據。
- delay_IIC();
-
- if(IIC_SDA)//如果數據線為高平電平。
- Data=Data|0x01;//則給緩沖字節的最低位寫1。
- IIC_SCL=0;//拉低時鐘線,為讀取下一位數據做準備。
- delay_IIC();
- }
- return Data;//返回讀取的一個字節數據。
- }
- void IIC_single_byte_write(uchar Waddr,uchar Data) //向任意地址寫入一個字節數據函數
- {
- IIC_start();//產生起始信號
- IIC_write_byte(0xd0);//寫入設備地址(寫)
- IIC_Tack();//等待設備的應答
- IIC_write_byte(Waddr);//寫入要操作的單元地址。
- IIC_Tack();//等待設備的應答。
- IIC_write_byte(Data);//寫入數據。
- IIC_Tack();//等待設備的應答。
- IIC_stop();//產生停止符號。
- }
- uchar IIC_single_byte_read(uchar Waddr) //從任意地址讀取一個字節數據函數
- {
- uchar Data;//定義一個緩沖寄存器。
- IIC_start();//產生起始信號
- IIC_write_byte(0xd0);//寫入設備地址(寫)
- IIC_Tack();//等待設備的應答
- IIC_write_byte(Waddr);//寫入要操作的單元地址。
- IIC_Tack();//等待設備的應答。
- IIC_stop();//產生停止符號。
- IIC_start();//產生起始信號
- IIC_write_byte(0xd1);//寫入設備地址(寫)
- IIC_Tack();//等待設備的應答
- Data=IIC_read_byte();//寫入數據。
- delay_IIC();
- IIC_stop();//產生停止符號。
- return Data;//返回讀取的一個字節數據。
- }
- /*****************************************************************************************************
- ********************************************時鐘寫入函數**********************************************
- *****************************************************************************************************/
- void Set_RTC()
- {
- uchar i,tmp;
- for(i=0;i<7;i++)
- {
- tmp=RTC_Data[i]/10;
- RTC_Data1[i]=RTC_Data[i]%10;
- RTC_Data1[i]=RTC_Data1[i]+tmp*16;
- }
- for(i=0;i<7;i++)
- {
- IIC_single_byte_write(rtc_address[i],RTC_Data1[i]);
- }
- IIC_single_byte_write(0x0e,0x0c);
- }
- /*****************************************************************************************************
- *******************************************時鐘初始化函數*********************************************
- *****************************************************************************************************/
- void DS3231_Init()
- {
- IIC_SDA=1;
- IIC_SCL=1;
- IIC_single_byte_write(0x0e,0x0c);
- }
- /*****************************************************************************************************
- ********************************************時鐘讀取函數**********************************************
- *****************************************************************************************************/
- void Read_RTC()
- {
- uchar i,tmp,tmp1,tmp2;
- for(i=0;i<7;i++)
- {
- tmp = IIC_single_byte_read(rtc_address[i]);
- tmp1 = tmp/16;
- tmp2 = tmp%16;
- RTC_Data[i]=tmp1*10+tmp2;
- }
- }
- void Ram_init()
- {
- Read_RTC(); //讀取 秒分時日月周年
- if((!RTC_Data[6])&&(!RTC_Data[4])&&(!RTC_Data[3])&&(!RTC_Data[2])&&(!RTC_Data[1])&&(!RTC_Data[0]))
- {
- RTC_Data[0]=0; //秒 //秒分時日月周年 最低位讀寫位
- RTC_Data[1]=0; //分
- RTC_Data[2]=12; //時
- RTC_Data[3]=3; //日
- RTC_Data[4]=11; //月
- RTC_Data[5]=2; //周
- RTC_Data[6]=15; //年
- Set_RTC(); //寫入 秒分時日月周年
- }
- RTC_Set_ID=0;
- }
- /*****************************************************************************************************
- *******************************************ADC初始化函數**********************************************
- *****************************************************************************************************/
- void InitADC()
- {
- P1ASF = 0x80; //Open channels ADC function 1000 0000 p1.7使用AD功能
- ADC_RES = 0;
- ADC_LOW2 = 0;
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
- }
- /*****************************************************************************************************
- *********************************************ADC處理函數**********************************************
- *****************************************************************************************************/
- void GetADCResult(unsigned char ch,unsigned int *value)
- {
- ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
- _nop_(); //Must wait before inquiry
- _nop_();
- _nop_();
- _nop_();
- _nop_(); //Must wait before inquiry
- _nop_();
- while(!(ADC_CONTR & ADC_FLAG));//Wait complete flag
- ADC_CONTR &= ~ADC_FLAG; //Close ADC
- *value = 0;
- *value = ADC_RES;
- *value = ((*value)*4 + ADC_LOW2);
- }
- /*****************************************************************************************************
- **********************************************走時函數************************************************
- *****************************************************************************************************/
- void Time_Fun()
- {
- static uchar T10Ms_Cnt=0,T200Ms_Cnt=0;
- static uchar Buzz_On_Cnt=0,RTC_Save_Cnt=0;
-
- T10Ms_Cnt++;
- if(T10Ms_Cnt>=5)
- {
- T10Ms_Cnt=0;
- KeyDataProcess();
- if(laba_flag)
- {
- Buzz_On_Cnt++;
- if(Buzz_On_Cnt>=10)
- {
- laba_flag=0;
- Buzz_On_Cnt=0;
- }
- }
- if(RTC_Save_Flag) //按確定鍵RTC_Save_Flag=1,保存數據
- {
- RTC_Save_Cnt++;
- if(RTC_Save_Cnt>=50)
- {
- RTC_Save_Cnt=0;
- RTC_Save_Flag=0;
- RTC_Set_ID=0;
- Set_RTC();
- }
- }
- }
- T200Ms_Cnt++;
- if(T200Ms_Cnt>=5)
- {
- T200Ms_Cnt=0;
- if(!RTC_Set_ID)
- Read_RTC();
- GetADCResult(7,&temp[2]);
- if(gk==1) //開光控
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
1.8CLOCK.rar
(56.9 KB, 下載次數: 261)
2018-9-23 16:09 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|