附件里面有設(shè)計(jì)任務(wù),根據(jù)附件原理圖改正里面的程序。完整的word文檔請?jiān)诒疚淖詈笙螺d附件,下面是部分內(nèi)容預(yù)覽:
目 錄 一、原理 ……………………………………………………………………………………………1 二、硬件介紹 ………………………………………………………………………………………1 2.1 單片機(jī)介紹…………………………………………………………………………………1 2.2 AT24C02I2C數(shù)據(jù)存儲(chǔ) ……………………………………………………………………2 2.3 PCF8591 A/D轉(zhuǎn)換 …………………………………………………………………………2 2.4 LCD1602 液晶顯示模塊……………………………………………………………………3 硬件連接及工作過程簡介………………………………………………………………………4 3.1 硬件連接……………………………………………………………………………………4 3.2 工作過程簡介………………………………………………………………………………5 三、工作流程圖 ……………………………………………………………………………………6 四、程序清單 ………………………………………………………………………………………7 五、PCB圖 …………………………………………………………………………………………18 六、總結(jié)……………………………………………………………………………………………18 八、參考文獻(xiàn)………………………………………………………………………………………19
一、原理本文所設(shè)計(jì)的是一種以單片機(jī)STC12C5A60S2(引腳排序及基本功能同AT89S51)作為主控芯片的雙通道電壓采集電路,將采集到的模擬信號(hào)電壓值利用PCF8591來進(jìn)行模數(shù)轉(zhuǎn)換,PCF8591是一個(gè)單片集成、單獨(dú)供電、低功耗、8-bitCMOS數(shù)據(jù)獲取信號(hào)。其中PCF8591共有4個(gè)模擬輸入、一個(gè)模擬輸出和一個(gè)串行口I2C總線接口,通過PLCF8591將轉(zhuǎn)換成的數(shù)字信號(hào)電壓值傳給液晶顯示屏,并將所測電壓值在LCD1602液晶顯示屏中顯示出來,而且要利用AT24C04設(shè)置電壓上下限,在電壓超出上下限時(shí)顯示屏要有所表示.本文主要針對(duì)雙通道的數(shù)據(jù)采集與顯示,繼而推廣多通道數(shù)據(jù)采集的方法,重點(diǎn)分析介紹了基于AT89S51數(shù)字電壓采集的硬件設(shè)計(jì)和軟件設(shè)計(jì)。
圖3-1硬件連接原理圖
SDA、SCL是IIC數(shù)據(jù)線和時(shí)鐘線,可連接于單片機(jī)任何IO管腳在。在本次設(shè)計(jì)中通過芯片AT24C02來編寫所測電壓的上下限值。 我們這次試驗(yàn)所測得電壓是直流電壓0至5伏是模擬信號(hào)由于我們所測得電壓要在 LCD1602 液晶顯示屏中顯示出來,但是LCD1602液晶顯示屏接受和表達(dá)數(shù)字信號(hào),所以要用PCF8591 A/D轉(zhuǎn)換芯片把采集的模擬信號(hào)電壓值轉(zhuǎn)換成數(shù)值信號(hào),經(jīng)過AT89S51再把信號(hào)傳給LCD液晶顯示屏,最終在液晶顯示屏上顯示出電壓值。如果采集的電壓值在設(shè)定的電壓值之間,則電壓值能在液晶顯示屏上顯示出電壓,如果超出了則在液晶顯示屏上有所表示。在此次試驗(yàn)中因?yàn)槭请p通道采集電壓,所以我們測兩條電路的電壓,我在這兩條電路上各串聯(lián)了一個(gè)滑動(dòng)變阻器,用來改變所測的電壓值。
五、程序清單 - #include "common.h"
- float v_low = 2.8; //電壓范圍下限
- float v_high = 4.5; //電壓范圍上限
- uchar BUF[2]; //從at24c04中讀取的數(shù)據(jù)存儲(chǔ)在這
- uchar w_buf[2]; //寫入at24c04中的數(shù)據(jù)存在這里
- //延時(shí)函數(shù)大約1ms
- void delay_ms(int ms)
- {
- int i;
- while(ms--)
- {
- for(i=0;i<100;i++);
- }
- }
- //連續(xù)寫入兩個(gè)數(shù)據(jù)
- void AT24C04_Write(uchar dat_1,uchar dat_2)
- {
- AT24C04_Start(); //起始信號(hào)
- AT24C04_SendByte(0xa0); //發(fā)送設(shè)備地址+寫信號(hào)
- AT24C04_SendByte(0x00); //發(fā)送存儲(chǔ)單元地址
- AT24C04_SendByte(dat_1); //寫入數(shù)據(jù)1
- AT24C04_SendByte(dat_2); //寫入數(shù)據(jù)2
- AT24C04_Stop(); //停止信號(hào)
- }
- //連續(xù)讀出兩個(gè)數(shù)據(jù)
- void AT24C04_ReadPage()
- {
- uchar i;
- AT24C04_Start(); //起始信號(hào)
- AT24C04_SendByte(0xa0); //發(fā)送設(shè)備地址+寫信號(hào)
- AT24C04_SendByte(0x00); //發(fā)送存儲(chǔ)單元地址
- AT24C04_Start(); //起始信號(hào)
- AT24C04_SendByte(0xa1); //發(fā)送設(shè)備地址+讀信號(hào)
- for (i=0; i<2; i++)
- {
- BUF[i] = AT24C04_RecvByte();
- if (i == 1)
- {
- AT24C04_SendACK(1); //最后一個(gè)數(shù)據(jù)需要會(huì)NAK
- }
- else
- {
- AT24C04_SendACK(0); //回應(yīng)ACK
- }
- }
- AT24C04_Stop(); //停止信號(hào)
- }
- //LCD顯示數(shù)字處理函數(shù)
- void show_num(uchar num,uchar flag)
- {
- uchar temp[3],i;
- float re_val; //電壓實(shí)際值
- float read_low,read_h; //將從AT24C04中讀取電壓范圍數(shù)據(jù)轉(zhuǎn)化成對(duì)應(yīng)小數(shù)形式
- re_val = num/255.0*5.0; //實(shí)際電壓計(jì)算公式
- num = re_val*10; //保留一位小數(shù)
- AT24C04_ReadPage();//從AT24C04中讀取電壓范圍數(shù)據(jù),存儲(chǔ)在BUF數(shù)組中
- // BUF[0]表示下限,BUF[1]表示上限
- //存入AT24C04中的數(shù)據(jù)是uchar unsigned型,在這里轉(zhuǎn)化成float型
- read_low = BUF[0]/10.0;
- read_h = BUF[1]/10.0;
- if(re_val >= read_low && re_val <= read_h) //如果電壓在范圍內(nèi)
- {
- temp[0] = num/10 + '0';
- temp[1] = '.';
- temp[2] = num%10 + '0';
- }else if(re_val < read_low ) //如果低于設(shè)定值
- {
- temp[0] = 'L';
- temp[1] = 'O';
- temp[2] = 'W';
- }else if(re_val > read_h ) //如果高于設(shè)定值
- {
- temp[0] = 'H';
- temp[1] = 'I';
- temp[2] = 'G';
- }
-
- for(i=0;i<3;i++) //用液晶顯示結(jié)果
- {
- LCD_Manifest(flag,3+i,temp[i]);
- }
- //顯示電壓范圍的上限
- num = read_h * 10;
- temp[0] = num/10 + '0';
- temp[1] = '.';
- temp[2] = num%10 + '0';
- for(i=0;i<3;i++) //用液晶顯示結(jié)果
- {
- LCD_Manifest(1,12+i,temp[i]);
- }
- //顯示電壓范圍的下限
- num = read_low * 10;
- temp[0] = num/10 + '0';
- temp[1] = '.';
- temp[2] = num%10 + '0';
- for(i=0;i<3;i++) //用液晶顯示結(jié)果
- {
- LCD_Manifest(2,12+i,temp[i]);
- }
- }
- //主函數(shù)
- void main()
- {
- uchar val; //電壓值
- LCD_Init(); //液晶初始化
- IIC_Init(); //I2C總線初始化
- w_buf[0] = v_low*10;
- w_buf[1] = v_high*10;
- AT24C04_Write(w_buf[0],w_buf[1]); //將數(shù)據(jù)寫入AT24C04
-
- LCD_Manifest(1,0,'V'); //在lcd1602中顯示字符
- LCD_Manifest(1,1,'1');
- LCD_Manifest(1,2,':');
- LCD_Manifest(2,0,'V');
- LCD_Manifest(2,1,'2');
- LCD_Manifest(2,2,':');
- LCD_Manifest(1,10,'H');
- LCD_Manifest(1,11,':');
- LCD_Manifest(2,10,'L');
- LCD_Manifest(2,11,':');
- while(1)
- {
- //按鍵檢測程序
- if(key_1 == 0) //調(diào)節(jié)范圍的下限
- {
- delay_ms(100); //延時(shí)消除抖動(dòng)
- if(key_1 == 0)
- {
- // v_low = v_low - 0.1;
- // if(v_low < 0.0)
- // v_low = v_high;
- w_buf[0] = v_low*10;
- w_buf[1] = v_high*10;
- AT24C04_Write(w_buf[0],w_buf[1]); //將數(shù)據(jù)寫入AT24C04
- }
- }
- if(key_2 == 0) //調(diào)節(jié)范圍的上限
- {
- delay_ms(100); //延時(shí)消除抖動(dòng)
- if(key_2 == 0)
- {
- v_high = v_high + 0.1;
- if(v_high > 5.0)
- v_high = v_low;
- w_buf[0] = v_low*10;
- w_buf[1] = v_high*10;
- AT24C04_Write(w_buf[0],w_buf[1]); //將數(shù)據(jù)寫入AT24C04
- }
- }
- ADC_Send_Byte(0x90,0x41);//通道一ADC轉(zhuǎn)換
- val=ADC_Receive_Byte(0x90); //讀取AD轉(zhuǎn)換的值
- show_num(val,1);
- ADC_Send_Byte(0x90,0x42);//通道二ADC轉(zhuǎn)換
- val=ADC_Receive_Byte(0x90); //讀取AD轉(zhuǎn)換的值
- show_num(val,2);
- }
- }
- #include<iic.h>
- void IIC_Init()//總線初始化
- {
-
- SCL=1;
- IIC_DELAY();
- SDA=1;
- IIC_DELAY();
- }
- void IIC_Start() //啟動(dòng)信號(hào)
- {
-
- SDA=1;
- IIC_DELAY();
- SCL=1;
- IIC_DELAY();
- SDA=0;
- IIC_DELAY();
- }
- void IIC_Stop() //停止信號(hào)
- {
-
- SDA=0;
- IIC_DELAY();
- SCL=1;
- IIC_DELAY();
- SDA=1;
- IIC_DELAY();
- }
- void IIC_Ack() //應(yīng)答信號(hào)
- {
- unsigned char i;
- SCL=1;
- IIC_DELAY();;
- while((SDA==1)&&(i<255))i++;
- SCL=0;
- IIC_DELAY();
- }
- void IIC_Write_Byte(u8 date)//寫一個(gè)字節(jié)
- {
- u8 i,temp;
- temp=date;
- for(i=0;i<8;i++)
- {
- temp=temp<<1;
- SCL=0;
- IIC_DELAY();
- SDA=CY;//最高位將移入PSW寄存器的CY位中,然后將CY賦給SDA
- IIC_DELAY();
- SCL=1;
- IIC_DELAY();
- }
- SCL=0;
- IIC_DELAY();
- SDA=1;
- IIC_DELAY();
- }
- u8 IIC_Read_Byte()//讀一個(gè)字節(jié)
- {
- u8 i,temp;
- for(i=0;i<8;i++)
- {
- SCL=0;
- IIC_DELAY();
- temp=(temp<<1)|SDA;
- IIC_DELAY();
- SCL=1;
- IIC_DELAY();
- }
- SCL=0;
- IIC_DELAY();
- SDA=1;
- IIC_DELAY();
- return temp;
- }
- #include <reg51.h>
- #include"lcd1602.h"
- void delay(u8 z)//延時(shí)函數(shù)
- {
- unsigned char x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void LCD_Write_Cmd(u8 com )//液晶寫命令
- {
- LCD_RS=0;//選擇寫命令模式
- LCD_dat=com;//將要寫的命令字送到數(shù)據(jù)總線上
- delay(1);
- LCD_E=1;//使能端給一高脈沖,高脈沖有效
- delay(1);
- LCD_E=0;
- }
- void LCD_Write_Data(u8 date)//數(shù)據(jù)寫命令
- {
- LCD_RS=1;//選擇寫數(shù)據(jù)模式
- LCD_dat=date;
- delay(1);
- LCD_E=1;//使能端給一高脈沖,高脈沖有效
- delay(1);
- LCD_E=0;
- }
- void LCD_Init()//液晶初始化
- {
-
- LCD_WR=0;
- LCD_Write_Cmd(0x38);//設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
- LCD_Write_Cmd(0x0c);//設(shè)置開顯示,不顯示光標(biāo)
- LCD_Write_Cmd(0x06);//寫一個(gè)字符后地址指針自動(dòng)加1
- LCD_Write_Cmd(0x80);//數(shù)據(jù)指針定位到第一行第一個(gè)字處
- }
- // 使得寫命令和寫數(shù)據(jù)通過一個(gè)函數(shù)完成
- void LCD_Manifest(u8 row,u8 add,u8 date)
- {
- if(row==1) LCD_Write_Cmd(0x80+add);
- if(row==2) LCD_Write_Cmd(0xc0+add);
- LCD_Write_Data(date);
- }
- #include"iic.h"
- #include"pcf8591.h"
- //ADC發(fā)送字節(jié)[命令]數(shù)據(jù)函數(shù)
- void ADC_Send_Byte(u8 addr,u8 com)
- {
- IIC_Start(); //啟動(dòng)總線
- IIC_Write_Byte(addr); //發(fā)送器件地址
- IIC_Ack();
- IIC_Write_Byte(com); //發(fā)送數(shù)據(jù)
- IIC_Ack();
- IIC_Stop(); //結(jié)束總線
- }
- //ADC讀字節(jié)數(shù)據(jù)函數(shù)
- u8 ADC_Receive_Byte(u8 addr)
- {
- u8 c;
- IIC_Start(); //啟動(dòng)總線
- IIC_Write_Byte(addr+1); //發(fā)送器件地址,如果是讀則最低位為1即0x91
- IIC_Ack();
- c=IIC_Read_Byte(); //讀取數(shù)據(jù)
- IIC_Ack(); //發(fā)送非就答位
- IIC_Stop(); //結(jié)束總線
- return(c);
- }
- #include"AT24C04.h"
- void Delay5us()
- {
- BYTE n = 4;
- while (n--)
- {
- _nop_();
- _nop_();
- }
- }
- void Delay5ms()
- {
- WORD n = 2500;
- while (n--)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- void AT24C04_Start()
- {
- AT_SDA = 1; //拉高數(shù)據(jù)線
- AT_SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- AT_SDA = 0; //產(chǎn)生下降沿
- Delay5us(); //延時(shí)
- AT_SCL = 0; //拉低時(shí)鐘線
- }
- void AT24C04_Stop()
- {
- AT_SDA = 0; //拉低數(shù)據(jù)線
- AT_SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- AT_SDA = 1; //產(chǎn)生上升沿
- Delay5us(); //延時(shí)
- }
- void AT24C04_SendACK(bit ack)
- {
- AT_SDA = ack; //寫應(yīng)答信號(hào)
- AT_SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- AT_SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- }
- bit AT24C04_RecvACK()
- {
- AT_SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- CY = AT_SDA; //讀應(yīng)答信號(hào)
- AT_SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- return CY;
- }
- void AT24C04_SendByte(BYTE dat)
- {
- BYTE i;
- for (i=0; i<8; i++) //8位計(jì)數(shù)器
- {
- dat <<= 1; //移出數(shù)據(jù)的最高位
- AT_SDA = CY; //送數(shù)據(jù)口
- AT_SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- AT_SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- }
- AT24C04_RecvACK();
- }
- BYTE AT24C04_RecvByte()
- {
- BYTE i;
- BYTE dat = 0;
- AT_SDA = 1; //使能內(nèi)部上拉,準(zhǔn)備讀取數(shù)據(jù)
- for (i=0; i<8; i++) //8位計(jì)數(shù)器
- {
- dat <<= 1;
- AT_SCL = 1; //拉高時(shí)鐘線
- Delay5us(); //延時(shí)
- dat |= AT_SDA; //讀數(shù)據(jù)
- AT_SCL = 0; //拉低時(shí)鐘線
- Delay5us(); //延時(shí)
- }
- return dat;
- }
復(fù)制代碼
七、總結(jié) 本次課程設(shè)計(jì),我學(xué)到了很多的東西,對(duì)匯編語言程序設(shè)計(jì)加深了理解和掌握,我們這次設(shè)計(jì)的要求主要是熟悉微型計(jì)算機(jī)技術(shù)中所學(xué)到的幾中芯片的使用,掌握它們的初始化編程,并學(xué)會(huì)他們的基本應(yīng)用,這是一個(gè)比較全面的設(shè)計(jì),和以前的實(shí)驗(yàn)相比較復(fù)雜很多,一方面要求我們設(shè)計(jì)硬件電路,另一方面需要對(duì)設(shè)計(jì)的硬件電路進(jìn)行編程,這就需要軟件和硬件相結(jié)合,具體的電路具體分析,在此次設(shè)計(jì)中還用到了AT24C02芯片,在此次之前我們從沒用到這個(gè)芯片,對(duì)這個(gè)芯片非常陌生,而且網(wǎng)上也沒有什么系統(tǒng)的解釋,和AT89S51的管腳的連線也不清楚,但是最后通過不停地調(diào)試,最后還是被解決了。通過這次課程設(shè)計(jì)后,我對(duì)學(xué)硬件有了一定的體會(huì),它要求我們認(rèn)真仔細(xì)的做好每個(gè)環(huán)節(jié),對(duì)所有的問題要考慮周全,它和軟件不同,對(duì)具體的電路要編寫適合該電路的程序,電路一改,程序也要跟著改,從中我也學(xué)會(huì)了很多實(shí)際應(yīng)用的知識(shí)。通過本次設(shè)計(jì),我才發(fā)現(xiàn)我所學(xué)的東西的膚淺,知識(shí)面的不牢固,在選擇方案的時(shí)候,產(chǎn)生模棱兩可的情況。經(jīng)常是邊設(shè)計(jì)邊復(fù)習(xí)學(xué)習(xí)過的課本知識(shí)。這些使我知道“紙上談兵”是絕對(duì)不行,只有通過實(shí)踐,自己親自動(dòng)手試一試,才能發(fā)現(xiàn)自己知識(shí)的缺陷,才能更好的與所學(xué)的知識(shí)相結(jié)合。在課程設(shè)計(jì)中我們每個(gè)人都能學(xué)到很多,有很大的收獲。做任何事情所要有的態(tài)度和心態(tài),首先我明白了做學(xué)問要一絲不茍,對(duì)于出現(xiàn)的任何問題和偏差都不要輕視,要通過正確的途徑去解決,在做事情的過程中要有耐心和毅力,不要一遇到困難就打退堂鼓,只要堅(jiān)持下去就可以找到思路去解決問題的。在工作中要學(xué)會(huì)與人合作的態(tài)度,認(rèn)真聽取別人的意見,這樣做起事情來就可以事倍功半。
課程設(shè)計(jì)任務(wù)書下載:
任務(wù)書10----雙通道電壓采集電路設(shè)計(jì)(LCD顯示).doc
(36.5 KB, 下載次數(shù): 19)
2016-6-5 11:07 上傳
點(diǎn)擊文件名下載附件
設(shè)計(jì)任務(wù)
完整的設(shè)計(jì)文檔下載:
單片機(jī)課設(shè).doc
(214.5 KB, 下載次數(shù): 49)
2016-6-5 11:14 上傳
點(diǎn)擊文件名下載附件
根據(jù)里面的設(shè)計(jì)原理圖寫程序
|