/*****************頭文件********************/
#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--;
}
|