本人初学msp430f149单片机,第一次接触IAR软件,用的是5.3版本的。
做的是基于AD7190芯片的电子称。代码如下:
main.c:
#include <msp430x14x.h>
#include "cry1602.h"
#include "cry1602.c"
#define AD_DIN_H P5OUT |= 0X01;
#define AD_DIN_L P5OUT &= ~0X01;
#define ARDY P5IN & 0X04;
#define ADOUT P5IN & 0X04;
#define AD_CLK_H P5OUT |= 0X02;
#define AD_CLK_L P5OUT &= ~0X02;
uchar tishi1[] = {"Weight:"};
uchar tishi2[] = {"kg"};
/*************************时钟初始化******************************/
void jingzhen_8M()
{
volatile unsigned int i;
BCSCTL1 &= ~XT2OFF;
do
{
IFG1 &= ~OFIFG;
for (i = 0xFF; i > 0; i--);
}
while ((IFG1 & OFIFG));
BCSCTL2 |= SELM_2+SELS;
}
/*********************延时函数**********************************/
void delay(unsigned int time)
{
unsigned int s;
for(s=0;s<time;s++);
}
//=============写一个字节======================//
void AD7190_Write( unsigned char temp)
{
unsigned char loop;
for(loop=0;loop<8;loop++)
{
if(temp&0x80){ AD_DIN_H; }
else AD_DIN_L ;
AD_CLK_L;
AD_CLK_H;
temp=temp<<1 ;
}
}
//===============读一个字节==========================//
unsigned char AD7190_Read(void)
{
unsigned char recdata;
unsigned char loop;
recdata=0;
for(loop=0;loop<8;loop++)
{
AD_CLK_L;
recdata=recdata<<1;
if((P5IN&0X04)==0X04) recdata=recdata +1;
else _NOP();
AD_CLK_H;
}
return (recdata);
}
//==================AD7190初始化=================================//
void AD7190_init (void)
{
AD7190_Write(0Xff);
AD7190_Write(0Xff);
AD7190_Write(0Xff);
AD7190_Write(0Xff);
AD7190_Write(0Xff);//连续写入40个1,ADC复位
delay(100); //延时函数
while((P5IN&0X04)==0x04); //配置寄存器设置
AD7190_Write(0X10);//选择Configuration regisster(24 bit,with 3 turns)
AD7190_Write(0x80);//chop enabled 在REFIN1(+)与REFIN1(-)之间施加外部电压
AD7190_Write(0x02);//选择AIN3(+) 与AIN4(-)
AD7190_Write(0x0f);//unbuffer model,current关闭,gain =128,单极性(双极性可以增大输入范围)
while((P5IN&0X04)==0x04); //配置寄存器设置
AD7190_Write(0x08);//选择模式寄存器,内部零点校准(24 bit,with 3 turns)
AD7190_Write(0x88);//Internal zero-scale calibration Model
AD7190_Write(0x00);
AD7190_Write(0x01);
while((P5IN&0X04)==0x04); //模式寄存器设置
AD7190_Write(0x08);//选择模式寄存器,内部满量程校准(24 bit,with 3 turns)
AD7190_Write(0xa8);//Internal full-scale calibration Model
AD7190_Write(0x00);
AD7190_Write(0x01);
while((P5IN&0X04)==0x04);
AD7190_Write(0x08);//选择模式寄存器(24 bit,with 3 turns)
AD7190_Write(0x08);//连续转换模式
AD7190_Write(0x00);
AD7190_Write(0x05);//控制输出数据速率
}
//========================读数据=====================//
unsigned int Read_AD7190(void)
{
unsigned long AD_result;
AD7190_Write(0x58);
AD_result= AD7190_Read();
AD_result=AD_result<<8;
AD_result= AD7190_Read()+ AD_result;
AD_result=AD_result<<8;
AD_result= AD7190_Read()+ AD_result;
return AD_result;
}
/***************全局变量***************/
uchar key_Pressed; //按键是否被按下:1--是,0--否
uchar key_val; //存放键值
uchar key_Flag; //按键是否已放开:1--是,0--否
//设置键盘逻辑键值与程序计算键值的映射
uchar key_Map[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
/*******************************************
函数名称:Init_Keypad
功 能:初始化扫描键盘的IO端口
参 数:无
返回值 :无
********************************************/
void Init_Keypad(void)
{
P1DIR = 0xf0; //P1.0~P1.3设置为输入状态, P1.4~P1.7设置为输出状态
P1OUT |= 0xf0; // P1.4~P1.7输出高电平
key_Flag = 0;
key_Pressed = 0;
key_val = 0;
}
/*******************************************
函数名称:Check_Key
功 能:扫描键盘的IO端口,获得键值
参 数:无
返回值 :无
********************************************/
void Check_Key(void)
{
uchar row ,col,tmp1,tmp2;
tmp1 = 0x80;
for(row = 0;row < 4;row++) //行扫描
{
P1OUT = 0xf0; //P1.4~P1.7输出全1
P1OUT -= tmp1; //P1.4~p1.7输出四位中有一个为0
tmp1 >>=1;
if ((P1IN & 0x0f) < 0x0f) //是否P1IN的P1.0~P1.3中有一位为0
{
tmp2 = 0x01; // tmp2用于检测出那一位为0
for(col = 0;col < 4;col++) // 列检测
{
if((P1IN & tmp2) == 0x00) // 是否是该列,等于0为是
{
key_val = key_Map[row * 4 + col]; // 获取键值
return; // 退出循环
}
tmp2 <<= 1; // tmp2右移1位
}
}
}
}
/*******************************************
函数名称:delay
功 能:延时约15ms,完成消抖功能
参 数:无
返回值 :无
********************************************/
void delay1()
{
uint tmp;
for(tmp = 12000;tmp > 0;tmp--);
}
/*******************************************
函数名称:Key_Event
功 能:检测按键,并获取键值
参 数:无
返回值 :无
********************************************/
void Key_Event(void)
{
uchar tmp;
P1OUT &= 0x00; // 设置P1OUT全为0,等待按键输入
tmp = P1IN; // 获取 p1IN
if ((key_Pressed == 0x00)&&((tmp & 0x0f) < 0x0f)) //如果有键按下
{
key_Pressed = 1; // 如果有按键按下,设置key_Pressed标识
delay1(); //消除抖动
Check_Key(); // 调用check_Key(),获取键值
}
else if ((key_Pressed == 1)&&((tmp & 0x0f) == 0x0f)) //如果按键已经释放
{
key_Pressed = 0; // 清除key_Pressed标识
key_Flag = 1; // 设置key_Flag标识
}
else
{
_NOP();
}
}
cry1602.c:
#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 P3DIR
#define CLR_RS P3OUT&=~BIT0; //RS = P3.0
#define SET_RS P3OUT|=BIT0;
#define CLR_RW P3OUT&=~BIT1; //RW = P3.1
#define SET_RW P3OUT|=BIT1;
#define CLR_EN P3OUT&=~BIT2; //EN = P3.2
#define SET_EN P3OUT|=BIT2;
/*******************************************
函数名称: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)
{
CtrlDir |= 0x07; //控制线端口设为输出状态
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--);
}
}
cry1602.h:
void DispStr(unsigned char x,unsigned char y,unsigned char *ptr);
void DispNChar(unsigned char x,unsigned char y, unsigned char n,unsigned char *ptr);
void LocateXY(unsigned char x,unsigned char y);
void Disp1Char(unsigned char x,unsigned char y,unsigned char data);
void LcdReset(void);
void LcdWriteCommand(unsigned char cmd,unsigned char chk);
void LcdWriteData( unsigned char data );
void WaitForEnable(void);
void Delay5ms(void);
编译时会出现
Error[e46]: Undefined external "main" referred in ?cstart ( D:\IAR\430\LIB\DLIB\dl430fn.r43 )
Error while running Linker
希望有大神求解,谢谢!
|
|