/*********************************************************
程序功能:MCU的片内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 //结果数
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转换结果的数组
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();
/************************主函数****************************/
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;
}
/******************************************************************
函数名称:ADC12ISR
功 能:ADC中断服务函数,在这里用多次平均的
计算P6.0口的模拟电压数值
参 数:无
返回值 :无
*****************************************************************/
#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);
}
}
/*******************************************
函数名称:Trans_val
功 能:将16进制ADC转换数据变换成三位10进制
真实的模拟电压数据,并在液晶上显示
参 数:Hex_Val--16进制数据
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) //定时器中断函数
{
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) //次数
{
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) //按键中断函数
{
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 依据所需要的引脚
//采用上拉电阻会多费电吗
/*******************************************
函数名称:delay
功 能:用于消抖的延时
参 数:无
返回值 :无
********************************************/
void delay(void)
{
unsigned int tmp;
for(tmp = 12000;tmp > 0;tmp--);
}
void delay(void);
/********************主函数********************/
void Key_Scan()
{
unsigned char temp;
// P1DIR = 0xf0; //设置P1.0~P.4为输入状态
// P2DIR = 0xff;
// P2OUT = 0xff;
while(1)
{
if(keyin != 0x0f) //键值有改变
{
delay(); //延时消抖
if(keyin != 0x0f) //再次检测按键状态
{
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>
//****************************************************
//延时函数
//****************************************************
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;
/*******************************************
函数名称:DispNchar
功 能:让液晶从某个位置起连续显示N个字符
参 数:x--位置的列坐标
y--位置的行坐标
n--字符个数
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;
}
}
}
/*******************************************
函数名称:LocateXY
功 能:向液晶输入显示字符位置的坐标信息
参 数: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);
}
/*******************************************
函数名称:Disp1Char
功 能:在某个位置显示一个字符
参 数:x--位置的列坐标
y--位置的行坐标
data--显示的字符数据
返回值 :无
********************************************/
void Disp1Char(uchar x,uchar y,uchar data)
{
LocateXY( x, y );
LcdWriteData( data );
}
/*******************************************
函数名称:LcdReset
功 能:对1602液晶模块进行复位操作
参 数:无
返回值 :无
********************************************/
void LcdReset(void) //复位1602液晶
{
CtrlDir |= BIT5+BIT6+BIT7; //控制线端口设为输出状态
DataDir = 0xFF; //数据端口设为输出状态
LcdWriteCommand(0x38, 0); //规定的复位操作
Delay5ms();
LcdWriteCommand(0x38, 0);
Delay5ms();
LcdWriteCommand(0x38, 0);
Delay5ms();
LcdWriteCommand(0x38, 1); //显示模式设置
LcdWriteCommand(0x08, 1); //显示关闭
LcdWriteCommand(0x01, 1); //显示清屏
LcdWriteCommand(0x06, 1); //写字符时整体不移动
LcdWriteCommand(0x0c, 1); //显示开,不开游标,不闪烁
}
/*******************************************
函数名称:LcdWriteCommand
功 能:向液晶模块写入命令
参 数:cmd--命令,
chk--是否判忙的标志,1:判忙,0:不判
返回值 :无
********************************************/
void LcdWriteCommand(uchar cmd,uchar chk)
{
if (chk) WaitForEnable(); // 检测忙信号?
CLR_RS;
CLR_RW;
_NOP();
DataPort = cmd; //将命令字写入数据端口
_NOP();
SET_EN; //产生使能脉冲信号
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函数名称:LcdWriteData
功 能:向液晶显示的当前地址写入显示数据
参 数:data--显示字符数据
返回值 :无
********************************************/
void LcdWriteData( uchar data )
{
WaitForEnable(); //等待液晶不忙
SET_RS;
CLR_RW;
_NOP();
DataPort = data; //将显示数据写入数据端口
_NOP();
SET_EN; //产生使能脉冲信号
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函数名称:WaitForEnable
功 能:等待1602液晶完成内部操作
参 数:无
返回值 :无
********************************************/
void WaitForEnable(void)
{
P4DIR &= 0x00; //将P4口切换为输入状态
CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();
while((P4IN & Busy)!=0); //检测忙标志
CLR_EN;
P4DIR |= 0xFF; //将P4口切换为输出状态
}
/*******************************************
函数名称:Delay5ms
功 能:延时约5ms
参 数:无
返回值 :无
********************************************/
void Delay5ms(void)
{
uint i=40000;
while (i != 0)
{
i--;
}
}
/*******************************************
函数名称:Delay400ms
功 能:延时约400ms
参 数:无
返回值 :无
********************************************/
void Delay400ms(void)
{
uchar i=50;
uint j;
while(i--)
{
j=7269;
while(j--);
}
}
|