在线情况
楼主
  • 头像
  • 级别
    • 积分7
    • 经验183
    • 文章8
    • 注册2010-07-18
    430AD采样串口传输 程序
    [SIZE=3][SIZE=5][COLOR=#F709F7]#include <msp430x44x.h>
    #define REFVOL 2.5                    //参考电压2.5V

    unsigned char adc_Flag;
    unsigned int result[6][100];
    unsigned char RXDATA_BUF[10];
    unsigned int RX_count=0;
    unsigned char temp;

    /******************初始化AD*******************/
    void init_ADC12(void)
    {
    ADC12CTL0 = ADC12ON + REFON + REF2_5V +SHT0_6+MSC;
    ADC12CTL1 = SHS_0 + SHP + CONSEQ_3;  

    ADC12MCTL0 = INCH_0 + SREF_1; //通道0,单片机P6.0口
    ADC12MCTL1 = INCH_1 + SREF_1; //通道1,单片机P6.1口
    ADC12MCTL2 = INCH_2 + SREF_1; //通道2,单片机P6.2口
    ADC12MCTL3 = INCH_3 + SREF_1; //通道3,单片机P6.3口
    ADC12MCTL4 = INCH_4 + SREF_1; //通道4,单片机P6.4口
    ADC12MCTL5 = INCH_10 + SREF_1 + EOS;//内部温度传感

    ADC12CTL1 &= 0x0fff; //设置起始采样通道
    ADC12CTL0 |= ENC;          //使能转换;
    }

    /******************启动AD*******************/
    void start_ADC12()
    {
    ADC12IE = 0x0020;        //使能中断;
    ADC12CTL0 |= ADC12SC;    //开始采样

    adc_Flag = 0;
    }

    /******************中断向量*******************/
    #pragma vector = ADC_VECTOR
    __interrupt void ADC_Interrupt(void)
    {
      switch(ADC12IFG)
      {
      case 0x003F:
        {
        result[0][temp] = ADC12MEM0;
        result[1][temp] = ADC12MEM1;
        result[2][temp] = ADC12MEM2;
        result[3][temp] = ADC12MEM3;
        result[4][temp] = ADC12MEM4;
        result[5][temp] = ADC12MEM5;  
        temp++;
          if(temp>100 || temp==100)
          {
          temp = 0;
          adc_Flag = 1;
         
          ADC12IE &= 0xffdf;
          }
        }
        break;
       
      default:
        break;
      }
    }

    /******************数据格式转换****/
    void format_Data(void)
    {
    unsigned char i,j,k;
       for(i=0; i<5; i++)
       {
          for(j=0; j<100; j++)
          {
          result[i][j] = (int)(((REFVOL * result[i][j]) / 4096) * 1000);     //计算出来的为采样端口电压的值的1000倍
          }
       }
       
       for(k=0; k<100; k++)
       {
          result[5][k] = (int)(((REFVOL * result[5][j]) / 4096 - 0.986) / 0.00355);    //计算出来的为通道10的温度值
       }
       
    }
    /******************初始化串口*******************/
    void init_uart(void)                 
    {
        unsigned int i;
       
        FLL_CTL1 |= XT2OFF + SELM_XT2 + SELS;  
    //选择MCLK时钟源
       
          do                                     //等待时钟稳定
          {
            IFG1 &= ~OFIFG;
            for(i=0; i<0xff; i++);
          }while((FLL_CTL0 & XT2OF) == XT2OF);
       
        UCTL0 |= SWRST;                       //控制寄存器位
        UCTL0 |= CHAR;
        UTCTL0 = SSEL0+SSEL1;                 //选择发送时钟源复位
        UBR00 = 0XA0;                         //波特率9600
        UBR10 = 0X01;
        UMCTL0 = 0X5E;
        UCTL0 &= ~SWRST;                      //选择发送时钟源置位
       
        ME1 |= URXE0 + UTXE0;                   //使能发送,接收功能
        IE1 |= URXIE0 + UTXIE0;               //使能发送,接收中断
        IFG1 = 0X00;                          //清标志位
        P2SEL |= 0X30;                        //模块选用P2.4,5作为串口线
        P2DIR |= 0X10;                        //输出方向
    }

    /*---------------------------------------------------------*/
    void uart_start(void)                   //启动发送
    {  
        IE1 |= UTXIE0;
        while((UTCTL0&BIT0)!=BIT0);
        TXBUF0 = ' ';
    }
    /*----------------------------------------------------------*/
    void uart_receive(void)                 //接收
    {
        RXDATA_BUF[RX_count]=RXBUF0;
        RX_count++;
    }
    /*-----------------------------------------------------------*/
    void uart_send(void)                    //发送
    {  
    unsigned char i,j;
    unsigned char temp1;
      for(i=0; i<5; i++)
      {  
        for(j=0; j<100; j++)
        {
        temp1 = result[i][j] >> 8;
        TXBUF0 = temp1;
        TXBUF0 = result[i][j];
        }  
      }
      IE1 &= 0x7f;
    }

    #pragma vector=USART0RX_VECTOR //接收中断
    __interrupt void UART0_RX_ISR()
    {
        uart_receive();
    }

    #pragma vector=USART0TX_VECTOR //发送中断
    __interrupt void UART0_TX_ISR()
    {
        uart_send();
    }



    /********************main*************************/
    void main(void)
    {
    WDTCTL = WDTHOLD + WDTPW;

    init_ADC12();
    init_uart();
    _EINT();

      while(1)
      {
        start_ADC12();
        while(adc_Flag == 0);
        format_Data();
        uart_start();
      }
    程序在单步调试的时候串口传输正确,但是全速运行的时候数据就不对了,理论上串口产生一次中断将会执行uart_send,但是全速运行的时候,没传输几个字节后就会跳到uart_start处,能给分析一下为什么吗?谢谢[EM10]

    [IMG=0,absmiddle]http://[/IMG]<br>}<br>[/IMG][/i][/i][/i][/i][/SIZE][/SIZE][/COLOR]
    微控网感谢您的参与
    在线情况
    14
    • 头像
    • 级别
      • 积分21
      • 经验516
      • 文章33
      • 注册2009-10-13
      发送数据没必要,用中断方式吧,采用主动发送就行。
      此帖受到1次评价, 累计:积分+1
      再思考一下
      在线情况
      15
      • 头像
      • 级别
        • 积分7
        • 经验183
        • 文章8
        • 注册2010-07-18
        [QUOTE][b]下面引用由[u]zhb19820430[/u]发表的内容:[/b]

        发送数据没必要,用中断方式吧,采用主动发送就行。[/QUOTE]

        采用查询方式的时候有个问题:那就是UTXIFG0在查询方式的时候需要软件复位,中断的方式的时候只要相应中断就硬件复位了。但是查询方式的时候,我怎么知道数据是否发送完呢?
        微控网感谢您的参与
        在线情况
        16
        • 头像
        • 级别
          • 积分7
          • 经验183
          • 文章8
          • 注册2010-07-18
          [QUOTE][b]下面引用由[u]zhb19820430[/u]发表的内容:[/b]

          发送数据没必要,用中断方式吧,采用主动发送就行。[/QUOTE]


          你好,我感觉我的程序问题在于单片机串口下一帧数据发送的时候没能等到上一帧数据发送完。要连续发送数据,且采用查询方式的话我目前的问题是如何确定上一帧数据已经发送完毕。调试的时候,我发现TXEPT位始终是1,而在向UTXBUF0中写入数据后,UTXIFG0置1,但是查询方式的时候不会硬件复位,所以不清楚数据何时发送完毕。不知道你能不能给解释一下,谢谢
          微控网感谢您的参与
          Powered by LeadBBS 9.2 .
          Page created in 0.1719 seconds with 5 queries.