|
- /***********************************************
- 程序功能:实现对云台的角度控制和ad采集功能
- ************************************************/
- #include <msp430x14x.h>
- #define DRE_out P3DIR |= BIT3 //连接485芯片的DE,RE端口的IO设置为输出状态
- #define DE P3OUT |= BIT3 //设置485芯片处于发送状态
- #define RE P3OUT &= ~BIT3 //设置485芯片处于接收状态
- #define Num_of_Results 16 //对连续采集16次数据(进行平均,数据处理)
- typedef unsigned char uchar;
- typedef unsigned int uint;
- uint results[Num_of_Results]; //保存ADC转换结果的数组
- uint average; //转换出来的数值
- uchar tcnt = 0;
- char receive_order[5];//赋初值
- unsigned char order1[7]={0xFF,0x01,0x00,0x08,0x00,0x1E,0x27};//云台指令向上转
- unsigned char order2[7]={0xFF,0x01,0x00,0x10,0x00,0x1E,0x2F};//云台指令向下转
- unsigned char order3[7]={0xFF,0x01,0x00,0x04,0x1E,0x00,0x23};//云台指令向左转
- unsigned char order4[7]={0xFF,0x01,0x00,0x02,0x1E,0x00,0x21};//云台指令向右转
- unsigned char order5[7]={0xFF,0x01,0x00,0x0C,0x1E,0x1E,0x49};//云台指令向左上转
- unsigned char order6[7]={0xFF,0x01,0x00,0x0A,0x1E,0x1E,0x47};//云台指令向右上转
- unsigned char order7[7]={0xFF,0x01,0x00,0x14,0x1E,0x1E,0x51};//云台指令向左下转
- unsigned char order8[7]={0xFF,0x01,0x00,0x12,0x1E,0x1E,0x4F};//云台指令向右下转
- unsigned char order9[7]={0xFF,0x01,0x00,0x00,0x00,0x00,0x01};//云台指令-停止
-
- unsigned char order0[7]={0xFF,0x01,0x00,0x07,0x00,0x01,0x09};//云台的初始预置位
-
- uchar order_horizontal_angle[7]={0xff,0x01,0x00,0x4B,0x00,0x00,0x4C};//水平角度-0
- uchar order_vertical_angle[7]={0xff,0x01,0x00,0x4D,0x00,0x00,0x4E};//垂直角度-0
-
- /*******************************************
- 函数名称:Delays
- 功 能:延时一会
- 参 数:无
- 返回值 :无
- ********************************************/
- void Delays()
- {
- int k=20;
- int j;
- while(k--)
- {
- j=20;
- while(j--);
- }
- }
- /*****************************************
- 函数名称:InitMSP430
- ****************************************/
- void InitMSP430()
- {
- /*下面六行程序关闭所有的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;
-
- WDTCTL = WDTPW + WDTHOLD; //关闭看门狗
- P6DIR |= BIT2;P6OUT |= BIT2; //关闭电平转换
-
- DRE_out;
- DE;
-
-
- }
- /*****************************************
- 函数名称:向云台发送指令
- 功 能:发送指令
- 参数:
- 返回值:
- ******************************************/
- void send_order(unsigned char order[])
- {
- int i=0;
- for(i=0;i<7;i++)
- {
- TXBUF1 = order[i];
- while(!(IFG2 & UTXIFG1)); //等待发送结束
- IFG2 &= ~UTXIFG1;
- }
- }
- /*******************************************
- 函数名称:InitUART0
- 功 能:初始化UART0端口
- 参 数:无
- 返回值 :无
- ********************************************/
- void InitUART0(void)
- {
- P3SEL |= 0x30; // P3.4,P3.5选做UART0的通信端口
- ME1 |= URXE0 + UTXE0; // 使能USART0的TXD和RXD
- UCTL0 |= CHAR; // 8-bit character
- UTCTL0 |= SSEL0; // 驱动时钟UCLK = ACLK
- UBR00 = 0x0D; // 波特率2400
- UBR10 = 0x00; //
- UMCTL0 = 0x6B; // Modulation
- UCTL0 &= ~SWRST; // Initialize USART state machine
- }
- /*******************************************
- 函数名称:InitUART1
- 功 能:设置MCU的UART1对应的寄存器
- 参 数:无
- 返回值 :无
- ********************************************/
- void InitUART1(void)
- {
- P3SEL |= 0xC0; //将P3.6,P3.7选做UART1的通信端口
- ME2 |= UTXE1 + URXE1; //使能USART1的TXD和RXD
- UCTL1 |= CHAR; //选择8-bit字符
- UTCTL1 |= SSEL0; //驱动时钟选择ACLK
- UBR01 = 0x0D; //波特率2400
- UBR11 = 0x00;
- UMCTL1 = 0x6B; //调整
- UCTL1 &= ~SWRST; //初始化UART状态机
- }
- /********************************************
- 函数名称:Init_ADC
- 功 能:初始化ADC
- 参 数:无
- 返回值 :无
- ********************************************/
- void Init_ADC(void)
- {
- P6SEL |= 0x01; // 使能ADC通道
- ADC12CTL0 = ADC12ON + SHT0_10 + MSC; // 打开ADC,设置采样时间
- ADC12CTL1 = SHP + CONSEQ_2; // 使用采样定时器
-
- for ( int k=0; k<0x3600;k++){} //等待电压稳定
-
- ADC12IE = 0x01; // 使能ADC中断
- ADC12CTL0 |= ENC; // 使能转换
- ADC12CTL0 |= ADC12SC; // 开始转换
- }
- /*******************************************
- 函数名称:Trans_val
- 功 能:将16进制ADC转换数据变换成三位10进制
- 真实的模拟电压数据
- 参 数:Hex_Val--16进制数据
- 返回值 :无
- ********************************************/
- void Trans_val(uint Hex_Val,uchar *ptr)
- {
- //unsigned long caltmp;
- // float caltmp1;
- //float Curr_Volt;
- // uchar t1;
-
- unsigned long caltmp;
- uint Curr_Volt;
- uchar t1;
-
- caltmp = Hex_Val;
- caltmp = (caltmp << 5) + Hex_Val; //caltmp = Hex_Val * 33
- caltmp = (caltmp << 3) + (caltmp << 1); //caltmp = caltmp * 10
- //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);
-
- // P2OUT ^=BIT2; //用于测试是否接收到数据
- // Delays();
- // P2OUT |=BIT2;
- // Delays();
-
- }
- /*******************************************
- 函数名称:Send1Char
- 功 能:向PC机发送一个字符
- 参 数:sendchar--要发送的字符
- 返回值 :无
- ********************************************/
- void Send1Char(uchar sendchar)
- {
- while (!(IFG1 & UTXIFG0)); //等待发送寄存器为空
- TXBUF0 = sendchar;
-
- }
- /*******************************************
- 函数名称:PutSting
- 功 能:向PC机发送字符串并换行指令
- 参 数:ptr--指向发送字符串的指针
- 返回值 :无
- ********************************************/
- void PutString(uchar *ptr)
- {
- while(*ptr != '\0')
- {
- Send1Char(*ptr++); // 发送数据
- }
- while (!(IFG1 & UTXIFG0));
- TXBUF0 = '\n'; //发送换行指令
- TXBUF0 = '\n'; //发送换行指令
- }
- /*******************************************
- 函数名称:ad-convert
- 功 能:进行ad转换,将P6.0口的电压值进行采集
- 参 数:
- 返回值 :无
- ********************************************/
- void ad_convert()
- {
- uchar i;
- uchar buffer[5];
-
- Init_ADC();
- Delays();
- _EINT();
- Delays();
- buffer[4] = '\0';
-
- 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);
- ADC12CTL0 &= ~ENC; // 使能转换关闭
-
-
- P2OUT ^=BIT0; //用于测试是否接收到数据
- Delays();
- P2OUT |=BIT0;
- Delays();
- }
- /****************主函数****************/
- void main(void)
- {
- InitMSP430(); //初始化MSP430的基本设置
- InitUART0(); //初始化UART0-rs232与PC通信
- InitUART1();//初始化UART1-rs485与云台通信
-
- //char receive_order[5];//赋初值
- int k=0;
- int r_finish=1;
- int angle;
- uchar order_horizontal_angle[7]={0xff,0x01,0x00,0x4B,0x00,0x00,0x4C};//水平角度-0
- uchar order_vertical_angle[7]={0xff,0x01,0x00,0x4D,0x00,0x00,0x4E};//垂直角度-0
- while (1)
- {
- while(r_finish)
- {
- if(IFG1 & URXIFG0) //如果收到字符
- {
- receive_order[k++]=RXBUF0;//将收到的字节赋值给receive_order
-
- if(k==5)//判断是否接收到5个字符
- {
- if(receive_order[4]==receive_order[1]+receive_order[2]+receive_order[3])//将第2,3,4字符相加是否与第5个字符相等,用于校验这一帧字节信息的完整性
- {
- if(receive_order[0]==0xFF)//验证打头的字节为0xFF
- {
- r_finish=0;//验证成功,将r_finish置零,跳出加收字符的循环
-
- }
- }
- else//没有接受到正确的帧信息,将接受数组receive_order[m]清空
- {
- for(int m=0;m<5;m++)
- {
- receive_order[m]=0;
- }
- r_finish=1;//继续在接受pc命令中循环,等待新的帧信息
- k=0;//将接收数组个数清空,重新接受
- }
- }
- }
- }
-
- P2OUT ^=BIT1; //用于测试是否接收到数据
- Delays();
- P2OUT |=BIT1;
- Delays();
-
- switch(receive_order[1])
- {
- case 0x0A:
- order_horizontal_angle[0]=0xFF;//命令格式
- order_horizontal_angle[1]=0x01;//命令格式
- order_horizontal_angle[2]=0x00;//命令格式
- order_horizontal_angle[3]=0x4B;//将云台的控制命令的第四位设为4B,表示水平旋转
- angle=receive_order[2]<<8;//将第三位左移8位,最为角度的高8位
- angle+= receive_order[3];//pc发下的命令中,第三位和第四位代表将要旋转的角度,将该值进行处理
- angle=angle*100;//按照云台的角度计算-需*100
- order_horizontal_angle[4]=angle>>8;
- order_horizontal_angle[5]=angle&0x00ff;
- order_horizontal_angle[6]=order_horizontal_angle[1]+order_horizontal_angle[2]+order_horizontal_angle[3]+order_horizontal_angle[4]+order_horizontal_angle[5];//云台命令的校验位
- send_order(order_horizontal_angle); //数组的实参和形参---发送水平旋转命令
- angle=0;//清空
- break;
-
- case 0x0B:
- order_horizontal_angle[0]=0xFF;//命令格式
- order_horizontal_angle[1]=0x01;//命令格式
- order_horizontal_angle[2]=0x00;//命令格式
- order_vertical_angle[3]=0x4D;//将云台的控制命令的第四位设为4B,表示垂直旋转
-
- switch(receive_order[2])//用来判断正负角度
- {
- case 0x00://正方向转动
- angle=receive_order[3];
- angle=36000-angle*100;
- break;
- case 0x01://负方向转动
- angle=receive_order[3];
- angle=angle*100;
- break;
- }
- order_vertical_angle[4]=angle>>8;
- order_vertical_angle[5]=angle&0x00ff;
- order_vertical_angle[6]=order_vertical_angle[1]+order_vertical_angle[2]+order_vertical_angle[3]+order_vertical_angle[4]+order_vertical_angle[5];//云台命令的校验位
- send_order( order_vertical_angle); //数组的实参和形参---发送垂直转动命令
- angle=0;//清空
- break;
-
- case 0x00:
- send_order(order0);//设置为预置位0
- break;
-
- case 0x09:
- send_order(order9); //数组的实参和形参---发送停止命令
- break;
-
- case 0x01:
- send_order(order1); //发送向上命令
- break;
-
- case 0x02:
- send_order(order2);//发送向下命令
- break;
-
- case 0x03:
- send_order(order3); //发送向左命令
- break;
-
- case 0x04:
- send_order(order4);//向右
- break;
-
- case 0x05:
- send_order(order5); //左上
- break;
-
- case 0x06:
- send_order(order6); //右上
- break;
-
- case 0x07:
- send_order(order7); //左下
- break;
-
- case 0x08:
- send_order(order8);//右下
- break;
-
- case 0x10:
- // average=0;
-
- ad_convert();
- //average=0;
- break;
-
- }
- for(int m=0;m<5;m++)
- {
- receive_order[m]=0;
- }
- r_finish=1;
- k=0;
- }
- }
- /*******************************************
- 函数名称:ADC12ISR
- 功 能:ADC中断服务函数,在这里用16次平均的
- 计算P6.0口的模拟电压数值
- 参 数:无
- 返回值 :无
- ********************************************/
- #pragma vector=ADC_VECTOR
- __interrupt void ADC12ISR (void)
- {
- static uchar index = 0;
-
- results[index++] = ADC12MEM0; // Move results
- // average=ADC12MEM0;
- if(index == Num_of_Results)
- {
- uchar i;
- average = 0;
- for(i = 0; i < Num_of_Results; i++)
- {
- average += results[i];
- }
- average >>= 4; //测量16次,除以16,求品均值
- index = 0;
- tcnt++;
- if(tcnt == 250) //主要是降低串口发送速度
- {
- LPM1_EXIT;
- tcnt = 0;
- }
- }
- }
复制代码
|
|