[求助] 新手第一次提问,真心调试了几天,有bug解决不了,求助!

peiyangyisheng   2013-5-31 20:23 楼主
硬件为MSP430G2553,小弟大一,还没有数电和模电基础,硬学试试。
麻烦先看看要求:
1.AD 模块的使用
使用内部ADC 模块持续测量一个外部电压(0—2.5V )
2.定时器模块的使用
用 1  中测量的电压值决定两个 LED  中一个的闪烁频率,电压越高闪烁越快,另一个暂时熄灭
3.  外部中断,按键的使用
测量电压的同时,如果按一次按键,则触发外部中断,使两个LED 交换闪烁和熄灭状态
4 .串行通信模块的使用
在 3  的中断触发后,串口发送一个小写a  到z  的英文字母,如按第一次发送一个 a,按第二次发送一个b。(发送至z后从按开始重新发送)同时用串口接收自己发送的数据。
  1. #include

  2. unsigned int adc_value=0;
  3. unsigned int t=0;
  4. unsigned char re;
  5. float voltage_value;
  6. unsigned char flag=0;
  7. void delay(int i)                //延迟函数,用于按键软件防抖
  8. {
  9.   while(i--);
  10. }
  11. void main( void )
  12. {
  13.   WDTCTL = WDTPW + WDTHOLD;                //关闭看门狗
  14.   
  15.   //ADC配置
  16.   ADC10CTL0 = ADC10SHT_2 + ADC10ON + ADC10IE + REF2_5V + REFON + SREF0;                // 设置采样保持,打开ADC10,打开ADC中断,设置2.5V的参考电压
  17.   ADC10CTL1 = INCH_4 ;                // 单通道输入 通道4
  18.   ADC10AE0 |= BIT5;                // P1.5 输入
  19.   P1DIR |= BIT0+BIT6;                // 设置P1.0为LED1输出,设置P1.6为LED2输出
  20.   ADC10CTL0 |= ENC + ADC10SC;                // 开始转换

  21.   //定时器配置
  22.   TACCTL0 = CCIE;                //使Timer_A能触发中断                           
  23.   TACCR0 = 0;                //配置Timer_A倒计时初始值
  24.   TACTL = TASSEL_2 + MC_2;                 //选择时钟源为子系统时钟,模式控制设置为计时从0到TACCR0

  25.   //按键设置
  26.   P1DIR &= ~BIT3;                //P1.3设置为输入
  27.   P1OUT |= BIT3;                //P1.3处于高电位
  28.   P1REN |= BIT3;                //使P1.3能上拉下拉电阻
  29.   P1IES |= BIT3;                //P1.3高电位到低电位触发中断
  30.   P1IE         |= BIT3;                //使P1.3能申请中断
  31.   P1IFG = 0;                        //中断标记复位

  32.   //UART配置
  33.   BCSCTL1 = CALBC1_1MHZ;
  34.   DCOCTL = CALDCO_1MHZ;
  35.   P1SEL = BIT1 + BIT2;                      // P1.1 = RXD, P1.2=TXD
  36.   P1SEL2 = BIT1 + BIT2;                     // P1.1 = RXD, P1.2=TXD
  37.   UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  38.   UCA0BR0 = 104;                            // 1MHz 9600
  39.   UCA0BR1 = 0;                              // 1MHz 9600
  40.   UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  41.   UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  42.   IE2 |= UCA0RXIE;                          // Enable USCI_A0 RX interrupt

  43.   _EINT();                //打开总中断
  44.   while(1)
  45.   {
  46.   }
  47. }

  48. // ADC中断函数
  49. #pragma vector=ADC10_VECTOR
  50. __interrupt void ADC10_ISR(void)
  51. {
  52.   while(!(P1IN&BIT3))
  53.         _EINT();       
  54.   adc_value = ADC10MEM;                 //将转换值存入adc_value中
  55.   voltage_value = adc_value/1024.0*2.5;
  56.   ADC10CTL0 |= ENC + ADC10SC;           //开始下一次转换
  57. }

  58. //定时器中断函数
  59. #pragma vector=TIMER0_A0_VECTOR
  60. __interrupt void Timer_A (void)
  61. {
  62.   if(flag==0)
  63.   {
  64.     P1OUT &= ~BIT6;
  65.     P1OUT ^= BIT0;
  66.   }
  67.   else
  68.   {
  69.     P1OUT &=~BIT0;
  70.     P1OUT ^=BIT6;
  71.   }
  72.   CCR0 += (int)((2.5-voltage_value)/2.5*65535);
  73. }

  74. //按键中断函数
  75. #pragma vector=PORT1_VECTOR
  76. __interrupt void p1()
  77. {
  78.   delay(2000);
  79.   if(!(P1IN&BIT3))
  80.     flag = !flag;
  81.   while(!(P1IN&BIT3));
  82.   delay(2000);
  83.   while (!(IFG2&UCA0TXIFG));
  84.   UCA0TXBUF='a'+(t++)%26;
  85.   _EINT();
  86.   P1IFG = 0;
  87. }

  88. //UART接收中断函数
  89. #pragma vector=USCIAB0RX_VECTOR
  90. __interrupt void USCI0RX_ISR(void)
  91. {
  92.   re = UCA0RXBUF;                    // TX -> RXed character
  93. }
现在出现问题有:
1.在未测量电压时,LED会无规律乱闪,当测量电压时(P1.4接GND或VCC),只能以恒定间隔闪动,不满足要求1,找不出原因;
2.貌似测电压要等一段时间才能测准确,P1.4接GND时会出各种各样的电压值;
3.控制灯频率和UART通信的时钟都是SMCLK,这个会不会有影响?
真心谢谢帮助的人!

回复评论 (5)

回复 楼主 peiyangyisheng 的帖子

你的功能划分挺明确了,那就一个功能一个功能的调试,
先只写第一个功能,调通了,再加入第二个,依此类推;

找事例程序,改改,拼在一起就是你要的功能了。
点赞  2013-6-1 11:08

回复 楼主 peiyangyisheng 的帖子

ADC10CTL1 = INCH_4 ;                // 单通道输入 通道4
  ADC10AE0 |= BIT5;                // P1.5 输入
你到底使用的哪个通道
点赞  2013-6-1 16:46
你安装的是那个编译软件???CCS还是IAR??
点赞  2013-6-1 16:48
LZ注意,在执行中断服务函数的时候,单片机会自动关闭全局中断使能,通过代码的语句,想必你知道这一点。
另一点:中断服务函数执行完之后,全局中断使能会再次自动开启。
《MCU工程师炼成记》作者之一
点赞  2013-6-1 22:52
先打基础,每个模块单独调,调这个模块的同时也是学习和积累的过程。这样有助于以后的学习和发展!
点赞  2013-6-2 15:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复