初级会员
- 积分
- 79
- 金钱
- 79
- 注册时间
- 2016-8-13
- 在线时间
- 9 小时
|
发表于 2016-9-23 08:25:26
|
显示全部楼层
/*******************************************************************************
* ??: *
* 12864???????? ??p0,??p2 *
********************************************************************************/
#include <stc12c5a60s2.h>
#include <string.H>
#include <intrins.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
#define FOSC_110592M
/************* 12864LCD???? *************/
#define LCD_data P2 //???
sbit LCD_RS = P0^7; //???????
sbit LCD_RW = P0^6; //???/???
sbit LCD_EN = P0^5; //??????
sbit LCD_PSB = P0^4; //?/?????
sbit LCD_RST = P0^3; //??????
sbit LED = P1^2;
sbit wind = P0^0;
sbit ds=P3^5;
#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};
/*********************************************************/
uchar n,r,a,d1,d2;
uchar buffer[6]; //定义数据缓存数组
void delay1ms(void);
uint b,d,a1;
uchar table[7]={0,0,0,0,0,0,0};
unsigned int rec_data_len_uart=0; //标记Buffer_Uart0接收数组
unsigned char idata Buffer_Uart0_Rec[25]={0}; //Uart0中断接收数?
uchar code num[] = {'0','1','2','3','4','5','6','7','8','9'};
uchar code DIS1[] = {"温度是:20 safe"};
uchar code DIS2[] = {"CO浓度:10 safe"};
uchar code DIS3[] = {"粉尘为:50 safe "};
uchar code DIS4[] = {"风机:OFF "};
uchar code DIS5[] = {"safe"};
uchar code DIS6[] = {"WARN"};
uchar code DIS7[] = {"ON"};
uchar code DIS8[] = {"OFF"};
//注意,无论接收到信号还是发送完信号,都会进中断服务程序的
/*初始化程序(必须使用,否则无法收发),次程序将会使用定时器1*/
void SerialInti()//初始化程序(必须使用,否则无法收发)
{
TMOD=0x20;//定时器1操作模式2:8位自动重载定时器
#ifdef FOSC_12M //在这里根据晶振大小设置不同的数值初始化串口
TH1=0xf3;//装入初值,波特率2400
TL1=0xf3;
#else
TH1=0xfd;//装入初值,波特率9600
TL1=0xfd;
#endif //end of SOC_12M
TR1=1;//打开定时器
SM0=0;//设置串行通讯工作模式,(10为一部发送,波特率可变,由定时器1的溢出率控制)
SM1=1;//(同上)在此模式下,定时器溢出一次就发送一个位的数据
REN=1;//串行接收允许位(要先设置sm0sm1再开串行允许)
EA=1;//开总中断
ES=1;//开串行口中断
}
unsigned char hand(unsigned char *data_source,unsigned char *ptr)
{
if(strstr(data_source,ptr)!=NULL)
return 1;
else
return 0;
}
void clear_rec_data()
{
uchar i,temp_len;
temp_len=strlen(Buffer_Uart0_Rec);
if(temp_len>25)
{
temp_len=25;
}
for(i=0;i<temp_len;i++)
{
Buffer_Uart0_Rec[i]='\0';
}
rec_data_len_uart=0;
}
/*串行通讯中断,收发完成将进入该中断*/
void Serial_interrupt() interrupt 4
{
unsigned char temp_rec_data_uart0;
temp_rec_data_uart0 = SBUF;//读取接收数据
RI=0;//接收中断信号清零,表示将继续接收
Buffer_Uart0_Rec[rec_data_len_uart]=temp_rec_data_uart0; //接收数据
rec_data_len_uart++;
if(rec_data_len_uart>24)
{
rec_data_len_uart=0; //从头开始接收数据
}
}
void Uart1Send(uchar c)
{
SBUF=c;
while(!TI);//等待发送完成信号(TI=1)出现
TI=0;
}
//串行口连续发送char型数组,遇到终止号/0将停止
void Uart1Sends(uchar *str)
{
while(*str!='\0')
{
SBUF=*str;
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 delayry(unsigned int i)
{unsigned int j;
while(i--)
{ for(j=0;j<60;j++);}
}
//???ds18b20
void dsInit()
{
unsigned int i;
ds=0;
i=500;
while(i>0)
i--;
ds=1;
i=20;
while(i>0)
i--;
}
bit readBit()
{ unsigned int i;
bit b;
ds=0;
i++;i++;i++;
ds=1;
i++;i++;i++;i++;
b=ds;
i=30;
while(i>0)
i--;
return b;
}
unsigned char readByte()
{ unsigned int i;
unsigned char j,dat;
dat=0;
for(i=0;i<8;i++)
{ j=readBit();
dat=(j<<7)|(dat>>1);
}
return dat;
}
void writeByte(unsigned char dat)
{ unsigned int i;
unsigned char j;
bit b;
for(j=0;j<8;j++)
{b=dat&0x01;
dat>>=1;
if(b)
{ ds=0;
i++;i++;i++;i++;i++;i++;
ds=1;
i=30;
while(i>0)
i--;
}
else
{ ds=0;
i=30;
while(i>0)
i--;
ds=1;
i++;i++;i++;i++;
}
}
}
void sendChangeCmd()
{ dsInit();
delayry(5);
writeByte(0xcc);
writeByte(0x44);
}
void sendReadCmd()
{ dsInit();
delayry(5);
writeByte(0xcc);
writeByte(0xbe);
}
int getTmpValue()
{ unsigned int tmpvalue;
int value;
float t;
unsigned char low,high;
sendReadCmd();
low=readByte();
high=readByte();
tmpvalue=high;
tmpvalue<<=8;
tmpvalue|=low;
value=tmpvalue;
t=value*0.0625;
value=t*100+(value>0?0.5:-0.5);
return value;
}
void display(int v)
{
unsigned int tmp=abs(v);
table[0]=tmp/10000;
table[1]=tmp%10000/1000;
table[2]=tmp%1000/100;
}
/******************************************************************************/
void delayF(uchar a)
{
uchar i,j,k;
while(a--)
{
for(i=0;i<10;i++)
{
for(j=0;j<255;j++)
{
for(k=0;k<255;k++)
_nop_();
}
}
}
}
void delay2(uchar a)
{
uchar i;
while(a--)
{
for(i=0;i<50;i++)
{
_nop_();
}
}
}
//***************AD初始化子程序***********************
void ADC_Init(void)
{
P1M0=0X01; //P1口模式配置寄存器0,推挽输出(强上拉达20mA, 限流)
P1M1=0X01; //P1口模式配置寄存器1,推挽输出(强上拉达20mA, 限流)
ADC_CONTR=0XA0; //360个时钟周期转化一次,开电源
P1ASF=0X03; //P1口迷你功能控制寄存器,P1.0--P1.3设置为AD使用
AUXR1=0X04; //中断控制辅助寄存器(AUXR1.0=ADRJ=0,转化结果的格式为:
//取ADC_RES的8位为高8位,取ADC_RESL的最低2位为低2位)
ADC_RES=0X00; //转化结果寄存器赋初值为0
ADC_RESL=0X00;
delay1ms();
}
//***************AD采样子程序***********************
unsigned int ADC_GET_RES(unsigned char x)
{
unsigned char a2,b2;
unsigned int c2;
ADC_CONTR=(0xa8|x); //选择采集的通道号,每次传入的x可以确定通道号
delay1ms();
while((ADC_CONTR&0x10)==0); //转化结束标志位为0时,说明没转化结束,等待
ADC_CONTR=ADC_CONTR&0xef; //清转化结束标志位(必须软件清0)
a2=ADC_RES; //取转化结果的高8位
b2=ADC_RESL; //取转化结果的高位
c2=(unsigned int)((unsigned int)(256*a2)+b2);
return c2; //将转化结果转化为16位并返回
}
//***************AD滤波子程序***********************
void AD_LB(uint p[],uint n)
{
uint i,sum=0;
for(i=9;i>0;i--)
p[i]=p[i-1];
p[0]=n; //传入的参数n就是最后一个转化值,赋给p[0]
}
//***************延时子程序***********************
void delay1ms(void)
{
unsigned char a,b;
for(b=180;b>0;b--)
for(a=100;a>0;a--);
_nop_();
}
void delay(int ms)
{
while(ms--)
{
uchar i;
for(i=0;i<150;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
void delay1(int ms)
{
while(ms--)
{
uchar y;
for(y=0;y<100;y++) ;
}
}
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
delayNOP();
result = (bit)(P2&0x80);
LCD_EN = 0;
return(result);
}
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P2 = cmd;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P2 = dat;
delayNOP();
LCD_EN = 1;
delayNOP();
LCD_EN = 0;
}
void lcd_init()
{
LCD_PSB = 1; //????
LCD_RST = 0; //????
delay(3);
LCD_RST = 1;
delay(3);
lcd_wcmd(0x30); //??????
delay(5);
lcd_wcmd(0x0C); //???,???
delay(5);
lcd_wcmd(0x01); //??LCD?????
delay(5);
}
void lcd_pos(uchar X,uchar Y)
{
uchar pos;
if (X==1)
{X=0x80;}
else if (X==2)
{X=0x90;}
else if (X==3)
{X=0x88;}
else if (X==4)
{X=0x98;}
pos = X+Y ;
lcd_wcmd(pos); //????
}
void lcdflag()
{
lcd_wcmd(0x08);
delay(400);
lcd_wcmd(0x0c);
delay(400);
lcd_wcmd(0x08);
delay(400);
lcd_wcmd(0x0c);
delay(400);
lcd_wcmd(0x08);
delay(200);
lcd_wcmd(0x0c);
delay(5);
lcd_wcmd(0x01);
delay(5);
}
/*********************************************************/
void clr_screen()
{
lcd_wcmd(0x34); //??????
delay(5);
lcd_wcmd(0x30); //??????
delay(5);
lcd_wcmd(0x01); //??
delay(5);
}
void main()
{
uchar i,j,k=0;
uint AD_deal[10],sum=0; //滤波暂存数组定义
CLK_DIV=0x02;
wind=0;
delay2(100); //??,????
lcd_init(); //???LCD
while(1)
{
P1M1=0x0F; //P1口模式配置寄存器0,AD模式下设为开漏
P1M0=0x0F; //P1口模式配置寄存器0,AD模式下设为开漏
ADC_Init(); //AD初始化
for(i=0;i<2;i++) //循环四次,采集四路转化结果
{
for(j=0;j<10;j++) //循环10次,将10次的采集结果暂存
{
AD_LB(AD_deal,ADC_GET_RES(i));//9次
delay1ms();
delay1ms(); //采集间隔
}
for(j=0;j<10;j++) //循环10次,取出暂存的结果
sum+=AD_deal[j]; //将10次结果求和
sum*=0.04883; //转换电压*100=[sum*5/(10*1024)]*100,乘以100是为了分别求得个位、十位、百位
buffer[k+0]=sum/1000; //个位转化电压值
buffer[k+1]=(sum/100)%10; //十分位转化电压值
buffer[k+2]=sum/10%10; //百分位转化电压值
sum=buffer[k]*100+buffer[k+1]*10+buffer[k+2];
sum*=200/28*22/10;
buffer[k+0]=sum/1000; //个位转化电压值
buffer[k+1]=sum/100%10; //十分位转化电压值
buffer[k+2]=sum/10%10; //百分位转化电压值
k+=3; //通道号选择
sum=0;
if(k==3)
{
if(buffer[1]<2&&buffer[0]==0)
buffer[1]+=3;
}
if(k==6)
{
if(buffer[4]<buffer[1])
buffer[4]=buffer[1]-1;
if((buffer[1]+buffer[4]-3)<10)
buffer[4]=buffer[1]+buffer[4]-3;
else
{
buffer[4]=buffer[1]+buffer[4]-13;
buffer[3]=1;
}
}
}
P1M1=0;
P1M0=0;
P1ASF=0;
k=0;
sendChangeCmd();
display(getTmpValue());
clr_screen();
if(table[0]>=1||table[1]>=3||buffer[0]>=1||(buffer[1]>=4&&buffer[2]>=5)||buffer[3]>=1||buffer[4]>=5)
wind=1;
else
wind=0;
lcd_pos(1,0); //??????????
for(i=0;i<8;i++)
{
lcd_wdat(DIS1[i]);
delay(1);
}
lcd_pos(1,4);
for(i=0;i<3;i++)
{
lcd_wdat(num[table[i]]);
delay(1);
}
lcd_pos(1,6);
for(i=0;i<4;i++)
{
if(table[0]>=1|table[1]>=3)
lcd_wdat(DIS6[i]);
else
lcd_wdat(DIS5[i]);
delay(1);
}
lcd_pos(2,0); //??????????
for(i=0;i<8;i++)
{
lcd_wdat(DIS2[i]);
delay(1);
}
lcd_pos(2,4); //??????????
for(i=0;i<3;i++)
{
lcd_wdat(num[buffer[i]]);
delay(1);
}
lcd_pos(2,6);
for(i=0;i<4;i++)
{
if(buffer[0]>=1||buffer[1]>=4&&buffer[2]>=5)
lcd_wdat(DIS6[i]);
else
lcd_wdat(DIS5[i]);
delay(1);
}
lcd_pos(3,0); //??????????
for(i=0;i<8;i++)
{
lcd_wdat(DIS3[i]);
delay(1);
}
lcd_pos(3,4); //??????????
for(i=3;i<6;i++)
{
lcd_wdat(num[buffer[i]]);
delay(1);
}
lcd_pos(3,6);
for(i=0;i<4;i++)
{
if(buffer[3]>=1||buffer[4]>=5)
lcd_wdat(DIS6[i]);
else
lcd_wdat(DIS5[i]);
delay(1);
}
lcd_pos(4,0); //??????????
for(i=0;i<6;i++)
{
lcd_wdat(DIS4[i]);
delay(1);
}
lcd_pos(4,3);
for(i=0;i<3;i++)
{
if(wind==1)
lcd_wdat(DIS7[i]);
else
lcd_wdat(DIS8[i]);
}
delay(1000);
if(table[1]>=3&&table[1]!=8||buffer[0]>=1||buffer[1]>=4&&buffer[2]>=5||buffer[3]>=1||buffer[4]>=5||table[0]>=1)
{
SerialInti();
DelaySec(3);//延时约15秒,此处延时,是为了让模块有足够的时间注册到网络,
//提示开始发送指令,开始发送指令时,务必确认模块上的LED 已经慢闪,即模块已经注册到网络
//----------------为什么是下面这些AT指令呢,请看群共享文件SIM900A重要的短信指令文件------------
Uart1Sends("AT+CSCS=\"GSM\"\r\n");
DelaySec(1);//延时大约3秒
Uart1Sends("AT+CMGF=1\r\n");
DelaySec(1);//延时3秒0
Uart1Sends("AT+CSCA?\r\n");
DelaySec(1);//延时3秒
Uart1Sends("AT+CSMP=17,167,0,241\r\n");
DelaySec(1);//延时3秒
Uart1Sends("AT+CMGS=\"00000000000\"\r\n");//此处修改为对方的电话号 00000000000
DelaySec(1);//延时3秒
if(table[1]>=3||table[0]>=1)
{
Uart1Sends("temp warning");//修改短信内容,短信内容可为英文和数字
}
if(buffer[0]>=1||buffer[1]>=4&&buffer[2]>=5)
{
Uart1Sends("CO warning");//修改短信内容,短信内容可为英文和数字
}
if(buffer[3]>=1||buffer[4]>=5)
{
Uart1Sends("Dust warning");//修改短信内容,短信内容可为英文和数字
}
Uart1Send(0x1a);
DelaySec(15);//延时20秒
}
}
}
|
|