正在调这个程序,可以显示数据,但也有些问题。
#include <msp430x16x.h>
#include <math.h>
#define LCD_CTL P5OUT //P5为控制口
#define PSB_L ~BIT5 //数据串口(S)工作方式选择
#define PSB_H BIT5 //数据并口(P)工作方式选择
#define EN_L ~BIT4
#define EN_H BIT4 // ENABLE P5.4
#define RW_L ~BIT3 // WRITE P5.3
#define RW_H BIT3 // READ
#define RS_L ~BIT2 // DATA ;P5.2
#define RS_H BIT2 // COMMAND
#define RST_L ~BIT0 // P5.0 LCD复位
#define RST_H BIT0
#define BLIGHT_ON BIT1 // 开背光 P5.1
#define BLIGHT_OFF ~BIT1
#define LCD_DATA_IN P4OUT //P4为数据口
#define LCD_DATA_OUT P4IN //P4为数据口
#define LCD_DATA_DIR P4DIR //数据口方向选择
#define x1 0x80
#define x2 0x90
#define x3 0x88
#define x4 0x98
#define comm 0
#define dat 1
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
#define CSS BIT0
unsigned int XDATA_L,YDATA_L,ZDATA_L,XDATA_H,YDATA_H,ZDATA_H,XDATA,YDATA,ZDATA,X_DATA,Y_DATA,Z_DATA;
unsigned int count=0,count1=0,c=0,cc=0;
unsigned int x,y,z;
unsigned int xsign,ysign,zsign;
float angle;
/////////////////////////////////////////////////////////////////////////////
//子程序名:int_colok()
//功能: 时钟初始化子程序
void init_clock()
{
unsigned char i;//定义局部变量i
BCSCTL1&=~XT2OFF;//打开高频晶体震荡器
BCSCTL2|=SELM1+SELS;//MCLK和SMCLK的时钟源都选择XT2CLK,即都是8MHZ
do//(至少执行一次DO循环)
{
IFG1&=~OFIFG;//清除晶体震荡出错标志位
for(i=0;i<100;i++)
_NOP();//简单的延时等待
}while((IFG1&OFIFG));//判断晶体震荡是否出错,如果还是出错,则继续执行DO循环
IFG1&=~OFIFG;
}
void chk_busy(void)
{
LCD_DATA_DIR=0x00;
_NOP();
LCD_CTL&=RS_L; //rs=H; //DATA
LCD_CTL|=RW_H; //rw=1; //read
LCD_CTL|=EN_H; //LCD_E=1;
_NOP();
while(LCD_DATA_OUT&0x80); //DB7:buy;
LCD_CTL&=EN_L; //LCD_E=0;
}
void wr_lcd(uchar dat_comm,uchar content)
{
chk_busy();
LCD_DATA_DIR=0xff;
LCD_DATA_IN =0x00;
if(dat_comm)
{
LCD_CTL|=RS_H; //rs=1; //data
LCD_CTL&=RW_L; //rw=0; //write
}
else
{
LCD_CTL&=RS_L; //rs=0; //command
LCD_CTL&=RW_L; //rw=0; //write
}
_NOP();
LCD_DATA_IN =content; //output data or comm
_NOP();
LCD_CTL|=EN_H; // LCD_E=1;
__delay_cycles(50);
LCD_CTL&=EN_L; // LCD_E=0;
}
/*------------------初始化-----------------*/
void init_lcd (void)
{
LCD_CTL&=RST_L; //复位LCD屏
_NOP();
LCD_CTL|=RST_H;
LCD_CTL|=PSB_H;
LCD_CTL|=BLIGHT_ON; //开背景灯
_NOP();
wr_lcd (comm,0x30); /*30---基本指令动作*/
wr_lcd (comm,0x01); /*清屏,地址指针指向00H*/
wr_lcd (comm,0x06); /*光标的移动方向*/
wr_lcd (comm,0x0c); /*开显示,关游标*/
}
void display_en(uchar *en,uint add,uint n) //ch[]为要显示的字符数组
//add为显示的初始位置,第一行最左端为0x80,第二行最左端为0x90
//num为要显示字母或数字的个数
{ // uchar en1[]={"10000Hz"};
uchar i;
wr_lcd (comm,add); //显示下列字符的初始位置,在第一行最左端
for(i=0;i<n;i++)
wr_lcd (dat,en[i]);
}
void display_numz(uint num,uint add,uint n) //整数
{
uchar i,df[5]={0},z;
uint m=1;
for(i=0;i<n-1;i++)
m=m*10;
for(i=0;i<n;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
display_en(df,add,n);
}
void display_numc(uchar num,uint add,uint n) //整数
{
uchar i,df[5]={0},z;
uint m=1;
for(i=0;i<n-1;i++)
m=m*10;
for(i=0;i<n;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
display_en(df,add,n);
}
void display_numf(float nuf,uint add,uint n) //显示带两位小数的浮点数
{
uchar i,df[6]={0},z;
uint m=1000,num,data;
data=(uint)nuf;
if(data>=100)
{
num=(uint)(nuf*10);
for(i=0;i<3;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
df[3]='.';
for(i=4;i<=n;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
display_en(df,add,n+1);
}
if(data<100&data>=10)
{
num=(uint)(nuf*100);
for(i=0;i<2;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
df[2]='.';
for(i=3;i<=n;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
display_en(df,add,n+1);
}
if(data<10)
{
num=(uint)(nuf*1000);
z=(uchar)(num/m);
df[0]=z+'0';
num=num-z*m;
m = m/10;
df[1]='.';
for(i=2;i<=n;i++)
{
z=(uchar)(num/m);
df[i]=z+'0';
num=num-z*m;
m = m/10;
}
display_en(df,add,n+1);
}
}
void display_ch(uint *ch,uint add,uint n) //ch[]为要显示的汉字国标编号
//add为显示的初始位置,第一行最左端为0x80,第二行最左端为0x90
//num为要显示汉字的个数
{ //uint ch[]={0xC6B5,0xC2CA}; //频率
uchar i;
wr_lcd (comm,add); //显示下列字符的初始位置,在第一行最左端
for(i=0;i<n;i++)
{
wr_lcd (dat, ch[i]/256);
wr_lcd (dat, ch[i]%256);
}
}
void xianshi()
{
unsigned char en1[]={"角度传感器"};
unsigned char en2[]={"X"};
unsigned char en3[]={"Y"};
unsigned char en4[]={"Z"};
display_en(en1,0x82,10);
display_en(en2,0x90,2);
display_en(en3,0x88,2);
display_en(en4,0x98,2);
}
/***************************************************/
/*I/O初始化子程序 */
/***************************************************/
void IOInit() //1--OUT;0--IN
{
P3DIR = 0XFB; // P3.3--CLK; P3.2--MISO; P3.1--MOSI; P3.0--/CS 1011
P3SEL = 0X0E;
}
void SensorWrite_add (unsigned int add)
{
TXBUF0 = ((add&0Xff)<<1)|0x80; //0--read; 1--write; bit0--don't care bit//选择地址,8位地址
P3OUT &= ~ CSS;
while(0==(UTCTL0&TXEPT));
_NOP();
P3OUT |= CSS;
}
void SensorWrite (unsigned int addr,unsigned int data)
{
//SensorWrite_add (0x3a);
TXBUF0 = ((addr&0Xff)<<1)|0x80; //0--read; 1--write; bit0--don't care bit//选择地址,8位地
P3OUT &= ~ CSS; //Clear Chip Select
while(0==(UTCTL0&TXEPT));
_NOP();
TXBUF0 = data;
while (0==(UTCTL0&TXEPT));
_NOP();
P3OUT |= CSS;
}
unsigned int SensorRead(unsigned int addr)
{
P3OUT &= ~ CSS; //Clear Chip Select
TXBUF0 = ((addr&0Xff)<<1); //0--read; 1--write; bit0--don't care bit
while (0==(UTCTL0&TXEPT));
_NOP();
TXBUF0 = 0x00;
while (0==(UTCTL0&TXEPT));
// count=0;
// while(!(UTCTL0&TXEPT)&&(count<100));
_NOP();
//while (!(IFG1&URXIFG0));
P3OUT |= CSS;
return RXBUF0;
}
void judge()
{
if((x&0x0080)==0x00)
{
xsign=0x2b;
}
else
{
xsign=0x2d;
x=~x+1;
x&=0x00ff;
}
if((z&0x0080)==0x00)
{
zsign=0x2b;
}
else
{
zsign=0x2d;
z=~z+1;
z&=0x00ff;
}
}
unsigned int MMA_mesure()
{
x=SensorRead(0x06);
z=SensorRead(0x08);
judge();
angle=((float)x/94)*90;
return 1;
}
void MMA_calibrate() // 校验
{
x=SensorRead(0x06);
y=SensorRead(0x07);
z=SensorRead(0x08);
x=0-x;
y=0-y;
z=0-z;
SensorWrite(0x10,x);
SensorWrite(0x12,y);
SensorWrite(0x14,z);
}
void SensorInit(void)
{
SensorWrite(0x0D,0x80); //I2C总线关闭,spi使能
SensorWrite(0x16,0x05); //0x51--4线SPImode,INT2读取数据准备状态,2g测试,自测未使能
//testd=SensorRead(0x16);
SensorWrite(0x17,0x03); //清除INT1、INT2的标志位
//SensorWrite(0x17,0x00);
SensorWrite(0x18,0x90); //0X80--250 Hz; 0X00--125Hz , 0XC0 -- +/-禁止Y轴读数
/* SensorWrite(0x1A,0x00);//设置0x1A寄存器:Level detection threshold limit value
SensorWrite(0x19,0x00);
SensorWrite(0x10,0x00); //XOFFSET(0x20),更改后结果不对
SensorWrite(0x11,0x00);
SensorWrite(0x12,0x00); //YOFFSET(0x60),更改后结果不对
SensorWrite(0x13,0x00);
SensorWrite(0x14,0x00); //ZOFFSET(0x1c),更改后结果不对
SensorWrite(0x15,0x00);
SensorWrite(0x1D,0x00);//设置0x1d寄存器:Latency time value
SensorWrite(0x1E,0x00);//设置0x1e寄存器:Time window for 2nd pulse value*/
/*
SensorWrite(0x1B,0x00);//设置0x1B寄存器:Pulse detection threshold limit value
SensorWrite(0x1C,0x00);//设置0x1C寄存器:Pulse duration value
*/
}
void SPI_ctl()
{
//UART1 配置
U0CTL = SWRST;
U0CTL |= CHAR +SYNC +MM; //设置为SPI主机,8位发送;SPI复位
U0TCTL = 0x00;
U0TCTL |= CKPH+SSEL1+STC; // 时钟边沿选择,并选SMCLK为时钟源,设置为3线SPI
U0BR0 = 0X00;
U0BR1 = 0X7d; //波特率:0X7D00对应250HZ;0XfA00对应125HZ;
U0MCTL = 0X00; //同步时设为0X00;异步时为小数调整部分
ME1 = USPIE0; //SPI模块使能
U0CTL &= ~SWRST; //SPI复位置零
// IE1 |= URXIE0; //+ UTXIE0接收中断使能
int i =500;
do (i--);
while (i != 0); //等待一段时间,使SPI同步
}
void init_timer()
{
TACTL=TASSEL_1+TACLR+MC_1;
CCTL0=CCIE;
CCR0=1000;
}
void main()
{
WDTCTL=WDTPW+WDTHOLD;
P5DIR=0xff;
P5OUT=0x00;
init_clock();
IOInit();
SPI_ctl();
SensorInit();
init_lcd();
xianshi();
init_timer();
MMA_calibrate();
_EINT();
while(1)
{
MMA_mesure();
display_numf(angle,0X92,6);
display_numf(x,0X9a,6);
}
}
#pragma vector=TIMERA0_VECTOR
__interrupt void timera0 ()
{
count1++;
} |