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