EasyARM1138调18B20参考了例程,18B20的DQ端用1138的0口的话可以调通,改成其他口就不行了。
例程用的是PF0,可以调通,改成PF1~7或PA1~7就不行,而PA0可以调通。
总是显示: 16.1C,温度升高后变成16.2C,室温23C。
DEBUG看就是读口值时老是高电平,用的5.1K上拉。
都说是延时问题,但是我只改和口有关的值,其他语句没改怎么不行呢?
原参考网址:
http://mcublog.com/home/space.ph ... o=blog&id=18863
我的程序:
/***************************************************
为方便插线我用段位串口液晶LCD0801显示18B20
PA0-DQ(18B20),PF0\PA0口都能调通
****************************************************/
/***************************************************
用PA2口的语句用星号注释出来了,大家看看有什么问题,调不通
****************************************************/
#include "systemInit.h"
#include <hw_types.h>
#include <hw_memmap.h>
#include <hw_sysctl.h>
#include <hw_gpio.h>
#include <sysctl.h>
#include <gpio.h>
#define uchar unsigned char
#define uint unsigned int
uchar display[5]={0,0,0,0,0};
uchar ditab[16]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; //温度的小数值
uchar tplsb,tpmsb;
//宏定义LCD,CLK,DIN占PD2,PD3
#define LCD_PERIPH SYSCTL_PERIPH_GPIOD
#define LCD_PORT GPIO_PORTD_BASE
#define LCD_PIN_CLK GPIO_PIN_2
#define LCD_PIN_DIN GPIO_PIN_3
//用于位操作
#define LCD_CLK HWREG(LCD_PORT+(GPIO_O_DATA+(LCD_PIN_CLK << 2)))
#define LCD_DIN HWREG(LCD_PORT+(GPIO_O_DATA+(LCD_PIN_DIN << 2)))
void LCD0801(unsigned char bufdian[7],unsigned char buf[8]);
//定义18B20
#define DQ GPIO_PORTA_BASE , GPIO_PIN_0
/***************************************************
#define DQ GPIO_PORTA_BASE , GPIO_PIN_2
****************************************************/
void Delay(unsigned int ulVal);
void Delay1(unsigned int ulVal);
void TxReset(void);
void RxWait(void);
uchar RdBit(void);
uchar RdByte(void);
void WrByte(uchar b);
void convert(void);
void RdTemp(void);
void work_temp(void);
// 主函数(程序入口)
int main(void)
{
jtagWait(); // 防止JTAG失效,重要!
clockInit(); // 时钟初始化:晶振,6MHz
SysCtlPeriEnable(LCD_PERIPH); // 使能LCD所在的GPIO端口
GPIOPinTypeOut(LCD_PORT,LCD_PIN_CLK); // 设置LCD所在管脚为输出
GPIOPinTypeOut(LCD_PORT,LCD_PIN_DIN);
SysCtlPeriEnable(SYSCTL_PERIPH_GPIOA); //使能GPIOA口外设
GPIOPinTypeOut(GPIO_PORTA_BASE ,0xff); //GPIOA为输出
uchar bai=0; //LCD百位
uchar shi=0; //LCD十位
uchar ge=0; //LCD十位
uchar xiao=0;//LCD小数
//LCD需显示内容
unsigned char lcdbufzhi[8]={0x15,0x15,1,1,3,8,0x15,0x15}; //LCD数值
//显示:"--1138--"
unsigned char lcdbufdian[7]={0,0,0,0,0,0,0}; //LCD小数点
//显示:"--1138--"
LCD0801(lcdbufzhi,lcdbufdian);
for (;;)
{
convert(); //启动温度转换
Delay1(800); //延时800ms
RdTemp(); //读取转换结果
work_temp(); //温度数据处理
GPIOPinTypeOut(GPIO_PORTA_BASE ,0xff); //GPIO A为输出
bai=display[3]; //百位
shi=display[2];
ge=display[1];
xiao=display[0];
//LCD需显示内容
unsigned char lcdbufzhi[8]={0x15,bai,shi,ge,xiao,0x0c,0x15,0x15}; //LCD数值
//显示:"-XXXXC--"
unsigned char lcdbufdian[7]={0,0,0,1,0,0,0}; //LCD小数点
//显示:"-XXX.XC--"
LCD0801(lcdbufzhi,lcdbufdian);
}
}
// 延时1us
void Delay(unsigned int ulVal)
{
unsigned int i,j=0;
for(i=0;i<ulval;i++)
j++;
}
// 延时1ms
void Delay1(unsigned int="int" ulVal)
{
unsigned="unsigned" int="int" i,j;
for(i=0;i<ulval;i++)
{
for(j=0;j<1000;j++)
Delay(1);
}
}
/* 产生复位脉冲初始化DS18B20 */
void TxReset(void)
{
uint="uint" i;
HWREGB(0x40004400)|=0x01; //设置DQ为输出
/***************************************************
HWREGB(0x40004400)|=0x04; //设置DQ为输出
****************************************************/
GPIOPinWrite(DQ, 0);
i= 1000;
while="while" (i>0) i--;
GPIOPinWrite(DQ, 1); // 产生上升沿
i = 36;
while (i>0) i--;
}
/* 等待应答脉冲 */
void RxWait(void)
{
uint i,data;
HWREGB(0x40004400)&=~0x01; //设置DQ为输入
/***************************************************
HWREGB(0x40004400)&=~0x04; //设置DQ为输入
****************************************************/
do
{
data=GPIOPinRead(DQ);
data=((data)&0x01)>>0;
/***************************************************
data=((data)&0x04)>>2;
****************************************************/
}
while(data);
do
{
data=GPIOPinRead(DQ);
data=((data)&0x01)>>0;
/***************************************************
data=((data)&0x04)>>2;
****************************************************/
}
while(!data); // 检测到应答脉冲
i = 15;
while (i>0) i--;
}
/* 读取数据的一位,满足读时隙要求 */
uchar RdBit(void)
{
uint i,b;
HWREGB(0x40004400)|=0x01; //设置DQ为输出
/***************************************************
HWREGB(0x40004400)|=0x04; //设置DQ为输出
****************************************************/
GPIOPinWrite(DQ, 0);
i =1;
while (i>0) i--;
HWREGB(0x40004400)&=~0x01; //设置DQ为输入
/***************************************************
HWREGB(0x40004400)&=~0x04; //设置DQ为输入
****************************************************/
GPIOPinWrite(DQ, 1);
i = 15;
while (i>0) i--;
b = GPIOPinRead(DQ);
b=((b)&0x01)>>0;
/***************************************************
b=((b)&0x04)>>2;
****************************************************/
i = 110;
while(i>0) i--;
return (b);
}
/* 读取数据的一个字节 */
uchar RdByte(void)
{
uchar i,j,b;
b = 0;
for (i=1;i<=8;i++)
{
j = RdBit();
b = (j<<7)|(b>>1);
// b=0xff;
}
return(b);
}
/* 写数据的一个字节,满足写1和写0的时隙要求 */
void WrByte(uchar b)
{
uint i;
uchar j,btmp;
HWREGB(0x40004400)|=0x01; //设置DQ为输出
/***************************************************
HWREGB(0x40004400)|=0x04; //设置DQ为输出
****************************************************/
for(j=1;j<=8;j++)
{
btmp = b&1;
b = b>>1; // 取下一位(由低位向高位)
if (btmp)
{ /* 写1 */
GPIOPinWrite(DQ, 0);
i = 15;
while(i>0) i--; // 延时,使得15us以内拉高
GPIOPinWrite(DQ, 1);
i = 100;
while(i>0) i--; // 整个写1时隙不低于60us
}
else
{ /* 写0 */
GPIOPinWrite(DQ, 0);
i = 110;
while(i>0) i--; // 保持低在60us到120us之间
GPIOPinWrite(DQ, 1);
i = 15;
while(i>0) i--;
}
}
}
/* 启动温度转换 */
void convert(void)
{
TxReset(); // 产生复位脉冲,初始化DS18B20
RxWait(); // 等待DS18B20给出应答脉冲
Delay1(1); // 延时
WrByte(0xcc); //跳过rom命令
WrByte(0x44); //启动温度转换命令
}
/* 读取转换结果 */
void RdTemp(void)
{
TxReset(); // 产生复位脉冲,初始化DS18B20
RxWait(); // 等待DS18B20给出应答脉冲
Delay1(1); // 延时
WrByte(0xcc); //跳过rom命令
WrByte(0xbe); //读取暂存器命令
tplsb = RdByte(); // 温度值低位字节(其中低4位为二进制的“小数”部分)
tpmsb = RdByte(); // 高位值高位字节(其中高5位为符号位)
}
//温度数据处理函数
void work_temp(void)
{
unsigned char n=0;
if(tpmsb>127)
{
tpmsb=(256-tpmsb); //负温度求补码
tplsb=(256-tplsb);
n=1;
}
display[4]=tplsb&0x0f;
display[0]=ditab[display[4]]; //温度的小数
display[4]=((tplsb&0xf0)>>4)|((tpmsb&0x0f)<<4);
display[3]=display[4]/100; //温度的百位
display[1]=display[4]%100;
display[2]=display[1]/10; //温度的十位
display[1]=display[1]%10; //温度的个位
if(n)
Delay(1); //延时10us
}
//LCD0801驱动子程序,buf[]为数值,bufdian[]为小数点位置
void LCD0801(unsigned char buf[8],unsigned char bufdian[7])
{
...
} |
|