开放中断后影响到18B20的读取时序,使显示出现不正常
我使用的芯片是690,频率为内部8M,使用数码管显示18B20的温度数据,能正常显示,但当开放中断,就出现255的闪动。中断有定时中断及串行接收。我应该如何处理才好?麻烦各位大大指教。多谢。 单总线芯片操作,开始读关中断,读完成开中断 原子操作或者合理安排中断和读取程序的时间使之避免冲突,同时在显示程序中处理一下数据,温度不可能突变、且在一定范围内。 其实读取温度不需要多久,完全不会影响显示,关键地方在启动温度转换以后不要傻等,去忙别的,等转换完成再来读取,同时启动下次转换 本帖最后由 mon51 于 2016-7-31 08:12 编辑现在初级入门者很多,都不想细说了。给一个代码。
#define SECK (800/TK) //1秒中的主程序的系数
#define NOP_1uS() NOP()
//**************************************
#define SkipK 0xcc //跳过命令
#define ConvertK 0x44 //转化命令
#define RdDs18b20K 0xbe //读温度命令
//***********************************
#define DQ GPIO0
//-----------------------------------
//功能:写18B20
//***********************************
void Delay10uS(unsigned char i){
while(i--){
NOP_1uS(); NOP_1uS(); NOP_1uS();
NOP_1uS(); //NOP_1uS(); NOP_1uS();
// NOP_1uS();
}
}
//-----------------------------------
void Write_18B20(unsigned char n){
unsigned char i;
for(i=0;i<8;i++){
DQ=0;
Delay10uS(1);//延时13us 左右
DQ=n & 0x01;
n=n>>1;
Delay10uS(12);//延时50us 以上
DQ=1;
}
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void){
unsigned char i;
unsigned char temp=0;
for(i=0;i<8;i++){
temp >>=1;
DQ=0;
NOP_1uS();
DQ=1;
TRISIO0=1;
NOP_1uS();NOP_1uS();NOP_1uS();
NOP_1uS();NOP_1uS();//NOP_1uS();//延时5us
if(DQ) temp |=0x80;
TRISIO0=0;
Delay10uS(84);//5延时40us
DQ=1;
}
return temp;
}
//-----------------------------------
//返回=0 失败!
char DS18b20_Init (void){
DQ=0;
Delay10uS(60);//延时500us
DQ=1;
TRISIO0=1;
Delay10uS(10);//延时90us(4.9*n+13.56uS)
if(DQ){ //0001 1111b=1f
TRISIO0=0;
return 0; //失败0
}
TRISIO0=0;
Delay10uS(40);//400uS
DQ=1;
return 1;
}
/**********************************
要将测到的数值乘于0.0625即可得到实际温度;如果温度小于
0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。
例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为
0191H,-25.0625℃的数字输出为FF6FH,
-55℃的数字输出为FC90H。
***********************************/
void GetTemp_ds18b20(void){
static unsigned int flag=0;
signed int t;
signed long tt;
if(flag==0){
if(DS18b20_Init()==0) return;
Write_18B20(SkipK);
Write_18B20(ConvertK);
flag++;
}else{
//-- 等待 时间1秒 ---
if(flag++>=SECK){
flag=0;
if(DS18b20_Init()){
Write_18B20(SkipK);
Write_18B20(RdDs18b20K);
t=Read_18B20(); //读低位
t=Read_18B20()<<8 | t; //读低高位
//--------------------------------------
// ---乘以0.0625 --- 采用整数运算 放大10000=》625
tt =(signed long)t*625;
tt /=1000; //温度数据是小数点后一位!
Temp=tt; //数据返回!
}
}
}
}
单总线的器件,时序太重要了。必须关闭中断。 单总线的时序非常重要,但可以不关中断.要改变一下思路 youkebing 发表于 2016-7-31 08:37
单总线的时序非常重要,但可以不关中断.要改变一下思路
怎么改?莫非是也写到中断里…… 读时,关中断,没啥技巧。 runapp 发表于 2016-8-21 14:30
怎么改?莫非是也写到中断里……
我写过一个用spi,读的方式,可以不关中断,你可以试试 youkebing 发表于 2016-8-21 15:36
我写过一个用spi,读的方式,可以不关中断,你可以试试
惭愧啊,没用过硬件spi呢还 fengyunyu 发表于 2016-8-21 14:50
读时,关中断,没啥技巧。
有技巧可以不关中断的,比如楼上说的用SPI等. 不是有官方例子用串口的吗 开中断影响读18B20,要么中断执行时间太长,要么读18B20时序在临界状态。
页:
[1]