用單片機控制總裝車間中的LED照明系統,使其輸出恒定照度的光,以滿足總裝生產工序中的照明需要。 要求: 1. 設計一個給LED供電的可控恒流源電路; 2. 要求恒流源輸出電流大小可調,調節范圍:下限為(學號末兩位×100)mA ,上限為(學號末兩位×10)mA;(310mA—3100mA) 3. 設計用戶輸入環節(硬件線路和程序),實現人工設定給LED供電的恒流源的電流大小; 4. 設計恒流源輸出電流檢測電路和顯示電路,編程實現輸出電流大小的檢測和顯示; 5. 構建閉環系統,并運用 數字控制算法(如PID)使輸出電流相對穩定在用戶設定的數值,利用Matlab作為輔助工具整定算法參數、仿真驗證算法性能,并通過編程用單片機實現; 6. 設計、繪制系統電路 PCB,設計包含手寫簽名的 Logo,并放置在Top Layer的正中位置。 2. 硬件總體設計 2.1 總體設計方案 由設計要求可知,需使用MCS-51系列單片機,構建控制系統,實現LED燈亮度的控制。所以采用AT89C52 單片機為核心,以3*3按鍵鍵盤作為輸入端,以達到控制所需輸出電流的功能,并且由LCD1602顯示模塊可以顯示輸入電流的大小和電流源輸出的電流大小。在設計中,采用PCF8591芯片進行AD/DA轉換,單片機通過I2C通信協議控制PCF8591 AD轉換輸出的電壓所需電壓,輸入壓控電壓源,通過采樣電阻的電壓DA轉換獲得電流源輸出的電流值,經過單片機計算最后顯示實際輸出電流。 該直流電機控制系統的設計,在總體上大致可分為以下6個部分組成:AT89C52單片機最小系統,3*3按鍵鍵盤,直流穩壓源,1602顯示模塊,AD/DA轉換模塊,可控電流源模塊。系統總體方案圖如圖 1 所示。 圖 1 系統總體方案圖 2.2 工作原理 2.2.2 直流穩壓電源原理 本設計共用到電源有四種:即± 12V、+5V、負載電源。可選用的有開關電源和穩壓電源兩種,由于開關電源的紋波系數比較大。因此采用常用的穩壓電源來作為整個系統的電源。穩壓電源由電源變壓器、整流電路、濾波電路和穩壓電路組成,如圖 2 所示: 圖2 直流穩壓電源原理圖 整流和濾波電路:整流作用是將交流電壓 變換成脈動電壓。濾波電路一般由電容組成, 其作用是脈動電壓中的大部分紋波加以濾除,以得到較平滑的直流電壓。再通過穩壓電路得到平直的直流電壓。 圖2 直流穩壓電源仿真圖 2.2.2 電流源原理 首先,在數控方面采用單片機比 CPLD 和 FPGA 等可編程邏輯器件好,因為此處只是一般用途的控制,沒有必要選用價格昂貴的 CPLD 和 FPGA,而且他們用在此處并不合適,控制起來顯得很麻煩。而單片機則不同,他有著非常成熟的技術,這方面的參考文獻也很多,而且他從來就是用于控制方面的,在這方面有著天生的優勢。還有他價格也不貴,僅幾元人民幣。對于這樣的應用系統比較劃得來。其次在恒流源方面,我們方案也很好。從理論上看,運放是接成比較器的,作為模擬反饋的,這樣在只要運放的輸入不變,那么三極管的Vbe是不變的,根據三極管的共射極輸入特性可知,Vbe不變時,Ie和Ic也保持不變,而且Ic=βIb, Ie=(1+β)Ib 。當β比較大時Ic≈Ie 。當運放的輸入改變時,也改變了Vbe值,這樣也就改變了Ic和Ie的值,而且這個變化基本也是呈線性的。這也就是本系統的恒流原理。由于器件受溫度的影響以及局部非線性的存在,這樣的恒流源不能做到真正的恒流,因此,當外界條件發生變化時,我們要及時給予補償,只有這樣才能做到真正的恒流。這也就是為什么要加入模數轉換器的真正原因,他能實時測量電流的變化并按照一定的算法及時給予補償,采用數字補償逐次逼近的方式作為反饋調整環節,由程序控制調節功率管的輸出。當改變負載大小時,基本上不影響電流的輸出。模數轉換器還起到測量的作用,同時送顯示讓我們知道實際的電流輸出值。 2.3 AT89C52最小系統 2.3.1 AT89C52芯片簡介 采用AT89C52是MSC-51系列單片機的升級版,由世界著名半導體公司 ATMEL在購買MSC-51設計結構后,利用自身優勢技術——閃存生產技術對舊技術進行改進和擴展,同時使用新的半導體生產工藝,最終得到成型產品。與此同時,世界上其他的著名公司也通過基本的51內核,結合公司自身技術進行改進生產,推廣了一批如51F020等高性能單片機。AT89C52片內集成256字節程序運行空間, 8K字節Flash存儲空間,支持最大64k外部存儲擴展。根據不同的運行速度和功耗的要求,時鐘頻率可以設置在0-33M之間。片內資源有4組I/O控制端口、3個定時器、8個中斷、軟件設置低耗能模式、看門狗和斷電保護。可以在4V到5.5V寬電壓范圍內正常工作。不斷發展的半導體工藝也讓該單片機的功耗不斷降低。同時,該單片機支持計算機并口下載,簡單的數字芯片就可以制成下載線,僅僅幾塊錢的價格讓該型號單片機暢銷 10 年不衰。根據不同場合的要求,這款單片機提供了多種封裝,本次設計根據最小系統有時需要更換單片機的具體情況,使用雙列直插PID-40 的封裝。 2.3.2 AT89C52最小系統組成 AT89C52最小系統由AT89C52芯片、復位電路和時鐘電路組成。復位電路和時鐘電路是維持單片機最小系統運行的基本模塊。時鐘電路采用12M晶振組成。復位電路通常分為兩種:上電復位和手動復位。有時系統在運行過程中出現程序跑飛的情況,在程序開發過程中,經常需要手動復位,所以本次設計選用手動復位。 圖3 AT89C52最小系統圖 2.4 3*4按鍵鍵盤 鍵盤使用12個彈跳按鈕形成3*4輸入鍵盤,按鈕鍵值為“0-9”、“確定”和“設置”。“0-9”一共10個按鈕實現所需輸出電流值的輸入控制,控制范圍為310mA-3100mA; “確定”鍵實現數據計算并輸出所需電壓,以控制電流源的輸出電流;“設置”鍵實現二次數據輸入,按下時會使數值返回默認值,以達到電流值的重新輸入。 圖4 3*4按鍵輸入模塊 2.5 LCD1602顯示模塊 2.5.1 LCD1602簡介 點陣圖形式液晶由M×N個顯示單元組成,假設LCD顯示屏有64行,每行有128列,每8列對應1字節的8位,即每行由16字節,共16×8=128個點組成。顯示屏上64×16個顯示單元與顯示RAM區的1024字節相對應,每一字節的內容與顯示屏上相應位置的亮暗對應。例如顯示屏第一行的亮暗由RAM區的000H~00FH的16字節的內容決定,當(000H)=FFH時,屏幕左上角顯示一條短亮線,長度為8個點;當(3FFH)=FFH時,屏幕右下角顯示一條短亮線;當(000H)=FFH,(001H)=00H,(002H)=00H…,(00EH)=00H,(00FH)=00H時,在屏幕的頂部顯示一條由8條亮線和8條暗線組成的虛線。這就是LCD顯示的基本原理。 字符型液晶顯示模塊是一種專門用于顯示字母、數字和符號等的點陣式LCD,目前常用16×1,16×2,20×2和40×2等的模塊。一般的LCD1602字符型液晶顯示器的內部控制器大部分為HD44780,能夠顯示英文字母、阿拉伯數字、日文片假名和一般性符號。 2.5.2 LCD1602連接與控制 LCD1602顯示模塊與單片機P2.5、P2.6、P2.7以及P0口連接,通過單片機編寫LCD控制子程序,實現LCD1602的數據傳輸和顯示控制。以顯示用戶輸入電流的值以及電流源最后輸出的值。通過LCD1602實現人機交互的功能,以達到實時顯示輸出電流大小的顯示。 圖5 LCD1602顯示模塊 2.6 AD/DA轉換模塊 2.6.1 PCF8591簡介 PCF8591是一個單片集成、單獨供電、低功耗、8-bit CMOS數據獲取器件。PCF8591具有4個模擬輸入、1個模擬輸出和1個串行I2C總線接口。PCF8591的3個地址引腳A0, A1和A2可用于硬件地址編程,允許在同個I2C總線上接入8個PCF8591器件,而無需額外的硬件。在PCF8591器件上輸入輸出的地址、控制和數據信號都是通過雙線雙向I2C總線以串行的方式進行傳輸。 2.6.2 PCF8591轉換模塊 由于系統要求同時要求AD/DA轉換,而如果采用單獨的AD/DA芯片,需要的控制引腳比較多,而PCF8591芯片集成了4個AD轉換引腳和一個DA轉換引腳,適合系統的所需的要求,同時使用I2C通信協議,只需要連接單片機兩個引腳,節約了單片機的引腳,并且使用簡單,控制方便。 圖6 AD/DA轉換模塊 2.7 可控電流源模塊 用“運放 +大功率三極管”的結構構成恒流源。大功率三極管選用 TIP122 型號,它是應用范圍廣、功率小、頻率低的達林頓,NPN 極性型,特征頻率 :1000(MHz),集電極允許電流:8(A),集電極最大允許耗散功率:48(W)。其性能滿足本設計要求,同時可以通過功率管的不同容量來滿足不同的應用要求。采用常用的大功率電阻作為采樣電阻,輸出電流波動比較大,而康錳銅絲是一種溫度特性佳的阻性元件,選其作為取樣電阻,其兩端電壓正比于流過的電流,因此該電壓的反饋就是負載電流的反饋。 圖7可控電流源模塊 3. 程序設計 3.1主程序:
- ///*************************************************************************
- ///工業生產中的產品數量自動計量系統創新設計
- ///功能:通過MUC-51芯片控制電流源輸出電流,實現LED燈亮度控制
- ///*************************************************************************
- #include<reg52.h>
- #include<iic.h>
- #include<lcd1602.h>
-
- #define KEY_PRESET(code) { P1=code; temp=P1; temp=temp&code; delay(10);}
-
- uchar str1[16]="310mA<=I<=3100mA";
- uchar str2[16]="set: out: ";
- uchar str3[16]=" Error occurred ";
- uchar dianliu[4]={0,0,0,0};
-
- uchar key_num,key_flag,key_count=0,OK_flag;
- ulong pian,bai,shi,ge,set_value;
- float key_value;
- uchar h,l,temp;
- ulong back_voltage1,back_current;
-
- void get_Data();
- void set_Data();
- uchar keyscan();
- bit DACconversion(uchar sla,uchar c,uchar Val);
- bit ISendByte(uchar sla,uchar c);
- uchar IRcvByte(uchar sla);
- void delay1(uint j);
- ///*************************************************************************
- ///主函數
- ///*************************************************************************
- void main()
- {
- INIT_I2c();//iic總線初始化
- LCD_Init();//LCD1602初始化
- while(1)
- {
- get_Data();
- set_Data();
- }
-
- }
-
- //*******************************************************************
- //DAC 變換, 轉化函數
- //*******************************************************************
- bit DACconversion(uchar sla,uchar c, uchar Val)
- {
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(c); //發送控制字節
- if(ack==0)return(0);
- SendByte(Val); //發送DAC的數值
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- return(1);
- }
- //*******************************************************************
- //ADC發送字節[命令]數據函數
- //*******************************************************************
- bit ISendByte(uchar sla,uchar c)
- {
- Start_I2c(); //啟動總線
- SendByte(sla); //發送器件地址
- if(ack==0)return(0);
- SendByte(c); //發送數據
- if(ack==0)return(0);
- Stop_I2c(); //結束總線
- return(1);
- }
- //*******************************************************************
- //ADC讀字節數據函數
- //*******************************************************************
- uchar IRcvByte(uchar sla)
- {
- uchar c;
- Start_I2c(); //啟動總線
- SendByte(sla+1); //發送器件地址
- if(ack==0)return(0);
- c=RcvByte(); //讀取數據0
- Ack_I2c(1); //發送非就答位
- Stop_I2c(); //結束總線
- return(c);
- }
- ///*************************************************************************
- ///按鍵掃描函數
- ///*************************************************************************
- uchar keyscan()
- {
- KEY_PRESET(0X0F);
- if(temp!=0X0F)//是否有鍵按下
- {
- delay(10);
- temp=P1;
- temp=temp&0X0F;
- if(temp!=0X0F) //確實有鍵按下
- {
- key_flag=1;//按下鍵標志位
- switch(temp)
- {
- case 0X0E:h=0;break; //行
- case 0X0D:h=1;break;
- case 0X0B:h=2;break;
- case 0X07:h=3;break;
- default:break;
- }
- KEY_PRESET(0XF0);
- switch(temp)
- {
- case 0XE0:l=0;break; //列
- case 0XD0:l=1;break;
- case 0XB0:l=2;break;
- case 0X70:l=3;break;
- default:break;
- }
- key_num=3*h+l;//按下鍵的鍵值
- if(key_num<=9) key_count++;
- while(temp!=0XF0)//等待釋放
- {
- temp=P1;
- temp=temp&0XF0;
- }
- }
- }
- return key_num;//返回鍵值
- }
- void get_Data()
- {
- uchar i;
- keyscan(); //鍵盤掃描
- if(key_flag==1)//有鍵按下
- {
- if(key_num<=9&&key_count<5) //只允許輸入一個四位的數值
- {
- if(key_count==1)//輸入電流值第一位
- {
- LCD_Manifest(2,4,keyscan());
- pian=keyscan();
- }
- if(key_count==2)//輸入電流值第二位
- {
- LCD_Manifest(2,5,keyscan());
- bai=keyscan();
- }
- if(key_count==3)//輸入電流值第三位
- {
- LCD_Manifest(2,6,keyscan());
- shi=keyscan();
- }
- if(key_count==4)//輸入電流值第四位
- {
- LCD_Manifest(2,7,keyscan());
- ge=keyscan();
- }
- key_flag=0; //按下鍵標志位清零
- }
- if(key_num==10&&key_count>=4)//確認鍵按下
- OK_flag=1;//確認鍵按下標志位
- if(key_num==11)//設置鍵按下
- {
- OK_flag=0;//確認鍵按下標志位清零
- key_count=0; //按下數字計數清零
- LCD_Write_Cmd(0x80);//數據指針定位到第一行第一個字處
- for(i=0;i<16;i++)
- LCD_Write_Data(str1[i]);//液晶顯示第一行待?
-
- LCD_Write_Cmd(0x80+0x40);//將數據指針定位到第二行第一個
- for(i=0;i<16;i++)
- LCD_Write_Data(str2[i]);//液晶顯示第二行寫
-
- }
- }
-
- }
- void set_Data()
- {
- if(OK_flag==1) //按下確定鍵,將數值送給DA
- {
- uchar i;
- key_value=pian*1000+bai*100+shi*10+ge;
- if(key_value>=310&&key_value<=3100)
- {
- key_value=key_value/5000*255;
- set_value=(uchar)key_value;//將按鍵輸入值變成整形賦給變量
-
- DACconversion(0x90,0x40,set_value) ; //DAC轉換
- delay(100);
-
- ISendByte(0x90,0x40);//通道一ADC轉換
- delay(100);
- back_voltage1=IRcvByte(0x90);
-
- back_current=back_voltage1*5000/255;
- dianliu[0]=back_current/1000;
- dianliu[1]=back_current%1000/100;
- dianliu[2]=back_current%1000%100/10;
- dianliu[3]=back_current%1000%100%10;
-
-
- LCD_Manifest(2,12,dianliu[0]);//輸出電流值千位
- LCD_Manifest(2,13,dianliu[1]);//輸出電流值百位
- LCD_Manifest(2,14,dianliu[2]);//輸出電流值十位
- LCD_Manifest(2,15,dianliu[3]);////輸出電流值個位
- }
- else
- {
-
- LCD_Write_Cmd(0x80+0x40);//將數據指針定位到第二行第一個
- for(i=0;i<16;i++)
- LCD_Write_Data(str3[i]);//液晶顯示第二行寫
- }
- }
- }
復制代碼
4. 系統仿真 4.1系統仿真圖: 圖8 系統仿真圖 4.2 PCB圖 圖9 PCB圖 4.3 3D視圖 圖10 3D視圖 5. 元器件清單列表 6. 設計總結
在查找資料的過程中,由于參數比較苛刻,所以很少有例子進行參考,只得盡可能完成自己的設計,在數模和模數轉換的芯片中,由于ADC0809和DAC0832兩個芯片所需引腳比較多,所以選擇比較簡單的PCF8591芯片,進行設計,但是同時也是導致電流難以達到設計要求,只能加大負載電壓,在電流源的設計中,由于做簡單模型,實際應用仍需加許多的支路已達到供電電壓的濾波作用,本設計還有許多不能不完善的地方。在這次設計中,我發現一個完整的方案仍然會有很多不足之處,在實際的使用可能還有不穩定的情況,所以,還需要努力學習。
51hei.png (4.52 KB, 下載次數: 31)
下載附件
2020-1-6 01:49 上傳
全部資料51hei下載地址:
工業控制系統綜合設計.zip
(695.03 KB, 下載次數: 65)
2020-1-5 14:30 上傳
點擊文件名下載附件
內含protues仿真文件 下載積分: 黑幣 -5
|