专家
公告
财富商城
电子网
旗下网站
首页
问题库
专栏
标签库
话题
专家
NEW
门户
发布
提问题
发文章
STM32
各位发烧友们,能看下我的代码为什么报错了吗?
2019-07-14 19:11
发布
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
站内问答
/
STM32/STM8
11171
7
966
友情提示:
此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
7条回答
樱花很美
2019-07-15 08:12
//延时函数
#include "delay.h"
#include "intrins.h"
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void delay_ms(u16 ms)
{
u16 i;
for(i=0;i<ms;i++)
Delay1ms();
}
#include "uart.h"
#include "timer0.h"
u16 USART1_RX_STA=0;
u8 USART1_RX_REC_ATCOMMAD;
u8 Flag_Rec_Call=0;
xdata u8 USART1_RX_BUF[USART1_MAX_RECV_LEN]; //
void Uart1Init(void) //9600bps@11.05926MHz
{
PCON &= 0x7F; //
SCON = 0x50; //
AUXR &= 0xBF; //
AUXR &= 0xFE; //
TMOD &= 0x0F; //
TMOD |= 0x20; //
TL1 = 0xFD; //
TH1 = 0xFD; //
ET1 = 0; //
TR1 = 1; //
ES=1; //
}
/*----------------------------
UART1 发送串口数据
-----------------------------*/
void UART1_SendData(u8 dat)
{
ES=0; //关串口中断
SBUF=dat;
while(TI!=1); //等待发送成功
TI=0; //清除发送中断标志
ES=1; //开串口中断
}
/*----------------------------
UART1 发送字符串
-----------------------------*/
void UART1_SendString(char *s)
{
while(*s)//检测字符串结束符
{
UART1_SendData(*s++);//发送当前字符
}
}
///*----------------------------
//UART1 发送字符串
//避免出现 软件报重复调用
//-----------------------------*/
//void UART1_SendString_other(char *s)
//{
// while(*s)//检测字符串结束符
// {
// UART1_SendData(*s++);//发送当前字符
// }
//}
/*******************************************************************************
* 函数名 : Uart1
* 描述 : 串口1中断服务入口函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
******************************/
void Uart1_INTER() interrupt 4
{
if (RI)
{
RI = 0; //清除RI位
if(USART1_RX_STA<USART1_MAX_RECV_LEN) //?1?éò??óê?êy?Y
{
TIM_SetCounter();
if(USART1_RX_STA==0) TR0=1; //开启定时器
USART1_RX_BUF[USART1_RX_STA++]=SBUF; //保存串口数据
}
else
{
USART1_RX_STA|=1<<15; //????±ê???óê?íê3é
}
}
if (TI)
{
TI = 0; //清除TI位
}
}
#include "SIMxxx.h"
u8 SIM900_CSQ[4];
u8* sim900a_check_cmd(u8 *str)
{
char *strx=0;
if(USART1_RX_STA&0X8000) //
{
USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//
strx=strstr((const char*)USART1_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART1_RX_STA=0;USART1_RX_REC_ATCOMMAD=1;
UART1_SendString(cmd);
if(ack&&waittime)
{
while(--waittime)
{
delay_ms(10);
if(USART1_RX_STA&0X8000)
{
if(sim900a_check_cmd(ack))break;
USART1_RX_STA=0;
}
}
if(waittime==0)res=1;
}
USART1_RX_STA=0;USART1_RX_REC_ATCOMMAD=0;
return res;
}
u8 sim900a_work_test(void)
{
if(sim900a_send_cmd((u8 *)"AT ",(u8 *)"OK",100))
{
if(sim900a_send_cmd((u8 *)"AT ",(u8 *)"OK",100))return SIM_COMMUNTION_ERR; //通信不上
}
if(sim900a_send_cmd((u8 *)"AT+CPIN? ",(u8 *)"READY",400))return SIM_CPIN_ERR; //没有SIM卡
if(sim900a_send_cmd((u8 *)"AT+CREG? ",(u8 *)"0,1",400))
{
if(strstr((const char*)USART1_RX_BUF,"0,5")==NULL)
{
if(!sim900a_send_cmd((u8 *)"AT+CSQ ",(u8 *)"OK",200))
{
memcpy(SIM900_CSQ,USART1_RX_BUF+15,2);
}
return SIM_CREG_FAIL; //等待附着到网络
}
}
return SIM_OK;
}
u8 SIM900A_CONNECT_SERVER(u8 *IP_ADD,u8 *COM)
{
u8 dtbuf[50];
if(sim900a_send_cmd((u8 *)"AT+CGATT? ",(u8 *)": 1",100)) return 1;
if(sim900a_send_cmd((u8 *)"AT+CIPSHUT ",(u8 *)"OK",500)) return 2;
if(sim900a_send_cmd((u8 *)"AT+CSTT ",(u8 *)"OK",200)) return 3;
if(sim900a_send_cmd((u8 *)"AT+CIICR ",(u8 *)"OK",600)) return 4;
if(!sim900a_send_cmd((u8 *)"AT+CIFSR ",(u8 *)"ERROR",200)) return 5;
sprintf((char*)dtbuf,"AT+CIPSTART="TCP","%s","%s" ",IP_ADD,COM);
if(sim900a_send_cmd((u8 *)dtbuf,(u8 *)"CONNECT OK",200)) return 6;
return 0;
}
u8 SIM900A_GPRS_SEND_DATA(u8 *temp_data)
{
u8 cmd[3];
//UART3SendString("启动数据发送,数据内容:",strlen("启动数据发送,数据内容:"));
if(sim900a_send_cmd("AT+CIPSEND ",">",100)) return 1;
//UART3SendString((u8*)temp_data,strlen((u8*)temp_data)); UART3SendString(" ",2);
if(sim900a_send_cmd(temp_data,NULL,0)) return 2;
cmd[0]=0x1a;cmd[1]=0;
if(sim900a_send_cmd(cmd,(u8 *)"SEND OK",1500)) return 3;
//UART3SendString("数据发送成功",strlen("数据发送成功")); UART3SendString(" ",2);
return 0;
}
#include "TIMER0.h"
sbit RUNING_LED=P2^1;
void Timer0Init(void) //10毫秒@115200
{
AUXR &= 0x7F;
TMOD &= 0xF0;
TMOD |= 0x01; //
TL0 = 0x00; //
TH0 = 0xDC; //
TF0 = 0; //
ET0 = 1; //
TR0 = 0; //停止计时
}
void TIM_SetCounter(void) //重新装值
{
TL0 = 0x00; //
TH0 = 0xDC; //
}
/*******************************************************************************
* 函数名 : Timer0_ISR
* 描述 : 定时器0中断服务入口函数,20ms中断一次
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0_ISR() interrupt 1
{
TR0=0;//关定时器
USART1_RX_STA|=1<<15; //
USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//添加结束符
if(!USART1_RX_REC_ATCOMMAD)
{
USART1_RX_STA=0;
if(strstr((char*)USART1_RX_BUF,"RING")!=NULL) Flag_Rec_Call=1;//检测是否是来电话了
}
}
#include <reg52.h>
typedef unsigned char uint8 ;
typedef unsigned int uint16;
sbit wd = P3^2; //定义数据单总线;
sbit e =P1^5; // 定义1602液晶显示器数据使能端口;
sbit rs=P1^0; // 定义数据/指令选择端口;
sbit rw=P1^1; // 定义 读/写 选择端口;
sbit BF=P0^7; // 定义繁忙位;
bit w=0; //定义一个全局一位变量;
//===========1602液晶显示器模块;===============
busy() //液晶屏繁忙检测函数;
{ e=0;
rs=0;
rw=0;
P0=0xff;
do
{ e=0; //使能位清零;
rs=0; //指令;
rw=1; //读;
e=1; //数据传输启动;
}while(BF); //如果BF==0;则液晶处于空闲状态;
e=0;
}
play_data(uint8 wr) //液晶写入数据;
{
busy(); //繁忙检测;
P0=wr; //装载数据;
rs=1; //数据;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
play_cmd(uint8 cmd) //液晶写入指令;
{
busy(); //繁忙检测;
P0=cmd; //装载数据;
rs=0; //指令;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
reset_1602() //1602液晶显示器初始化函数;
{
play_cmd(0x38);
play_cmd(0x0c);
play_cmd(0x06);
play_cmd(0x01);
}
//=========温度传感器延时模块============================
// sbit led= P1^0;
delay(uint8 num ) //如果unm等于1;延时16.28微妙;
{
while(num--); //如果num大于一,则16.28+(num-1)*6.51.
}
delay2() //此函数延时3.26微秒;
{
uint8 j=0;
j=9;
}
delay3()
{
uint16 s=60000;
while(s--);
}
reset_1820() //========复位温度传感器; ========
{
while(wd)
{
wd=1;
delay(140); //拉高总线,延时大概921微妙左右;(延时值自定);
wd=0; //总线由单片机拉低,下为延时函数,大概800微秒左右;
delay(61); //1个此函数会延时400微妙左右;
delay(61); //两个是800微妙左右;
wd=1; //主机拉高总线,68微秒左右;
delay(9); //延时68微妙左右
if(wd==0) //如果wd是0就终止复位;(代表复位成功);
{
while(wd==0); //总线一旦为低,那么就等待从机再将总线拉高.
break; //终止while循环;(reset function end)
}
else
{
wd=1;
delay(20); //延时140微妙;
}
}
delay(30); //此时总线为高电平并延时205微妙,复位成功!;
// if(wd)led=0;//此语句为检验是否复位成功;P1^0外接9012三极管接led小灯;
}
write_byte(uint8 dat)
{
uint8 i=0;
for(i=0;i<8;i++)
{
wd=0; //A点;
delay2(); //延时
wd=dat & 0x01;
dat>>=1;
delay(6); //A点到此处用时65.11微秒;
wd=1; //总线释放;
delay2(); //延时3.26微秒;
}
} //========此函数执行完成之后总线为高电平;
uint8 read_byte() //=====读8位数据;===================
{
uint8 j=0, dat =0;
for(j=0;j<8;j++)
{
dat>>=1;
wd=0; // A点 mcu拉低电平3.26微秒;
delay2(); // 延时3.26微秒;
wd=1;
if(wd)
{
dat|=0x80;
} //读完数据后A点到此处是11.93微秒,保持在15微秒之内;
delay(9); // A点到此处80.29微秒; 理想时间范围是60--120微秒;
wd=1; //释放总线;
delay2(); //延时3.26微秒;
}
return dat;
}
start_sensor() //启动传感器;
{
reset_1820();
write_byte(0xcc); //跳跃命令;
write_byte(0x44); //转换temperature(温度)命令;
}
uint8 read_temp() //从温度传感器度温度数据过程;
{
uint8 ak[2];
uint16 dat=0 , j=0;
reset_1820(); //复位温度传感器
write_byte(0xcc); //跳跃rom命令;
write_byte(0xbe) ; // 发出读数据命令;
ak[0]=read_byte(); //读取第一个字节数据;
ak[1]=read_byte(); //读取第二个字节数据;
dat=ak[1]; //要把两个八位数据载入1个16位变量里;
dat<<=8;
dat|=ak[0];
j= dat;
//==========以下是把温度传感器内部数据编译成16进制编码;
if((j>>11)==0x1f) //此语句是负温度进入.0x1f是二进制5个全1;
{
dat=(~dat)+1; //负温度要取反加一操作;
dat/=16; //传感器给的温度系数要除以16后,得到的数才是常规温度系数;
w=0; //此语句是在主函数中用来判断是正温度还是负温度;
return dat; //向主函数返回数据,并终止函数;
}
j=dat;
if((j>>11)==0) //如果是零则是正温度;
{
dat/=16; //数据直接除以16,就得到了常规温度系数;
w=1; //1代表正;
return dat; //向主函数返回数据,并终止函数;
}
return 130; //向主函数返回数据,并终止函数;
}
delay_ms() //延时1秒;
{
uint8 i=250;
uint16 j=608;
while(j--)
{ while(i--);
i=250;
}
}
error() //测温出错;
{ uint8 i=5, j=0 ,ak[]="Error!";
while(i--)
{
play_cmd(0x82);
while(ak[j]!=' ')
{
play_data(ak[j++]);
} j=0;
delay3();
play_cmd(0x01);
delay3();
}
}
#endif
/* reg52.h 中文注释详解 */
/*--------------------------------------------------------------------------
REG52.H
Header file for generic 80C52 and 80C32 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/
#ifndef __REG52_H__
#define __REG52_H__
/* 特殊字节(8位)寄存器 */
sfr P0 = 0x80; // P0口特殊寄存器寻址位
sfr P1 = 0x90; // P1口特殊寄存器寻址位
sfr P2 = 0xA0; // P2口特殊寄存器寻址位
sfr P3 = 0xB0; // P3口特殊寄存器寻址位
sfr PSW = 0xD0; //程序状态字寄存器
sfr ACC = 0xE0; //累加器
sfr B = 0xF0; //B 特殊寄存器
sfr SP = 0x81; //堆栈指针寄存器
sfr DPL = 0x82; //数字指针(低位)
sfr DPH = 0x83; //数字指针(高位)
sfr PCON = 0x87; //电源控制寄存器
sfr TCON = 0x88; //定时器/计数器 0 和 1 控制
sfr TMOD = 0x89; //定时器/计数器 0 和 1 模式
sfr TL0 = 0x8A; //定时器/计数器 0 低8位寄存器
sfr TL1 = 0x8B; //定时器/计数器 1低8位寄存器
sfr TH0 = 0x8C; //定时器/计数器 0高8位寄存器
sfr TH1 = 0x8D; //定时器/计数器 1高8位寄存器
sfr IE = 0xA8; //中断允许寄存器
sfr IP = 0xB8; //中断优先寄存器(低)
sfr SCON = 0x98; //串口控制寄存器
sfr SBUF = 0x99; //串口数据缓冲器
/* 8052扩展寄存器 */
sfr T2CON = 0xC8; //定时器/计数器2 控制
sfr RCAP2L = 0xCA; //定时器/计数器2 重载/捕捉低位
sfr RCAP2H = 0xCB; //定时器/计数器2 重载/捕捉高位
sfr TL2 = 0xCC; //定时器/计数器2 低位
sfr TH2 = 0xCD; //定时器/计数器2 高位
/* 位寄存器 */
/* PSW (程序状态字寄存器) */
sbit CY = PSW^7; //进位、借位标志。进位、借位CY=1;否则CY=0
sbit AC = PSW^6; //辅助进位、借位标志。当D3向D4有借位或进位时,AC=1;否则AC=0
sbit F0 = PSW^5; //用户标志位
sbit RS1 = PSW^4; //寄存器组选择控制位1
sbit RS0 = PSW^3; //寄存器组选择控制位0
sbit OV = PSW^2; //溢出标志。有溢出OV=1,否则OV=0
sbit F1 = PSW^1; //保留位,无定义
sbit P = PSW^0; //8052 only 奇偶校验标志位,由硬件置位或清0;
//存在ACC中的运算结果有奇数个1时P=1,否则P=0
/* TCON (定时器/计数器 0 和 1 控制) */
sbit TF1 = TCON^7; //定时器1溢出标志位。当字时器1计满溢出时,
//由硬件使TF1置"1",并且申请中断。
//进入中断服务程序后,由硬件自动清"0",在查询方式下用软件清 "0"
sbit TR1 = TCON^6; //定时器1运行控制位。由软件清"0"关闭定时器1。
//当GATE=1,且INT1为高电平时,TR1置"1"启动定时器1;
//当GATE=0,TR1置"1" 启动定时器1
sbit TF0 = TCON^5; //定时器0溢出标志。其功能及操作情况同TF1。
sbit TR0 = TCON^4; //定时器0运行控制位。其功能及操作情况同TR1。
sbit IE1 = TCON^3; //外部中断1请求标志。
sbit IT1 = TCON^2; //外部中断1触发方式选择位。
sbit IE0 = TCON^1; //外部中断0请求标志。
sbit IT0 = TCON^0; //外部中断0触发方式选择位。
/* IE (中断允许寄存器) */
sbit EA = IE^7; //允许/禁止总中断
sbit ET2 = IE^5; //8052 only 允许/禁止定时器2(T2)中断
sbit ES = IE^4; //允许/禁止串口中断
sbit ET1 = IE^3; //允许/禁止T1溢出中断
sbit EX1 = IE^2; //允许/禁止外部中断1(INT1)
sbit ET0 = IE^1; //允许/禁止T0溢出中断
sbit EX0 = IE^0; //允许/禁止外部中断0(INT0)
/* IP (中断优先寄存器低) */
sbit PT2 = IP^5; //定时/计数器T2优先级设定位。
sbit PS = IP^4; //串行口优先级设定位;
sbit PT1 = IP^3; //定时/计数器T1优先级设定位;
sbit PX1 = IP^2; //外部中断0优先级设定位;
sbit PT0 = IP^1; //定时/计数器T0优先级设定位;
sbit PX0 = IP^0; //外部中断0优先级设定位;
/* P3 (第二功能) */
sbit RD = P3^7; //外部数据存储器读脉冲
sbit WR = P3^6; //外部数据存储器写脉冲
sbit T1 = P3^5; //定时器/计数器1外部输入
sbit T0 = P3^4; //定时器/计数器0外部输入
sbit INT1 = P3^3; //外部中断0。
sbit INT0 = P3^2; //外部中断1。
sbit TXD = P3^1; //串行数据输出口
sbit RXD = P3^0; //串行数据输入口
/* SCON(控制寄存器,它是一个可寻址的专用寄存器,用于串行数据的通信控制) */
sbit SM0 = SCON^7; //串行口工作方式控制位0。
sbit SM1 = SCON^6; //串行口工作方式控制位1。
sbit SM2 = SCON^5; //多机通信控制位。
sbit REN = SCON^4; //允许接收位。用于控制数据接收的允许和禁止,
// ren=1时,允许接收,ren=0时,禁止接收。
sbit TB8 = SCON^3; //发送接收数据位8。
sbit RB8 = SCON^2; //接收数据位8。
sbit TI = SCON^1; //发送中断标志位。
sbit RI = SCON^0; //接收中断标志位。
/* P1(第二功能) */
sbit T2EX = P1^1; // 8052 only 定时/计数器2捕捉/重装入触发
sbit T2 = P1^0; // 8052 only 定时/计数器2外部输入
/* T2CON (定时器/计数器2 控制) */
sbit TF2 = T2CON^7; //定时器2 溢出标记
sbit EXF2 = T2CON^6; //定时器2 外部标记
sbit RCLK = T2CON^5; //0=串口时钟应用定时器1 溢出, 1=定时器 2
sbit TCLK = T2CON^4; //0=串口时钟应用定时器1 溢出, 1=定时器 2
sbit EXEN2 = T2CON^3; //定时器 2 外部允许
sbit TR2 = T2CON^2; //0=停止定时器, 1=开始定时器
sbit C_T2 = T2CON^1; //0=定时器, 1=计数器
sbit CP_RL2 = T2CON^0; //0=重载, 1=捕捉选择。
#endif
#include <reg52.h>
typedef unsigned char uint8 ;
typedef unsigned int uint16;
sbit wd = P3^2; //定义数据单总线;
sbit e =P1^5; // 定义1602液晶显示器数据使能端口;
sbit rs=P1^0; // 定义数据/指令选择端口;
sbit rw=P1^1; // 定义 读/写 选择端口;
sbit BF=P0^7; // 定义繁忙位;
bit w=0; //定义一个全局一位变量;
//===========1602液晶显示器模块;===============
busy() //液晶屏繁忙检测函数;
{ e=0;
rs=0;
rw=0;
P0=0xff;
do
{ e=0; //使能位清零;
rs=0; //指令;
rw=1; //读;
e=1; //数据传输启动;
}while(BF); //如果BF==0;则液晶处于空闲状态;
e=0;
}
play_data(uint8 wr) //液晶写入数据;
{
busy(); //繁忙检测;
P0=wr; //装载数据;
rs=1; //数据;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
play_cmd(uint8 cmd) //液晶写入指令;
{
busy(); //繁忙检测;
P0=cmd; //装载数据;
rs=0; //指令;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
reset_1602() //1602液晶显示器初始化函数;
{
play_cmd(0x38);
play_cmd(0x0c);
play_cmd(0x06);
play_cmd(0x01);
}
//=========温度传感器延时模块============================
// sbit led= P1^0;
delay(uint8 num ) //如果unm等于1;延时16.28微妙;
{
while(num--); //如果num大于一,则16.28+(num-1)*6.51.
}
delay2() //此函数延时3.26微秒;
{
uint8 j=0;
j=9;
}
delay3()
{
uint16 s=60000;
while(s--);
}
reset_1820() //========复位温度传感器; ========
{
while(wd)
{
wd=1;
delay(140); //拉高总线,延时大概921微妙左右;(延时值自定);
wd=0; //总线由单片机拉低,下为延时函数,大概800微秒左右;
delay(61); //1个此函数会延时400微妙左右;
delay(61); //两个是800微妙左右;
wd=1; //主机拉高总线,68微秒左右;
delay(9); //延时68微妙左右
if(wd==0) //如果wd是0就终止复位;(代表复位成功);
{
while(wd==0); //总线一旦为低,那么就等待从机再将总线拉高.
break; //终止while循环;(reset function end)
}
else
{
wd=1;
delay(20); //延时140微妙;
}
}
delay(30); //此时总线为高电平并延时205微妙,复位成功!;
// if(wd)led=0;//此语句为检验是否复位成功;P1^0外接9012三极管接led小灯;
}
write_byte(uint8 dat)
{
uint8 i=0;
for(i=0;i<8;i++)
{
wd=0; //A点;
delay2(); //延时
wd=dat & 0x01;
dat>>=1;
delay(6); //A点到此处用时65.11微秒;
wd=1; //总线释放;
delay2(); //延时3.26微秒;
}
} //========此函数执行完成之后总线为高电平;
uint8 read_byte() //=====读8位数据;===================
{
uint8 j=0, dat =0;
for(j=0;j<8;j++)
{
dat>>=1;
wd=0; // A点 mcu拉低电平3.26微秒;
delay2(); // 延时3.26微秒;
wd=1;
if(wd)
{
dat|=0x80;
} //读完数据后A点到此处是11.93微秒,保持在15微秒之内;
delay(9); // A点到此处80.29微秒; 理想时间范围是60--120微秒;
wd=1; //释放总线;
delay2(); //延时3.26微秒;
}
return dat;
}
start_sensor() //启动传感器;
{
reset_1820();
write_byte(0xcc); //跳跃命令;
write_byte(0x44); //转换temperature(温度)命令;
}
uint8 read_temp() //从温度传感器度温度数据过程;
{
uint8 ak[2];
uint16 dat=0 , j=0;
reset_1820(); //复位温度传感器
write_byte(0xcc); //跳跃rom命令;
write_byte(0xbe) ; // 发出读数据命令;
ak[0]=read_byte(); //读取第一个字节数据;
ak[1]=read_byte(); //读取第二个字节数据;
dat=ak[1]; //要把两个八位数据载入1个16位变量里;
dat<<=8;
dat|=ak[0];
j= dat;
//==========以下是把温度传感器内部数据编译成16进制编码;
if((j>>11)==0x1f) //此语句是负温度进入.0x1f是二进制5个全1;
{
dat=(~dat)+1; //负温度要取反加一操作;
dat/=16; //传感器给的温度系数要除以16后,得到的数才是常规温度系数;
w=0; //此语句是在主函数中用来判断是正温度还是负温度;
return dat; //向主函数返回数据,并终止函数;
}
j=dat;
if((j>>11)==0) //如果是零则是正温度;
{
dat/=16; //数据直接除以16,就得到了常规温度系数;
w=1; //1代表正;
return dat; //向主函数返回数据,并终止函数;
}
return 130; //向主函数返回数据,并终止函数;
}
delay_ms() //延时1秒;
{
uint8 i=250;
uint16 j=608;
while(j--)
{ while(i--);
i=250;
}
}
error() //测温出错;
{
uint8 i=5, j=0 ,ak[]="Error!";
while(i--)
{
play_cmd(0x82);
while(ak[j]!=' ')
{
play_data(ak[j++]);
} j=0;
delay3();
play_cmd(0x01);
delay3();
}
}
main()
{
uint8 dat=0 ,j=3,len=0 ,num[]="start.....";
reset_1602();
while(j--) //这是启动电源时,液晶显示:start....(并闪烁3次)
{ play_cmd(0x82);
while(num[len]!=' ')
{
play_data(num[len++]);
}
len=0;
delay3();
play_cmd(0x01);
delay3();
}
while(1)
{
start_sensor(); //启动温度传感器;
delay_ms(); //等待1秒;
dat = read_temp(); //读取温度数据并赋给dat变量;
if(dat==130) //如果返回来的数据是130,表明采集温度出错;
{
error();
}
else if(w==1) //如果w是1,就代表正温度.输出;
{
play_cmd(0x83);
play_data(dat/10+'0');
play_data(dat%10+'0');
}
else //否则,就是负温度,输出时前面加一个负号;
{
play_cmd(0x82);
play_data('-');
play_data(dat/10+'0');
play_data(dat%10+'0');
}
} //我的亲娘四舅奶奶啊!!!!!!终于完成了!!!!2013年5月9日19:32:10
}
加载中...
查看其它7个回答
一周热门
更多
>
相关问题
STM32F4上I2C(在PROTEUS中模拟)调试不通的问题
6 个回答
芯片供应紧张,准备换个MCU,MM32L系列替换STM32L系列的怎么样?
7 个回答
STM32同时使用两个串口进行数据收发时数据丢包的问题
5 个回答
STM32F103串口通信死机问题
4 个回答
STM32WLE5CC连接SX1268在LoRa模式下能与 SX1278互通吗?
2 个回答
相关文章
ST公司第一款无线低功耗单片机模块有效提高物联网设计生产效率
0个评论
如何实现对单片机寄存器的访问
0个评论
通过USB用STM32片内自带Bootloader下载程序及注意事项
0个评论
欲练此功必先自宫之STM32汇编启动,放慢是为了更好的前行
0个评论
×
关闭
采纳回答
向帮助了您的知道网友说句感谢的话吧!
非常感谢!
确 认
×
关闭
编辑标签
最多设置5个标签!
STM32
保存
关闭
×
关闭
举报内容
检举类型
检举内容
检举用户
检举原因
广告推广
恶意灌水
回答内容与提问无关
抄袭答案
其他
检举说明(必填)
提交
关闭
×
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
×
付费偷看金额在0.1-10元之间
确定
×
关闭
您已邀请
0
人回答
查看邀请
擅长该话题的人
回答过该话题的人
我关注的人
#include "delay.h"
#include "intrins.h"
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
void delay_ms(u16 ms)
{
u16 i;
for(i=0;i<ms;i++)
Delay1ms();
}
#include "uart.h"
#include "timer0.h"
u16 USART1_RX_STA=0;
u8 USART1_RX_REC_ATCOMMAD;
u8 Flag_Rec_Call=0;
xdata u8 USART1_RX_BUF[USART1_MAX_RECV_LEN]; //
void Uart1Init(void) //9600bps@11.05926MHz
{
PCON &= 0x7F; //
SCON = 0x50; //
AUXR &= 0xBF; //
AUXR &= 0xFE; //
TMOD &= 0x0F; //
TMOD |= 0x20; //
TL1 = 0xFD; //
TH1 = 0xFD; //
ET1 = 0; //
TR1 = 1; //
ES=1; //
}
/*----------------------------
UART1 发送串口数据
-----------------------------*/
void UART1_SendData(u8 dat)
{
ES=0; //关串口中断
SBUF=dat;
while(TI!=1); //等待发送成功
TI=0; //清除发送中断标志
ES=1; //开串口中断
}
/*----------------------------
UART1 发送字符串
-----------------------------*/
void UART1_SendString(char *s)
{
while(*s)//检测字符串结束符
{
UART1_SendData(*s++);//发送当前字符
}
}
///*----------------------------
//UART1 发送字符串
//避免出现 软件报重复调用
//-----------------------------*/
//void UART1_SendString_other(char *s)
//{
// while(*s)//检测字符串结束符
// {
// UART1_SendData(*s++);//发送当前字符
// }
//}
/*******************************************************************************
* 函数名 : Uart1
* 描述 : 串口1中断服务入口函数
* 输入 :
* 输出 :
* 返回 :
* 注意 :
******************************/
void Uart1_INTER() interrupt 4
{
if (RI)
{
RI = 0; //清除RI位
if(USART1_RX_STA<USART1_MAX_RECV_LEN) //?1?éò??óê?êy?Y
{
TIM_SetCounter();
if(USART1_RX_STA==0) TR0=1; //开启定时器
USART1_RX_BUF[USART1_RX_STA++]=SBUF; //保存串口数据
}
else
{
USART1_RX_STA|=1<<15; //????±ê???óê?íê3é
}
}
if (TI)
{
TI = 0; //清除TI位
}
}
#include "SIMxxx.h"
u8 SIM900_CSQ[4];
u8* sim900a_check_cmd(u8 *str)
{
char *strx=0;
if(USART1_RX_STA&0X8000) //
{
USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//
strx=strstr((const char*)USART1_RX_BUF,(const char*)str);
}
return (u8*)strx;
}
u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime)
{
u8 res=0;
USART1_RX_STA=0;USART1_RX_REC_ATCOMMAD=1;
UART1_SendString(cmd);
if(ack&&waittime)
{
while(--waittime)
{
delay_ms(10);
if(USART1_RX_STA&0X8000)
{
if(sim900a_check_cmd(ack))break;
USART1_RX_STA=0;
}
}
if(waittime==0)res=1;
}
USART1_RX_STA=0;USART1_RX_REC_ATCOMMAD=0;
return res;
}
u8 sim900a_work_test(void)
{
if(sim900a_send_cmd((u8 *)"AT ",(u8 *)"OK",100))
{
if(sim900a_send_cmd((u8 *)"AT ",(u8 *)"OK",100))return SIM_COMMUNTION_ERR; //通信不上
}
if(sim900a_send_cmd((u8 *)"AT+CPIN? ",(u8 *)"READY",400))return SIM_CPIN_ERR; //没有SIM卡
if(sim900a_send_cmd((u8 *)"AT+CREG? ",(u8 *)"0,1",400))
{
if(strstr((const char*)USART1_RX_BUF,"0,5")==NULL)
{
if(!sim900a_send_cmd((u8 *)"AT+CSQ ",(u8 *)"OK",200))
{
memcpy(SIM900_CSQ,USART1_RX_BUF+15,2);
}
return SIM_CREG_FAIL; //等待附着到网络
}
}
return SIM_OK;
}
u8 SIM900A_CONNECT_SERVER(u8 *IP_ADD,u8 *COM)
{
u8 dtbuf[50];
if(sim900a_send_cmd((u8 *)"AT+CGATT? ",(u8 *)": 1",100)) return 1;
if(sim900a_send_cmd((u8 *)"AT+CIPSHUT ",(u8 *)"OK",500)) return 2;
if(sim900a_send_cmd((u8 *)"AT+CSTT ",(u8 *)"OK",200)) return 3;
if(sim900a_send_cmd((u8 *)"AT+CIICR ",(u8 *)"OK",600)) return 4;
if(!sim900a_send_cmd((u8 *)"AT+CIFSR ",(u8 *)"ERROR",200)) return 5;
sprintf((char*)dtbuf,"AT+CIPSTART="TCP","%s","%s" ",IP_ADD,COM);
if(sim900a_send_cmd((u8 *)dtbuf,(u8 *)"CONNECT OK",200)) return 6;
return 0;
}
u8 SIM900A_GPRS_SEND_DATA(u8 *temp_data)
{
u8 cmd[3];
//UART3SendString("启动数据发送,数据内容:",strlen("启动数据发送,数据内容:"));
if(sim900a_send_cmd("AT+CIPSEND ",">",100)) return 1;
//UART3SendString((u8*)temp_data,strlen((u8*)temp_data)); UART3SendString(" ",2);
if(sim900a_send_cmd(temp_data,NULL,0)) return 2;
cmd[0]=0x1a;cmd[1]=0;
if(sim900a_send_cmd(cmd,(u8 *)"SEND OK",1500)) return 3;
//UART3SendString("数据发送成功",strlen("数据发送成功")); UART3SendString(" ",2);
return 0;
}
#include "TIMER0.h"
sbit RUNING_LED=P2^1;
void Timer0Init(void) //10毫秒@115200
{
AUXR &= 0x7F;
TMOD &= 0xF0;
TMOD |= 0x01; //
TL0 = 0x00; //
TH0 = 0xDC; //
TF0 = 0; //
ET0 = 1; //
TR0 = 0; //停止计时
}
void TIM_SetCounter(void) //重新装值
{
TL0 = 0x00; //
TH0 = 0xDC; //
}
/*******************************************************************************
* 函数名 : Timer0_ISR
* 描述 : 定时器0中断服务入口函数,20ms中断一次
* 输入 :
* 输出 :
* 返回 :
* 注意 :
*******************************************************************************/
void Timer0_ISR() interrupt 1
{
TR0=0;//关定时器
USART1_RX_STA|=1<<15; //
USART1_RX_BUF[USART1_RX_STA&0X7FFF]=0;//添加结束符
if(!USART1_RX_REC_ATCOMMAD)
{
USART1_RX_STA=0;
if(strstr((char*)USART1_RX_BUF,"RING")!=NULL) Flag_Rec_Call=1;//检测是否是来电话了
}
}
#include <reg52.h>
typedef unsigned char uint8 ;
typedef unsigned int uint16;
sbit wd = P3^2; //定义数据单总线;
sbit e =P1^5; // 定义1602液晶显示器数据使能端口;
sbit rs=P1^0; // 定义数据/指令选择端口;
sbit rw=P1^1; // 定义 读/写 选择端口;
sbit BF=P0^7; // 定义繁忙位;
bit w=0; //定义一个全局一位变量;
//===========1602液晶显示器模块;===============
busy() //液晶屏繁忙检测函数;
{ e=0;
rs=0;
rw=0;
P0=0xff;
do
{ e=0; //使能位清零;
rs=0; //指令;
rw=1; //读;
e=1; //数据传输启动;
}while(BF); //如果BF==0;则液晶处于空闲状态;
e=0;
}
play_data(uint8 wr) //液晶写入数据;
{
busy(); //繁忙检测;
P0=wr; //装载数据;
rs=1; //数据;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
play_cmd(uint8 cmd) //液晶写入指令;
{
busy(); //繁忙检测;
P0=cmd; //装载数据;
rs=0; //指令;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
reset_1602() //1602液晶显示器初始化函数;
{
play_cmd(0x38);
play_cmd(0x0c);
play_cmd(0x06);
play_cmd(0x01);
}
//=========温度传感器延时模块============================
// sbit led= P1^0;
delay(uint8 num ) //如果unm等于1;延时16.28微妙;
{
while(num--); //如果num大于一,则16.28+(num-1)*6.51.
}
delay2() //此函数延时3.26微秒;
{
uint8 j=0;
j=9;
}
delay3()
{
uint16 s=60000;
while(s--);
}
reset_1820() //========复位温度传感器; ========
{
while(wd)
{
wd=1;
delay(140); //拉高总线,延时大概921微妙左右;(延时值自定);
wd=0; //总线由单片机拉低,下为延时函数,大概800微秒左右;
delay(61); //1个此函数会延时400微妙左右;
delay(61); //两个是800微妙左右;
wd=1; //主机拉高总线,68微秒左右;
delay(9); //延时68微妙左右
if(wd==0) //如果wd是0就终止复位;(代表复位成功);
{
while(wd==0); //总线一旦为低,那么就等待从机再将总线拉高.
break; //终止while循环;(reset function end)
}
else
{
wd=1;
delay(20); //延时140微妙;
}
}
delay(30); //此时总线为高电平并延时205微妙,复位成功!;
// if(wd)led=0;//此语句为检验是否复位成功;P1^0外接9012三极管接led小灯;
}
write_byte(uint8 dat)
{
uint8 i=0;
for(i=0;i<8;i++)
{
wd=0; //A点;
delay2(); //延时
wd=dat & 0x01;
dat>>=1;
delay(6); //A点到此处用时65.11微秒;
wd=1; //总线释放;
delay2(); //延时3.26微秒;
}
} //========此函数执行完成之后总线为高电平;
uint8 read_byte() //=====读8位数据;===================
{
uint8 j=0, dat =0;
for(j=0;j<8;j++)
{
dat>>=1;
wd=0; // A点 mcu拉低电平3.26微秒;
delay2(); // 延时3.26微秒;
wd=1;
if(wd)
{
dat|=0x80;
} //读完数据后A点到此处是11.93微秒,保持在15微秒之内;
delay(9); // A点到此处80.29微秒; 理想时间范围是60--120微秒;
wd=1; //释放总线;
delay2(); //延时3.26微秒;
}
return dat;
}
start_sensor() //启动传感器;
{
reset_1820();
write_byte(0xcc); //跳跃命令;
write_byte(0x44); //转换temperature(温度)命令;
}
uint8 read_temp() //从温度传感器度温度数据过程;
{
uint8 ak[2];
uint16 dat=0 , j=0;
reset_1820(); //复位温度传感器
write_byte(0xcc); //跳跃rom命令;
write_byte(0xbe) ; // 发出读数据命令;
ak[0]=read_byte(); //读取第一个字节数据;
ak[1]=read_byte(); //读取第二个字节数据;
dat=ak[1]; //要把两个八位数据载入1个16位变量里;
dat<<=8;
dat|=ak[0];
j= dat;
//==========以下是把温度传感器内部数据编译成16进制编码;
if((j>>11)==0x1f) //此语句是负温度进入.0x1f是二进制5个全1;
{
dat=(~dat)+1; //负温度要取反加一操作;
dat/=16; //传感器给的温度系数要除以16后,得到的数才是常规温度系数;
w=0; //此语句是在主函数中用来判断是正温度还是负温度;
return dat; //向主函数返回数据,并终止函数;
}
j=dat;
if((j>>11)==0) //如果是零则是正温度;
{
dat/=16; //数据直接除以16,就得到了常规温度系数;
w=1; //1代表正;
return dat; //向主函数返回数据,并终止函数;
}
return 130; //向主函数返回数据,并终止函数;
}
delay_ms() //延时1秒;
{
uint8 i=250;
uint16 j=608;
while(j--)
{ while(i--);
i=250;
}
}
error() //测温出错;
{ uint8 i=5, j=0 ,ak[]="Error!";
while(i--)
{
play_cmd(0x82);
while(ak[j]!=' ')
{
play_data(ak[j++]);
} j=0;
delay3();
play_cmd(0x01);
delay3();
}
}
#endif
/* reg52.h 中文注释详解 */
/*--------------------------------------------------------------------------
REG52.H
Header file for generic 80C52 and 80C32 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/
#ifndef __REG52_H__
#define __REG52_H__
/* 特殊字节(8位)寄存器 */
sfr P0 = 0x80; // P0口特殊寄存器寻址位
sfr P1 = 0x90; // P1口特殊寄存器寻址位
sfr P2 = 0xA0; // P2口特殊寄存器寻址位
sfr P3 = 0xB0; // P3口特殊寄存器寻址位
sfr PSW = 0xD0; //程序状态字寄存器
sfr ACC = 0xE0; //累加器
sfr B = 0xF0; //B 特殊寄存器
sfr SP = 0x81; //堆栈指针寄存器
sfr DPL = 0x82; //数字指针(低位)
sfr DPH = 0x83; //数字指针(高位)
sfr PCON = 0x87; //电源控制寄存器
sfr TCON = 0x88; //定时器/计数器 0 和 1 控制
sfr TMOD = 0x89; //定时器/计数器 0 和 1 模式
sfr TL0 = 0x8A; //定时器/计数器 0 低8位寄存器
sfr TL1 = 0x8B; //定时器/计数器 1低8位寄存器
sfr TH0 = 0x8C; //定时器/计数器 0高8位寄存器
sfr TH1 = 0x8D; //定时器/计数器 1高8位寄存器
sfr IE = 0xA8; //中断允许寄存器
sfr IP = 0xB8; //中断优先寄存器(低)
sfr SCON = 0x98; //串口控制寄存器
sfr SBUF = 0x99; //串口数据缓冲器
/* 8052扩展寄存器 */
sfr T2CON = 0xC8; //定时器/计数器2 控制
sfr RCAP2L = 0xCA; //定时器/计数器2 重载/捕捉低位
sfr RCAP2H = 0xCB; //定时器/计数器2 重载/捕捉高位
sfr TL2 = 0xCC; //定时器/计数器2 低位
sfr TH2 = 0xCD; //定时器/计数器2 高位
/* 位寄存器 */
/* PSW (程序状态字寄存器) */
sbit CY = PSW^7; //进位、借位标志。进位、借位CY=1;否则CY=0
sbit AC = PSW^6; //辅助进位、借位标志。当D3向D4有借位或进位时,AC=1;否则AC=0
sbit F0 = PSW^5; //用户标志位
sbit RS1 = PSW^4; //寄存器组选择控制位1
sbit RS0 = PSW^3; //寄存器组选择控制位0
sbit OV = PSW^2; //溢出标志。有溢出OV=1,否则OV=0
sbit F1 = PSW^1; //保留位,无定义
sbit P = PSW^0; //8052 only 奇偶校验标志位,由硬件置位或清0;
//存在ACC中的运算结果有奇数个1时P=1,否则P=0
/* TCON (定时器/计数器 0 和 1 控制) */
sbit TF1 = TCON^7; //定时器1溢出标志位。当字时器1计满溢出时,
//由硬件使TF1置"1",并且申请中断。
//进入中断服务程序后,由硬件自动清"0",在查询方式下用软件清 "0"
sbit TR1 = TCON^6; //定时器1运行控制位。由软件清"0"关闭定时器1。
//当GATE=1,且INT1为高电平时,TR1置"1"启动定时器1;
//当GATE=0,TR1置"1" 启动定时器1
sbit TF0 = TCON^5; //定时器0溢出标志。其功能及操作情况同TF1。
sbit TR0 = TCON^4; //定时器0运行控制位。其功能及操作情况同TR1。
sbit IE1 = TCON^3; //外部中断1请求标志。
sbit IT1 = TCON^2; //外部中断1触发方式选择位。
sbit IE0 = TCON^1; //外部中断0请求标志。
sbit IT0 = TCON^0; //外部中断0触发方式选择位。
/* IE (中断允许寄存器) */
sbit EA = IE^7; //允许/禁止总中断
sbit ET2 = IE^5; //8052 only 允许/禁止定时器2(T2)中断
sbit ES = IE^4; //允许/禁止串口中断
sbit ET1 = IE^3; //允许/禁止T1溢出中断
sbit EX1 = IE^2; //允许/禁止外部中断1(INT1)
sbit ET0 = IE^1; //允许/禁止T0溢出中断
sbit EX0 = IE^0; //允许/禁止外部中断0(INT0)
/* IP (中断优先寄存器低) */
sbit PT2 = IP^5; //定时/计数器T2优先级设定位。
sbit PS = IP^4; //串行口优先级设定位;
sbit PT1 = IP^3; //定时/计数器T1优先级设定位;
sbit PX1 = IP^2; //外部中断0优先级设定位;
sbit PT0 = IP^1; //定时/计数器T0优先级设定位;
sbit PX0 = IP^0; //外部中断0优先级设定位;
/* P3 (第二功能) */
sbit RD = P3^7; //外部数据存储器读脉冲
sbit WR = P3^6; //外部数据存储器写脉冲
sbit T1 = P3^5; //定时器/计数器1外部输入
sbit T0 = P3^4; //定时器/计数器0外部输入
sbit INT1 = P3^3; //外部中断0。
sbit INT0 = P3^2; //外部中断1。
sbit TXD = P3^1; //串行数据输出口
sbit RXD = P3^0; //串行数据输入口
/* SCON(控制寄存器,它是一个可寻址的专用寄存器,用于串行数据的通信控制) */
sbit SM0 = SCON^7; //串行口工作方式控制位0。
sbit SM1 = SCON^6; //串行口工作方式控制位1。
sbit SM2 = SCON^5; //多机通信控制位。
sbit REN = SCON^4; //允许接收位。用于控制数据接收的允许和禁止,
// ren=1时,允许接收,ren=0时,禁止接收。
sbit TB8 = SCON^3; //发送接收数据位8。
sbit RB8 = SCON^2; //接收数据位8。
sbit TI = SCON^1; //发送中断标志位。
sbit RI = SCON^0; //接收中断标志位。
/* P1(第二功能) */
sbit T2EX = P1^1; // 8052 only 定时/计数器2捕捉/重装入触发
sbit T2 = P1^0; // 8052 only 定时/计数器2外部输入
/* T2CON (定时器/计数器2 控制) */
sbit TF2 = T2CON^7; //定时器2 溢出标记
sbit EXF2 = T2CON^6; //定时器2 外部标记
sbit RCLK = T2CON^5; //0=串口时钟应用定时器1 溢出, 1=定时器 2
sbit TCLK = T2CON^4; //0=串口时钟应用定时器1 溢出, 1=定时器 2
sbit EXEN2 = T2CON^3; //定时器 2 外部允许
sbit TR2 = T2CON^2; //0=停止定时器, 1=开始定时器
sbit C_T2 = T2CON^1; //0=定时器, 1=计数器
sbit CP_RL2 = T2CON^0; //0=重载, 1=捕捉选择。
#endif
#include <reg52.h>
typedef unsigned char uint8 ;
typedef unsigned int uint16;
sbit wd = P3^2; //定义数据单总线;
sbit e =P1^5; // 定义1602液晶显示器数据使能端口;
sbit rs=P1^0; // 定义数据/指令选择端口;
sbit rw=P1^1; // 定义 读/写 选择端口;
sbit BF=P0^7; // 定义繁忙位;
bit w=0; //定义一个全局一位变量;
//===========1602液晶显示器模块;===============
busy() //液晶屏繁忙检测函数;
{ e=0;
rs=0;
rw=0;
P0=0xff;
do
{ e=0; //使能位清零;
rs=0; //指令;
rw=1; //读;
e=1; //数据传输启动;
}while(BF); //如果BF==0;则液晶处于空闲状态;
e=0;
}
play_data(uint8 wr) //液晶写入数据;
{
busy(); //繁忙检测;
P0=wr; //装载数据;
rs=1; //数据;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
play_cmd(uint8 cmd) //液晶写入指令;
{
busy(); //繁忙检测;
P0=cmd; //装载数据;
rs=0; //指令;
rw=0; //写入;
e=1; //传输开始;
e=0; //传输结束;
}
reset_1602() //1602液晶显示器初始化函数;
{
play_cmd(0x38);
play_cmd(0x0c);
play_cmd(0x06);
play_cmd(0x01);
}
//=========温度传感器延时模块============================
// sbit led= P1^0;
delay(uint8 num ) //如果unm等于1;延时16.28微妙;
{
while(num--); //如果num大于一,则16.28+(num-1)*6.51.
}
delay2() //此函数延时3.26微秒;
{
uint8 j=0;
j=9;
}
delay3()
{
uint16 s=60000;
while(s--);
}
reset_1820() //========复位温度传感器; ========
{
while(wd)
{
wd=1;
delay(140); //拉高总线,延时大概921微妙左右;(延时值自定);
wd=0; //总线由单片机拉低,下为延时函数,大概800微秒左右;
delay(61); //1个此函数会延时400微妙左右;
delay(61); //两个是800微妙左右;
wd=1; //主机拉高总线,68微秒左右;
delay(9); //延时68微妙左右
if(wd==0) //如果wd是0就终止复位;(代表复位成功);
{
while(wd==0); //总线一旦为低,那么就等待从机再将总线拉高.
break; //终止while循环;(reset function end)
}
else
{
wd=1;
delay(20); //延时140微妙;
}
}
delay(30); //此时总线为高电平并延时205微妙,复位成功!;
// if(wd)led=0;//此语句为检验是否复位成功;P1^0外接9012三极管接led小灯;
}
write_byte(uint8 dat)
{
uint8 i=0;
for(i=0;i<8;i++)
{
wd=0; //A点;
delay2(); //延时
wd=dat & 0x01;
dat>>=1;
delay(6); //A点到此处用时65.11微秒;
wd=1; //总线释放;
delay2(); //延时3.26微秒;
}
} //========此函数执行完成之后总线为高电平;
uint8 read_byte() //=====读8位数据;===================
{
uint8 j=0, dat =0;
for(j=0;j<8;j++)
{
dat>>=1;
wd=0; // A点 mcu拉低电平3.26微秒;
delay2(); // 延时3.26微秒;
wd=1;
if(wd)
{
dat|=0x80;
} //读完数据后A点到此处是11.93微秒,保持在15微秒之内;
delay(9); // A点到此处80.29微秒; 理想时间范围是60--120微秒;
wd=1; //释放总线;
delay2(); //延时3.26微秒;
}
return dat;
}
start_sensor() //启动传感器;
{
reset_1820();
write_byte(0xcc); //跳跃命令;
write_byte(0x44); //转换temperature(温度)命令;
}
uint8 read_temp() //从温度传感器度温度数据过程;
{
uint8 ak[2];
uint16 dat=0 , j=0;
reset_1820(); //复位温度传感器
write_byte(0xcc); //跳跃rom命令;
write_byte(0xbe) ; // 发出读数据命令;
ak[0]=read_byte(); //读取第一个字节数据;
ak[1]=read_byte(); //读取第二个字节数据;
dat=ak[1]; //要把两个八位数据载入1个16位变量里;
dat<<=8;
dat|=ak[0];
j= dat;
//==========以下是把温度传感器内部数据编译成16进制编码;
if((j>>11)==0x1f) //此语句是负温度进入.0x1f是二进制5个全1;
{
dat=(~dat)+1; //负温度要取反加一操作;
dat/=16; //传感器给的温度系数要除以16后,得到的数才是常规温度系数;
w=0; //此语句是在主函数中用来判断是正温度还是负温度;
return dat; //向主函数返回数据,并终止函数;
}
j=dat;
if((j>>11)==0) //如果是零则是正温度;
{
dat/=16; //数据直接除以16,就得到了常规温度系数;
w=1; //1代表正;
return dat; //向主函数返回数据,并终止函数;
}
return 130; //向主函数返回数据,并终止函数;
}
delay_ms() //延时1秒;
{
uint8 i=250;
uint16 j=608;
while(j--)
{ while(i--);
i=250;
}
}
error() //测温出错;
{
uint8 i=5, j=0 ,ak[]="Error!";
while(i--)
{
play_cmd(0x82);
while(ak[j]!=' ')
{
play_data(ak[j++]);
} j=0;
delay3();
play_cmd(0x01);
delay3();
}
}
main()
{
uint8 dat=0 ,j=3,len=0 ,num[]="start.....";
reset_1602();
while(j--) //这是启动电源时,液晶显示:start....(并闪烁3次)
{ play_cmd(0x82);
while(num[len]!=' ')
{
play_data(num[len++]);
}
len=0;
delay3();
play_cmd(0x01);
delay3();
}
while(1)
{
start_sensor(); //启动温度传感器;
delay_ms(); //等待1秒;
dat = read_temp(); //读取温度数据并赋给dat变量;
if(dat==130) //如果返回来的数据是130,表明采集温度出错;
{
error();
}
else if(w==1) //如果w是1,就代表正温度.输出;
{
play_cmd(0x83);
play_data(dat/10+'0');
play_data(dat%10+'0');
}
else //否则,就是负温度,输出时前面加一个负号;
{
play_cmd(0x82);
play_data('-');
play_data(dat/10+'0');
play_data(dat%10+'0');
}
} //我的亲娘四舅奶奶啊!!!!!!终于完成了!!!!2013年5月9日19:32:10
}
一周热门 更多>