|
給大家分享一個51單片機雙積分式AD轉換的Proteus仿真,下面是原理圖:
0.png (58.61 KB, 下載次數: 188)
下載附件
2016-10-12 15:55 上傳
0.png (54.91 KB, 下載次數: 167)
下載附件
2016-10-12 15:56 上傳
0.png (58.89 KB, 下載次數: 166)
下載附件
2016-10-12 15:54 上傳
單片機雙積分式AD轉換的所有資料下載(包含源程序和proteus仿真):
單片機雙積分式AD轉換電路源程序Proteus仿真.rar
(63.1 KB, 下載次數: 170)
2016-10-12 15:56 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
單片機源程序:
- /*-------------------------------------------------------------------
- LCD1602.c 1602用的函數
-
- 作者:liunian
- 郵箱:liunian_leon@sohu.com
- 日期:7.13
-
- 版本:V1.0 適合初學者使用
- -------------------------------------------------------------------*/
- #include<reg51.h>
- #include<absacc.h>
- #include<intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- sbit EN=P2^2; //使能信號
- sbit RW=P2^1; //讀寫控制信號
- sbit RS=P2^0; //數據命令選擇端口
- sbit P34=P3^4;
- sbit P35=P3^5;
- #define D_port P0 //傳送數據的端口設為P0,以上端口根據實際硬件電路圖可做修改
- uint ss,lo,loo;
- uchar kl = 0;
- unsigned char code love[]="Dual Integral AD";
- unsigned char code no[]=" ";
- unsigned char code time[]="0123456789ABCDEF:MinHour ";
- unsigned char code tin[]= "Vin:";
- unsigned char code tvref[]="Vref:";
- /****************1MS延時函數******************************/
- void delay(unsigned int n)
- {
- unsigned int i,j;
- for(j=n;j>0;j--)
- for(i=112;i>0;i--);
- }
- /*液晶***************查詢液晶是否忙*************************/
- void Checkbusy()
- {
-
- D_port=0xff; //P0全部置1,可以查詢判斷P0口狀態,讀取液晶的命令
- RS=0;
- RW=1;
- EN=1;
- _nop_(); //讀液晶命令時各控制位的狀態幾時序
- while(D_port&0x80) //判斷最高位狀態,最高位是液晶忙的狀態位
- {
- EN=0;
- _nop_();
- _nop_();
- EN=1;
- _nop_();
- _nop_();
- } //如果液晶忙,則循環查詢
- EN=0;
- }
- /*液晶***************寫數據到液晶***************************/
- D_write(uchar a)
- {
- Checkbusy(); //檢查忙標志位
- D_port=a;
- RS=1;
- RW=0;
- EN=1; //寫數據各控制位的值既對應的時序
- _nop_();
- _nop_();
- _nop_(); //發送數據,此處是發送到P0口,程序前已經定義
- EN=0;
- }
- /*液晶***************寫指令到液晶***************************/
- C_write(uchar a)
- {
- Checkbusy(); //檢查忙標志位
- D_port=a;
- RS=0;
- RW=0;
- EN=1; //寫指令各控制位的值既對應的時序
-
- _nop_();
- _nop_();
- _nop_(); //發送指令,此處是發送到P0口,程序前已經定義
- EN=0;
- }
- /*液晶**************液晶初始化******************************/
- Initial()
- {
- D_port=0;
- delay(20);
- C_write(0x38);
- delay(10);
- C_write(0x38);
- delay(10);
- C_write(0x38);
- delay(10);
- Checkbusy();
- C_write(0x38);
- Checkbusy();
- C_write(0x08); //關閉顯示
- Checkbusy();
- C_write(0x01); //清屏
- Checkbusy();
- C_write(0x06); //顯示光標右移設置
- Checkbusy();
- C_write(0x0c); //顯示開,光標不顯示,不閃爍
- delay(5);
- } //根據1602初始化的指令順序來初始化LCD,相關初始化步驟可查閱相關資料
- /*液晶**************設定顯示位置函數************************/
- setpos(uchar posx,uchar posy)
- {
- posx=posx&0xf; //將顯示在第幾位置轉為二十六進制,每行總共16個位置
- posy=posy&0x1; //設置顯示在第幾行
- C_write(posx|posy*0x40+0x80); //設置位置命令最高位必須為一,所以要加0x80
- }
- /*液晶**************顯示一個字符子程序**********************/
- displaychar(uchar x,uchar y,uchar a)
- {
- Checkbusy(); //檢查忙標志位
- setpos(x,y); //設置顯示位置
- D_write(a); //將要顯示的數據寫到液晶
- }
- /*液晶**************顯示一串字符串**************************/
- displaystring(uchar x,uchar y,unsigned char code *string)
- {
- uchar length=0; //定義一個字符串長度
- Checkbusy();
- while(string[length]!='\0') //字符串是以'\0'結束的,因此只要每結束就顯示下一字符
- {
- displaychar(x,y,string[length++]); //顯示一個字符子程序
- x++; //液晶顯示的位置+1
- }
- }
- /*液晶**************顯示個數**************************/
- void lcd_byte(unsigned char x, unsigned char y ,unsigned int byte_data) //以十進制的方式顯示一個字符變量
- {
- unsigned int temp_data;
- temp_data=byte_data/10000; //求萬位數
- displaychar(x+0,y,temp_data+48); //轉化為ASCII值再顯示
- temp_data=byte_data % 10000 /1000; //求千位數
- displaychar(x+1,y,temp_data+48); //轉化為ASCII值再顯示
-
- temp_data=byte_data%1000/100; //求百位數
- displaychar(x+2,y,temp_data+48); //轉化為ASCII值再顯示
-
- temp_data=byte_data%100/10; //求十位數
- displaychar(x+3,y,temp_data+48); //轉化為ASCII值再顯示
-
- temp_data=byte_data%10; //求個位數
- displaychar(x+4,y,temp_data+48); //轉化為ASCII再再顯示
- }
- void my_t0(void) interrupt 1 //定時器0中斷用于固定時間對輸入待測電壓進行積分
- {
- TR0 = 0; //T0中斷關
- P34=1; //選擇-2.5V基準
- TH0 = 0;
- TL0 = 0;
- //lo=lo+1;
- //TMOD=TMOD | 0x8;
- //TF0 = 0; //清除T0中斷標志
- TR0 = 1; //T0中斷開
- EX0 = 1; //INT0中斷開
- }
- void my_int0(void) interrupt 0 //外部中斷 用于反積分過程結束檢測
- {
- TR0 = 0; //T0中斷關
- TF0 = 0; //清除T0中斷標志
- EX0 = 0; //INT0中斷關
- ss = TH0 * 256 + TL0;
- P34=1; //選擇-2.5V基準
- // P35=1; //選擇放電
- TH0 = 0;
- TL0 = 0;
- kl = 0;
- }
- main()
- {
- Initial();
- P34=1; //選擇-2.5V基準
- //P35=1; //選擇放電
- displaystring( 0, 0, love);
- delay(500);
- displaystring( 0, 0, no);
- displaystring( 0, 1, tvref);
- EA = 1; //中斷開
- ET0 = 1; //定時計數0中斷開
- IP = 1; //定時0中斷最高優先級 =2
- TMOD = 1; //定時0模式1 2個16位定時/計數器
- TCON=0x00; //INT0負邊緣觸發或低電平觸發在此好象作用相同
- displaystring( 0, 0, tin);
- while(1)
- {
- if(kl==0)
- {
- P34=1; //選擇-2.5V基準
- //P35=1; //選擇放電
- delay(26);
- TMOD = 1;
- TH0 = 0x63;
- TL0 = 0xC0;
- //loo=loo+1;
- P34=0; //選擇輸入電壓基準
- //P35=0; //選擇測量
- kl = 1;
- TR0 = 1; //定時計數0起動
- TF0 = 0; //清除T0中斷標志
- }
- delay(500);
- //lo=ss*0.0773;
- loo=ss-lo;
- if(loo>32767)
- {loo=65535-loo;}
- lo=ss;
- lcd_byte(5,0,ss);
- lcd_byte(5,1,loo);
- //lcd_byte(11,1,loo);
- }
- }
復制代碼
|
評分
-
查看全部評分
|