搜索
bottom↓
回复: 25

公布M8电压表全部代码和仿真,顺便请教个问题

[复制链接]

出0入0汤圆

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

源代码工程和仿真工程

源代码
  1. #include <avr/io.h>
  2. #include <avr/interrupt.h>
  3. #include <avr/signal.h>
  4. #include <avr/wdt.h>
  5. #include <avr/delay.h>
  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.        
  49. p[0]=i/1000;
  50. i=i%1000;
  51. p[1]=i/100;
  52. i=i%100;
  53. p[2]=i/10;
  54. i=i%10;
  55. p[3]=i;
  56. }

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

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

  87. SIGNAL(SIG_ADC)
  88. {

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

  106. void adc_init()
  107. {

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

  109. //        ADCSRA = 0B11000111;  //0xc7
  110.         ADCSRA=_BV(ADEN)|_BV(ADIE)|_BV(ADFR)|_BV(ADPS1)|_BV(ADPS0);
  111.         ADCSRA|=_BV(ADSC);//自由模式开始转换
  112.        
  113. }


  114. int main(void)
  115. {
  116.         port_init();
  117.         adc_init();
  118. _delay_ms(500);                //延时待系统稳定;
  119.         uint ada ,i,v;
  120.        
  121.         wdt_enable(WDTO_1S);
  122.         sei();
  123. while(1)
  124. {
  125.           cli();
  126.                 v= g_nAdValue;
  127.                 ada=(v+3)*30/128;

  128.           Process(ada,Data);
  129.            Display(Data);

  130.           sei();
  131.                 wdt_reset();//喂狗
  132. }

  133. return 0;
  134. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2012-10-18 22:58:37 | 显示全部楼层
睡觉前顶下。。哎。。
求个人真难

出0入0汤圆

 楼主| 发表于 2012-10-19 20:46:45 | 显示全部楼层

竟然木人回复。。。

出0入0汤圆

发表于 2012-10-19 22:28:43 | 显示全部楼层
顶顶吧,没用过这个编译器

出0入0汤圆

发表于 2012-10-20 08:04:48 | 显示全部楼层
垃圾一般的代码 错误那么多 不知道怎么编译通过生产HEX文件的

出0入0汤圆

 楼主| 发表于 2012-10-20 10:06:41 | 显示全部楼层
yklstudent 发表于 2012-10-20 08:04
垃圾一般的代码 错误那么多 不知道怎么编译通过生产HEX文件的

怎么修改啊,大哥

出0入0汤圆

发表于 2012-10-20 13:37:15 | 显示全部楼层
chary_5 发表于 2012-10-20 10:06
怎么修改啊,大哥

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#ifndef F_CPU
#define F_CPU        8000000
#endif
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int

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

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

void Display(uchar *p) //间隔5ms显示
{
        uchar i,sel=0x01;
        for(i=0;i<4;i++)
        {
                  PORTB=sel;
                  if(i==2)
                    PORTD=0x7f-Table[p]; //0111 1111
                  else
                        PORTD=0xff-Table[p];
                   _delay_us(10);
                   sel=sel<<1;
        }
}

/*
void Display(uchar *p) //间隔5ms显示
{
uchar sel=0x01;
for(uchar i=0;i<4;i++)
{
PORTC=~sel;
  if(i==2)
    PORTD= Table[p] + 0x80; //0111 1111 1000 0000
  else
          PORTD = Table[p];
   _delay_ms(10);
   sel=sel<<1;
}
}
*/

void Process(uint i,uchar *p)
{
        p[0]=i/1000;
        i=i%1000;
        p[1]=i/100;
        i=i%100;
        p[2]=i/10;
        i=i%10;
        p[3]=i;
}

void port_init()
{
        DDRB=0xff;                    //set port b as input port 1111 0000 the first 4 bits as output, the latter 4 bits as input
          PORTB=0xff;
          DDRC=0x00;                    //设置C口为推挽1输出;
          PORTC=0x00;
          DDRD=0xff;                    //设置C口为推挽1输出;
          PORTD=0xff;
          PORTB=0x00;                  
          PORTD=0x00;
}

//********************************************************
//函数名:Timer0_Init
//输入:无
//输出:无
//描述:ATmega 8 Timer0 初始化,中断周期10ms
//********************************************************
void Timer0_Init(void)
{
        TCCR0=0x04;//256分频,8M/1024,
        TCNT0=0X00;//计数器清零
        TIMSK|=0x01;//使能TOIE0中断
        TIFR|=0X01; //清楚中断标识位
}

void Start_ADC(void)
{
        ADCSRA |= _BV(ADIE);
        ADMUX = 0x00;
        _delay_us(2);
        ADCSRA |= _BV(ADSC);
}


void Stop_ADC(void)
{
        ADCSRA &= ~_BV(ADIE);
}

//********************************************************
//函数名:SIGNAL(SIG_ADC)
//输入:无
//输出:无
//描述:AD测量中断服务程序
//********************************************************
SIGNAL(SIG_ADC)
{
        uchar n;
        ADValue[ADTimes++] = (ADCL+ADCH*256);
        //g_nAdValue = ADValue[0];
        if(ADTimes>=16)
        {         
                tmp16=0;
                for(n=0;n<16;n++ )
                {
                        tmp16+=ADValue[n];
                }
                g_nAdValue = (tmp16>>4);
                   ADTimes = 0;
        }
          
}

void adc_init()
{
          ADMUX = 0B00000000;                // INTERNAL Vref 2.56V select first ADC4;0000 0100
        ADCSRA=_BV(ADEN)|_BV(ADIE)|_BV(ADPS2)|_BV(ADPS1)|_BV(ADPS0);       
}

/*
void adc_init()
{
          ADMUX = 0B00000000;                // INTERNAL Vref 2.56V select first ADC4;0000 0100
        ADCSRA = 0xC5;
}

uint ADC_READ(void)
{
        ADCSRA |= _BV(ADSC);
        while((ADCSRA&_BV(ADIF))==0X10);
        return (ADCL+ADCH*256);
}
*/

int main(void)
{
        uint ada,v;
        _delay_ms(500);                //延时待系统稳定;
        port_init();
        adc_init();
       
        //wdt_enable(WDTO_1S);
        sei();
        //Start_ADC();
        while(1)
        {
                  //cli();
                //g_nAdValue = ADC_READ();
                Start_ADC();
                v= g_nAdValue;
                ada=(v+3)*30/128;

                  Process(ada,Data);
                   Display(Data);
                Stop_ADC();
                //wdt_reset();//喂狗
        }
        return 0;
}

哎 这里资料那么多 怎么就不知道有效利用呢

出0入0汤圆

发表于 2012-10-20 13:38:34 | 显示全部楼层
本帖最后由 yklstudent 于 2012-10-20 13:45 编辑

对了 我这个把AD口改为AD0了
数码管位段口由PC口改为PB口  
具体为:PC0-----PB0
             PC1-----PB1
             PC2-----PB2
             PC3-----PB3

出0入0汤圆

发表于 2012-10-20 13:39:31 | 显示全部楼层
还有那些变量加上volatile  不然好像要被GCC优化掉

出0入0汤圆

 楼主| 发表于 2012-10-20 22:22:02 | 显示全部楼层
yklstudent 发表于 2012-10-20 13:38
对了 我这个把AD口改为AD0了
数码管位段口由PC口改为PB口  
具体为:PC0-----PB0

非常感谢LS的指点
我现在编译试试

出0入0汤圆

 楼主| 发表于 2012-10-20 22:52:26 | 显示全部楼层
中断好像可以工作了,但是数据根本对不上啊
下面是截图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-10-20 23:57:55 | 显示全部楼层
chary_5 发表于 2012-10-20 22:52
中断好像可以工作了,但是数据根本对不上啊
下面是截图

这是我运行的效果 显示没问题。。你自己再看看吧

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-10-21 05:03:44 来自手机 | 显示全部楼层
mark 收藏

出0入0汤圆

 楼主| 发表于 2012-10-21 10:36:51 | 显示全部楼层
yklstudent 发表于 2012-10-20 23:57
这是我运行的效果 显示没问题。。你自己再看看吧

我修改了这个地方,加了红色的地方,否则编译报错

void Display(uchar *p) //间隔5ms显示
{
        uchar i,sel=0x01;
        for(i=0;i<4;i++)
        {
                  PORTB=sel;
                  if(i==2)
                    PORTD=0x7f-Table[p]; //0111 1111
                  else
                        PORTD=0xff-Table[p];
                   _delay_us(10);
                   sel=sel<<1;
        }
}

厚着脸皮,说一句,能否上传下你的工程??呵呵
谢谢

出0入0汤圆

 楼主| 发表于 2012-10-21 10:48:41 | 显示全部楼层
换了未选线的顺序还是一样的,奇怪了,,
怎么你的正常,我的是乱七八糟 的数据?

出0入0汤圆

 楼主| 发表于 2012-10-21 11:22:17 | 显示全部楼层
yklstudent 发表于 2012-10-20 13:38
对了 我这个把AD口改为AD0了
数码管位段口由PC口改为PB口  
具体为:PC0-----PB0

我也这样修改的,其他什么都没动过?????
什么原因

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-10-21 14:33:59 | 显示全部楼层
chary_5 发表于 2012-10-21 11:22
我也这样修改的,其他什么都没动过?????
什么原因

这个就是全部,HEX文件是default内的 外面的HEX是你老得

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2012-10-21 16:18:16 | 显示全部楼层
yklstudent 发表于 2012-10-21 14:33
这个就是全部,HEX文件是default内的 外面的HEX是你老得

大哥,你hex显示结果是和你说的一致
但没有给出源代码啊,你在前面给出的源代码根本显示不了哦
救人救到底吧,谢谢

出0入0汤圆

发表于 2012-10-21 17:58:26 | 显示全部楼层
本帖最后由 yklstudent 于 2012-10-21 18:03 编辑
chary_5 发表于 2012-10-21 16:18
大哥,你hex显示结果是和你说的一致
但没有给出源代码啊,你在前面给出的源代码根本显示不了哦
救人救到 ...


那个C文件就是

出0入0汤圆

发表于 2012-10-21 18:02:06 | 显示全部楼层
不是有个C文件嘛 程序就是那个 可以编译的 生成的HEX文件在default文件夹下就对了  那个才是

出0入0汤圆

 楼主| 发表于 2012-10-21 18:22:57 | 显示全部楼层
呵呵,default下没有代码文件哦



还有哦,AD下的hex大小不到2KB,
default下Hex大小是12KB



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-10-21 20:27:38 | 显示全部楼层
chary_5 发表于 2012-10-21 18:22
呵呵,default下没有代码文件哦

哎 表达能力问题差了
你上面的图片里的M8_AD.c文件不就程序嘛
那个就是  你还要上面

出0入0汤圆

发表于 2012-10-21 20:29:28 | 显示全部楼层
AD文件下得.HEX是你以前的
default文件下得.HEX是改后的  那个就是M8_AD.c文件编译生成的

出0入0汤圆

 楼主| 发表于 2012-10-21 21:18:17 | 显示全部楼层
多谢大侠这么热心的帮助
奇怪了,用default下的Makefile编译出来的就正常,用AD下的就不显示第二位了,
而且两者编译出来大小相差很大。。。
研究下Makefile导致的原因

出0入0汤圆

 楼主| 发表于 2012-10-26 23:04:43 | 显示全部楼层
  1. int main(void)
  2. {
  3.         uint ada,v;
  4.         _delay_ms(500);                //延时待系统稳定;
  5.         port_init();
  6.         adc_init();
  7.         
  8.         //wdt_enable(WDTO_1S);
  9.         sei();
  10.         //Start_ADC();
  11.         while(1)
  12.         {
  13.                   //cli();
  14.                 //g_nAdValue = ADC_READ();
  15.                 Start_ADC();
  16.                 v= g_nAdValue;
  17.                 [color=Red]ada=(v+3)*30/128;[/color]//这句话什么意思???

  18.                   Process(ada,Data);
  19.                    Display(Data);
  20.                 Stop_ADC();
  21.                 //wdt_reset();//喂狗
  22.         }
  23.         return 0;
  24. }
复制代码

出0入0汤圆

 楼主| 发表于 2012-10-26 23:04:59 | 显示全部楼层
ada=(v+3)*30/128;//这句话什么意思???
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-29 12:14

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表