我在proteus上用MSP430F2132仿真,可总显示0,不知道为什么,手册看的蛋疼,求大神帮帮忙
程序如下:
#include "msp430f2132.h"
#define CPU_F ((double)8000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define uchar unsigned char
#define uint unsigned int
#define DQ BIT4 //P3.4-->DQ
#define DQ1 P3OUT |= BIT4 //DS18B20接口为P3.4口
#define DQ0 P3OUT &= ~BIT4
#define DQIN P3DIR &= ~BIT4
#define DQOUT P3DIR |= BIT4
#define READ_DQ (P3IN&DQ)//读DQ电平
#define RS_CLR P2OUT &= ~BIT0 //RS置低
#define RS_SET P2OUT |= BIT0 //RS置高
#define RW_CLR P2OUT &= ~BIT1 //RW置低
#define RW_SET P2OUT |= BIT1 //RW置高
#define EN_CLR P2OUT &= ~BIT2 //E置低
#define EN_SET P2OUT |= BIT2 //E置高
unsigned char x;
unsigned char y;
uint temp;
uint Temp;
uint i;
uint MSB; //高字节
uint LSB; //低字节
void Port_init()
{
P1SEL = 0x00;
P1DIR = 0xFF;
P2SEL = 0x00;
P2DIR|= BIT0 + BIT1 + BIT2; //控制口设置为输出模式
}
void write_com(uchar com) //输入数据
{
RS_CLR; //RS置低 输入指令
RW_CLR;
EN_SET;
P1OUT=com;
delay_ms(5);
EN_CLR; //E置低 1->0 执行指令
}
void write_data(uchar data) //输出数据
{
RS_SET; //RS置高 RS=1输出数据
RW_CLR;
EN_SET;
P1OUT=data;
delay_ms(5);
EN_CLR; //E置低 1->0 执行指令
}
void LCD_clear(void)
{
write_com(0x01); //清屏幕显示
delay_ms(5);
}
void LCD_init() //1602初始化,请参考1602的资料
{
EN_CLR;
write_com(0x38); //设置16*2显示,5*7点阵,8位数据接口
delay_ms(5);
write_com(0x08); //光标不显示
delay_ms(5);
write_com(0x01); //0000000001 清屏
delay_ms(5);
write_com(0x06); //写入新数据后光标右移,显示频不移动
delay_ms(5);
write_com(0x0C); //显示开及光标设置
delay_ms(5);
}
void display_xy(unsigned char x,unsigned char y)
{
if(y==0x01)
{
x = x + 0x40 + 0x80; }
else
{
x = x+0x80; //数据指针设置 80H+地址码 (0-27H,40H-67H)
}
write_com(x);
}
void Disp1Char(uchar x,uchar y,uchar data)
{
display_xy(x,y);
write_data(data); ////输出数据
}
void Disp_float(uint f_data)
{
unsigned char lcd_table[3];
uint aa;
aa=f_data;
lcd_table[0]= aa/100;
lcd_table[1]= aa%100/10;
lcd_table[2]=aa%10;
Disp1Char(5,0,(lcd_table[0]+0x30)); //显示整数部分的十位数 0x30的原因CGROM和CGRAM与字符的对应关系
Disp1Char(6,0,(lcd_table[1]+0x30));//显示小数部分的个位
Disp1Char(7,0,(0x2e)); //显示小数点"." 小数点对应00101110
Disp1Char(8,0,(lcd_table[2]+0x30)); //显示小数部分的十分位
//加上0x30以便直接得到相应的ASCII码去显示
}
void DS18B20_Init(void) //DS18B20初始化函数
{
uchar present = 1;
while(present)
{
DQOUT;
DQ0; //拉低总线
delay_us(500); //精确延时 大于 480us
DQ1; //释放总线
delay_us(15);
DQIN;
delay_us(70);
if(READ_DQ)
{
present = 1;
}
else present = 0;
delay_us(430);
}
DQOUT;
DQ1;
}
void DS18B20_WriteData(uchar data) //写一个字节
{
uchar i = 0;
for(i = 0;i < 8;i++)
{
DQ0;
delay_us(15);
if(data & 0x01)
{
DQ1;
}
else
{
DQ0;
//delay_us(45);
}
delay_us(45);
DQ1;
delay_us(1);
data >>= 1;
}
}
uchar DS18B20_ReadData(void) //读一个字节
{
uchar i = 0;
uchar data = 0;
for(i = 0;i<8;i++)
{
data >>= 1;
DQ0;
delay_us(15);
DQ1;
DQIN;
if(READ_DQ)
{
data |= 0x80;
}
delay_us(45);
DQOUT;
}
return data;
}
void Read_Temp(void) //读取温度
{
//uchar a = 0,b = 0;
//uint temp = 0;
DS18B20_Init();//初始化,每次写命令都从初始化开始
DS18B20_WriteData(0xCC); //跳过ROM命令
DS18B20_WriteData(0x44); //温度转换命令
DS18B20_Init();//初始化,每次写命令都从初始化开始
DS18B20_WriteData(0xCC); //跳过ROM命令
DS18B20_WriteData(0xBE); //
LSB=DS18B20_ReadData();//读温度低字节
MSB=DS18B20_ReadData(); //读温度高字节
DS18B20_Init();
}
uint GetT(void)
{
uchar flag = 0;
if((MSB&0xf0)>0)
{
flag = 1;
}
else
{
flag = 0;
}
if(flag)
{
temp = ((MSB<<8 ) | LSB ) ;//高八位第八位进行整合
temp= ((~temp)+1); //求反,补一
temp*= 0.0625; //求出十进制
}
else
{
temp = ((MSB<<8 ) |LSB) * 0.0625;
}
return temp;
}
void main(void)
{
WDTCTL = WDTPW + WDTHOLD;//停止看门狗
BCSCTL1 = CALBC1_8MHZ;//MCLK为DCO,8MHZ
DCOCTL = CALDCO_8MHZ;
Port_init();
delay_ms(100); //延时100ms
LCD_init();
LCD_clear(); //清屏
delay_ms(250);
//DQOUT;
while(1)
{
Read_Temp();
Temp = GetT();
//delay_ms(10);
Disp_float(Temp); //显示结果
}
}
file:///C:/Documents%20and%20Settings/Administrator/Application%20Data/Tencent/Users/165079418/QQ/WinTemp/RichOle/RNXVKV6OQ4$2%60H%7DZ]66C%7DRF.jpg
此帖出自
小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>