/*********************************************************
程序功能:MCU的片內(nèi)ADC對P6.0端口的電壓進行轉換
將模擬電壓值顯示在1602液晶上。
*********************************************************/
#include <msp430x14x.h>
#include "cry1602.h"
#include "hx711.h"
#define uchar unsigned char
#define uint unsigned int
#define Num_of_Results 1 //結果數(shù)
uchar shuzi[] = {"0123456789."};
uchar tishi[] = {"The weight is"};
uchar tishi1[]= {"2.5d pe g "};
signed char st=0,wdis=1,lcd=1;
float p=1;
long int Curr_Volt,Curr_Volt0=0;
static uint results[Num_of_Results],t=0; //保存ADC轉換結果的數(shù)組
unsigned char dised[13][5];
signed char ptr[6];
signed char ptr0[5]={0,0,0,0,0};
void Trans_val(uint Hex_Val);
void keyinit();
void initb();
/************************主函數(shù)****************************/
void main(void)
{
WDTCTL = WDTPW+WDTHOLD; //關閉看門狗
LcdReset(); //復位1602液晶
keyinit(); //初始化
DispNChar(1,0,13,tishi); //顯示提示信息
Disp1Char(11,1,'k'); //顯示電壓單位
P6SEL |= 0x01; // 使能ADC通道
PORT_Init();
/***********************************************************
ADC12CTL0 = ADC12ON+SHT0_8+MSC; // 打開ADC,設置采樣時間
ADC12CTL1 = SHP+CONSEQ_2; // 使用采樣定時器
ADC12MCTL0=SREF0;
ADC12IE = 0x01; // 使能ADC中斷
ADC12CTL0 |= ENC; // 使能轉換
ADC12CTL0 |= ADC12SC; // 開始轉換
************************************************************/
initb(); // 初始化定時器b
_EINT();
LPM0;
}
/******************************************************************
函數(shù)名稱:ADC12ISR
功 能:ADC中斷服務函數(shù),在這里用多次平均的
計算P6.0口的模擬電壓數(shù)值
參 數(shù):無
返回值 :無
*****************************************************************/
#pragma vector=ADC_VECTOR
__interrupt void ADC12ISR (void)
{
static uint index = 0;
unsigned long sum = 0;
results[index++] = ADC12MEM0; // 移動的結果
if(index == Num_of_Results)
{
uint i;
index = 0;
for(i = 0; i < Num_of_Results; i++)
{
sum += results[i];
}
sum = sum/1;
Trans_val(sum);
}
}
/*******************************************
函數(shù)名稱:Trans_val
功 能:將16進制ADC轉換數(shù)據(jù)變換成三位10進制
真實的模擬電壓數(shù)據(jù),并在液晶上顯示
參 數(shù):Hex_Val--16進制數(shù)據(jù)
n--變換時的分母等于2的n次方
返回值 :無
********************************************/
/*去皮計價需要先切換到計價模式,在按去皮鍵*/
void Trans_val(uint Hex_Val) //轉換值 Hex_Val16進制值
{
// unsigned long caltmp;
// uchar l;
uchar l;
long int temp1;
uint m,pa;
double cal=0,tempc;
tempc=(double)(Hex_Val);
cal=tempc/0xffff*4.1;
//cal=cal*p; //價格
Curr_Volt=(long int)(cal*10000)-Curr_Volt0; //去皮后
if(Curr_Volt>=100000)Curr_Volt=99999;
if(Curr_Volt<=0)Curr_Volt=0;
//Curr_Volt=Curr_Volt-112;
ptr[0]=Curr_Volt/10000;
temp1=Curr_Volt-(long int)(ptr[0]*(long int)10000);
ptr[1]=temp1/1000;
temp1=temp1-ptr[1]*1000;
ptr[3]=temp1/100;
temp1=temp1-ptr[3]*100;
ptr[4]=temp1/10;
ptr[5]=temp1-ptr[4]*10;
ptr[2] = 10;
if(wdis==1&&lcd)
{
for(l = 0;l < 6;l++)
Disp1Char((l + 2),1,shuzi[ptr[l]]);
}
if(wdis==2&&lcd)
{
pa=(uint)(p*10);
m=pa/10;
Disp1Char(1,0,shuzi[m]);
m=pa-m*10;
Disp1Char(3,0,shuzi[m]);
for(l = 0;l < 6;l++)
Disp1Char((2 + l),1,shuzi[ptr[l]]);
}
}
void keyinit() //初始化
{
P1DIR=0xf0;
P1IES=0x0f;
P1IE =0x0f;
P1IFG=0x00;
}
void initb() // 初始化定時器b
{
TBCTL=TBSSEL_1+TBCLR+MC_0+MC_1;
TBCCTL0 = CCIE;
TBCCR0=50000;
}
void priceinit() //價格
{
wdis=2;
p=10;
Curr_Volt0=(long int)((double)(Curr_Volt0)*p);
DispNChar(1,0,13,tishi1);
}
#pragma vector=TIMERB0_VECTOR
__interrupt void Timer_B0(void) //定時器中斷函數(shù)
{
int i;
unsigned long long sum;
for(i = 0; i < Num_of_Results; i++)
{
sum=(HX711_Read()>>8);
sum += results[i];
}
// sum = sum/1;
Trans_val(sum);
TBCCR0 =10000; // Add Offset to CCR0
if(t==13) //次數(shù)
{
LcdReset();
lcd=0;
}
if(t==0&&lcd&&wdis==1)
{
DispNChar(1,0,13,tishi); //顯示提示信息
Disp1Char(11,1,'k'); //顯示電壓單位
}
if(t==0&&lcd&&wdis==2)
{
DispNChar(1,0,13,tishi1);
Disp1Char(11,1,'d');
}
st++;
if(st>=13)st=0;
}
#pragma vector=PORT1_VECTOR
__interrupt void Keyin(void) //按鍵中斷函數(shù)
{
switch(P1IFG)
{
case 0x01:
{
Curr_Volt0=Curr_Volt;
break;
}
case 0x02:
priceinit();
break;
case 0x04:
p=p+0.1;break;
case 0x08:
p=p-0.1;break;
}
P1IFG=0x00;
if(p<0)p=0;
if(p>5)p=5;
}
/*********************key.c***********************/
#include "key.h"
#define keyin (P1IN & 0x0f) //P1.0 to P1.4 依據(jù)所需要的引腳
//采用上拉電阻會多費電嗎
/*******************************************
函數(shù)名稱:delay
功 能:用于消抖的延時
參 數(shù):無
返回值 :無
********************************************/
void delay(void)
{
unsigned int tmp;
for(tmp = 12000;tmp > 0;tmp--);
}
void delay(void);
/********************主函數(shù)********************/
void Key_Scan()
{
unsigned char temp;
// P1DIR = 0xf0; //設置P1.0~P.4為輸入狀態(tài)
// P2DIR = 0xff;
// P2OUT = 0xff;
while(1)
{
if(keyin != 0x0f) //鍵值有改變
{
delay(); //延時消抖
if(keyin != 0x0f) //再次檢測按鍵狀態(tài)
{
temp=keyin;
while(keyin != 0x0f); //等待按鍵被放開
switch(temp) //轉換鍵值
{
case 0x0e:
P2OUT = 0xfe;break;
case 0x0d:
P2OUT = 0xfd;break;
case 0x0b:
P2OUT = 0xfb;break;
case 0x07:
P2OUT = 0xf7;break;
default:
P2OUT = 0xff;break;
}
delay();delay();delay();delay();delay();delay();delay();delay();
}
}
}
}
/***************hx711*******************/
#include<msp430x14x.h>
#include "hx711.h"
//#include<intrins.h>
//****************************************************
//延時函數(shù)
//****************************************************
void Delay_hx711_us(unsigned int t)
{
//_nop_();
//_nop_();
while(t--);
}
// I/O配置
void PORT_Init(void)
{
P5SEL &=~ (BIT1+BIT2);
P5DIR &=~ BIT2;//SDA 讀取
P5DIR |= BIT1;//SCK 時鐘
}
//****************************************************
//讀取HX711
//****************************************************
unsigned long HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i;
P5OUT |= BIT2; //SDA
Delay_hx711_us(4);
P5OUT &=~ BIT1;//SCK
count=0;
while( P5IN&BIT2 ); //SDA
for(i=0;i<24;i++)
{
{
P5OUT |= BIT1; //SCK
count=count<<1;
P5OUT &=~ BIT1;//SCK
if(P5IN&BIT2)//SDA
count++;
}
}
P5OUT |= BIT1; //SCK
Delay_hx711_us(4);
//P5OUT &=~ BIT1;//SCK
//Delay_hx711_us(4);
//P5OUT |= BIT1; //SCK
//Delay_hx711_us(4);
P5OUT &=~ BIT1;//SCK
return(count);
}
/*****************1602******************/
#include <msp430x14x.h>
#include "cry1602.h"
typedef unsigned char uchar;
typedef unsigned int uint;
/**************宏定義***************/
#define DataDir P4DIR
#define DataPort P4OUT
#define Busy 0x80
#define CtrlDir P5DIR
#define CLR_RS P5OUT&=~BIT5; //RS = P3.0
#define SET_RS P5OUT|=BIT5;
#define CLR_RW P5OUT&=~BIT6; //RW = P3.1
#define SET_RW P5OUT|=BIT6;
#define CLR_EN P5OUT&=~BIT7; //EN = P3.2
#define SET_EN P5OUT|=BIT7;
/*******************************************
函數(shù)名稱:DispNchar
功 能:讓液晶從某個位置起連續(xù)顯示N個字符
參 數(shù):x--位置的列坐標
y--位置的行坐標
n--字符個數(shù)
ptr--指向字符存放位置的指針
返回值 :無
********************************************/
void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) //顯示提示信息
{
uchar i;
for (i=0;i<n;i++)
{
Disp1Char(x++,y,ptr[i]);
if (x == 0x0f)
{
x = 0;
y ^= 1;
}
}
}
/*******************************************
函數(shù)名稱:LocateXY
功 能:向液晶輸入顯示字符位置的坐標信息
參 數(shù):x--位置的列坐標
y--位置的行坐標
返回值 :無
********************************************/
void LocateXY(uchar x,uchar y)
{
uchar temp;
temp = x&0x0f;
y &= 0x01;
if(y)
temp |= 0x40; //如果在第2行
temp |= 0x80;
LcdWriteCommand(temp,1);
}
/*******************************************
函數(shù)名稱:Disp1Char
功 能:在某個位置顯示一個字符
參 數(shù):x--位置的列坐標
y--位置的行坐標
data--顯示的字符數(shù)據(jù)
返回值 :無
********************************************/
void Disp1Char(uchar x,uchar y,uchar data)
{
LocateXY( x, y );
LcdWriteData( data );
}
/*******************************************
函數(shù)名稱:LcdReset
功 能:對1602液晶模塊進行復位操作
參 數(shù):無
返回值 :無
********************************************/
void LcdReset(void) //復位1602液晶
{
CtrlDir |= BIT5+BIT6+BIT7; //控制線端口設為輸出狀態(tài)
DataDir = 0xFF; //數(shù)據(jù)端口設為輸出狀態(tài)
LcdWriteCommand(0x38, 0); //規(guī)定的復位操作
Delay5ms();
LcdWriteCommand(0x38, 0);
Delay5ms();
LcdWriteCommand(0x38, 0);
Delay5ms();
LcdWriteCommand(0x38, 1); //顯示模式設置
LcdWriteCommand(0x08, 1); //顯示關閉
LcdWriteCommand(0x01, 1); //顯示清屏
LcdWriteCommand(0x06, 1); //寫字符時整體不移動
LcdWriteCommand(0x0c, 1); //顯示開,不開游標,不閃爍
}
/*******************************************
函數(shù)名稱:LcdWriteCommand
功 能:向液晶模塊寫入命令
參 數(shù):cmd--命令,
chk--是否判忙的標志,1:判忙,0:不判
返回值 :無
********************************************/
void LcdWriteCommand(uchar cmd,uchar chk)
{
if (chk) WaitForEnable(); // 檢測忙信號?
CLR_RS;
CLR_RW;
_NOP();
DataPort = cmd; //將命令字寫入數(shù)據(jù)端口
_NOP();
SET_EN; //產(chǎn)生使能脈沖信號
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函數(shù)名稱:LcdWriteData
功 能:向液晶顯示的當前地址寫入顯示數(shù)據(jù)
參 數(shù):data--顯示字符數(shù)據(jù)
返回值 :無
********************************************/
void LcdWriteData( uchar data )
{
WaitForEnable(); //等待液晶不忙
SET_RS;
CLR_RW;
_NOP();
DataPort = data; //將顯示數(shù)據(jù)寫入數(shù)據(jù)端口
_NOP();
SET_EN; //產(chǎn)生使能脈沖信號
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函數(shù)名稱:WaitForEnable
功 能:等待1602液晶完成內(nèi)部操作
參 數(shù):無
返回值 :無
********************************************/
void WaitForEnable(void)
{
P4DIR &= 0x00; //將P4口切換為輸入狀態(tài)
CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();
while((P4IN & Busy)!=0); //檢測忙標志
CLR_EN;
P4DIR |= 0xFF; //將P4口切換為輸出狀態(tài)
}
/*******************************************
函數(shù)名稱:Delay5ms
功 能:延時約5ms
參 數(shù):無
返回值 :無
********************************************/
void Delay5ms(void)
{
uint i=40000;
while (i != 0)
{
i--;
}
}
/*******************************************
函數(shù)名稱:Delay400ms
功 能:延時約400ms
參 數(shù):無
返回值 :無
********************************************/
void Delay400ms(void)
{
uchar i=50;
uint j;
while(i--)
{
j=7269;
while(j--);
}
}
|