|
30黑幣
捕獲.PNG (28.42 KB, 下載次數(shù): 63)
下載附件
2019-6-15 22:01 上傳
- #include<reg52.h>
- #include<string.h>
- #include <stdio.h>
- #include"intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
- uchar code table[]={'0','1','2','3','4','5','6','7','8','9'};
- uchar code table1[]="ALC warn=90mg/L"; //初始顯示
- uchar code table2[]="current="; //報(bào)警濃度和實(shí)測濃度表示
- uchar code table3[]="mg/L";
- sbit led=P2^6;
- sbit beep=P1^3;
- sbit lcdrs=P2^5; //1602液晶的RS腳接在P2.3口上
- sbit lcdrw=P2^4; //1602液晶的RW腳接在P2.4口上
- sbit lcden=P2^3; //1602液晶的E腳接在P2.5口上
- sbit SDA=P3^6;
- sbit SCL=P3^7;
- int count,t,num;
- uchar cur1,cur2,cur3;
- uint cur_bj=90; //CO報(bào)警值
- unsigned char ADbuf;//設(shè)置8位的寄存器用來暫存A/D轉(zhuǎn)換結(jié)果
- void delay(unsigned int z)
- {
- uint i,j;
- for(i=z;i>0;i--)
- for(j=110;j>0;j--);
- }
- /*******************************延時(shí)函數(shù)*********************************/
- void delayms(unsigned int ms)
- {
- unsigned char i=100,j;
- for(;ms;ms--)
- {
- while(--i)
- {
- j=10;
- while(--j);
- }
- }
- }
- /*******************************報(bào)警函數(shù)*********************************/
- void led_warn()
- {
- led=~led;
- delay(200);
- }
- void beep_warn()
- {
- beep=~beep;
- delay(200);
- }
- /******************************寫命令函數(shù)********************************/
- void write_com(uchar com)
- {
- lcdrs=0;
- P0=com; //讀命令
- delay(1);
- lcden=1; //啟動(dòng)脈沖
- delay(1);
- lcden=0;
- }
- /******************************寫數(shù)據(jù)函數(shù)********************************/
- void write_data(uchar date)
- {
- lcdrs=1;
- P0=date; //寫命令
- delay(1);
- lcden=1; //啟動(dòng)脈沖
- delay(1);
- lcden=0;
- }
- /******************************LCD初始化*********************************/
- void init_1602()
- {
- lcden=0;
- write_com(0x38); //設(shè)置16*2顯示;5*7點(diǎn)陣;8位數(shù)據(jù)接口
- write_com(0x0c); //設(shè)置開顯示,不顯示光標(biāo)
- write_com(0x06); //寫一個(gè)字符后地址指針自動(dòng)加1
- write_com(0x01); //設(shè)置清0,數(shù)據(jù)指針清零
- }
- void IICstart(void)
- {
- SDA=1; //先將SDA=1,以準(zhǔn)備在SCL=1時(shí),將SDA=0
- SCL=1; //時(shí)鐘總線拉高
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- SDA=0; //SCL=1時(shí),將SDA拉低即產(chǎn)生啟動(dòng)信號
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- SCL=0; //將SCL=0,完成啟動(dòng)信號操作
- }
- /*****************************IIC停止信號函數(shù)***********************************/
- void IICstop(void)
- {
- SDA=0; //先將SDA=0,以準(zhǔn)備在SCL=1時(shí),將SDA=1
- SCL=1; //時(shí)鐘總線拉高
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- SDA=1; //SCL=1時(shí),將SDA拉高即產(chǎn)生停止信號
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- SCL=0; //將SCL=0,完成啟動(dòng)信號操作
- }
- /*****************************向IIC總線寫入1個(gè)字節(jié)函數(shù)**************************/
- void Write1Byte(unsigned char Buf1)
- {
- unsigned char k; //1個(gè)字節(jié)要分8次寫入,需要定義一個(gè)寄存器用來計(jì)數(shù)
- for(k=0;k<8;k++) //做一個(gè)8次的循環(huán),每次寫入1位,需要寫8次
- {
- if(Buf1&0x80) //從最高位開始寫
- {
- SDA=1; //如果欲寫入數(shù)據(jù)為1,就將數(shù)據(jù)線置1
- }
- else
- {
- SDA=0; //如果欲寫入數(shù)據(jù)為0,就將數(shù)據(jù)線寫0
- }
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- SCL=1; //時(shí)鐘線做一個(gè)上升沿,將一位數(shù)據(jù)寫入
- Buf1=Buf1<<1; //數(shù)據(jù)左移一位,將下次要寫入的位數(shù)據(jù)移到最高位
- _nop_(); //略做延時(shí)
- SCL=0; //將SCL=0,以準(zhǔn)備通過上升沿將數(shù)據(jù)寫入
- _nop_(); //略做延時(shí)
- }
- SDA=1; //將SDA=1,準(zhǔn)備讀應(yīng)答信號
- _nop_(); //略做延時(shí)
- SCL=1; //將SCL=1,做個(gè)上升沿準(zhǔn)備讀應(yīng)答信號
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- SCL=0; //將SCL=0,結(jié)束應(yīng)答信號讀操作
- }
- /****************************從IIC總線讀入1個(gè)字節(jié)函數(shù)******************************/
- unsigned char Read1Byte(void)
- {
- unsigned char k; //1個(gè)字節(jié)要分8次讀出,需要定義一個(gè)寄存器用來計(jì)數(shù)
- unsigned char t=0; //定義一個(gè)寄存器用保存讀出數(shù)據(jù)
- for(k=0;k<8;k++) //做一個(gè)8次的循環(huán),每次讀入1位,需要讀8次
- {
- t=t<<1; //數(shù)據(jù)左移一位,空出最低位以準(zhǔn)備保存讀入的一位數(shù)據(jù)
- SDA=1; //將SDA寫1準(zhǔn)備讀
- SCL=1; //將SCL=1,做個(gè)上升沿準(zhǔn)備讀一位數(shù)據(jù)
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- if(SDA==1) //讀一位數(shù)據(jù),并判斷
- {
- t=t|0x01; //如果讀入數(shù)據(jù)為1,就將接收緩沖區(qū)最低一位置1
- }
- else
- {
- t=t&0xfe; //如果讀入數(shù)據(jù)為0,就將接收緩沖區(qū)最低一位寫0
- }
- SCL=0; //SCL恢復(fù)為0,結(jié)束一位數(shù)據(jù)讀操作
- _nop_(); //略做延時(shí)
- _nop_(); //略做延時(shí)
- }
- return t; //將讀入的一個(gè)字節(jié)返回
- }
- /******************************軟件模擬IIC向PCF8591指定地址寫一個(gè)字節(jié)函數(shù)********************************/
- void WritePCF8591(unsigned char Databuf)
- { //直接調(diào)用本函數(shù)即可啟動(dòng)PCF8591的D/A轉(zhuǎn)換
- IICstart(); //IIC啟動(dòng)信號
- Write1Byte(0x90); //發(fā)送PCF8591的器件地址和寫信號
- Write1Byte(0x40); //發(fā)送器件子地址
- Write1Byte(Databuf); //發(fā)送數(shù)據(jù)
- IICstop(); //產(chǎn)生IIC停止信號
- }
- /******************************軟件模擬IIC從PCF8563指定地址讀一個(gè)字節(jié)函數(shù)************************************/
- unsigned char ReadPCF8591(unsigned char Ch)
- { //直接調(diào)用本函數(shù)即可從PCF8591的Ch通道讀出數(shù)據(jù)返回
- unsigned char buf; //定義一個(gè)寄存器用來暫存讀出的數(shù)據(jù)
- IICstart(); //IIC啟動(dòng)信號
- Write1Byte(0x90); //發(fā)送PCF8591的器件地址和寫信號
- Write1Byte(0x40|Ch); //發(fā)送器件通道參數(shù)Ch=0-3
- IICstart(); //IIC啟動(dòng)信號
- Write1Byte(0x91); //發(fā)送PCF8591的器件地址和讀信號
- buf=Read1Byte();//讀一個(gè)字節(jié)數(shù)據(jù)
- IICstop(); //產(chǎn)生IIC停止信號
- return(buf); //將讀出數(shù)據(jù)返回
- }
- /******************************顯示初始值函數(shù)**********************************/
- void dis_init()
- {
- uchar a,b,c;
- write_com(0x80+0x00); //初始化顯示
- for(a=0;a<15;a++)
- {
- write_data(table1[a]);
- delay(1);
- }
- delay(200);
- write_com(0x80+0x40); //第二行顯示酒精濃度表示單位
- for(b=0;b<8;b++)
- {
- write_data(table2[ b]);[/b][ b]
- delay(1);
- }
- write_com(0x80+0x4B); //第二行顯示酒精濃度表示單位
- for(c=0;c<4;c++)
- {
- write_data(table3[c]);
- delay(1);
- }
- }
- /*********************************1602顯示濃度數(shù)據(jù)h和酒精報(bào)警程序**************************/
- void dis_cur(uint t)
- {
- uchar i;
- t=t*100/255;
- i=t/100;
- write_com(0x80+0x48); //顯示濃度百位
- write_data(table[ i]);[/i][ i]
- cur1=table[ i];[/i][ i]
- i=t%100/10;
- write_com(0x80+0x49);
- write_data(table[ i]);[/i][ i]
- cur2=table[ i];[/i][ i]
- i=t%100%10;
- write_com(0x80+0x4A); //顯示濃度個(gè)位
- write_data(table[ i]);[/i][ i]
- cur3=table[ i];[/i][ i]
- if(t>cur_bj)
- {
- led_warn();
- beep_warn();
- }
- else
- {
- led=1;
- beep=1;
- }
- }
- /*******************************串口初始化********************************/
- void UARTinit()
- {
- // TMOD=0X21;
- // SCON=0X40;
- TMOD=0x20;
- PCON=0x00;
- SCON=0x50;
- TH1=0XFF;
- TL1=0XFD;
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- TR1=1;
- TR0=1;
- EA=1;
- ES=1;
- TI=0;
- ET0=1;
- }
- /*******************************發(fā)送一個(gè)字節(jié)************************************/
- void UART_Send_Byte(unsigned char mydata)
- {
- ES=0;
- TI=0;
- SBUF=mydata;
- while(!TI);
- TI=0;
- ES=1;
- }
- /****************************發(fā)送文本串****************************************/
- void UART_Send_Str(char *s)
- {
- int i=0;
- while(s[ i]!=0)[/i][ i]
- {
- UART_Send_Byte(s[ i]);[/i][ i]
- i++;
- }
- }
- void T0_time() interrupt 1
- {
- count++;
- TH0=(65536-45872)/256;
- TL0=(65536-45872)%256;
- if(count==400)
- {
- count=0;
- num=1;
- }
- }
- main()
- {
- uchar g,s,b;
- // uchar i = 0;
- // uchar code Buffer[]="0" ; //所要發(fā)送的數(shù)據(jù)
- // uchar *p;
- led=1;
- beep=1;
- lcdrw=0; //確定讀操作
- init_1602(); //初始化LCD1602
- delay(5);
- dis_init(); //1602顯示初始化
- delay(2000);
- UARTinit(); //串口初始化
-
-
- // Com_Init();
- // p = Buffer;
- while(1)
- {
- ADbuf=ReadPCF8591(0); //將AIN0通道A/D轉(zhuǎn)換結(jié)果暫存在ADbuf
- dis_cur(ADbuf); //濃度顯示
- b=ADbuf/100;
- s=ADbuf%100/10;
- g=ADbuf%100%10;
- if(num==1)
- {
- UART_Send_Byte(g);
- UART_Send_Byte(s);
- UART_Send_Byte(b);
- // UART_Send_Str("hello");
- // UART_Send_Str("ADbuf/100");
- // UART_Send_Str("ADbuf%100/10");
- // UART_Send_Str("ADbuf%100%10");
- }
- /*
- SBUF = *p ;
- while(!TI){ ;//如果發(fā)送完畢,硬件會置位TI
- _nop_(); //此句似乎可以去掉
- }
- TI = 0; //TI清零
- p++;
- if(*p == '\0')
- break; */
- }
- }
復(fù)制代碼 |
|