正在做毕设,
单片机用的是飞思卡尔的jm60,程序写好后连接传感器就只能读出全是1来,我也不知道是发送的程序有问题还是接受的,或者是初始化的。延时函数都是用示波器看过的应该没问题。另外飞思卡尔的单片机需要设置i/o口是输入还是输出,设置为1是输出,0是输入。 有人用过dsb20的话还希望可以帮我看看,新手在这里谢过了!
#include <hidef.h> /* for EnableInterrupts macro */
#include "deriva
tive.h" /* include peripheral declarations */
short i,j;
unsigned char Tem_h=0,Tem_l=0;
unsigned char x;
#define _nop_() _asm(nop);
/*函数声明----所有时钟测的是周期,所以时间应该是一半-----*/
void clkset(); //busclk=12m
void delay1s(); //上电延时函数,1s多
void delayms(int c); //毫秒机延时 实测500ms
void delay10us(); //10us延时 实测5us
void DSset();
unsigned char Readonechar();
void Sendonechar(unsigned char date);
void delayus(int c); //实测42(70) 1(4) 8(14) 28(46.8) 前面是c括号里是us数
void Read_tem(void);
/*子函数-----------------------------------*/
void delayus(int c)
{while(c--)
{
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}
}
void delay10us() //
{for(i=0;i<3;i++)
{ _nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
_nop_();_nop_();
}
_nop_();
}
void delayms(int c)
{
for(i=0;i<c;i++)
for(j=0;j<490;j++)
{_nop_();
_nop_();
}
}
void delay1s()
{for(i=0;i<1100;i++)
for(j=0;j<1200;j++)
{;
}
}
void clkset()
{ MCGC2=0x36; //选择外部振荡器和另外配置
while(!MCGSC_OSCINIT) ; //振荡器稳定标志位
MCGC1=0xB8; //选择外部参考。128分频
while(MCGSC_IREFST);
while(MCGSC_CLKST!=2); //外部参考时钟被选择
MCGC1=0x90; // RDIV = 2; //0x90; //RDIV = 4
MCGC3=0x46; //0x46 24倍频; //0x44;//16倍频
while(!MCGSC_PLLST);
while(!MCGSC_LOCK);
MCGC1=0x08; //切换到PLL 0x10;
while(MCGSC_CLKST!=3); //4/4*24=24m,busclk=12m
}
void DSset()
{x=1;
PTBDD_PTBDD4=1;
PTBD_PTBD4=1; //设置成输出给高电平
delayus(1); //延时4us
PTBD_PTBD4=0; //拉低时钟线
delayms(1);
PTBD_PTBD4=1; //保持500us左右给上升沿(实测494us)
delayus(1); //略作延时
PTBDD_PTBDD4=0; //设置成输入口
delayus(42); //延时70us用x去检测传感器返回的低电平
x=PTBD_PTBD4; //x=0时初始化成功标志
delayus(1);
}
//看变量表示能看到想在1和0之间转换,应该初始化没有问题
unsigned char Readonechar(void) //读一个字节
{
unsigned char date;
for(i=0;i<8;i++)
{PTBDD_PTBDD4=1; //设置成输出
PTBD_PTBD4=1; //给高电平
delayus(1); //略延时
PTBD_PTBD4=0;
delayus(1); //拉低保持4us
PTBD_PTBD4=1; //拉高总线
PTBDD_PTBDD4=0; //设置成输入
date>>=1; //移位
delayus(1);
if(PTBD_PTBD1) //读:如果的是1的话这样取或就可以
date|=0x80;
delayus(30); //保证每个周期至少60us以上,这里大概是50us
}
return date;
}
void Sendonechar(unsigned char date)
{ PTBDD_PTBDD4=1;//设置成输出
for(i=0;i<8;i++)
{PTBD_PTBD4=1;
delayus(1); //给高电平,再略延时
PTBD_PTBD4=0;
delayus(8); //延时14us
PTBD_PTBD4=date&(0x01); //看给的数据是多少是0就还是0;
delayus(28);
//47us 保证60us
date>>=1;
delayus(1); //右移一位等待发送
}
}
void Read_tem(void)
{ DSset(); //复位
delayms(1);
Sendonechar(0xcc);
Sendonechar(0x44);
//温度转换命令
delay1s(); //给温度转换的时间1s
DSset();
delayms(1);
Sendonechar(0xcc);
Sendonechar(0xbe);
Tem_h=Readonechar();
Tem_l=Readonechar();
}
void main(void)
{
EnableInterrupts; /* enable interrupts */
/* include your code here */
clkset(); //设置时钟
SOPT1=0; //关看门狗
PTBDD_PTBDD4=1;
PTBD_PTBD4=1; //设置成输出并给高电平
PTBDD_PTBDD1=1;
PTBD_PTBD1=1;
/* for(;;)
{
delayus(28);
PTBD_PTBD1=1;
delayus(28);
PTBD_PTBD1=0;
} */ //延时测试程序
for(;;)
{delay1s();
Read_tem();
delay1s();
}
//__RESET_WATCHDOG(); /* feeds the dog */
/* loop forever */
/* please make sure that you never leave main */
}
恩,我再看看,对这个输入输出设置转换时的电平变化确实拿不准,楼主还记的用什么方法解决的么?io转换结束马上给电平?
谢过了
一周热门 更多>