PIC18F25J10 4M晶振。 不知道哪里程序出错了,数码管一直初始化,预计应该是18B20失败了 大神帮忙看看程序可否谢谢
#include "p18cxxx.h" //头文件
#include "delays.h"
#include "SEG.h"
//#define nop asm("nop")
#define uchar unsigned char
#define uint unsigned int
#define uch unsigned char //给unsigned char起别名 uch
#define DQ LATCbits.LATC2 //定义18B20数据端口
#define DQ_LOW() DQ = 0; DQ_DIR = 0 //设置数据口为输出
unsigned char TLV=0 ; //采集到的温度高8位
unsigned char THV=0; //采集到的温度低8位
unsigned char TZ=0; //转换后的温度值整数部分
unsigned char TX=0; //转换后的温度值小数部分
unsigned int wd; //转换后的温度值BCD码形式
unsigned char shi; //整数十位
unsigned char ge; //整数个位
unsigned char shifen; //十分位
unsigned char baifen; //百分位
unsigned char qianfen; //千分位
unsigned char wanfen; //万分位
#define TMR0HLOAD 0xf6 //4MHZ 2.5mS
#define TMR0LLOAD 0x4D
unsigned char TickClock = 0; //系统时基
#define SCLK LATBbits.LATB0 //74HC164时钟
#define SDAT LATBbits.LATB1 //74HC164数据
const unsigned char SegCode[] = //图型表
{
Bmp0Map,Bmp1Map,Bmp2Map,Bmp3Map,Bmp4Map,Bmp5Map,
Bmp6Map,Bmp7Map,Bmp8Map,Bmp9Map,BmpAMap,BmpBMap,
BmpCMap,BmpDMap,BmpEMap,BmpFMap
};
const unsigned char SegCS[6] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF}; //显示片选
unsigned char SegBuf[6] = {BmpPMap,Bmp1Map,BmpCMap,Bmp1Map,Bmp8Map,BmpFMap}; //显示缓冲
unsigned uint temper;
uchar a1,a2,a3,a4;
void disp();
//延时函数
void delay(char x,char y)
{
char z;
do{
z=y;
do{;}while(--z);
}while(--x);
}
//其指令时间为:7+(3*(Y-1)+7)*(X-1)如果再加上函数调用的call 指令、页面设定、传递参数花掉的7 个指令。
//则是:14+(3*(Y-1)+7)*(X-1)。
//--------------------------------------------------
//------------------------------------------------------------------------------
//复位DS18B20函数
reset(void)
{
char presence=1;
while(presence)
{
DQ=0 ; //主机拉至低电平
delay(2,70); //延时503us
DQ=1; //释放总线等电阻拉高总线,并保持15~60us
delay(2,8); //延时70us
if(DQ==1) presence=1; //没有接收到应答信号,继续复位
else presence=0; //接收到应答信号
delay(2,60); //延时430us
}
}
//-----------------------------------------------
//写18b20写字节函数
void write_byte(uch val)
{
uch i;
uch temp;
for(i=8;i>0;i--)
{
temp=val&0x01; //最低位移出
DQ=0;
Nop();
Nop();
Nop();
Nop();
Nop(); //从高拉至低电平,产生写时间隙
if(temp==1) DQ=1; //如果写1,拉高电平
delay(2,7); //延时63us
DQ=1;
Nop();
Nop();
val=val>>1; //右移一位
}
}
//------------------------------------------------
//18b20读字节函数
uch read_byte(void)
{
uch i;
uch value=0; //读出温度
static j;
for(i=8;i>0;i--)
{
value>>=1;
DQ=0;
Nop();
Nop();
Nop();
Nop();
Nop();
Nop(); //6us
DQ=0; //拉至高电平
Nop();
Nop();
Nop();
Nop();
Nop(); //4us
j=DQ;
if(j) value|=0x80;
delay(2,7); //63us
}
return(value);
}
//-------------------------------------------------
//启动温度转换函数
void get_temp()
{
int i;
DQ=1;
reset(); //复位等待从机应答
write_byte(0XCC); //忽略ROM匹配
write_byte(0X44); //发送温度转化命令
for(i=20;i>0;i--)
{
disp(); //调用多次显示函数,确保温度转换完成所需要的时间
}
reset(); //再次复位,等待从机应答
write_byte(0XCC); //忽略ROM匹配
write_byte(0XBE); //发送读温度命令
TLV=read_byte(); //读出温度低8
THV=read_byte(); //读出温度高8位
DQ=1; //释放总线
TZ=(TLV>>4)|(THV<<4)&0X3f; //温度整数部分
TX=TLV<<4; //温度小数部分
if(TZ>100) TZ/100; //不显示百位
ge=TZ%10;//个位 //整数部分个位
shi=TZ/10;//十位 //整数十位
wd=0;
if (TX & 0x80) wd=wd+5000;
if (TX & 0x40) wd=wd+2500;
if (TX & 0x20) wd=wd+1250;
if (TX & 0x10) wd=wd+625; //以上4条指令把小数部分转换为BCD码形式
shifen=wd/1000; //十分位
baifen=(wd%1000)/100; //百分位
qianfen=(wd%100)/10; //千分位
wanfen=wd%10; //万分位
Nop();
}
//-------------------------------------------------------------------------------
// 数码管显示驱动
//-------------------------------------------------------------------------------
void SegDisplay(void)
{
static unsigned char i = 0;
unsigned char j;
unsigned char tep;
tep = SegCS[i]; //片选输出
for(j=0;j<8;j++) //8位
{
if(tep&0x80) SDAT = 1;
else SDAT = 0;
SCLK = 1;
SCLK = 0;
tep = tep<< 1;
}
tep = SegBuf[i]; //数据输出
for(j=0;j<8;j++) //8位
{
if(tep&0x80) SDAT = 1;
else SDAT = 0;
SCLK = 1;
SCLK = 0;
tep = tep<< 1;
}
if(i < 5) i ++; //扫描6位
else i = 0;
}
/*
//-------------------------------------------------------------------------------
// ADC采集程序
//-------------------------------------------------------------------------------
unsigned int SampleADValue[8]; // 8次采样
unsigned int AvgADValue = 0; // AD采样平均值
unsigned char ADConverStep = 0; // AD采样频步
void GET_ADValue(void)
{
unsigned char i;
unsigned int ConverValue;
do
{
}while(ADCON0bits.GO_DONE); //等待转换完成
ConverValue = ADRESH; //处理10位结果
ConverValue = (ConverValue << 8) + ADRESL;
SampleADValue[ADConverStep] = ConverValue;
if (ADConverStep == 7)
{
ConverValue = 0;
for (i = 0; i < 8 ; i++)
{
ConverValue += SampleADValue[i];
}
AvgADValue = ConverValue >> 3;
ADConverStep = 0;
}
else
{
ADConverStep++;
}
}
*/
//-------------------------------------------------------------------------------
// TMR1定时器初始化
//-------------------------------------------------------------------------------
void TMR1_Init(void)
{
TMR1H = 0xF0; //4mS 4MHz
TMR1L = 0x98;
T1CONbits.RD16 = 1; //16位定时方式
T1CONbits.TMR1CS = 0; //内部FOSC/4
PIE1bits.TMR1IE = 1; //T1中断 ON
}
/*
//-------------------------------------------------------------------------------
// ADC初始化
//-------------------------------------------------------------------------------
void ADC_Init(void) // ADC 初始化
{
ADCON0 = 0b00000001; // ADC模块使能
ADCON1 = 0b00001110; // AN0 ADC输入
ADCON2 = 0b10111111; // 右对齐 FRC
}
*/
//-------------------------------------------------------------------------------
// 高优先级中断向量
//-------------------------------------------------------------------------------
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh(void)
{
_asm
goto Interrupt_High //跳到中断程
_endasm
}
//-------------------------------------------------------------------------------
// 高优先级中断服务程序
//-------------------------------------------------------------------------------
#pragma interrupt Interrupt_High
void Interrupt_High(void)
{
if(PIR1bits.TMR1IF) //T1中断
{
PIR1bits.TMR1IF = 0; //清除标志位
TMR1H = 0xF0; //4MS
TMR1L = 0x98;
SegDisplay(); //扫描显示
TickClock = 1; //置位
}
if(PIR1bits.RCIF) // 接收中断
{
PIR1bits.RCIF = 0;
TXREG = RCREG; // 将收到的数据发出
if(RCSTAbits.OERR) // 接收溢出错误处理
{
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
}
}
}
//-------------------------------------------------------------------------------
// 计算温度值
/*//-------------------------------------------------------------------------------
int GET_TempValue(unsigned int ADCValue)
{
ADCValue = (32*ADCValue)/10; // y = (3300/1024)* x
if(ADCValue >500) ADCValue = (ADCValue - 500); //零上 500mV时 零度
else ADCValue = (500 - ADCValue); //零下
return ADCValue;
} */
void initled()//初始化数码管
{
SegBuf[0] = Bmp0Map; // "T"
SegBuf[1] = Bmp0Map; // "P"
SegBuf[2] = Bmp0Map; //千位
SegBuf[3] = Bmp0Map;//百位
SegBuf[4] = Bmp0Map;
SegBuf[5] = Bmp0Map;
}
//-------------------------------------------------------------------------------
// 数码管分段显示函数
//-------------------------------------------------------------------------------
void disp()
{
SegBuf[0] =SegCode[6]; // "T"
SegBuf[1] =SegCode[5]; // "P"
SegBuf[2] =SegCode[4];//千位
SegBuf[3] =SegCode[baifen];//百位
SegBuf[4] =SegCode[qianfen]; //十位 有小数点
SegBuf[5] =SegCode[wanfen];//个位
}
void delay1(uint x)
{
uint i,j;
for(i=x;i>0;i--)
for(j=110;j>0;j--);
}
//-------------------------------------------------------------------------------
// 主程序部分
//-------------------------------------------------------------------------------
void main(void)
{
unsigned int SystemTick = 0; // 串口发数据定时
TRISC = 0b11010011; //RA2 RA3 RA5 输出
TRISB = 0b11111100; //RB0 RB1 输出
TMR1_Init(); //定时器1初始化
// ADC_Init(); //ADC初始化
disp();//
INTCONbits.PEIE = 1; //外设中断允许
INTCONbits.GIE = 1; //总中断允许
T1CONbits.TMR1ON= 1; //使能T1
// initled();
// disp();
while(1)
{
get_temp();
disp(); //显示温度值
}
}
|