一個課程設計,方波發生器的,數碼管顯示
全部文件下載:
程序.zip
(47.9 KB, 下載次數: 17)
2016-4-12 15:25 上傳
點擊文件名下載附件
方波發生器 下載積分: 黑幣 -5
- #include "reg52.h"
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define PCF8591 0x90 //PCF8591 地址
- #define THCO 0xee //11.0592MHZ晶振
- #define TLCO 0x00 //定時5ms時間常數值
- #define NOP() _nop_() /* 定義空指令 */
- unsigned char cnt=0,hz=10;
- float fd=1.0,t,a;
- unsigned char Data_Buffer[4]={1,2,3,4};
- uchar code Duan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76};
- sbit P24=P2^4; //四個數碼管的位碼口定義
- sbit P25=P2^5;
- sbit P26=P2^6;
- sbit P27=P2^7;
- sbit P20=P2^0; //四個獨立按鍵
- sbit P21=P2^1;
- sbit P22=P2^2;
- sbit P32=P3^2;
- bit flag=0;
- sbit P14=P1^4;
- sbit SCL=P3^6; //I2C 時鐘
- sbit SDA=P3^7; //I2C 數據
- bit ack; /*應答標志位*/
-
- /*******************************************************************
- 起動總線函數
- 函數原型: void Start_I2c();
- 功能: 啟動I2C總線,即發送I2C起始條件.
- ********************************************************************/
- void Start_I2c()
- {
- SDA=1; /*發送起始條件的數據信號*/
- NOP();
- SCL=1;
- NOP(); /*起始條件建立時間大于4.7us,延時*/
- NOP();
- NOP();
- NOP();
- NOP();
- SDA=0; /*發送起始信號*/
- NOP(); /* 起始條件鎖定時間大于4μs*/
- NOP();
- NOP();
- NOP();
- NOP();
- SCL=0; /*鉗住I2C總線,準備發送或接收數據 */
- NOP();
- NOP();
- }
- /*******************************************************************
- 結束總線函數
- 函數原型: void Stop_I2c();
- 功能: 結束I2C總線,即發送I2C結束條件.
- ********************************************************************/
- void Stop_I2c()
- {
- SDA=0; /*發送結束條件的數據信號*/
- NOP(); /*發送結束條件的時鐘信號*/
- SCL=1; /*結束條件建立時間大于4μs*/
- NOP();
- NOP();
- NOP();
- NOP();
- NOP();
- SDA=1; /*發送I2C總線結束信號*/
- NOP();
- NOP();
- NOP();
- NOP();
- }
- /*******************************************************************
- 字節數據發送函數
- 函數原型: void SendByte(UCHAR c);
- 功能: 將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
- 此狀態位進行操作.(不應答或非應答都使ack=0)
- 發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
- ********************************************************************/
- void SendByte(unsigned char c)
- {
- unsigned char BitCnt;
-
- for(BitCnt=0;BitCnt<8;BitCnt++) /*要傳送的數據長度為8位*/
- {
- if((c<<BitCnt)&0x80)SDA=1; /*判斷發送位*/
- else SDA=0;
- NOP();
- SCL=1; /*置時鐘線為高,通知被控器開始接收數據位*/
- NOP();
- NOP(); /*保證時鐘高電平周期大于4μs*/
- NOP();
- NOP();
- NOP();
- SCL=0;
- }
-
- NOP();
- NOP();
- SDA=1; /*8位發送完后釋放數據線,準備接收應答位*/
- NOP();
- NOP();
- SCL=1;
- NOP();
- NOP();
- NOP();
- if(SDA==1)ack=0;
- else ack=1; /*判斷是否接收到應答信號*/
- SCL=0;
- NOP();
- NOP();
- }
- /*******************************************************************
- 字節數據接收函數
- 函數原型: UCHAR RcvByte();
- 功能: 用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
- 發完后請用應答函數應答從機。
- ********************************************************************/
- unsigned char RcvByte()
- {
- unsigned char retc;
- unsigned char BitCnt;
-
- retc=0;
- SDA=1; /*置數據線為輸入方式*/
- for(BitCnt=0;BitCnt<8;BitCnt++)
- {
- NOP();
- SCL=0; /*置時鐘線為低,準備接收數據位*/
- NOP();
- NOP(); /*時鐘低電平周期大于4.7μs*/
- NOP();
- NOP();
- NOP();
- SCL=1; /*置時鐘線為高使數據線上數據有效*/
- NOP();
- NOP();
- retc=retc<<1;
- if(SDA==1)retc=retc+1; /*讀數據位,接收的數據位放入retc中 */
- NOP();
- NOP();
- }
- SCL=0;
- NOP();
- NOP();
- return(retc);
- }
- /********************************************************************
- 應答子函數
- 函數原型: void Ack_I2c(bit a);
- 功能: 主控器進行應答信號(可以是應答或非應答信號,由位參數a決定)
- ********************************************************************/
- void Ack_I2c(bit a)
- {
-
- if(a==0)SDA=0; /*在此發出應答或非應答信號 */
- else SDA=1;
- NOP();
- NOP();
- NOP();
- SCL=1;
- NOP();
- NOP(); /*時鐘低電平周期大于4μs*/
- NOP();
- NOP();
- NOP();
- SCL=0; /*清時鐘線,鉗住I2C總線以便繼續接收*/
- NOP();
- NOP();
- }
- bit ISendByte(unsigned char sla,unsigned char c);
- unsigned char IRcvByte(unsigned char sla);
- void delay(unsigned int t);
- bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val);
- /******************************/
- void main(void) //主程序
- {
-
- TMOD=0x11; //設置定時器0工作模式,16位計數模式
- TH0=THCO;
- TL0=TLCO;
- TR0=1; //啟動定時器
- ET0=1; //使能定時器中斷
- EA=1; //開總中斷
- P14=0;
- while(1)
- {
-
- if(P20==0&&hz<90)
- {
- delay(7000);
- if(P20==0)
- {
- hz++;
- }
- }
- if(P21==0&&hz>10)
- {
- delay(7000);
- if(P21==0)
- {
- hz--;
- }
- }
- if(P22==0&&fd<=4)
- {
- delay(7000);
- if(P22==0)
- {
- fd=fd+0.1;
- }
- }
- if(P32==0&&fd>0)
- {
- delay(7000);
- if(P32==0)
- {
- fd=fd-0.1;
- }
- }
- a=fd*51;
- if(flag==1)
- {
- flag=0;
- cnt++;
- if(cnt%2==1) DACconversion(PCF8591,0x40,a);
- else DACconversion(PCF8591,0x40,0);
- Data_Buffer[0]=hz/10;
- Data_Buffer[1]=hz%10;
- Data_Buffer[2]=(int)fd;
- Data_Buffer[3]=(int)(fd*10)%10;
- }
- }
- }
- void timer0() interrupt 1 //定時器中斷服務子程序
- {
- static unsigned int count=0;//軟計時變量定義
- static unsigned char Bit=0; //靜態變量,退出程序后,值保留
-
- TH0=THCO;
- TL0=TLCO;
-
- Bit++;
- if(Bit>=4)Bit=0;
- P2|=0xf0; //先關位碼
- P0=Duan[Data_Buffer[Bit]]; //開段碼
- if(Bit==2)P0|=0x80;
- switch(Bit) //送位碼
- {
- case 0: P24=0;break;
- case 1: P25=0;break;
- case 2: P26=0;break;
- case 3: P27=0;break;
- }
- t=(float)1/hz;
- t=t/2;
- t=t*1000;
- count++;
- if(count>=(t/5)) //半個周期時間到
- {
- count=0;
- flag=1;
- }
- }
- /*******************************************************************
- DAC 變換, 轉化函數
- *******************************************************************/
- bit DACconversion(unsigned char sla,unsigned char c, unsigned char Val)
- {
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(c); //發送控制字節
- if(ack==0)return(0);
- SendByte(Val); //發送DAC的數值
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- return(1);
- }
- /*******************************************************************
- ADC發送字節[命令]數據函數
- *******************************************************************/
- bit ISendByte(unsigned char sla,unsigned char c)
- {
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(c); //發送數據
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- return(1);
- }
- void delay(unsigned int t)
- {
- while(t--);
- }
復制代碼
|