|
這個程序也是在本論壇上找的,在使用ADC0832模塊讀取電壓值時,發(fā)現(xiàn)轉(zhuǎn)換的電壓值同電壓表顯示的有偏差,現(xiàn)在想通過修正使兩者基本一致,即不同的電壓范圍加上相應(yīng)的數(shù)字,條件如下:
1.AD值在0.2以下時不加;
2.大于0.2,小于1.0時加0.05;
3.大于1.0,小于3.0時加0.1
4.大于3.0,小于4.0時加0.13
5.大于4.0時,加0.16
還有一個需求:
電壓值在0.2以下或1.5-3.0范圍時點亮P3.0,其它的值均點亮P3.1。
感謝各位老師。
以下是目前使用的單片機程序:
- //-----------------------------------------------------------------
- // 說明: 調(diào)整VR1時,ADC0832將模擬電壓轉(zhuǎn)換為數(shù)字電壓顯示在1602液晶
- // 屏第0行,液晶屏第1行同時以進程條方式顯示當(dāng)前電壓大小.
- //
- //-----------------------------------------------------------------
- #include <reg51.h>
- #include <intrins.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- //ADC0832引腳定義
- sbit CS = P1^0; //片選線(電路中固定連接低電平)
- sbit CLK = P1^1; //時鐘線
- sbit DIO = P1^2; //數(shù)據(jù)線
- //LCD1602端口定義
- sbit RS = P2^5; //寄存器選擇
- sbit RW = P2^6; //讀寫控制
- sbit E = P2^7; //使能控制
- #define LCD_PORT P0 //液晶端口
- uchar Disp_Buff1[] = " VOLTAGE: 0.00V"; //數(shù)字電壓顯示緩沖
- uchar Disp_Buff2[16]; //進程條圖形顯示緩沖
- #define delay4us() { _nop_();_nop_();_nop_();_nop_();}
- //-----------------------------------------------------------------
- // 延時函數(shù)
- //-----------------------------------------------------------------
- void delay_ms(uint x)
- {
- uchar t; while(x--) for(t = 0; t < 120; t++);
- }
- //-----------------------------------------------------------------
- // 讀LCD忙狀態(tài)
- //-----------------------------------------------------------------
- bit Read_LCD_Busy_Flag()
- {
- uchar result;
- LCD_PORT=0xff; //液晶屏端口電平拉高
- RS=0;RW=1; //選擇命令寄存器,準(zhǔn)備讀
- E=1;delay4us(); result=P0; E=0; //下降沿讀命令寄存器
- return (result&0x80)? 1 : 0; //返回忙狀態(tài)
- }
- //-----------------------------------------------------------------
- // 寫LCD命令
- //-----------------------------------------------------------------
- void Write_LCD_Command(uchar cmd)
- {
- while(Read_LCD_Busy_Flag()); //液晶屏忙等待
- RS=0;RW=0; //選擇命令寄存器,準(zhǔn)備寫
- E=0; _nop_();_nop_();LCD_PORT=cmd; //數(shù)據(jù)送到液晶屏端口
- delay4us();E=1;delay4us();E=0; //寫入后禁止液晶屏
- }
- //-----------------------------------------------------------------
- // 寫LCD數(shù)據(jù)
- //-----------------------------------------------------------------
- void Write_LCD_Data(uchar dat)
- {
- while(Read_LCD_Busy_Flag()); //液晶屏忙等待
- RS=1;RW=0; //選擇數(shù)據(jù)寄存器,準(zhǔn)備寫
- E=0; LCD_PORT=dat; delay4us(); //數(shù)據(jù)送到液晶屏端口
- E=1;delay4us(); E=0; //寫入后禁止液晶屏
- }
- //-----------------------------------------------------------------
- // 在LCD指定行/列位置顯示字符串
- //-----------------------------------------------------------------
- void LCD_Show_String(uchar r,uchar c, char *s)
- {
- uchar i=0;
- uchar code DDRAM[]={0x80,0xc0}; //液晶屏上下兩行的DDRAM首地址
- Write_LCD_Command(DDRAM[r] | c); //設(shè)置顯示起始位置
- while(s[i] && i<16) Write_LCD_Data(s[i++]); //輸出顯示字符
- }
- //-----------------------------------------------------------------
- // LCD初始化
- //-----------------------------------------------------------------
- void LCD_Initialise()
- {
- Write_LCD_Command(0x38); delay_ms(1);
- Write_LCD_Command(0x0C); delay_ms(1);
- Write_LCD_Command(0x06); delay_ms(1);
- Write_LCD_Command(0x01); delay_ms(1);
- }
- //-----------------------------------------------------------------
- // 獲取AD轉(zhuǎn)換結(jié)果 ( 0通道 )
- //-----------------------------------------------------------------
- uchar Get_AD_Result()
- {
- uchar i,dat1=0,dat2=0;
- //使能ADC0832,時鐘線初始置低電平
- CS=0; CLK=0;
- //第1個時鐘脈沖上升沿之前,通過DIO選擇模式
- DIO=1; _nop_();_nop_();
- CLK=1; _nop_();_nop_();
- //第2個時鐘脈沖上升沿之前,通過DIO選擇模式
- //設(shè)DI=1選擇單端(SGL) 設(shè)DI=0 選擇分差(DIF)
- //下面設(shè)置的是單端模式
- CLK=0; DIO=1; _nop_();_nop_();
- CLK=1; _nop_();_nop_();
- //第2個時鐘脈沖上升沿之前,設(shè)DI=0/1,分別對應(yīng)選擇CH0/CH1
- CLK=0; DIO=0; _nop_();_nop_();
- CLK=1; _nop_();_nop_();
- //第3個時鐘脈沖下升沿之后置DI=1,釋放數(shù)據(jù)線,準(zhǔn)備接收(設(shè)置原理可參考第一章端口說明)
- //P1端口讀取數(shù)據(jù)時需要先寫1,否則總線將出現(xiàn)邏輯沖突(黃色方塊閃爍)
- CLK=0; DIO=1; _nop_();_nop_();
- //根據(jù)時序圖可知,在正式讀取轉(zhuǎn)換數(shù)據(jù)之前,此時的D0將固定輸出0
- //P3=(uchar)DIO;
- //第4~11,共8個下降沿讀數(shù)據(jù)(MSB-LSB)
- for(i=0;i<8;i++)
- {
- CLK=1; _nop_();_nop_();
- CLK=0; _nop_();_nop_();
- dat1<<=1;
- if(DIO)
- dat1=dat1+0x01;
- }
- //第11~18,共8個下降沿讀數(shù)據(jù)(LSB——MSB)
- for(i=0;i<8;i++)
- {
- dat2>>=1;
- if(DIO)
- dat2=dat2+0x80;
- CLK=1; _nop_();_nop_();
- CLK=0; _nop_();_nop_();
- }
- CS=1; //禁止ADC0832
- //如果MSB——LSB和LSB——MSB讀取的結(jié)果相同則返回讀取的結(jié)果,否則返回0
- if(dat1==dat2)
- return dat1;
- return 0x00;
- }
- //-----------------------------------------------------------------
- // 主程序
- //-----------------------------------------------------------------
- void main()
- {
- uchar AD; uint d; //注意d的類型為uint
- LCD_Initialise(); //初始化LCD
- while(1)
- {
- AD=Get_AD_Result(); //獲取A/D轉(zhuǎn)換值
- //根據(jù)四舍五入法計算電壓值(放大100倍以便分解)
- d=AD*500.0*2/511.0;
- //根據(jù)舍尾取整數(shù)計算電壓值(放大100倍以便分解)
- //將d = AD*500.0/256;
- //將AD轉(zhuǎn)換后得到數(shù)據(jù)分解為三個數(shù)位
- Disp_Buff1[11] = d / 100 +'0';
- Disp_Buff1[13] = d / 10 %10 +'0';
- Disp_Buff1[14] = d % 10 +'0';
- LCD_Show_String(0,0,Disp_Buff1);
- //將模數(shù)值折算為實心方塊及空心方框字符個數(shù),控制進程條圖形顯示
- }
- }
復(fù)制代碼 |
|