最近在學習ADC0832這款芯片,雖然說型號老了點,但是學懂了這個,其他AD芯片就不是這么難了。寫了程序, 給大家學習參考!
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
仿真結果.jpg (285.59 KB, 下載次數: 32)
下載附件
2023-12-9 10:57 上傳
單片機源程序如下:
- //-----------------------------------------------------------------
- // 說明: 調整VR1時,ADC0832將模擬電壓轉換為數字電壓顯示在1602液晶
- // 屏第0行,液晶屏第1行同時以進程條方式顯示當前電壓大小.
- //
- //-----------------------------------------------------------------
- #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; //數據線
- //LCD1602端口定義
- sbit RS = P2^0; //寄存器選擇
- sbit RW = P2^1; //讀寫控制
- sbit E = P2^2; //使能控制
- #define LCD_PORT P0 //液晶端口
- uchar Disp_Buff1[] = " VOLTAGE: 0.00V"; //數字電壓顯示緩沖
- uchar Disp_Buff2[16]; //進程條圖形顯示緩沖
- #define delay4us() { _nop_();_nop_();_nop_();_nop_();}
- //-----------------------------------------------------------------
- // 延時函數
- //-----------------------------------------------------------------
- void delay_ms(uint x)
- {
- uchar t; while(x--) for(t = 0; t < 120; t++);
- }
- //-----------------------------------------------------------------
- // 讀LCD忙狀態
- //-----------------------------------------------------------------
- bit Read_LCD_Busy_Flag()
- {
- uchar result;
- LCD_PORT=0xff; //液晶屏端口電平拉高
- RS=0;RW=1; //選擇命令寄存器,準備讀
- E=1;delay4us(); result=P0; E=0; //下降沿讀命令寄存器
- return (result&0x80)? 1 : 0; //返回忙狀態
- }
- //-----------------------------------------------------------------
- // 寫LCD命令
- //-----------------------------------------------------------------
- void Write_LCD_Command(uchar cmd)
- {
- while(Read_LCD_Busy_Flag()); //液晶屏忙等待
- RS=0;RW=0; //選擇命令寄存器,準備寫
- E=0; _nop_();_nop_();LCD_PORT=cmd; //數據送到液晶屏端口
- delay4us();E=1;delay4us();E=0; //寫入后禁止液晶屏
- }
- //-----------------------------------------------------------------
- // 寫LCD數據
- //-----------------------------------------------------------------
- void Write_LCD_Data(uchar dat)
- {
- while(Read_LCD_Busy_Flag()); //液晶屏忙等待
- RS=1;RW=0; //選擇數據寄存器,準備寫
- E=0; LCD_PORT=dat; delay4us(); //數據送到液晶屏端口
- 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); //設置顯示起始位置
- 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轉換結果 ( 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選擇模式
- //設DI=1選擇單端(SGL) 設DI=0 選擇分差(DIF)
- //下面設置的是單端模式
- CLK=0; DIO=1; _nop_();_nop_();
- CLK=1; _nop_();_nop_();
- //第2個時鐘脈沖上升沿之前,設DI=0/1,分別對應選擇CH0/CH1
- CLK=0; DIO=0; _nop_();_nop_();
- CLK=1; _nop_();_nop_();
- //第3個時鐘脈沖下升沿之后置DI=1,釋放數據線,準備接收(設置原理可參考第一章端口說明)
- //P1端口讀取數據時需要先寫1,否則總線將出現邏輯沖突(黃色方塊閃爍)
- CLK=0; DIO=1; _nop_();_nop_();
- //根據時序圖可知,在正式讀取轉換數據之前,此時的D0將固定輸出0
- //P3=(uchar)DIO;
- //第4~11,共8個下降沿讀數據(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個下降沿讀數據(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讀取的結果相同則返回讀取的結果,否則返回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轉換值
- //根據四舍五入法計算電壓值(放大100倍以便分解)
- d=AD*500.0*2/511.0;
- //根據舍尾取整數計算電壓值(放大100倍以便分解)
- //將d = AD*500.0/256;
- //將AD轉換后得到數據分解為三個數位
- 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);
- //將模數值折算為實心方塊及空心方框字符個數,控制進程條圖形顯示
- }
- }
復制代碼
所有資料51hei附件下載:
仿真程序.7z
(34.52 KB, 下載次數: 59)
2023-12-12 15:18 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|