MSP单片机AD转换实验.docx
《MSP单片机AD转换实验.docx》由会员分享,可在线阅读,更多相关《MSP单片机AD转换实验.docx(24页珍藏版)》请在冰豆网上搜索。
MSP单片机AD转换实验
A/D转换实验
一、转换原理
MSP430F149的A/D转换器原理请参考相关书籍。
实验板上与AD相关的硬件电路:
编程工作实际就是对以下寄存器的操作:
寄存器类型
寄存器缩写
寄存器的含义
转换控制
寄存器
ADC12CTL0
转换控制寄存器0
ADC12CTL1
转换控制寄存器1
中断
控制
ADC12IFG
中断标志寄存器
ADC12IE
中断使能寄存器
ADC12IV
中断向量寄存器
存储
及其
控制寄存器
ADC12MCTL0~ADC12MCTL15
存储控制寄存器0~15
ADC12MEM0~
ADC12MEM15
存储寄存器0~15
设计主程序和中断服务程序。
二、转换程序
1、程序1:
转换结果发送到PC
主程序中进行A/D初始化,中断服务程序读A/D转换结果,主程序中通过串口发送结果。
“”主程序与中断程序:
/*********************************************************
程序功能:
将ADC对端口电压的转换结果按转换数据和对应的
模拟电压的形式通过串口发送到PC机屏幕上显示
-----------------------------------------------------------
通信格式:
9600
测试说明:
打开串口调试精灵,正确设置通信格式,观察接收数据
**********************************************************/
#include<>
#include""
#defineNum_of_Results32
uintresults[Num_of_Results];//保存ADC转换结果的数组
uintaverage;
uchartcnt=0;
/***********************主函数***********************/
voidmain(void)
{
uchari;
ucharbuffer[5];
WDTCTL=WDTPW+WDTHOLD;//关狗
/*下面六行程序关闭所有的IO口*/
P1DIR=0XFF;P1OUT=0XFF;
P2DIR=0XFF;P2OUT=0XFF;
P3DIR=0XFF;P3OUT=0XFF;
P4DIR=0XFF;P4OUT=0XFF;
P5DIR=0XFF;P5OUT=0XFF;
P6DIR=0XFF;P6OUT=0XFF;
P6DIR|=BIT2;P6OUT|=BIT2;//关闭电平转换
P6DIR|=BIT6;P6OUT&=~BIT6;//关闭数码管显示
InitUART();
Init_ADC();
_EINT();
buffer[4]='\0';
while
(1)
LPM1;
Hex2Dec(average,buffer);
for(i=0;i<4;i++)
buffer[i]+=0x30;
PutString0("Thedigitalvalueis:
");
PutString(buffer);
Trans_val(average,buffer);
buffer[3]=buffer[2];
buffer[2]=buffer[1];
buffer[1]=0x2e-0x30;
PutString0("Theanalogvalueis:
}
/*******************************************
函数名称:
ADC12ISR
功能:
ADC中断服务函数,在这里用多次平均的
计算口的模拟电压数值
参数:
无
返回值:
********************************************/
#pragmavector=ADC_VECTOR
__interruptvoidADC12ISR(void)
staticucharindex=0;
results[index++]=ADC12MEM0;//Moveresults
if(index==Num_of_Results)
average=0;
for(i=0;i{average+=results[i];}average>>=5;//除以32index=0;tcnt++;if(tcnt==250)//主要是降低串口发送速度{LPM1_EXIT;tcnt=0;}}}“”A/D转换相关程序:#include<>typedefunsignedintuint;/********************************************函数名称:Init_ADC功能:初始化ADC参数:无返回值:无********************************************/voidInit_ADC(void){P6SEL|=0x01;//使能ADC通道ADC12CTL0=ADC12ON+SHT0_15+MSC;//打开ADC,设置采样时间ADC12CTL1=SHP+CONSEQ_2;//使用采样定时器ADC12IE=0x01;//使能ADC中断ADC12CTL0|=ENC;//使能转换ADC12CTL0|=ADC12SC;//开始转换}/********************************************函数名称:Hex2Dec功能:将16进制ADC转换数据变换成十进制表示形式参数:Hex_Val--16进制数据ptr--指向存放转换结果的指针返回值:无********************************************/voidHex2Dec(uintHex_val,uchar*ptr){ptr[0]=Hex_val/1000;ptr[1]=(Hex_val-ptr[0]*1000)/100;ptr[2]=(Hex_val-ptr[0]*1000-ptr[1]*100)/10;ptr[3]=(Hex_val-ptr[0]*1000-ptr[1]*100-ptr[2]*10);}/*******************************************函数名称:Trans_val功能:将16进制ADC转换数据变换成三位10进制真实的模拟电压数据,并在液晶上显示参数:Hex_Val--16进制数据返回值:无********************************************/voidTrans_val(uintHex_Val,uchar*ptr){unsignedlongcaltmp;uintCurr_Volt;uchart1;caltmp=Hex_Val;caltmp=(caltmp<<5)+Hex_Val;//caltmp=Hex_Val*33caltmp=(caltmp<<3)+(caltmp<<1);//caltmp=caltmp*10Curr_Volt=caltmp>>12;//Curr_Volt=caltmp/2^nptr[0]=Curr_Volt/100;//Hex->Dec变换t1=Curr_Volt-(ptr[0]*100);ptr[1]=t1/10;ptr[2]=t1-(ptr[1]*10);}“”串口程序:#include<>typedefunsignedcharuchar;/*******************************************函数名称:InitUART功能:初始化UART端口参数:无返回值:无********************************************/voidInitUART(void){P3SEL|=0x30;//,5=USART0TXD/RXDME1|=URXE0+UTXE0;//EnableUSART0T/RXDUCTL0|=CHAR;//8-bitcharacterUTCTL0|=SSEL0;//UCLK=ACLKUBR00=0x03;//32k/9600-UBR10=0x00;//UMCTL0=0x4A;//ModulationUCTL0&=~SWRST;//InitializeUSARTstatemachine}/*******************************************函数名称:Send1Char功能:向PC机发送一个字符参数:sendchar--要发送的字符返回值:无********************************************/voidSend1Char(ucharsendchar){while(!(IFG1&UTXIFG0));//等待发送寄存器为空TXBUF0=sendchar;}/*******************************************函数名称:PutSting功能:向PC机发送字符串并换行指令参数:ptr--指向发送字符串的指针返回值:无********************************************/voidPutString(uchar*ptr){while(*ptr!='\0'){Send1Char(*ptr++);//发送数据}while(!(IFG1&UTXIFG0));TXBUF0='\n';//发送换行指令}/*******************************************函数名称:PutSting0功能:向PC机发送字符串,无换行参数:ptr--指向发送字符串的指针返回值:无********************************************/voidPutString0(uchar*ptr){while(*ptr!='\0'){Send1Char(*ptr++);//发送数据}}2、程序2:转换结果显示在1602显示模块上“”程序#include<>#include""typedefunsignedcharuchar;typedefunsignedintuint;/**************宏定义***************/#defineDataDirP2DIR#defineDataPortP2OUT#defineBusy0x80#defineCtrlDirP6DIR#defineCLR_RSP6OUT&=~BIT3;//RS=#defineSET_RSP6OUT|=BIT3;#defineCLR_RWP6OUT&=~BIT4;//RW=#defineSET_RWP6OUT|=BIT4;#defineCLR_ENP6OUT&=~BIT5;//EN=#defineSET_ENP6OUT|=BIT5;/*******************************************函数名称:DispNchar功能:让液晶从某个位置起连续显示N个字符参数:x--位置的列坐标y--位置的行坐标n--字符个数ptr--指向字符存放位置的指针返回值:无********************************************/voidDispNChar(ucharx,uchary,ucharn,uchar*ptr){uchari;for(i=0;i{Disp1Char(x++,y,ptr[i]);if(x==0x0f){x=0;y^=1;}}}/*******************************************函数名称:LocateXY功能:向液晶输入显示字符位置的坐标信息参数:x--位置的列坐标y--位置的行坐标返回值:无********************************************/voidLocateXY(ucharx,uchary){uchartemp;temp=x&0x0f;y&=0x01;if(y)temp|=0x40;//如果在第2行temp|=0x80;LcdWriteCommand(temp,1);}/*******************************************函数名称:Disp1Char功能:在某个位置显示一个字符参数:x--位置的列坐标y--位置的行坐标data--显示的字符数据返回值:无********************************************/voidDisp1Char(ucharx,uchary,uchardata){LocateXY(x,y);LcdWriteData(data);}/*******************************************函数名称:LcdReset功能:对1602液晶模块进行复位操作参数:无返回值:无********************************************/voidLcdReset(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:不判返回值:无********************************************/voidLcdWriteCommand(ucharcmd,ucharchk){if(chk)WaitForEnable();//检测忙信号CLR_RS;CLR_RW;_NOP();DataPort=cmd;//将命令字写入数据端口_NOP();SET_EN;//产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:LcdWriteData功能:向液晶显示的当前地址写入显示数据参数:data--显示字符数据返回值:无********************************************/voidLcdWriteData(uchardata){WaitForEnable();//等待液晶不忙SET_RS;CLR_RW;_NOP();DataPort=data;//将显示数据写入数据端口_NOP();SET_EN;//产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:WaitForEnable功能:等待1602液晶完成内部操作参数:无返回值:无********************************************/voidWaitForEnable(void){P2DIR&=0x00;//将P4口切换为输入状态CLR_RS;SET_RW;_NOP();SET_EN;_NOP();_NOP();while((P2IN&Busy)!=0);//检测忙标志CLR_EN;P2DIR|=0xFF;//将P4口切换为输出状态}/*******************************************函数名称:Delay5ms功能:延时约5ms参数:无返回值:无********************************************/voidDelay5ms(void){uinti=40000;while(i!=0){i--;}}/*******************************************函数名称:Delay400ms功能:延时约400ms参数:无返回值:无********************************************/voidDelay400ms(void){uchari=50;uintj;while(i--){j=7269;while(j--);}}“”程序#include<>#include""typedefunsignedcharuchar;typedefunsignedintuint;/**************宏定义***************/#defineDataDirP2DIR#defineDataPortP2OUT#defineBusy0x80#defineCtrlDirP6DIR#defineCLR_RSP6OUT&=~BIT3;//RS=#defineSET_RSP6OUT|=BIT3;#defineCLR_RWP6OUT&=~BIT4;//RW=#defineSET_RWP6OUT|=BIT4;#defineCLR_ENP6OUT&=~BIT5;//EN=#defineSET_ENP6OUT|=BIT5;/*******************************************函数名称:DispNchar功能:让液晶从某个位置起连续显示N个字符参数:x--位置的列坐标y--位置的行坐标n--字符个数ptr--指向字符存放位置的指针返回值:无********************************************/voidDispNChar(ucharx,uchary,ucharn,uchar*ptr){uchari;for(i=0;i{Disp1Char(x++,y,ptr[i]);if(x==0x0f){x=0;y^=1;}}}/*******************************************函数名称:LocateXY功能:向液晶输入显示字符位置的坐标信息参数:x--位置的列坐标y--位置的行坐标返回值:无********************************************/voidLocateXY(ucharx,uchary){uchartemp;temp=x&0x0f;y&=0x01;if(y)temp|=0x40;//如果在第2行temp|=0x80;LcdWriteCommand(temp,1);}/*******************************************函数名称:Disp1Char功能:在某个位置显示一个字符参数:x--位置的列坐标y--位置的行坐标data--显示的字符数据返回值:无***********************
average+=results[i];
average>>=5;//除以32
index=0;
tcnt++;
if(tcnt==250)//主要是降低串口发送速度
LPM1_EXIT;
tcnt=0;
“”A/D转换相关程序:
typedefunsignedintuint;
/********************************************
Init_ADC
初始化ADC
voidInit_ADC(void)
P6SEL|=0x01;//使能ADC通道
ADC12CTL0=ADC12ON+SHT0_15+MSC;//打开ADC,设置采样时间
ADC12CTL1=SHP+CONSEQ_2;//使用采样定时器
ADC12IE=0x01;//使能ADC中断
ADC12CTL0|=ENC;//使能转换
ADC12CTL0|=ADC12SC;//开始转换
Hex2Dec
将16进制ADC转换数据变换成十进制
表示形式
Hex_Val--16进制数据
ptr--指向存放转换结果的指针
voidHex2Dec(uintHex_val,uchar*ptr)
ptr[0]=Hex_val/1000;
ptr[1]=(Hex_val-ptr[0]*1000)/100;
ptr[2]=(Hex_val-ptr[0]*1000-ptr[1]*100)/10;
ptr[3]=(Hex_val-ptr[0]*1000-ptr[1]*100-ptr[2]*10);
Trans_val
将16进制ADC转换数据变换成三位10进制
真实的模拟电压数据,并在液晶上显示
voidTrans_val(uintHex_Val,uchar*ptr)
unsignedlongcaltmp;
uintCurr_Volt;
uchart1;
caltmp=Hex_Val;
caltmp=(caltmp<<5)+Hex_Val;//caltmp=Hex_Val*33
caltmp=(caltmp<<3)+(caltmp<<1);//caltmp=caltmp*10
Curr_Volt=caltmp>>12;//Curr_Volt=caltmp/2^n
ptr[0]=Curr_Volt/100;//Hex->Dec变换
t1=Curr_Volt-(ptr[0]*100);
ptr[1]=t1/10;
ptr[2]=t1-(ptr[1]*10);
“”串口程序:
typedefunsignedcharuchar;
InitUART
初始化UART端口
voidInitUART(void)
P3SEL|=0x30;//,5=USART0TXD/RXD
ME1|=URXE0+UTXE0;//EnableUSART0T/RXD
UCTL0|=CHAR;//8-bitcharacter
UTCTL0|=SSEL0;//UCLK=ACLK
UBR00=0x03;//32k/9600-
UBR10=0x00;//
UMCTL0=0x4A;//Modulation
UCTL0&=~SWRST;//InitializeUSARTstatemachine
Send1Char
向PC机发送一个字符
sendchar--要发送的字符
voidSend1Char(ucharsendchar)
while(!
(IFG1&UTXIFG0));//等待发送寄存器为空
TXBUF0=sendchar;
PutSting
向PC机发送字符串并换行指令
ptr--指向发送字符串的指针
voidPutString(uchar*ptr)
while(*ptr!
='\0')
Send1Char(*ptr++);//发送数据
(IFG1&UTXIFG0));
TXBUF0='\n';//发送换行指令
PutSting0
向PC机发送字符串,无换行
voidPutString0(uchar*ptr)
2、程序2:
转换结果显示在1602显示模块上
“”程序
/**************宏定义***************/
#defineDataDirP2DIR
#defineDataPortP2OUT
#defineBusy0x80
#defineCtrlDirP6DIR
#defineCLR_RSP6OUT&=~BIT3;//RS=
#defineSET_RSP6OUT|=BIT3;
#defineCLR_RWP6OUT&=~BIT4;//RW=
#defineSET_RWP6OUT|=BIT4;
#defineCLR_ENP6OUT&=~BIT5;//EN=
#defineSET_ENP6OUT|=BIT5;
DispNchar
让液晶从某个位置起连续显示N个字符
x--位置的列坐标
y--位置的行坐标
n--字符个数
ptr--指向字符存放位置的指针
voidDispNChar(ucharx,uchary,ucharn,uchar*ptr)
for(i=0;i{Disp1Char(x++,y,ptr[i]);if(x==0x0f){x=0;y^=1;}}}/*******************************************函数名称:LocateXY功能:向液晶输入显示字符位置的坐标信息参数:x--位置的列坐标y--位置的行坐标返回值:无********************************************/voidLocateXY(ucharx,uchary){uchartemp;temp=x&0x0f;y&=0x01;if(y)temp|=0x40;//如果在第2行temp|=0x80;LcdWriteCommand(temp,1);}/*******************************************函数名称:Disp1Char功能:在某个位置显示一个字符参数:x--位置的列坐标y--位置的行坐标data--显示的字符数据返回值:无********************************************/voidDisp1Char(ucharx,uchary,uchardata){LocateXY(x,y);LcdWriteData(data);}/*******************************************函数名称:LcdReset功能:对1602液晶模块进行复位操作参数:无返回值:无********************************************/voidLcdReset(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:不判返回值:无********************************************/voidLcdWriteCommand(ucharcmd,ucharchk){if(chk)WaitForEnable();//检测忙信号CLR_RS;CLR_RW;_NOP();DataPort=cmd;//将命令字写入数据端口_NOP();SET_EN;//产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:LcdWriteData功能:向液晶显示的当前地址写入显示数据参数:data--显示字符数据返回值:无********************************************/voidLcdWriteData(uchardata){WaitForEnable();//等待液晶不忙SET_RS;CLR_RW;_NOP();DataPort=data;//将显示数据写入数据端口_NOP();SET_EN;//产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:WaitForEnable功能:等待1602液晶完成内部操作参数:无返回值:无********************************************/voidWaitForEnable(void){P2DIR&=0x00;//将P4口切换为输入状态CLR_RS;SET_RW;_NOP();SET_EN;_NOP();_NOP();while((P2IN&Busy)!=0);//检测忙标志CLR_EN;P2DIR|=0xFF;//将P4口切换为输出状态}/*******************************************函数名称:Delay5ms功能:延时约5ms参数:无返回值:无********************************************/voidDelay5ms(void){uinti=40000;while(i!=0){i--;}}/*******************************************函数名称:Delay400ms功能:延时约400ms参数:无返回值:无********************************************/voidDelay400ms(void){uchari=50;uintj;while(i--){j=7269;while(j--);}}“”程序#include<>#include""typedefunsignedcharuchar;typedefunsignedintuint;/**************宏定义***************/#defineDataDirP2DIR#defineDataPortP2OUT#defineBusy0x80#defineCtrlDirP6DIR#defineCLR_RSP6OUT&=~BIT3;//RS=#defineSET_RSP6OUT|=BIT3;#defineCLR_RWP6OUT&=~BIT4;//RW=#defineSET_RWP6OUT|=BIT4;#defineCLR_ENP6OUT&=~BIT5;//EN=#defineSET_ENP6OUT|=BIT5;/*******************************************函数名称:DispNchar功能:让液晶从某个位置起连续显示N个字符参数:x--位置的列坐标y--位置的行坐标n--字符个数ptr--指向字符存放位置的指针返回值:无********************************************/voidDispNChar(ucharx,uchary,ucharn,uchar*ptr){uchari;for(i=0;i{Disp1Char(x++,y,ptr[i]);if(x==0x0f){x=0;y^=1;}}}/*******************************************函数名称:LocateXY功能:向液晶输入显示字符位置的坐标信息参数:x--位置的列坐标y--位置的行坐标返回值:无********************************************/voidLocateXY(ucharx,uchary){uchartemp;temp=x&0x0f;y&=0x01;if(y)temp|=0x40;//如果在第2行temp|=0x80;LcdWriteCommand(temp,1);}/*******************************************函数名称:Disp1Char功能:在某个位置显示一个字符参数:x--位置的列坐标y--位置的行坐标data--显示的字符数据返回值:无***********************
Disp1Char(x++,y,ptr[i]);
if(x==0x0f)
x=0;
y^=1;
LocateXY
向液晶输入显示字符位置的坐标信息
voidLocateXY(ucharx,uchary)
uchartemp;
temp=x&0x0f;
y&=0x01;
if(y)temp|=0x40;//如果在第2行
temp|=0x80;
LcdWriteCommand(temp,1);
Disp1Char
在某个位置显示一个字符
data--显示的字符数据
voidDisp1Char(ucharx,uchary,uchardata)
LocateXY(x,y);
LcdWriteData(data);
LcdReset
对1602液晶模块进行复位操作
voidLcdReset(void)
CtrlDir|=0x07;//控制线端口设为输出状态
DataDir=0xFF;//数据端口设为输出状态
LcdWriteCommand(0x38,0);//规定的复位操作
Delay5ms();
LcdWriteCommand(0x38,0);
LcdWriteCommand(0x38,1);//显示模式设置
LcdWriteCommand(0x08,1);//显示关闭
LcdWriteCommand(0x01,1);//显示清屏
LcdWriteCommand(0x06,1);//写字符时整体不移动
LcdWriteCommand(0x0c,1);//显示开,不开游标,不闪烁
LcdWriteCommand
向液晶模块写入命令
cmd--命令,
chk--是否判忙的标志,1:
判忙,0:
不判
voidLcdWriteCommand(ucharcmd,ucharchk)
if(chk)WaitForEnable();//检测忙信号
CLR_RS;
CLR_RW;
_NOP();
DataPort=cmd;//将命令字写入数据端口
SET_EN;//产生使能脉冲信号
CLR_EN;
LcdWriteData
向液晶显示的当前地址写入显示数据
data--显示字符数据
voidLcdWriteData(uchardata)
WaitForEnable();//等待液晶不忙
SET_RS;
DataPort=data;//将显示数据写入数据端口
WaitForEnable
等待1602液晶完成内部操作
voidWaitForEnable(void)
P2DIR&=0x00;//将P4口切换为输入状态
SET_RW;
SET_EN;
while((P2IN&Busy)!
=0);//检测忙标志
P2DIR|=0xFF;//将P4口切换为输出状态
Delay5ms
延时约5ms
voidDelay5ms(void)
uinti=40000;
while(i!
=0)
i--;
Delay400ms
延时约400ms
voidDelay400ms(void)
uchari=50;
uintj;
while(i--)
j=7269;
while(j--);
for(i=0;i{Disp1Char(x++,y,ptr[i]);if(x==0x0f){x=0;y^=1;}}}/*******************************************函数名称:LocateXY功能:向液晶输入显示字符位置的坐标信息参数:x--位置的列坐标y--位置的行坐标返回值:无********************************************/voidLocateXY(ucharx,uchary){uchartemp;temp=x&0x0f;y&=0x01;if(y)temp|=0x40;//如果在第2行temp|=0x80;LcdWriteCommand(temp,1);}/*******************************************函数名称:Disp1Char功能:在某个位置显示一个字符参数:x--位置的列坐标y--位置的行坐标data--显示的字符数据返回值:无***********************
***********************
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1