MSP430F149_AD源程序通过
- 格式:pdf
- 大小:1.31 MB
- 文档页数:14
#include <MSP430x14x.h>#define ADCMEM ((int *) 0x0140) //ADC12MEMx定义void InitSYS(void);void InitUST0(void); //初始化系统及ADC 寄存器void InitUST1(void);void InitADC(void);void SetZero(void);int GetBusData(void);void SetBusData(int busvdata);void SendRomCode(void);void Averege(void);void Filter(void);void Analysis(void);void Delay(int delaydata);interrupt[ADC_VECTOR] void ADC12(void);interrupt[USART1RX_VECTOR] void USART1(void);unsigned char savedata[1500];unsigned char saveromdata[7];unsigned char enddata[3];unsigned int adtime;unsigned int recromok;unsigned int ave;unsigned int datai;unsigned int vdata;unsigned int time;void main(void) //使用中断方式{unsigned int i,busvdata,low,hi,ldata;InitSYS();InitUST0();InitUST1();InitADC();P1DIR |= 0x20;P1DIR |= 0x1c; //p1.4 p1.3 p1.2P1OUT |= BIT4;SetZero(); //设置x9015到零for(i=0;i<30000;i++){ _NOP(); } //wait to samplebusvdata=GetBusData(); //while(1){SetBusData(busvdata);busvdata=GetBusData();if(busvdata<150){ break; }}IE2 |=URXIE1;while(1){// for(time=0;time<256;time++)// {//IE2 |=URXIE1;//low=time;recromok=0;while(recromok!=1);SendRomCode();for(i=0;i<6500;i++){ _NOP(); } //wait to sampleADC12CTL0 |= 0x02;ADC12CTL0 |= 0x01; //start ADadtime=0;while(1){if(adtime>1500){ADC12CTL0 &= ~0x02;Filter();Averege();Analysis();for(i=0;i<3;i++){U1TXBUF = enddata[i];while((U1TCTL&0x01)==0);}/* if(enddata[0]==0x11){for(i=0;i<1500;i++){//ldata = savedata[i];//low = ldata | 0x00;U1TXBUF = savedata[i];//low; while((U1TCTL&0x01)==0);U1TXBUF = 0x00;;//low;while((U1TCTL&0x01)==0);//ldata = ldata>>8;//hi = ldata | 0x00;//U1TXBUF = hi;// while((U1TCTL&0x01)==0); }} */break;}//}}}}void SetZero(void){int i;P1OUT &= ~BIT4; //csP1OUT &= ~BIT3; //u/dfor(i=0;i<64;i++){P1OUT ^= BIT2; //inc}P1OUT |= BIT4; //cs}int GetBusData(void){unsigned char vdata1,vdata2;//,vdata;adtime=0;ADC12CTL0 |= 0x02;ADC12CTL0 |= 0x01; //start ADwhile(1){if(adtime>20){ADC12CTL0 &= ~0x02;break;}}//计算vdata1=(savedata[0]+savedata[1]+savedata[2]+savedata[3]+savedata[4]+savedata[5] +savedata[6]+savedata[7]+savedata[8]+savedata[9])/10;vdata2=(savedata[10]+savedata[11]+savedata[12]+savedata[13]+savedata[14]+saveda ta[15]+savedata[16]+savedata[17]+savedata[18]+savedata[19])/10;vdata=(vdata1+vdata2)/2;return(vdata);}void SetBusData(int busvdata){int i;unsigned int temp;unsigned int movetime;if(busvdata>150){temp=busvdata-150;movetime=(temp*20*3)/256/3;P1OUT &= ~BIT4; //csP1OUT |= BIT3; //u/dfor(i=0;i<movetime+1;i++){P1OUT ^= BIT2; //inc}P1OUT |= BIT4; //cs}}void SendRomCode(void){U0TXBUF = saveromdata[6];while((U0TCTL&0x01)==0);U0TXBUF = saveromdata[5];while((U0TCTL&0x01)==0);U0TXBUF = saveromdata[4];while((U0TCTL&0x01)==0);U0TXBUF = saveromdata[3];while((U0TCTL&0x01)==0);U0TXBUF = saveromdata[2];while((U0TCTL&0x01)==0);U0TXBUF = saveromdata[1];while((U0TCTL&0x01)==0);}void Filter(void){unsigned int i,j,m,a[3],ldata;for(i=0;i<1500;i++){a[0]=savedata[i];a[1]=savedata[i+1];a[2]=savedata[i+2];for(j=0;j<2;j++){for(m=1;m<3;m++){if(a[m]>a[j]){ldata=a[j];a[j]=a[m];a[m]=ldata;}}}savedata[i]=a[1];}}void Averege(void)//取5-20共15个得到总线电压值{unsigned int i,he;he=0;for(i=20;i<30;i++){he=he+savedata[i];}ave=he/10;}void Analysis(void){int delaytostart,start,error,n,aveadd,time32;enddata[0]=0;enddata[1]=0;enddata[2]=0;aveadd=ave+30; //问题:如果拉电流太小就达不到 200 datai=0;while(1){//============================================================================= =datai=datai+50;delaytostart=0;start=0;error=0;while(1){time32=0;if(savedata[datai]>aveadd){ time32++; }if(savedata[datai+1]>aveadd){ time32++; }if(savedata[datai+2]>aveadd){ time32++; }if(savedata[datai+3]>aveadd){ time32++; }if(savedata[datai+4]>aveadd){ time32++; }if(time32>=4){ start=1; break; }else if(delaytostart<700){ delaytostart++; datai++; }else{ error=1; break; }}if(error==1){ enddata[0]=0x11;enddata[1]=0x11;enddata[2]=0x22;break; }if(start==1){datai=datai+7;for(n=1;n<9;n++){switch(n){case 1: datai=datai+16;break;case 2: datai=datai+16;break;case 3: datai=datai+17;break;case 4: datai=datai+16;break;case 5: datai=datai+16;break;case 6: datai=datai+17;break;case 7: datai=datai+16;break;case 8: datai=datai+16;break;}time32=0;if(savedata[datai]>aveadd){ time32++; }if(savedata[datai+1]>aveadd){ time32++; }if(savedata[datai+2]>aveadd){ time32++; }if(time32>=2){switch(n){case 1: enddata[0] &= ~0x01;break;case 2: enddata[0] &= ~0x02;break;case 3: enddata[0] &= ~0x04;break;case 4: enddata[0] &= ~0x08;break;case 5: enddata[0] &= ~0x10;break;case 6: enddata[0] &= ~0x20;break;case 7: enddata[0] &= ~0x40;break;case 8: enddata[0] &= ~0x80;break;}}else{switch(n){case 1: enddata[0] |= 0x01;break;case 2: enddata[0] |= 0x02;break;case 3: enddata[0] |= 0x04;break;case 4: enddata[0] |= 0x08;break;case 5: enddata[0] |= 0x10;break;case 6: enddata[0] |= 0x20;break;case 7: enddata[0] |= 0x40;break;case 8: enddata[0] |= 0x80;break;}}//datai=datai+6;}}//============================================================================= datai=datai+50;delaytostart=0;start=0;error=0;while(1){time32=0;if(savedata[datai]>aveadd){ time32++; }if(savedata[datai+1]>aveadd){ time32++; }if(savedata[datai+2]>aveadd){ time32++; }if(savedata[datai+3]>aveadd){ time32++; }if(savedata[datai+4]>aveadd){ time32++; }if(time32>=4){ start=1;break; }else if(delaytostart<400){ delaytostart++; datai++; }else{ error=1;break; }}if(error==1){enddata[1]=0x11;enddata[2]=0x22;break;}if(start==1){datai=datai+7;for(n=1;n<9;n++){switch(n){case 1: datai=datai+16;break;case 2: datai=datai+16;break;case 3: datai=datai+17;break;case 4: datai=datai+16;break;case 5: datai=datai+16;break;case 6: datai=datai+17;break;case 7: datai=datai+16;break;case 8: datai=datai+16;break; }time32=0;if(savedata[datai]>aveadd){ time32++; }if(savedata[datai+1]>aveadd){ time32++; }if(savedata[datai+2]>aveadd){ time32++; }if(time32>=2){switch(n){case 1: enddata[1] &= ~0x01;break;case 2: enddata[1] &= ~0x02;break;case 3: enddata[1] &= ~0x04;break;case 4: enddata[1] &= ~0x08;break;case 5: enddata[1] &= ~0x10;break;case 6: enddata[1] &= ~0x20;break;case 7: enddata[1] &= ~0x40;break;case 8: enddata[1] &= ~0x80;break;}}else{switch(n){case 1: enddata[1] |= 0x01;break;case 2: enddata[1] |= 0x02;break;case 3: enddata[1] |= 0x04;break;case 4: enddata[1] |= 0x08;break;case 5: enddata[1] |= 0x10;break;case 6: enddata[1] |= 0x20;break;case 7: enddata[1] |= 0x40;break;case 8: enddata[1] |= 0x80;break;}}//datai=datai+6;}}//========================================================================== datai=datai+50;delaytostart=0;start=0;error=0;while(1){time32=0;if(savedata[datai]>aveadd){ time32++; }if(savedata[datai+1]>aveadd){ time32++; }if(savedata[datai+2]>aveadd){ time32++; }if(savedata[datai+3]>aveadd){ time32++; }if(savedata[datai+4]>aveadd){ time32++; }if(time32>=4){ start=1;break; }else if(delaytostart<400){ delaytostart++; datai++; }else{ error=1;break; }}if(error==1){ enddata[2]=0x22;break; }if(start==1){datai=datai+7;for(n=1;n<9;n++){switch(n){case 1: datai=datai+16;break;case 2: datai=datai+16;break;case 3: datai=datai+17;break;case 4: datai=datai+16;break;case 5: datai=datai+16;break;case 6: datai=datai+17;break;case 7: datai=datai+16;break;case 8: datai=datai+16;break; }time32=0;if(savedata[datai]>aveadd){ time32++; }if(savedata[datai+1]>aveadd){ time32++; }if(savedata[datai+2]>aveadd){ time32++; }if(time32>=2){switch(n){case 1: enddata[2] &= ~0x01;break;case 2: enddata[2] &= ~0x02;break;case 3: enddata[2] &= ~0x04;break;case 4: enddata[2] &= ~0x08;break;case 5: enddata[2] &= ~0x10;break;case 6: enddata[2] &= ~0x20;break;case 7: enddata[2] &= ~0x40;break;case 8: enddata[2] &= ~0x80;break;}}else{switch(n){case 1: enddata[2] |= 0x01;break;case 2: enddata[2] |= 0x02;break;case 3: enddata[2] |= 0x04;break;case 4: enddata[2] |= 0x08;break;case 5: enddata[2] |= 0x10;break;case 6: enddata[2] |= 0x20;break;case 7: enddata[2] |= 0x40;break;case 8: enddata[2] |= 0x80;break;}}//datai=datai+6;}}//============================================================================= ===========break;}//while(1)}void Delay(int delaydata){unsigned long i;for (i = delaydata; i > 0; i--);}void InitUST0(void){U0CTL |= SWRST; // USART模块被允许U0CTL &= ~SYNC;U0CTL |= CHAR; // 8位字符U0CTL |= SPB;U0TCTL |= SSEL0+SSEL1; // ACLKU0BR1 =0x0d; //0x0A; // 6MHz/2400bautU0BR0 =0x05; //0x3D;U0MCTL = 0x24; //06ME1 |=UTXE0+URXE0; // 使能 USAR01 TXD/RXDP3SEL |= 0x30; // P3.4,5 = USART0 TXD/RXDP3DIR |= 0x10; // P3.4 为输出U0CTL &= ~SWRST;//IE1 |=URXIE0;}void InitUST1(void){U1CTL |= SWRST; // USART模块被允许U1CTL &= ~SYNC;U1CTL |= CHAR; // 8位字符U1CTL |= SPB;U1TCTL |= SSEL0+SSEL1; // SMCLKU1BR1 =0x0d; //0x0A;// 6MHz/2400baut 8MHZ/2400baut//0dU1BR0 =0x05; //0x3D; //05U1MCTL =0x24; //12 //24ME2 |=UTXE1+URXE1; // 使能 USAR01 TXD/RXDP3SEL |= 0xc0; // P3.6,7 = USART1 TXD/RXDP3DIR |= 0x40; // P3.6 为输出U1CTL &= ~SWRST;}interrupt[USART1RX_VECTOR] void USART1(void) //ADC中断处理程序{int romhe;saveromdata[6]=saveromdata[5];saveromdata[5]=saveromdata[4];saveromdata[4]=saveromdata[3];saveromdata[3]=saveromdata[2];saveromdata[2]=saveromdata[1];saveromdata[1]=saveromdata[0];saveromdata[0]=U1RXBUF;romhe=saveromdata[6]+saveromdata[5]+saveromdata[4]+saveromdata[3]+saveromdata[2]+saveromdata[1];romhe = romhe&0x00ff;if(saveromdata[0]==romhe){recromok=1;//IE2 &=~URXIE1;}}void InitADC(void){P6SEL = 0xFF; // 所有P6口线均为ADC模块使用ADC12CTL0 &=~ 0x02; // 在进行设置时首先复位ADC的转换使能ADC12CTL0 = SHT0_7+MSC+ADC12ON; // 内部振荡器,置位MSC位,因此转换能自动进行//6=24us 17.375pot 8=46us 9.065pot//ADC12CTL1 = 0x0204; //0000 0010 0000 0100// ADC12SC 位触发采样和保持// 采样脉冲由采样定时器产生// 时钟源:内部振荡器// 时钟分频: 1// 转换模式: 单通道、重复转换// 选则参考电压和输入管脚ADC12CTL1 = 0x021c; //0000 00 1 0 000 11 10 0 SMCLK ADC12MCTL0 |= SREF_0; //Vr+=AVcc,;Vr-=AVssADC12MCTL0 |= INCH_3; //select anonalog inputADC12IE = 0x01; // 使能通道10 转换完成后中断ADC12CTL0 |= 0x02; // 使能ADC转换}interrupt[ADC_VECTOR] void ADC12(void) //ADC中断处理程序{ADCMEM[0]=ADCMEM[0]>>3;savedata[adtime]=ADCMEM[0];adtime++;//P1OUT ^=BIT5;}void InitSYS(void)int i;WDTCTL = WDTPW + WDTHOLD;//WDTCTL = WDT_ADLY_250; // WDT 250ms, ACLK, interval timer //IE1 |= WDTIE;BCSCTL1 &= ~XT2OFF; // XT2晶振 0--opendo{IFG1 &= ~OFIFG; // Clear OSCFault flagfor (i = 0xFF; i > 0; i--); // Time for flag to set}while ((IFG1 & OFIFG)); // OSCFault flag still set?BCSCTL2 |= SELM_2; // MCLK=XT2BCSCTL2 |= SELS; // SMCLK=XT2//FCTL2 = FWKEY + FSSEL0 + FN0; // MCLK/2 for Flash Timing Generator_EINT();}/* //n=5datai=datai+14;for(n=1;n<9;n++){switch(n){case 1: datai=datai+30;break;case 2: datai=datai+30;break;case 3: datai=datai+31;break;case 4: datai=datai+30;break;case 5: datai=datai+30;break;case 6: datai=datai+31;break;case 7: datai=datai+30;break;case 8: datai=datai+30;break;}*/。
MPS430F149单片机之_模拟电压AD转换数码管显示数值/************************************************************** ***将P6口输入的模拟电压AD转换后,从P4,P5口连接的数码管输出*************************************************************** **/#include //声明库/************************************************************** ******数据类型定义*************************************************************** ******/#define uchar unsigned char#define uint unsigned int/************************************************************** ******数码管段码定义0123456789*************************************************************** ******/ucharTable[10]={0xc0,0Xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //所需的段的位码uchar wei[4]={0XEF,0XDF,0XBF,0X7F};//控制位uint z,x,c,v, date=0; //定义数据类型/************************************************************** ********延时函数程序,参数i 延时时间*************************************************************** *******/void DelayMS(uint i){uint j;for(;i!=0;i--){for(j=200;j!=0;j--);}}/************************************************************** ********按键函数*************************************************************** *******/void KEY()//按键函数名{if(!(P1IN&BIT0))//判断按键按下{DelayMS(100);//消抖延时while(!(P1IN&BIT0));//判断按键松开date++;//按键数值加1}}/************************************************************** ********数码管动态扫描*************************************************************** ******/void Pre_Display(){/***********************数据转换*****************************/ z=date/1000; //求千位x=date%1000/100;//求百位c=date%100/10; //求十位v=date%10; //求个位P5OUT=wei[0]; //位控制P4OUT=Table[z]; //显示千位DelayMS(5); //延时P5OUT=wei[1]; //位控制P4OUT=Table[x]; //显示百位DelayMS(5); //延时P5OUT=wei[2]; //位控制P4OUT=Table[c]; //显示十位DelayMS(5); //延时P5OUT=wei[3]; //位控制P4OUT=Table[v]; //显示个位DelayMS(5); //延时}/************************************************************** ******I/O口初始化*************************************************************** ******/void Init_IO(void)//初始化I/O{P1DIR&=~BIT0;//设置P4口为输出P4DIR=0XFF;//设置P5口为输出P5DIR=0XFF;}/************************************************************** ******主函数*************************************************************** ******/void main(void)//主函数{Init_IO();//初始化I/OWDTCTL=WDTPW+WDTHOLD;//关闭看门狗while(1)//无限循环{KEY();//数码管显示数值Pre_Display();//数码管扫描显示函数}}/************************************************************** ******结束*************************************************************** ******/。
MPS430头文件摘要及注释一.ADC121..定义采样保持时间(ADC12CTL0)#define SHT0_0 (0*0x100u) //定义ADC12MEM0——ADC12MEM7采样#define SHT0_1 (1*0x100u) //保持时间为ADCCLK的多少个周期 eg:#define SHT0_2 (2*0x100u) //SHT0_0 代表采样保持时间为4个ADCCLK#define SHT0_3 (3*0x100u) //周期同理 SHT0_1为8个周期#define SHT0_4 (4*0x100u)#define SHT0_5 (5*0x100u)#define SHT0_6 (6*0x100u)#define SHT0_7 (7*0x100u)#define SHT0_8 (8*0x100u)#define SHT0_9 (9*0x100u)#define SHT0_10 (10*0x100u)#define SHT0_11 (11*0x100u)#define SHT0_12 (12*0x100u)#define SHT0_13 (13*0x100u)#define SHT0_14 (14*0x100u)#define SHT0_15 (15*0x100u)#define SHT1_0 (0*0x1000u) //定义ADC12MEM8——ADC12MEM15采样#define SHT1_1 (1*0x1000u) //保持时间为ADCCLK的多少个周期#define SHT1_2 (2*0x1000u) //使用方法同SHT0_x#define SHT1_3 (3*0x1000u)#define SHT1_4 (4*0x1000u)#define SHT1_5 (5*0x1000u)#define SHT1_6 (6*0x1000u)#define SHT1_7 (7*0x1000u)#define SHT1_8 (8*0x1000u)#define SHT1_9 (9*0x1000u)#define SHT1_10 (10*0x1000u)#define SHT1_11 (11*0x1000u)#define SHT1_12 (12*0x1000u)#define SHT1_13 (13*0x1000u)#define SHT1_14 (14*0x1000u)#define SHT1_15 (15*0x1000u)2.转换模式选择(ADC12CTL1)#define CONSEQ_0 (0*2u) //单通道单次转换#define CONSEQ_1 (1*2u) //多通道单次转换#define CONSEQ_2 (2*2u) //单通道多次转换#define CONSEQ_3 (3*2u) //多通道多次转换3..ADC12内核时钟源选择(ADC12CTL1)#define ADC12SSEL_0 (0*8u) //ADC内部时钟源 ADC12OSC #define ADC12SSEL_1 (1*8u) //ACLK#define ADC12SSEL_2 (2*8u) //MCLK#define ADC12SSEL_3 (3*8u) //SMCLK4.ADC时钟分频选择(ADC12CTL1)//分频数=三位二进制数加#define ADC12DIV_0 (0*0x20u) //1分频即不分频#define ADC12DIV_1 (1*0x20u) //2分频#define ADC12DIV_2 (2*0x20u)#define ADC12DIV_3 (3*0x20u)#define ADC12DIV_4 (4*0x20u)#define ADC12DIV_5 (5*0x20u)#define ADC12DIV_6 (6*0x20u)#define ADC12DIV_7 (7*0x20u) //8分频5..采样触发输入源选择(ADC12CTL1)#define SHS_0 (0*0x400u) //ADC12SC 位#define SHS_1 (1*0x400u) //TimerA_OUT1#define SHS_2 (2*0x400u) //TImerB_OUT0#define SHS_3 (3*0x400u) //TimerB_OUT16.转换结果数据存储寄存器选择(ADC12CTL1)#define CSTARTADD_0 (0*0x1000u) //结果存在ADC12MEM0 #define CSTARTADD_1 (1*0x1000u)#define CSTARTADD_2 (2*0x1000u)#define CSTARTADD_3 (3*0x1000u)#define CSTARTADD_4 (4*0x1000u)#define CSTARTADD_5 (5*0x1000u)#define CSTARTADD_6 (6*0x1000u)#define CSTARTADD_7 (7*0x1000u)#define CSTARTADD_8 (8*0x1000u)#define CSTARTADD_9 (9*0x1000u)#define CSTARTADD_10 (10*0x1000u)#define CSTARTADD_11 (11*0x1000u)#define CSTARTADD_12 (12*0x1000u)#define CSTARTADD_13 (13*0x1000u)#define CSTARTADD_14 (14*0x1000u)#define CSTARTADD_15 (15*0x1000u)注:在单通道单次转换情况下,转换结果存储寄存器的选择与ADC转换通道选择并没有必然联系,即从不同转换通道进入的数据经转换后,其结果在不引起错误的前提下,可存入任一个转换结果存储寄存器。
AD转换实验、转换原理MSP430F149勺A/D转换器原理请参考相关书籍。
实验板上与AD相关的硬件电路:RV§10K----------J6P61SIP2A1)输入电路{设计主程序和中断服务程序。
二、转换程序1、程序 1:转换结果发送到 PC主程序中进行 A/D 初始化,中断服务程序读 A/D 转换结果,主程序中通过串口发送结果。
“”主程序与中断程序:/*********************************************************程序功能:将ADC 对端口电压的转换结果按转换数据和对应的模拟电压的形式通过串口发送到PC 机屏幕上显示通信格式: 9600测试说明:打开串口调试精灵,正确设置通信格式,观察接收数据**********************************************************/ #include <> #include "" #include "" #include ""#define Num_of_Results 32 uint results[Num_of_Results]; // uint average; uchar tcnt = 0;主函数 ***********************/void main( void )保存ADC 转换结果的数组/***********************uchar i;uchar buffer[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("The digital value is: ");PutString(buffer);关狗关闭电平转换关闭数码管显示Trans_val(average,buffer);buffer[3] = buffer[2];buffer[2] = buffer[1];buffer[1] = 0x2e - 0x30;for(i = 0; i < 4; i++)buffer[i] += 0x30;PutString0("The analog value is: ");PutString(buffer);}}/*******************************************函数名称:ADC12ISR功能:ADC中断服务函数,在这里用多次平均的计算口的模拟电压数值参数:无返回值:无********************************************/#pragma vector=ADC_VECTOR__interrupt void ADC12ISR (void){static uchar index = 0;results[index++] = ADC12MEM0; // Move results if(index == Num_of_Results)uchar i;{average = 0;for(i = 0; i < Num_of_Results; i++){average += results[i];}average >>= 5; // 除以32index = 0;tcnt++;if(tcnt == 250) // 主要是降低串口发送速度{LPM1_EXIT;tcnt = 0;}}}“” A/D 转换相关程序:#include <>typedef unsigned int uint;/********************************************函数名称:Init_ADC功能:初始化ADC参数:无返回值:无****************************************** void Init_ADC(void) {P6SEL |= 0x01; //ADC12CTL0 = ADC12ON+SHT0_15+MSC; // ADC12CTL1 = SHP+CONSEQ_2; // ADC12IE = 0x01; // ADC12CTL0 |= ENC; // ADC12CTL0 |= ADC12SC; // } /********************************************函数名称: Hex2Dec 功能:将16进制ADC 转换数据变换成十进制表示形式参数: Hex_Val--16 进制数据ptr--指向存放转换结果的指针返回值 :无 ********************************************/ void Hex2Dec(uint Hex_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 进制数据 返回值 :无使能ADC 通道打开ADC 设置采样时间 使用采样定时器 使能ADC 中断 使能转换 开始转换********************************************/void Trans_val(uint Hex_Val,uchar *ptr){unsigned long caltmp;uint Curr_Volt;uchar t1;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 / 25ptr[0] = Curr_Volt / 100; //Hex->Dec变换t1 = Curr_Volt - (ptr[0] * 100);ptr[1] = t1 / 10;ptr[2] = t1 - (ptr[1] * 10);}“”串口程序:#include <>typedef unsigned char uchar;/*******************************************函数名称:InitUART功能:初始化UART端口参 数:无 返回值 :无********************************************/ void InitUART(void)ME1 |= URXE0 + UTXE0;// Enable USART0 T/RXDUCTL0 |= CHAR;// 8-bit characterUBR00 = 0x03; UBR10 = 0x00;// Initialize USART state machine/*******************************************函数名称: Send1Char 功 能:向 PC 机发送一个字符参数: sendchar-- 要发送的字符 返回值 :无********************************************/ void Send1Char(uchar sendchar)while (!(IFG1 & UTXIFG0)); // TXBUF0 = sendchar;'*****************************************函数名称: PutSting 功 能:向 PC 机发送字符串并换行指令 参数: ptr-- 指向发送字符串的指针返回值 :无********************************************/ void PutString(uchar *ptr)P3SEL |= 0x30;// ,5 = USART0 TXD/RXDUTCTL0 |= SSEL0; // UCLK = ACLK UMCTL0 = 0x4A;// Modulation// 32k/9600 - //UCTL0 &= ~SWRST; 等待发送寄存器为空{while(*ptr != '\0'){Send1Char(*ptr++); // 发送数据}while (!(IFG1 & UTXIFG0));TXBUF0 = '\n'; // 发送换行指令}/*******************************************函数名称:PutSting0功能:向PC 机发送字符串,无换行参数:ptr-- 指向发送字符串的指针返回值:无********************************************/void PutString0(uchar *ptr){while(*ptr != '\0'){Send1Char(*ptr++); // 发送数据2、程序2:转换结果显示在1602 显示模块上“”程序#include <>#include ""typedef unsigned char uchar;typedef unsigned int uint;**//************** 宏定义*************#define DataDir P2DIR#define DataPort P2OUT#define Busy 0x80#define CtrlDir P6DIR#define CLR_RS P6OUT&=~BIT3;//RS =#define SET_RS P6OUT|=BIT3;#define CLR_RW P6OUT&=~BIT4; //RW = #define SET_RW P6OUT|=BIT4;#define CLR_EN P6OUT&=~BIT5; //EN = #define SET_EN P6OUT|=BIT5;/*******************************************函数名称: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 A= 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)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-- 是否判忙的标志,返回值 :无********************************************/void LcdWriteCommand(uchar cmd,uchar chk) {CtrlDir |= 0x07;// 控制线端口设为输出状态 数据端口设为输出状态 // 规定的复位操作// 显示模式设置 // 显示关闭 // 显示清屏 // 写字符时整体不移动 // 显示开,不开游标,不闪烁 1:判忙, 0:不判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){P2DIR &= 0x00; // 将P4 口切换为输入状态CLR_RS;SET_RW;_NOP();SET_EN;_NOP();_NOP();while((P2IN & Busy)!=0); // 检测忙标志CLR_EN;P2DIR |= 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--)while(j--);}}“”程序#include <>#include ""typedef unsigned char uchar; typedef unsigned int uint;#define DataDir P2DIR #define DataPort P2OUT #define Busy 0x80#define CtrlDir P6DIR #define CLR_RSP6OUT&=~BIT3; //RS =#define SET_RS P6OUT|=BIT3;#define CLR_RW P6OUT&=~BIT4; //RW#define SET_RW P6OUT|=BIT4;#define CLR_EN P6OUT&=~BIT5;//EN #define SET_EN P6OUT|=BIT5;*****************************************函数名称: DispNchar功 能:让液晶从某个位置起连续显示参 数: x-- 位置的列坐标 y-- 位置的行坐标 n--字符个数 ptr--指向字符存放位置的指针返回值 :无 ********************************************/void DispNChar(uchar x,uchar y, uchar n,uchar *ptr) ************ 宏定义 ************* N 个字符{uchar i;for (i=0;i<n;i++){Disp1Char(x++,y,ptr[i]);if (x == 0x0f){x = 0;y A= 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();SET_EN; // 产生使能脉冲信号 _NOP();_NOP();CLR_EN;/*******************************************函数名称: LcdWriteData功 能:向液晶显示的当前地址写入显示数据参 数: data-- 显示字符数据返回值 :无 ********************************************/ void LcdWriteData( uchar data ){WaitForEnable(); // 等待液晶不忙SET_RS;CLR_RW;_NOP();检测忙信号DataPort = cmd;// _NOP();将命令字写入数据端口DataPort = data; // 将显示数据写入数据端口_NOP();SET_EN; // 产生使能脉冲信号_NOP();_NOP();CLR_EN;}/*******************************************函数名称:WaitForEnable功能:等待1602 液晶完成内部操作参数:无返回值:无********************************************/void WaitForEnable(void){P2DIR &= 0x00; // 将P4 口切换为输入状态CLR_RS;SET_RW; _NOP();SET_EN;_NOP();_NOP();CLR_EN;P2DIR |= 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--);}}。
MSP430F149的ADC操作1)ADC图解图1 ADC的原理图理解:1.ADC的时钟来源可以有四个(ACLK/MCLK/SMCLK/ADC12SO)由ADC12SSELx来选择。
并且可以由ADC12DIVx控制选择分频。
2.ADC的采样参考电压可以由SREF0,SREF1来选择四种参考电压。
3.INCHx控制选择模拟电压输入口。
4.SHSx选择控制方式。
2)ADC的内核1.ADC的转换公式当采样最高电压高过或等于参考电压的时候,是最大值0FFFH。
当采样最低电压低于或是等于参考电压的时候,是最小值000H。
2.控制ADC12的内核可以通过ADC12CTL0和ADC12CTL1两个寄存器来控制。
当不使用的时候可以通过ADC12ON位来控制关闭内核以达到低功耗的目的。
当修改转换使能标志ENC的时候,要先判断ADC12内核是否在进行转换工作,如果在转换工作期间关闭ENC(置零)那么最终得到错误的结果。
3)ADC的时钟来源ADC可以有四种时钟来源。
而ADC12OSC是ADC内置的一个时钟源,大概频率在5MHZ左右,不过该时钟源由个人设备、供电电压和外部温度的影响很大。
4)ADC的参考电压发生器ADC内部可以提供一个可以产生1.5V或是2.5V的产考电压发生器。
当设计使用的时候,需要将一个10uF的电容和一个0.1uF的电容并联到它的输出端。
而且使用的时候,打开发生器至少需要等待17ms以让参考电压达到一个稳定的值。
5)ADC的低功耗当ADC内核不适用的时候,它会自动进入关闭模式,在使用的时候自动苏醒。
而它的参考电压却不会自动关闭,要用手通过REFON手动关闭。
6)ADC的采样保持触发源它的触发源由四种选择。
1.ADC12SC位控制。
2.定时器A输出控制3.定时器B输出控制4.定时器B输出控制7)ADC的采样保持时间ADC的采样保持时间有两种模式。
1.拓展型采样时钟模式。
这个时候,采样的时间由SHI决定,也就是当SHI上升沿的时候开始采样,下降沿的时候结束采样。
/****************************************************************** MSP430F149的步进电机程序主要实现步进电机的加减速运行程序步进电机转速由慢到快逐步加速步进电机的匀速运行程序步进电机由快到慢逐步减速到停止******************************************************************/#include <msp430x14x.h>#define uchar unsigned char#define uint unsigned intuchar FFW[8]={0xFE,0xFC,0xFD,0xF9,0xFB,0xF3,0xF7,0xF6}; //步进电机的正转数组uchar REV[8]={0xF6,0xF7,0xF3,0xFB,0xF9,0xFD,0xFC,0xFE}; //步进电机的反转数组uchar rate ; //步进电机的速度/********************************************************延时函数delay8MHz时钟,********************************************************/void delay(uchar k){uint s;k = rate;do{for(s = 0 ; s <200 ; s++) ;}while(--k);}/********************************************************步进电机的正转程序********************************************************/void motor_ffw(){uchar i;for (i=0; i<8; i++) //一个周期转30度{P5OUT = FFW[i];//取数据delay(2); //调节转速}}/******************************************************** 步进电机反转程序********************************************************/ void motor_rev(){uchar i;for (i=0; i<8; i++) //一个周期转30度{P5OUT = REV[i]; //取数据delay(2); //调节转速}}/******************************************************** 控制步进电机运行程序*********************************************************/ void motor_turn(){uchar x;rate=0x30;x=0xff;do{motor_ffw(); //正转加速rate--;}while(rate!=0x0a);do{motor_ffw(); //正转匀速x--;}while(x!=0x01);do{motor_ffw(); //正转减速rate++;}while(rate!=0x30);do{motor_rev(); //反转加速rate--;}while(rate!=0x0a);do{motor_rev(); //反转匀速x--;}while(x!=0x01);do{motor_rev(); //反转减速rate++;}while(rate!=0x30);}/********************************************************主程序*********************************************************//********************主函数********************/void main(void){uchar i;WDTCTL = WDTPW + WDTHOLD; //关闭看门狗/*下面六行程序关闭所有的IO口*/P1DIR = 0XFF;P1OUT = 0XFF; //P1端口为输出端口//时钟初始化BCSCTL1&=~XT2OFF; //启动XT2振荡器BCSCTL2|=SELM1; //MCLK为XT2do{IFG1&=~OFIFG;for(i=0xFF;i>0;i--);}while((IFG1&OFIFG)!=0);while(1){P1OUT = 0x00; // 输出高电平motor_turn();}}。
12-Bit ADC Core:ADC CORE将一个模拟量转化为12位的数字量,并且将数字量存储到ADC12存储器中。
ADC CORE需要软件编程选择V R-和V R+的参考输入源,作为转换的上限值和下限值。
当模拟量输入等于或大于V R+时,转换结果N ADC =0FFFH;当模拟量输入等于或小于V R-时,转换结果N ADC =0H。
ADC12ON位用于打开ADC Core,ENC位:在每次转化之前都要置1.Conversion Clock SelectionADC12CLK用做转换时钟;或者当SHP=1()时,用于生成采样周期。
采样的时钟源有多个。
ADC12OSC大约5M Hz左右,但是与设备,供电电压,温度相关,具体参照规格书而定。
ADC12 Inputs and MultiplexerADC12模块模拟量输入源有16个,通过INCHx控制。
16个输入元分别是A0-A7(P6口),Ve REF+(Pin10), Ve REF-(Pin11)和4个内部输入源。
Voltage Reference GeneratorREFON=1,打开参考电压发生器。
REF2_5V = 1,参考电压为2.5V; REF2_5V = 0,参考电压为1.5V;INCHX=0AH,是模拟量输入源是温度传感器。
为了去耦,在参考电压输出引脚VREF+,接10uF和0.1uF的电容到A VSS.Auto Power-Down为了低功耗的应用。
ADC Core当不使用时自动关闭,在使用时,可以自动恢复打开;首次需软件打开。
ADC12OSC 用时自动打开,不用自动关闭。
参考电源需软件打开和关闭,不具有自动功能。
Sample and Conversion TimingSHI上升沿时An analog-to-digital conversion is initiated。
SAMPCON控制采样周期和启动转换:SAMPCON高电平时,采样。