/*****************头文件********************/
#include"DSP28_Device.h"
/****************端口宏定义*****************/
#define uchar unsigned char
#define uint unsigned int
#define rs GpioDataRegs.GPADAT.bit.GPIOA2//片选信号RS模组选端。高高电平有效。
//LCD第4脚 P102-6
#define rw GpioDataRegs.GPADAT.bit.GPIOA3//串行数据输入端。
//LCD第5脚 P102-7
#define en GpioDataRegs.GPADAT.bit.GPIOA4//串行同步时钟:上升沿时读取SID数据。
//LCD第6脚 P102-10
#define sta7 GpioDataRegs.GPBDAT.bit.GPIOB7 //忙标志检测。
#define SDA_DIR GpioMuxRegs.GPADIR.bit.GPIOA0
#define SCL_DIR GpioMuxRegs.GPADIR.bit.GPIOA1
#define SDA GpioDataRegs.GPADAT.bit.GPIOA0
#define SCL GpioDataRegs.GPADAT.bit.GPIOA1
//宏定义中不要分号。复位端,低电平有效。 可以不要直接接低电平。 LCD第17脚
//P101-5
/****************常量宏定义*****************/
unsigned char table1[]={"温度:"};
unsigned char teble2[]={"°C "};
unsigned char disp_table[];
#define comm 0//指令为0。
#define data 1 //数据为1。
#define SHT20ADDR 0x80
#define ACK 0
#define NACK 1
#define MEASURE_TEMP 0xe3 //温度测量命令(1110 0011)
#define MEASURE_HUMI 0xe5 //湿度测量命令(1110 0101)
#define RESET 0xFE //软复位命令 (1111 1110)
#define STATUS_REG_R 0xe7 //读状态寄存器命令(1110 0111)
#define STATUS_REG_W 0xe6 //写状态寄存器命令(1110 0110)
/***************全局变量定义****************/
unsigned char MSB, LSB;
float temp;
/****************函数声明*******************/
void Init_I2C();
void StartI2C();
void StopI2C();
void I2C_Ack(void);
void I2C_NACK(void);
unsigned char SHT20_read_one_byte_data(void);
unsigned char SHT20_write_one_byte_data(unsigned char write_byte);
void SET_Resolution(void);
float SHT2x_MeasureTemperature(void);
void float_to_char(float m);
void InitLcd(void);
void lcd_write_data_command(unsigned char,unsigned char);
void lcd_write_content(unsigned char );
void delayns(unsigned int tns);
void delayus1(unsigned int tus);
void main(void)
{
uint i;
float tempera=10,humid;
InitSysCtrl(); //初始化系统
DINT; //关中断
IER = 0x0000; //禁止CPU中断。
IFR = 0x0000; //清除CPU中断标志。
InitPieCtrl(); //初始化PIE控制寄存器
InitPieVectTable(); //初始化PIE中断矢量表
InitPeripherals(); //初始化外设
InitGpio(); //初始化GPIO口
EINT;
ERTM;
InitLcd();
Init_I2C();
lcd_write_data_command(comm,0x80); //显示第一行字符
for(i=0;table1[i]!='\0';i++)
{
lcd_write_data_command(data,table1[i]);
}
lcd_write_data_command(comm,0x85); //显示第二行字符
for(i=0;teble2[i]!='\0';i++)
{
lcd_write_data_command(data,teble2[i]);
}
while(1)
{
tempera = SHT2x_MeasureTemperature();//温度测量
float_to_char(tempera);
lcd_write_data_command(comm,0x82); //显示第二行字符
for(i=0;disp_table[i]!='\0';i++)
{
lcd_write_data_command(data,disp_table[i]);
}
// delayus1(50000);
}
}
/*---------------------浮点数字转换成字符------------------------------------------*/
void float_to_char(float m) //格式为125.7
{
uchar i=0;
unsigned int num;
num = (unsigned int)(m*10); //扩大10倍,方便分离各位
disp_table[0] = num/1000 + 0x30; //'0'的ASCII码0x30
disp_table[1] = num%1000/100 + 0x30;
disp_table[2] = num%100/10 + 0x30;
disp_table[3] = '.';
disp_table[4] = num%10 + 0x30;
disp_table[5] = '\0';
for(i=0;i<2;i++) //去掉无效的前导'0'字符
{
if(disp_table[i] == 0x30)
disp_table[i] = 0x20; //0x20是空格的ASCII码
else
break;
}
}
/*================================================================
【名称】
【功能】I2C启动信号
【备注】SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
================================================================*/
void Init_I2C()
{
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
SDA=0;
SCL=0;
delayus1(10);//时间咋样?
SDA=1;
SCL=1;//锁住I2C总线,准备发送数据或接收数据。
delayus1(80);
}
/*================================================================
【名称】
【功能】I2C启动信号
【备注】SCL、SDA同为高,SDA跳变成低之后,SCL跳变成低
================================================================*/
void StartI2C()
{
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
SDA=1;
SCL=1;
delayus1(10);//时间咋样?
SDA=0;
delayus1(10);//
SCL=0;//锁住I2C总线,准备发送数据或接收数据。
delayus1(10);
}
/*================================================================
【名称】
【功能】I2C停止信号
【备注】SCL、SDA同为低,SCL跳变成高之后,SDA跳变成高
================================================================*/
void StopI2C()
{
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
SDA=0;
SCL=0; //?要不?
delayus1(10);
SCL=1;
delayus1(10);
SDA=1;//发送I2C总线结束信号。
delayus1(10);
}
void I2C_Ack(void)
{
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
SDA=0;
SCL=1;
delayus1(8);
SCL=0;
delayus1(8);
}
void I2C_NACK(void)
{
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
SDA=1;
SCL=1;
delayus1(8);
SCL=0;
delayus1(8);
}
/*================================================================
【名称】
【功能】I2C读一个字节数据,返回ACK或者NACK
【备注】从高到低,依次发送
================================================================*/
unsigned char SHT20_read_one_byte_data(void)
{
unsigned char i;
unsigned char RDByte=0;
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
SDA=1;
// SCL=0;///?
EALLOW;
SDA_DIR=0;
EDIS;
for(i=0; i<8;i++)
{
SCL=1;
delayus1(2);
RDByte<<=1;
if(SDA!=0)
RDByte|=0x01; //自己改的??、?。
delayus1(2);
SCL=0;
delayus1(6);
}
//以下是I2C总线发送应答信号ACK或者NACK;
EALLOW;
SDA_DIR=1; //////////////???????????
EDIS;
SDA=1;
return RDByte;
}
/*================================================================
【名称】
【功能】I2C写一个字节数据,返回ACK或者NACK
【备注】从高到低,依次发送
================================================================*/
unsigned char SHT20_write_one_byte_data(unsigned char write_byte)
{
unsigned char i,ack;
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
SCL_DIR=1;
EDIS;
for(i=0; i<8;i++)
{
if(write_byte&0x80)//当WriteData的第7位为1时,SDA=1;
SDA=1;//
else
SDA=0;//
delayus1(1);
SCL=1; //输出SDA稳定后,拉高SCL给出上升沿,从机检测到后进行数据采样。
delayus1(10);//
write_byte<<=1;
SCL=0;
delayus1(1);
}
delayus1(4);
SDA=1;
SCL=1;
delayus1(20);
//以下是判断I2C总线接收应答信号ACK还是NACK;
EALLOW;
SDA_DIR=0;//向SHT20写一个数据。GPIO口使输出的。
EDIS;
delayus1(5);
if(SDA) //自己改的
ack=1;
else
ack=0;
SCL=0;
EALLOW;
SDA_DIR=1;//向SHT20写一个数据。GPIO口使输出的。
EDIS;
SDA=1;
delayus1(20);
return ack;
}
void SET_Resolution(void)
{
StartI2C();
if(SHT20_write_one_byte_data(SHT20ADDR&0xfe)==0)
{
if(SHT20_write_one_byte_data(0xe6)==0)
{
if(SHT20_write_one_byte_data(0x83)==0);
}
}
StopI2C();
}
/*----------------------------------------------------------------------
* 功能:SHT20测量温度T
* --------------------------------------------------------------------*/
float SHT2x_MeasureTemperature(void)
{
float Temperature;
EALLOW;
SCL_DIR=1;
EDIS;
SET_Resolution(); //设置SHT20传感器分辨率
StartI2C();
SHT20_write_one_byte_data(SHT20ADDR); //IIC地址1000000+写操作(0)
/*启动传输后,随后传输IIC首字节包括7位设备地址1000 000和一位SDA方向位(读R:1,写W:0)*/
SHT20_write_one_byte_data(MEASURE_TEMP); //写命令(0xe3)-触发温度测量
StartI2C();
SHT20_write_one_byte_data(SHT20ADDR|0x01); //IIC地址1000000+读操作(1)
SCL=1;
EALLOW;
SCL_DIR=0;
EDIS;
while(SCL!= 0)//????????
delayus1(10);
MSB = SHT20_read_one_byte_data();
I2C_Ack();
LSB = SHT20_read_one_byte_data();
I2C_Ack();
SHT20_read_one_byte_data();
I2C_NACK();
StopI2C();
LSB &= 0xfc; //屏蔽最低2位(stat)
temp = (MSB << 8) + LSB;
Temperature = (temp * 175.72) /65536- 46.85;
EALLOW;
SCL_DIR=1;
EDIS;
return (Temperature);
}
/*----------------------初始化LCD的函数----------------------------------*/
/*******************************************************************************
名称:
说明:
易出现的问题:
*******************************************************************************/
void InitLcd()
{
delayus1(1);//复位延时时间要足够。
lcd_write_data_command(comm,0x30);//30--基本指令动作,表示:功能设定。72us.
lcd_write_data_command(comm,0x30);//
lcd_write_data_command(comm,0x0c);//开显示,关游标。
lcd_write_data_command(comm,0x01);//清屏,地址指针指向00H。
delayus1(5000);
lcd_write_data_command(comm,0x06);//光标的移动方向。cd
lcd_write_data_command(comm,0x02);//清除显示。并使DDRAM地址计数器归0.
}
/*----------------------写内容的函数----------------------------------*/
/*******************************************************************************
名称:
说明:
易出现的问题:
*******************************************************************************/
//写数据到GPIOA0----GPIOA7中去。
void lcd_write_content(unsigned char cont)
{
GpioDataRegs.GPBDAT.all=cont&0x00ff;//与就是把cont的内容写进GpioDataRegs.GPBDAT.all中去。
}
/*----------------------写数据命令的函数----------------------------------*/
/*******************************************************************************
名称:
说明:
易出现的问题:
*******************************************************************************/
//LCD数据指令写函数。
void lcd_write_data_command(unsigned char data_command,unsigned char content)
{
rs=0;
rw=1;
if(data_command)
{
rs=1;
rw=0;
}
else
{
rs=0;
rw=0;
}
en=1;
delayus1(1);//这儿一定要延时一定时间裨蛳允韭衣搿?
lcd_write_content(content);//GpioDataRegs.GPADAT.all=cont&0xff;
delayus1(100); //这人也要延时,否则,数据写不去。
en=0;
}
void delayus1(unsigned int tus) //一个脉冲为1/15us ,所以为tus*100/150us。
{
int i,j;
for(j=0;j<tus;j++)
for(i=0;i<150;i++);
}
void delayns(unsigned int tns)//
{
while(tns>0)tns--;
}
|