/*這個是涵洞積水系統SIM900A發中文短信的一部分,整個程式都編譯成功了,就是運行不出現像*/
#include"SIM900A.h"
#include<reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//注意,無論接收到信號還是發送完信號,都會進中斷服務程式的
/*初始化程式(必須使用,否則無法收發),次程式將會使用定時器1*/
void SerialInti(void)//初始化程式(必須使用,否則無法收發)
{
TMOD=0x21;//定時器1操作模式2:8位自動多載定時器
TH1=0xfd;//裝入初值,波特率9600
TL1=0xfd;
TR1=1;//打開定時器
SM0=0;//設定串行通訊作業模式,(10為一部發送,波特率可變,由定時器1的溢位率控制)
SM1=1;//(同上)在此模式下,定時器溢位一次就發送一個位的資料
REN=1;//串行接收允許位(要先設定sm0sm1再開串行允許)
EA=1;//開總中斷
ES=1;//開串行口中斷
}
void Uart1BYTE(uchar temp)
{
SBUF=temp;
while(!TI);//等待發送完成信號(TI=1)出現
TI=0;
}
//串行口連續發送char型陣列,遇到終止號/0將停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
while(!TI);//等待發送完成信號(TI=1)出現
TI=0;
str++;
}
}
//延時函式大概是1s鐘
void DelaySec(int sec)
{
uint i,j=0;
for(i=0;i<sec;i++)
{
for(j=0;j<65535;j++)
{
}
}
}
void SIM900A(void)
{
Uart1Sends("AT+CSQ\r\n");
DelaySec(1);//延時1秒
Uart1Sends("AT+CMGF=1\r\n");//文本模式
DelaySec(1);//延時1秒
Uart1Sends("AT+CSMP=17,167,2,25\r\n");//設定在作業模式
DelaySec(1);//延時1秒
Uart1Sends("AT+CSCS=\"UCS2\"");//UCS2編碼字集
DelaySec(1);
Uart1Sends("AT+CMGS=\"00310037003800330032003100370032003000380033\"");//unicode電話號碼
DelaySec(3);
Uart1Sends("8B66544AFF0179EF6C348D859650");//內容unicode碼
DelaySec(3);//延時3秒
Uart1BYTE(0x1A);
}
/*這個是涵洞積水預警系統的主程式,里面加上SIM900A()這個函式后就涼了,沒加之前運行正常*/
#include"ds18b20.h"
#include"csb.h"
#include"lcd.h"
#include<reg52.h>
#include"main.h"
#include"SIM900A.h"
typedef unsigned char uchar;
typedef unsigned int uint;
uint temp1[3];
uchar count = 0;
uint a1=0,Threshold1=15,Threshold2=20;
//已用埠p0.0,p0.1,p0.2,p0.3,p0.4,p0.5,p0.6,p0.7,p2.7,p2.6
//p0.0,p0.1(超聲波)p0.2~p0.5(LCD)p2.0-2.3(按鍵)p0.6(DS18b20)
void main(void)
{
initc();//超聲波初始化
init(); //lcd初始化
SerialInti();
while(1)
{
switch(P2)
{
case 0xfe:{Threshold1=Threshold1+1;display1();break;}
case 0xfd:{Threshold1=Threshold1-1;display1();break;}
case 0xfb:{Threshold2=Threshold2+1;display2();break;}
case 0xf7:{Threshold2=Threshold2-1;display2();break;}
default:break;
}
while(count < 3)
{
temp1[count]=loop();
count++;
}
a1 = (uint)(temp1[0] + temp1[1] + temp1[2]) / 3;
a1=400-a1;
count = 0;
if(a1>Threshold2)
{
SIM900A(); //對就是這里,加了這句不出現像,除了發中文不對,可能還中斷還影響了整個程式。
display();
}
else if(a1>Threshold1)
{
display();//lcd顯示程式
}
else
{
display();
}
delay(3000);
}
} //0:加,1:減
void Serial_interrupt() interrupt 4//串口中斷
{
if(RI)
RI=0;//接收中斷信號清零,表示將繼續接收
if(TI)
TI=0;
}
/*這個是我單獨寫的發送中文短信的程式,失敗了,但是把其中中文短信的AT陳述句換成英文短信的就會成功收到短信*/
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
code char str1[]="AT+CSQ\r\n";
code char str2[]="AT+CSCS=\"UCS2\"\r\n";
code char str3[]="AT+CMGF=1\r\n";
code char str4[]="AT+CSMP=17,167,2,25";
code char str5[]="AT+CMGS=\"00310037003800330032003100370032003000380033\"\r\n";//手機號unicode碼
code char str6[]="8B66544AFF0179EF6C348D859650";//發送內容unicode碼
code char str7[]="AT+CMGD=1";
void DelaySec(int sec)
{
uint i,j=0;
for(i=0;i<sec;i++)
{
for(j=0;j<65535;j++)
{
}
}
}
void uart_init(void)
{
TMOD=0x20;
SCON=0x40;
TH1=0xfd;
TL1=0xfd;
TR1=1;
ES=1;
EA=1;
}
void sendonebyte(uint c)
{
ES=0;
SBUF=c;
while(!TI);
TI=0;
ES=1;
}
void main(void)
{
uint i=0;
uart_init();
while(str1[i]!='\0')
{
sendonebyte(str1[i++]);
}
DelaySec(1);
i=0;
while(str2[i]!='\0')
{
sendonebyte(str2[i++]);
}
DelaySec(1);
i=0;
while(str3[i]!='\0')
{
sendonebyte(str3[i++]);
}
DelaySec(1);
i=0;
while(str4[i]!='\0')
{
sendonebyte(str4[i++]);
}
DelaySec(1);
i=0;
DelaySec(5);
while(str5[i]!='\0')
{
sendonebyte(str5[i++]);
}
DelaySec(1);
i=0;
while(str6[i]!='\0')
{
sendonebyte(str6[i++]);
}
DelaySec(1);
i=0;
sendonebyte(0x1A);
while(str7[i]!='\0')
{
sendonebyte(str7[i++]);
}
DelaySec(1);
i=0;
while(1);
}
void uart_isr(void) interrupt 4
{
if(RI)
{
RI=0;
}
else
TI=0;
}
/*英文的發短信陳述句,大概,只不過我把Uart1Sends的函式改成了上面的sendonebyte()那種,不容易錯*/
Uart1Sends("AT+CMGF=1\r\n"); //方式1
DelaySec(1);//延時
Uart1Sends("AT+CMGS=\"10086\"\r\n"); //此處修改短信接收方電話號
DelaySec(1);//延時
Uart1Sends("ye"); //此處修改短信內容
DelaySec(1);//延時
Uart1BYTE(0X1A);
DelaySec(1);//延時
DelaySec(1);//延時
DelaySec(1);//延時
DelaySec(1);//延時
/*以下是涵洞積水預警系統的其他部分程式,避免需要時沒有,特意加上(不重要)*/
/*超聲波部分*/
#include<reg52.h>
#include<intrins.h>
#include"ds18b20.h"
#include"csb.h"
#include"lcd.h"
typedef unsigned char uchar;
typedef unsigned int uint;
/*定時器0初始化*/
void initc(void)
{
TMOD=0x21;//,定時器0作業在模式一。00000001
TH0=0;
TL0=0;
ET0=1;
EA=1;
TR0 = 0;
}
void trigger(void) //單片機輸入切換電平啟動
{
TRIGGER=0;
TRIGGER=1;
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
TRIGGER=0;
}
uint get_distance()
{
uint time = TH0*256+TL0;
float distance;
if(read_temperature() <= 10)
{
distance = time * (330.45 * 100) / 2000000;
}
else if(read_temperature() <= 30)
{
distance = time * (342.62 * 100) / 2000000;
}
else
{
distance = time * (354.85 * 100) / 2000000;
}
TH0 = TL0 = 0;
return (uint)distance;
}
uint loop(void)
{
trigger();
while(!ECH0);
TR0=1;
while(ECH0);
TR0=0;
delay(200);//延時(大于200ms)
return get_distance();
}
/*溫度傳感器*/
#include <reg52.h>
#include "ds18b20.h"
void delay_18B20(unsigned int i)
{
for(;i>0;i--);
}
//DS18B20芯片初始化
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ拉高
delay_18B20(8); //稍作延時
DQ = 0; //DQ拉低
delay_18B20(80); //延時大于480us
DQ = 1; //拉高總線
delay_18B20(14);
x=DQ; //若x=0初始化成功,若x=1初始化失敗
delay_18B20(20);
}
//通過單總線向DS18B20寫一個位元組
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
if(DQ)
{
delay_18B20(1);
DQ=1;
}
else
{
delay_18B20(5);
DQ=1;
}
dat>>=1; //算術右移
}
}
//從DS18B20讀取一個位元組
unsigned char ReadOneChar(void) //給DQ 0,1切換信號后便會得到1位的資料反饋到DQ上
{
unsigned char i=0;
unsigned char dat=0;
for (i=8;i>0;i--)
{
DQ=0; //拉低總線
dat>>=1;//每讀取移位向右移移位
DQ=1; //拉高總線
if(DQ)
dat|=0x80; //當DQ為1信號,軟體將1賦給那一位
delay_18B20(4);
}
return(dat);
}
unsigned char read_temperature(void)
{
unsigned char a = 0,b = 0,temp = 0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳過讀序列號操作
WriteOneChar(0x44); // 啟動溫度轉換
delay_18B20(100); //
Init_DS18B20();
WriteOneChar(0xCC); //跳過讀序列號操作
WriteOneChar(0xBE); //讀取溫度暫存器
delay_18B20(100);
a = ReadOneChar(); //讀溫度低位
b = ReadOneChar(); //讀溫度高位
temp = b; // 以下部分和你的是一樣的
temp <<= 8;
temp |= a;
if(temp < 0x8000)
{
temp = ((b * 256 + a) >> 4); // 完成的是十六進制轉為10進制 ,右移4位去掉小數部分,精度12位
}
else
{
temp = -((b * 256 + a) >> 4);
/*lcd12864*/
#include<reg52.h>
#include<intrins.h>
#include"lcd.h"
#include"main.h"
#include"ds18b20.h"
typedef unsigned char uchar;
typedef unsigned int uint;
uchar code hanzi1[]={"當前積\xfd水深度為:"};
uchar code hanzi2[]={"謹慎通行!"};
uchar code Temp[]={"溫度:"};
uchar code Threshold_A[]={"閾值A:"};
uchar code Threshold_B[]={"閾值B:"};
void delay(uint y) //單位:1ms
{ uint z;
uchar x;
for(z=0;z<y;z++)
{
for(x=0;x<120;x++);
}
}
void write_command(uchar command_data) //寫指令
{
uchar i,temp,temp1,temp2;
temp=0xf8;
delay(10);
CS=1;
SCLK=0;
for(i=0;i<8;i++)
{
SID=(bit)(temp&0x80);
SCLK=0;
SCLK=1;
temp=(temp<<1);
}
temp1=command_data;
temp1=(temp1&0xf0);
for(i=0;i<8;i++)
{
SID=(bit)(temp1&0x80);
SCLK=0;
SCLK=1;
temp1=(temp1<<1);
}
temp2=command_data;
temp2=(temp2<<4);
for(i=0;i<8;i++)
{
SID=(bit)(temp2&0x80);
SCLK=0;
SCLK=1;
temp2=(temp2<<1);
}
CS=0;
}
void write_data(uchar command_data) //寫資料
{
uchar temp,temp1,temp2,i;
temp=0xfa;
delay(10);
CS=1;
for(i=0;i<8;i++)
{
SID=(bit)(temp&0x80);
SCLK=0;
SCLK=1;
temp=(temp<<1);
}
temp1=command_data;
temp1=(temp1&0xf0);
for(i=0;i<8;i++)
{
SID=(bit)(temp1&0x80);
SCLK=0;
SCLK=1;
temp1=(temp1<<1);
}
temp2=command_data;
temp2=(temp2<<4);
for(i=0;i<8;i++)
{
SID=(bit)(temp2&0x80);
SCLK=0;
SCLK=1;
temp2=(temp2<<1);
}
CS=0;
}
void init(void) //初始化
{
PSB=0;
delay(100);
write_command(0x30); // 功能設定:一次送8位資料,,基本指令集。
write_command(0x04); // 點設定:顯示字符/游標從左到右移位,DDRAM地址加1。
write_command(0x0c); // 顯示設定:開顯示,關游標,當前關閉反白閃動。
write_command(0x01); // 清DDRAM
write_command(0x02); // DDRAM地址歸位
write_command(0x80); // 把顯示地址設為0X80,即為第一行的首位。
}
void display(void)
{
uchar temp[2];
uchar j,i;
uint temperature=(int)read_temperature();
init();
write_command(0x80); //第一行顯示
for(j=0;j<16;j++)
{
write_data(hanzi1[j]);
}
write_command(0x90);
write_data(a1/100+0x30);
write_data(a1%100/10+0x30);
write_data(a1%10+0x30);
write_data('c');
write_data('m');
if(a1>Threshold1)
{
write_command(0x88);
for(j=0;j<9;j++)
{
write_data(hanzi2[j]);
}
}
write_command(0x98);
for(i=0;i<6;i++)
{
write_data(Temp[i]); // 顯示溫度提示
}
temp[0]=temperature/10+0x30;
temp[1]=temperature%10+0x30;
write_command(0x98+5); // 顯示溫度值
for(i=0;i<2;i++)
{
write_data(temp[i]);
}
}
void display1(void)
{
uchar i;
init();
write_command(0x98);
for(i=0;i<6;i++)
{
write_data(Threshold_A[i]);
}
write_data(Threshold1/10+0x30);
write_data(Threshold1%10+0x30);
}
void display2(void)
{
uchar i;
init();
write_command(0x98);
for(i=0;i<6;i++)
{
write_data(Threshold_B[i]);
}
write_data(Threshold2/10+0x30);
write_data(Threshold2%10+0x30);
}
}
return(temp);
}
.h檔案應該不用了吧,放不下了,這么多估計也沒人看,我就賭賭運氣555,大四學渣慌如小狗,望大佬成全。
uj5u.com熱心網友回復:
希望有大佬幫忙哦,別看程式多,用看的不多,我把所有家當都用上了
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/256525.html
標籤:單片機/工控
下一篇:APP協議,求大神來做
