#include "io430.h"
typedef unsigned int uint;
typedef unsigned char uchar;
/****BH1750 IO定義******/
#define SCL_H P3OUT |= BIT6//此IO在硬件上需要更改
#define SCL_L P3OUT &= ~BIT6
#define SDA_H P3OUT |= BIT7
#define SDA_L P3OUT &= ~BIT7
#define SDA_IN P3DIR &= ~BIT7 //SDA改成輸入模式
#define SDA_OUT P3DIR |= BIT7 //SDA變回輸出模式
#define SDA_VAL P3IN&BIT7 //SDA的位值
/*********LCD1602 IO define************/
#define DataDir P4DIR
#define DataPort P4OUT
#define Busy 0x80
#define CtrlDir P5DIR
#define CLR_RS P5OUT&=~BIT0 //RS = P5.0
#define SET_RS P5OUT|=BIT0
#define CLR_RW P5OUT&=~BIT1//RW = P5.1
#define SET_RW P5OUT|=BIT1
#define CLR_EN P5OUT&=~BIT2//EN = P5.2
#define SET_EN P5OUT|=BIT2
#define _NOP() __no_operation()
#defineSlaveAddress0x46//定義器件在IIC總線中的從地址,根據ALT ADDRESS地址引腳不同修改
//ALT ADDRESS引腳接地時地址為0xA6,接電源時地址為0x3A
unsigned char ge,shi,bai,qian,wan;//顯示變量
int dis_data;
uchar BUF[8];
/******************************************************************************/
/*******************************延時函數***************************************/
/******************************************************************************/
/*******************************************
延時約15us的時間
********************************************/
void Delay5us(void)
{
uchar i;
for(i = 0;i < 15;i++);
_NOP();
}
void Delay5ms(void)
{
uint i=40000;
while (i != 0)
{
i--;
}
}
/*******************************************
延時MS的時間
********************************************/
void delay(uint x)
{
uchar i;
while(x--)for(i=0;i<125;i++);
}
/******************************************************************************/
/*******************************BH1750相關函數*********************************/
/******************************************************************************/
/**************************************
起始信號
**************************************/
void BH1750_Start()
{
SDA_H; //拉高數據線
SCL_H; //拉高時鐘線
Delay5us(); //延時
SDA_L; //產生下降沿
Delay5us(); //延時
SCL_L; //拉低時鐘線
}
/**************************************
停止信號
**************************************/
void BH1750_Stop()
{
SDA_L; //拉低數據線
SCL_H; //拉高時鐘線
Delay5us(); //延時
SDA_H; //產生上升沿
Delay5us(); //延時
}
/**************************************
發送應答信號
入口參數:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK(void)
{
SDA_L; //寫應答信號
_NOP();_NOP();
SCL_H; //拉高時鐘線
Delay5us(); //延時
SCL_L; //拉低時鐘線
_NOP();_NOP();
SDA_H;
Delay5us(); //延時
}
/********************************************
非應答
********************************************/
void mnack(void)
{
SDA_H;
_NOP(); _NOP();
SCL_H;
Delay5us();
SCL_L;
_NOP(); _NOP();
SDA_L;
Delay5us();
}
/**************************************
接收應答信號
**************************************/
uchar BH1750_RecvACK()
{
uchar ack;
SDA_H;
_NOP(); _NOP();
SCL_H;
_NOP(); _NOP();
SDA_IN;
_NOP(); _NOP();
ack = SDA_VAL; //讀入SDA數值
SCL_L;
Delay5us();
SDA_OUT;
if(ack) return 0;
else return 1;
}
/*******************************************
write1
********************************************/
void write1(void)
{
SDA_H;
//Delay5us();
SCL_H;
Delay5us();
SCL_L;
Delay5us();
}
/*******************************************
write0
********************************************/
void write0(void)
{
SDA_L;
// Delay5us();
SCL_H;
Delay5us();
SCL_L;
Delay5us();
}
/**************************************
向IIC總線發送一個字節數據
**************************************/
void BH1750_SendByte(unsigned char dat)
{
unsigned char i;
for (i = 0; i < 8; i++)
{ //8位計數器
if(dat&0x80)
write1();
else
write0();
dat <<= 1; //移出數據的最高位
}
BH1750_RecvACK();
}
/**************************************
從IIC總線接收一個字節數據
**************************************/
unsigned char BH1750_RecvByte()
{
unsigned char i;
unsigned char dat = 0,flag;
SDA_H; //使能內部上拉,準備讀取數據,
for (i = 0; i < 8; i++)
{ //8位計數器
//SDA_H;
//Delay5us();
SCL_H;
SDA_IN;
Delay5us();
flag=SDA_VAL;
dat <<= 1;
if(flag)
dat|=0x01;
SDA_OUT;
SCL_L;
Delay5us();
}
return dat;
}
/**********************************
**************寫入數據************/
void Single_Write_BH1750(unsigned char REG_Address)
{
BH1750_Start(); //起始信號
BH1750_SendByte(SlaveAddress); //發送設備地址+寫信號
BH1750_SendByte(REG_Address); //內部寄存器地址,請參考中文pdf22頁
// BH1750_SendByte(REG_data); //內部寄存器數據,請參考中文pdf22頁
BH1750_Stop(); //發送停止信號
}
/**************************************
初始化BH1750,根據需要請參考pdf進行修改
*************************************/
void Init_BH1750()
{
Single_Write_BH1750(0x01);
}
/***************************
*********單字節讀取*********/
/*
unsigned char Single_Read_BH1750(unsigned char REG_Address)
{
unsigned char REG_data;
BH1750_Start(); //起始信號
BH1750_SendByte(SlaveAddress); //發送設備地址+寫信號
BH1750_SendByte(REG_Address); //發送存儲單元地址,從0開始
BH1750_Start(); //起始信號
BH1750_SendByte(SlaveAddress+1); //發送設備地址+讀信號
REG_data=BH1750_RecvByte(); //讀出寄存器數據
BH1750_SendACK(1);
BH1750_Stop(); //停止信號
return REG_data;
}
*/
/*******************************
連續讀出BH1750內部數據
********************************/
void Multiple_Read_BH1750(void)
{
unsigned char i;
BH1750_Start(); //起始信號
BH1750_SendByte(0x47); //發送設備地址+讀信號
for (i = 0; i < 3; i++){ //連續讀取6個地址數據,存儲中BUF
BUF[i] = BH1750_RecvByte(); //BUF[0]存儲0x32地址中的數據
if (i == 3) {
mnack(); //最后一個數據需要回NOACK
}
else {
BH1750_SendACK(); //回應ACK
}
}
BH1750_Stop(); //停止信號
Delay5ms();
}
/*******************************************************************************/
/*******************************LCD1602函數************************************/
/*******************************************************************************/
void conversion(unsigned int temp_data) //數據轉換出 個,十,百,千,萬
{
wan = temp_data / 10000 + 0x30;
temp_data = temp_data % 10000;//取余運算
qian = temp_data / 1000 + 0x30;
temp_data = temp_data % 1000;//取余運算
bai = temp_data / 100 + 0x30;
temp_data = temp_data % 100;//取余運算
shi = temp_data / 10 + 0x30;
temp_data = temp_data % 10;//取余運算
ge = temp_data + 0x30;
}
void WaitForEnable(void)
{
DataDir &= 0x00;
CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();
while((P4IN & Busy)!=0); //檢測忙標志 //STA7為0 允許讀寫操作使能則退出循環
CLR_EN;
DataDir |= 0xFF; //將P4口切換為輸出狀態
}
/*******************************/
void WriteCommandLCM(unsigned char CMD,uchar Attribc)
{
if(Attribc)
WaitForEnable();
CLR_RS;
CLR_RW;
_NOP();
DataPort = CMD;
_NOP();
SET_EN;
_NOP();
_NOP();
CLR_EN;
}
/*******************************/
void WriteDataLCM(unsigned char dataW)
{
WaitForEnable();
SET_RS;
CLR_RW;
_NOP();
DataPort = dataW;
_NOP();
SET_EN;
_NOP();
_NOP();
CLR_EN;
}
/***********************************/
void InitLcd()
{
CtrlDir |= 0x07; //控制線端口設為輸出狀態
DataDir = 0xFF; //數據端口設為輸出狀態
WriteCommandLCM(0x38,0);
delay(15);
WriteCommandLCM(0x08,1);
delay(1);
WriteCommandLCM(0x01,1);
delay(1);
WriteCommandLCM(0x06,1);
delay(1);
WriteCommandLCM(0x0c,1);
delay(1);
}
/***********************************/
void DisplayOneChar(unsigned char X,unsigned char DData)
{
X |= 0x80;
WriteCommandLCM(X,0);
WriteDataLCM(DData);
}
void inmaindispaly()
{
uint temp;
dis_data=BUF[0];
dis_data=(dis_data<<8)+BUF[1];//合成數據
temp=dis_data;
conversion(temp); //計算數據和顯示
DisplayOneChar(0,'L');
DisplayOneChar(1,'i');
DisplayOneChar(2,'g');
DisplayOneChar(3,'h');
DisplayOneChar(4,'t');
DisplayOneChar(5,':');
DisplayOneChar(7,wan); //顯示數據
DisplayOneChar(8,qian);
DisplayOneChar(9,bai);
DisplayOneChar(10,shi);
DisplayOneChar(11,ge);
DisplayOneChar(13,'l'); ////顯示數單位
DisplayOneChar(14,'x');
}
int main( void )
{
P4DIR=0XFF;
P5DIR|=0X07;
P3DIR|=0XC0;
WDTCTL = WDTPW + WDTHOLD;// Stop watchdog timer to prevent time out reset
delay(20); //延時200ms
InitLcd(); //初始化LCD
Init_BH1750(); //初始化BH1750
while(1)
{
Single_Write_BH1750(0x01); // power on
Single_Write_BH1750(0x10); // H- resolution mode
delay(180); //延時180ms
Multiple_Read_BH1750(); //連續讀出數據,存儲在BUF中
inmaindispaly();
delay(1000);
}
}