|
此課設(shè)基于ADC0832和壓力傳感器MPX4115,把傳感器的值通過運(yùn)放電路調(diào)整,送入AD轉(zhuǎn)換,再經(jīng)單片機(jī)編程實(shí)現(xiàn)壓力的測(cè)量與顯示;涉及PWM控制,串口,按鍵控制PWM占空比等。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下:
- #include<math.h>
- #include<absacc.h>
- #include<intrins.h>
- #include<reg51.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- #define BUSY 0x80 //常量定義
- #define DATAPORT P0
- sbit Alarm_led_red =P1^6; //超過壓力表量程最大值紅燈報(bào)警
- sbit Alarm_led_green=P1^7; //低于壓力表量程最小值路燈報(bào)警
- sbit LCM_RS=P2^0;
- sbit LCM_RW=P2^1;
- sbit LCM_EN=P2^2;
-
- sbit k1=P2^3;
- sbit k2=P2^4;
- sbit k3=P2^5;
- sbit k4=P2^6;
- sbit ADCS =P3^5; //ADC0832 chip seclect
- sbit ADCLK =P3^6; //ADC0832 clock signal
- sbit ADDI =P3^7; //ADC0832 k in
- sbit ADDO =P3^7; //ADC0832 k out
-
- uchar ad_data; //采樣值存儲(chǔ)
- unsigned char ad_alarm; //報(bào)警值存儲(chǔ)單元
- unsigned char press_bai=0; //顯示值百位
- unsigned char press_shi=0; //顯示值十位
- unsigned char press_ge=0; //顯示值個(gè)位
- unsigned char press_dot=0; //顯示值十分位
- uchar code str0[]={"Press: . kpa. "};
- uchar code str1[]={"ZKB: 00 % "};
- uchar ZKB[2];
- uchar HighRH = 0;
- uchar HighRL = 0;
- uchar LowRH = 0;
- uchar LowRL = 0;
- unsigned int a;
- uchar rate;
- sbit PWMOUT = P1^0;
- uchar step, rec_data,flag;
- uchar Adc0832(unsigned char channel);
- void delay(uint);
- void lcd_wait(void); //檢測(cè)忙子程序
- void delay_LCM(uint); //延時(shí)子程序
- void initLCM(void); //初始化子程序
- void WriteCommandLCM(uchar WCLCM,uchar BusyC); //寫指令到LCM子程序
- void WriteDataLCM(uchar WDLCM); //寫數(shù)據(jù)到LCM子程序
- void DisplayOneChar(uchar X,uchar Y,uchar DData); //顯示指定坐標(biāo)的一個(gè)字符子函數(shù)
- void DisplayListChar(uchar X,uchar Y,uchar code *DData); //顯示指定坐標(biāo)的一串字符子函數(shù)
- void display(void); //系統(tǒng)顯示子函數(shù)
- void ConfigPWM(uchar rate);
- void alarm(void);
- void data_pro(void);
- void ConfigPWM(uchar dc);
- void key_setPWM(void);
- uchar duty_cycle(uchar ad_data);
- void display_zkb(void);
- void zkb_pro(void);
- void chuankou_init();
- /**********main funcation************/
- void main(void)
- {
-
-
- delay(50);
- initLCM( );
- chuankou_init();
- WriteCommandLCM(0x01,1); //清屏顯示
- DisplayListChar(0,0,str0);
- DisplayListChar(0,1,str1);
-
- delay(10);
- PWMOUT=1;
- EA = 1;
- ConfigPWM(rate);
- while(1)
- {
- ad_data =Adc0832(0); //采樣值存儲(chǔ)單元初始化為0
- alarm();
- data_pro();
- zkb_pro();
- display();
- display_zkb();
- a=duty_cycle(ad_data);
- ConfigPWM(a);
- key_setPWM();
- if(a!=rate)
- {
- ConfigPWM(rate);
- }
-
- if(RI==1)//串口
- {
- RI=0;
- rec_data=SBUF;
- step=rec_data*2;
- SBUF=rec_data;
- }
-
- }
- }
- void TIME_INIT()
- {
- TMOD|=0X02;
- IT0=1;
- IT1=1;
- TR1=1;
- EX1=1;
- EX0=1;
- ET0=1;
- TR0=1;
- EA=1;
- }
- void chuankou_init()
- {
- SCON|=0X50;
- TMOD|=0X20;
- PCON|=0X80;
- TH1=0XFA;
- TL1=0XFA;
- TR1=1;
-
- SM0=0;
- SM1=1;
- REN=1;
-
- EA=1;
- ES=1;
- }
-
- /********延時(shí)K*1ms,12.000mhz**********/
- void delay(uint x)
- {
- uchar i;
- while(x--)
- {
- for(i = 0;i < 120;i++)
- {;}
- }
- }
- /**********寫數(shù)據(jù)到ICM子函數(shù)************/
- void WriteCommandLCM(uchar WCLCM,uchar BusyC)
- {
- if(BusyC)
- lcd_wait(); //檢測(cè)忙信號(hào)
- DATAPORT=WCLCM;
- LCM_RS=0;
- LCM_RW=0;
- LCM_EN=1;
- _nop_();
- _nop_();
- _nop_();
- LCM_EN=0;
-
- }
- /**********????LCM???************/
- void WriteDataLCM(uchar WDLCM)
- {
- lcd_wait( );
- DATAPORT=WDLCM;
- LCM_RS=1; //選中數(shù)據(jù)寄存器
- LCM_RW=0; //寫模式
- LCM_EN=1;
- _nop_();
- _nop_();
- _nop_();
- LCM_EN=0;
- }
- /***********lcm內(nèi)部等待程序*************/
- void lcd_wait(void)
- {
- DATAPORT=0xff; //讀LCD前若單片機(jī)輸出低電平,而讀出LCD為高電平,則沖突,Proteus仿真會(huì)有顯示邏輯黃色
- LCM_EN=1;
- LCM_RS=0;
- LCM_RW=1;
- _nop_();
- _nop_();
- _nop_();
- while(DATAPORT&BUSY)
- {
- LCM_EN=0;
- _nop_();
- _nop_();
- LCM_EN=1;
- _nop_();
- _nop_();
- }
- LCM_EN=0;
-
- }
- /**********LCM??????***********/
- void initLCM( )
- {
- DATAPORT=0;
- delay(15);
- WriteCommandLCM(0x38,0); //三次顯示模式,不檢測(cè)忙信號(hào)
- delay(5);
- WriteCommandLCM(0x38,0);
- delay(5);
- WriteCommandLCM(0x38,0);
- delay(5);
- WriteCommandLCM(0x38,1); //8bit數(shù)據(jù)傳送,兩行顯示,5*7字型,檢測(cè)忙信號(hào)
- WriteCommandLCM(0x08,1); //關(guān)閉顯示,檢測(cè)忙信號(hào)
- WriteCommandLCM(0x01,1); //清屏,檢測(cè)忙信號(hào)
- WriteCommandLCM(0x06,1); //顯示光標(biāo)右移設(shè)置
- WriteCommandLCM(0x0c,1); //顯示屏打開,光標(biāo)不顯示,不閃爍,檢測(cè)忙信號(hào)
- }
- /****??????????????****/
- void DisplayOneChar(uchar X,uchar Y,uchar DData)
- {
- Y&=1;
- X&=15;
- if(Y)X|=0x40; //若Y為1(顯示第二行)地址譯碼+0x40
- X|=0x80; //指令碼為地址碼+0x80
- WriteCommandLCM(X,0);
- WriteDataLCM(DData);
- }
- /*******??????????????*****/
-
- void DisplayListChar(uchar X,uchar Y,uchar code *DData)
- {
- uchar ListLength=0;
- Y&=0x01;
- X&=0x0f;
- while(X<16)
- {
- DisplayOneChar(X,Y,DData[ListLength]);
- ListLength++;
- X++;
- }
- }
- /*****************???????*****************/
- void display(void)
- {
- WriteCommandLCM(0x0c,1); //顯示屏打開,光標(biāo)不顯示,不閃爍,檢測(cè)忙信號(hào)
- DisplayListChar(0,0,str0);
- DisplayListChar(0,1,str1);
- DisplayOneChar(7,0,press_bai+0x30);
- DisplayOneChar(8,0,press_shi+0x30);
- DisplayOneChar(9,0,press_ge +0x30);
- DisplayOneChar(10,0,056);
- DisplayOneChar(11,0,press_dot+0x30);
- }
- void display_zkb(void)
- {
- WriteCommandLCM(0x0c,1);
- DisplayListChar(0,1,str1);
- DisplayOneChar(7,1,ZKB[0]+0x30);
- DisplayOneChar(8,1,ZKB[1]+0x30);
- delay(1000); //穩(wěn)定顯示
- }
- /************?ADC0832??************/
- uchar Adc0832(unsigned char channel) //AD轉(zhuǎn)換,并返回結(jié)果
- {
- uchar i=0;
- uchar j;
- uint dat=0;
- uchar ndat=0;
- if(channel==0)channel=2;
- if(channel==1)channel=3;
- ADDI=1;
- _nop_();
- _nop_();
- ADCS=0; //拉低CS端
- _nop_();
- _nop_();
- ADCLK=1; //拉高CLK端
- _nop_();
- _nop_();
- ADCLK=0; //拉低CLK端,形成下降沿1
- _nop_();
- _nop_();
- ADCLK=1; //拉高CLK端
- ADDI=channel&0x1;
- _nop_();
- _nop_();
- ADCLK=0; //拉低CLK端,形成下降沿2
- _nop_();
- _nop_();
- ADCLK=1; //拉高CLK端
- ADDI=(channel>>1)&0x1;
- _nop_();
- _nop_();
- ADCLK=0; //拉低CLK端,形成下降沿3
- ADDI=1; //控制命令結(jié)束
- _nop_();
- _nop_();
- dat=0;
- for(i=0;i<8;i++)
- {
- dat|=ADDO; //收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0; //形成一次時(shí)鐘脈沖
- _nop_();
- _nop_();
- dat<<=1;
- if(i==7)dat|=ADDO;
- }
- for(i=0;i<8;i++)
- {
- j=0;
- j=j|ADDO; //收數(shù)據(jù)
- ADCLK=1;
- _nop_();
- _nop_();
- ADCLK=0; //形成一次時(shí)鐘脈沖
- _nop_();
- _nop_();
- j=j<<7;
- ndat=ndat|j;
- if(i<7)ndat>>=1;
- }
- ADCS=1; //拉低CS端
- ADCLK=0; //拉低CLK端
- ADDO=1; //拉高數(shù)據(jù)端,回到初始狀態(tài)
- dat<<=8;
- dat|=ndat;
- return(dat);
- }
- void zkb_pro(void)
- {
- unsigned int temp;
- temp=100*ad_data/256;
- if(temp>0 && temp<100)
- {
- ZKB[0]=temp/10;
- ZKB[1]=temp%10;
- }
- }
- void data_pro(void)
- {
- unsigned int temp;
- float press;
- if(14<ad_data<243) //壓力值介于15KPA,到115kpa之間,呈線性變化
- {
- int vary=ad_data; //y=(115-15)/(243-13)*X+15kpa
- //press=24+ad_data/2.67;
- press=((10.0/28.1)*vary)+9.3; //測(cè)試時(shí)補(bǔ)償值為9.3
- temp=(int)(press*10); //放大10倍,便于后面計(jì)算
- press_bai=temp/1000;
- press_shi=(temp%1000)/100;
- press_ge=((temp%1000)%100)/10;
- press_dot=((temp%1000)%100)%10;
- }
-
- }
- /*****************?????*******************/
- void alarm(void)
- {
- if(ad_data>=243)
-
- {
- Alarm_led_red=0;
- a=10000;
- while(a--);
- {
- }
- Alarm_led_red=1;
- a=10000;
- while(a--);
- {
- }
- }
- else
- { Alarm_led_red=1; }
-
-
- if(ad_data<=15)
- { Alarm_led_green=0;
- a=10000;
- while(a--);
- {
- }
- Alarm_led_green=1;
- a=10000;
- while(a--);
- {
- }
- }
- else
- { Alarm_led_green=1; }
-
- }
- uchar duty_cycle(uchar ad_data)
- {
- uchar rate;
-
- rate= 100*ad_data/256;
- return(rate);
- }
- /* ??????*/
- void key_setPWM()
- {
- if(k1==0)
- {
- delay(20);
- if(k1==0)
- {
- rate++;
- if(rate>99)rate=99;
- while(!k2);
- }
- }
- if(k2==0)
- {
- delay(20);
- if(k2==0)
- {
- rate--;
- if(rate<1)rate=1;
- while(!k2);}
- }
- if(k3==0)
- {
- delay(20);
- if(k3==0)
- {
- rate+=10;
- if(rate>99)rate=99;
- while(!k3);}
- }
- if(k4==0)
- {
- delay(20);
- if(k4==0)
- {
- rate-=10;
- if(rate<1)rate=1;
- while(!k4);
- }
- }
- }
- /*??????dc,??20Hz????*/
- void ConfigPWM(uchar dc)
- {
- unsigned long tmp; //臨時(shí)變量
- uint high, low;
- tmp = 11059200/12/20; //計(jì)算一個(gè)周期所需的計(jì)數(shù)值
- high = (tmp*dc)/100; //計(jì)算高電平所需計(jì)數(shù)值
- low = tmp - high; //計(jì)算低電平所需計(jì)數(shù)值
- high = 65536 - high + 12; //計(jì)算高電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
- low = 65536 - low + 12; //計(jì)算低電平的定時(shí)器重載值并補(bǔ)償中斷延時(shí)
- HighRH = (uchar)(high >>8); //高電平重載值拆分為高低字節(jié)
- HighRL = (uchar)high;
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
11502測(cè)控課設(shè).zip
(30.52 KB, 下載次數(shù): 251)
2019-1-11 19:57 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|