[求助] M8电压表全部代码和仿真,顺便请教个问题

chary8088   2012-10-18 22:17 楼主
初学AVR,参考网上的源代码做了电压表,使用AD中断,但中断不能正常工作
[AVR AD CONVERTER] Result is not written to the ADC register because it has been locked.
一直这样提示
先谢谢各位看官了,小弟都折腾了好几天了,没有进展,希望各位多多指点

源代码工程和仿真工程
M8_AD.rar (67.95 KB)
(下载次数: 28, 2012-10-18 22:17 上传)

源代码
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #define uchar unsigned char
  7. #define uint unsigned int

  8. uchar Table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴
  9. //uchar Table[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,};//共阳
  10. uchar Data[4]={0,0,0,0};

  11. static uint ADValue[16] = {0}; //AD采样值
  12. static uint g_nAdValue=0;//平均电压
  13. static ADTimes=0; //AD采样次数,第几次采样
  14. static tmp16; //AD采样和

  15. void Display(uchar *p) //间隔5ms显示
  16. {

  17. uchar i,sel=0x01;
  18. for(i=0;i<4;i++)
  19. {
  20. PORTC=sel;
  21. if(i==2)
  22. PORTD=0x7f-Table[p[i]]; //0111 1111
  23. else PORTD=0xff-Table[p[i]];
  24. _delay_ms(10);
  25. sel=sel<<1;
  26. }
  27. }

  28. /*
  29. void Display(uchar *p) //间隔5ms显示
  30. {
  31. uchar sel=0x01;
  32. for(uchar i=0;i<4;i++)
  33. {
  34. PORTC=~sel;
  35. if(i==2)
  36. PORTD= Table[p[i]] + 0x80; //0111 1111 1000 0000
  37. else
  38. PORTD = Table[p[i]];
  39. _delay_ms(10);
  40. sel=sel<<1;
  41. }
  42. }
  43. */

  44. void Process(uint i,uchar *p)
  45. {
  46. for(uchar j = 0; j < 4; j++)
  47. p[j] = 0;

  48. p[0]=i/1000;
  49. i=i%1000;
  50. p[1]=i/100;
  51. i=i%100;
  52. p[2]=i/10;
  53. i=i%10;
  54. p[3]=i;
  55. }

  56. void port_init()
  57. {
  58. DDRB=0xf0; //set port b as input port 1111 0000 the first 4 bits as output, the latter 4 bits as input
  59. PORTB=0xff;
  60. DDRC=0x0f; //设置C口为推挽1输出;
  61. PORTC=0x00;
  62. DDRD=0xff; //设置C口为推挽1输出;
  63. PORTD=0xff;
  64. PORTB=0x00;
  65. PORTD=0x00;
  66. }

  67. //********************************************************
  68. //函数名:Timer0_Init
  69. //输入:无
  70. //输出:无
  71. //描述:ATmega 8 Timer0 初始化,中断周期10ms
  72. //********************************************************
  73. void Timer0_Init(void)
  74. {
  75. TCCR0=0x04;//256分频,8M/1024,
  76. TCNT0=0X00;//计数器清零
  77. TIMSK|=0x01;//使能TOIE0中断
  78. TIFR|=0X01; //清楚中断标识位
  79. }
  80. //********************************************************
  81. //函数名:SIGNAL(SIG_ADC)
  82. //输入:无
  83. //输出:无
  84. //描述:AD测量中断服务程序
  85. //********************************************************

  86. SIGNAL(SIG_ADC)
  87. {

  88. ADCSRA|=(1<
  89. ADValue[ADTimes]=(ADCH<<8);
  90. ADValue[ADTimes]|=ADCL;
  91. //ADValue[ADTimes]|=(ADCH<<8);
  92. ADTimes++;
  93. if( ADTimes>=16)
  94. {
  95. ADTimes = 0;
  96. tmp16=0;
  97. for(char n=0;n<16;n++ )
  98. {
  99. tmp16+=ADValue[n];
  100. }
  101. g_nAdValue = tmp16/16;

  102. }
  103. }

  104. void adc_init()
  105. {

  106. ADMUX = 0B00000100; // INTERNAL Vref 2.56V select first ADC4;0000 0100

  107. // ADCSRA = 0B11000111; //0xc7
  108. ADCSRA=_BV(ADEN)|_BV(ADIE)|_BV(ADFR)|_BV(ADPS1)|_BV(ADPS0);
  109. ADCSRA|=_BV(ADSC);//自由模式开始转换

  110. }


  111. int main(void)
  112. {
  113. port_init();
  114. adc_init();
  115. _delay_ms(500); //延时待系统稳定;
  116. uint ada ,i,v;

  117. wdt_enable(WDTO_1S);
  118. sei();
  119. while(1)
  120. {
  121. cli();
  122. v= g_nAdValue;
  123. ada=(v+3)*30/128;

  124. Process(ada,Data);
  125. Display(Data);

  126. sei();
  127. wdt_reset();//喂狗
  128. }

  129. return 0;
  130. }

回复评论 (1)

很简单,但是没有校准,只是简单测量
点赞  2012-10-23 10:14
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复