OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5312|回复: 5

看同学的程序,不是很明白,可以帮我么!很着急

[复制链接]

2

主题

4

帖子

0

精华

新手入门

积分
32
金钱
32
注册时间
2015-6-4
在线时间
0 小时
发表于 2015-6-6 12:55:46 | 显示全部楼层 |阅读模式
5金钱

#include <mega16.h>

#include <delay.h>

#include <stdio.h>

#include <math.h>

bit udre;                                 //usart data register empty       串口数据寄存器空

bit adcsc;                                //ADC开始转换

bit usart_r_flag=0;                       //串口输出标志

bit adc_permm;                            //adc permmite ADC允许

unsigned char adc_flag=1;                // adc complete flag  ADC完成标志

unsigned char adch,adcl,channel_compl;    //ADC高电平,ADC低电平,通道

unsigned long int adc_temp;               //ADC数据暂存

unsigned long int irms;                   //电流有效值

unsigned long int urms;                   //电压有效值

unsigned long int adc_av=0;               //ADC平均值

signed long int adc_s;                    //

signed long int p_av;                     //功率平均

unsigned long int p_factor;                //功率因数

unsigned long int p_sum,p_sum_temp,e_sum;  //总和

unsigned char p_sum_count;                 //总和计数

unsigned char usart_count=0;               //串口计数

unsigned char usart_r[5];                  //串口数组

signed int Volt[100];                      //电压数组

signed int Curr[100];                      //电流数组

unsigned char Volth[100]={0x00};           //

unsigned char Voltl[100]={0x00};           //

 

void usart_trans(unsigned char s_data)       //串口发射

{

 

  UDR=s_data;

  do

  {

    udre=UCSRA.5;

  }

  while(!udre);

   UCSRA.6=1;

}

 

void usart_trans_addr(unsigned char *s_addr)        //串口发射地址

{

 

  UDR=*s_addr;

  do

  {

    udre=UCSRA.5;

  }

  while(!udre);

   UCSRA.6=1;

}

 

void _delay(unsigned int time_delay)           //延时

{

  unsigned int d_t;

  while(time_delay--)

    for(d_t=0;d_t<1;d_t++);

}

 

void l_delay(unsigned int time_delay)           //长延时

{

  unsigned int d_t;

  while(time_delay--)

    for(d_t=0;d_t<200;d_t++);

}

interrupt [USART_RXC] void usart_rx_isr(void)       //串口接收中断

{

if(usart_count>=0&&usart_count<=4)

usart_r[usart_count]=UDR;

usart_count++;

if(usart_r[0]==0x20)

{

    usart_r_flag=0; 

    UCSRB=0x00; 

    usart_count=0;

    #asm("cli");

    GICR&=0xdf;

    #asm("sei");

}

//PORTD.7^=1;

 

}

interrupt [ADC_INT] void adc_isr(void)             //ADC中断

{

adcl=ADCL;

adch=ADCH;

adc_flag=1;

}

interrupt [EXT_INT0] void ext_int0_isr(void)           //外部中断0

{

adc_permm=1;

 

}

interrupt [EXT_INT2] void ext_int2_isr(void)             //外部中断250HZ方波

{

 

adc_permm=1;

#asm("cli");

GICR&=0xdf;

#asm("sei");

//PORTD.7^=1;

 

}

 

void start_adc()                               //开始ADC

{

 GICR=0x00;  //close INT0,avoid INT0 happening during ADC-converting

 adc_flag=0;

 ADCSRA=0x89 | 0xC0;            

 do

  {

  adcsc=ADCSRA.6;

  }

  while(adcsc);

}

void start_adc_n_c() //ADC_Noise_Canceler Mode AD,噪声滤波

{

 #asm("cli");

 MCUCR|= 0x50;

 GICR=0x00;//close EXT_INT 

 #asm("sei");

 #asm("sleep")

 

}

void adc_mux_alter(unsigned char mux_)             //ADC通道转换

{

 ADMUX=0x20;

 ADMUX|=mux_;

 l_delay(10);

}

void usart_int(unsigned int x)                     //发送整型数据

{

    unsigned char int_x,int_y;

    int_x=x/256;

    int_y=x%256;

    usart_trans(int_x);

    usart_trans(int_y);

}

void usart_l_int(signed long int x)                  //发送32位整型数据

{

    unsigned char int_x,int_y,int_z,int_w;

    int_x=x/(256*65536);

    x=x%(256*65536);

    int_y=x/65536;

    x=x%65536;

    int_z=x/256;

    int_w=x%256;

    usart_trans(int_x); 

    l_delay(5);

    usart_trans(int_y);

    l_delay(5);

    usart_trans(int_z);

    l_delay(5);

    usart_trans(int_w);

    l_delay(10);

}

void trans_100byte(unsigned char *addr)              //发送100字节,检测

{

    unsigned char addr_;

        for(addr_=0;addr_<100;addr_++)

             {

                    usart_trans_addr(addr++);

                    l_delay(20);

             } 

 

             l_delay(10);

}

 

 

 

 

void adc_calcu(signed int *addr,unsigned u_i)               //ADC计算

{

    unsigned char k;

    adc_av=0;

    

   

    for(k=0;k<100;k++)

         {        

           *(addr+k)=(Volth[k]*4+Voltl[k]/64)*5;    

         }  

          for(k=0;k<92;k++)

         {        

           adc_av+=*(addr+k);    

         }

         adc_av/=92;

         for(k=0;k<100;k++)

           *(addr+k)-=adc_av;

         adc_temp=0;

         for(k=0;k<92;k++)

          { 

            adc_temp+=(long int) pow(*(addr+k),2);

          }  

          adc_temp/=92;

          adc_s=0;

          switch(u_i)

          { 

            case 0:

                {

                urms=0;

                urms=(int )sqrt(adc_temp);

                

                break;

                }

            case 1:

               {

                 irms=0;

                 irms=(int )sqrt(adc_temp);

                 break;

                }

          } 

         if(urms<=0x0200)

            urms=0;

         if(irms<=0x06)

            {

            irms=0;

            adc_s=0;

            }

         else

            irms-=0x04; 

 

}

 

           

void power_calcu()                             //功率计算

{

    unsigned char k;

    signed long int calcu1,calcu2;

    //signed long int calcu3,calcu4;

    p_av=0;

    adc_s=0;

    p_factor=0;

    for(k=0;k<92;k++)

    {   

        calcu1=Volt[k+3];

        calcu2=Curr[k];

        p_av+=calcu1 * calcu2;

    }

    p_av/=92;

    

    if(irms==0)

        p_av=0;

//    else

//        p_av+=0x10;

    

    

    //把有功功率、视在功率转化为扩大一百倍的十进制表示

    

     p_av/=1024;

     p_av*=26;

//     adc_s=urms*irms; 

//     adc_s/=1024;

//     adc_s*=26;  

//     p_factor=p_av*1000;

//     p_factor/=adc_s;

       p_sum_temp+=p_av;

       p_sum_count++;

       if(p_sum_count>=100)

       {

       p_sum=p_sum+p_sum_temp/10000*49; //每次转换完成需要1.780s178/36=4.9

       e_sum=e_sum+p_sum/10000;

       p_sum_temp=0;

       p_sum_count=1;

       }

   

}

 

void usart_send(unsigned char channel,unsigned char comm)             //通过发送模块无线

{

    usart_trans(0x45);

    _delay(4);

    usart_trans(0x53); 

    _delay(4);

    usart_trans(0x02);

    _delay(4);

    usart_trans(channel);

    _delay(4);

    usart_trans(comm); 

    _delay(4);

}

 

void main(void)

{

 unsigned int k;

 char i=0;

 //char adc_addr=0;

DDRB.2=0;

PORTB.2=0;

 

PORTC=0xff;

 

PORTD=0x80;

DDRD=0xfd;

 

 

MCUCR|=0X02;

MCUCSR|=0X40;  

GIFR|=0X60;

GICR|=0X20;

 

 

 

 

UCSRA=0x02;

UCSRB=0x98;

UCSRC=0x86;

UBRRH=0x00;

UBRRL=0x0c;

 

 

 

// ADC initialization

// ADC Clock frequency: 500.000 kHz

// ADC Voltage Reference: Int., cap. on AREF

// ADC Auto Trigger Source: ADC Stopped

ADMUX=0x20;

ADCSRA=0x8c;

PORTC=0X00;

ACSR|=0x80;

p_sum=0;

p_sum_temp=0;

p_sum_count=0;

channel_compl=0;

#asm("sei")

  start_adc();

usart_r_flag=0x01;

while(1)

{

 

if(!usart_r_flag)

  UCSRB=0x08;

  usart_send(0x01,0x00);

  usart_count=0;

  UCSRB=0x98;

while(!usart_r_flag)

{  

  while(usart_count<5)

    UCSRB=0x98;

  if(usart_r[0]==0x45 && usart_r[1]==0x53 && usart_r[2]==0x02 && usart_r[3]==0x01)

    {

        switch(usart_r[4])

        {  

            case 0:

                {

                 //usart_trans(usart_r[2]);

                 usart_trans(0x45);

                 usart_trans(0x53); 

                 usart_trans(0x0d);

                 usart_trans(0x01);  

                  usart_l_int(e_sum);

                 usart_int(urms*26);

                 usart_int(irms);

                 usart_l_int(p_av);

                 usart_r_flag=1; 

                 GIFR|=0xe0;

                 GICR=0x20; 

                UCSRB=0x00;

                

                // usart_l_int(adc_s);

                 //usart_int(p_factor);

                 //usart_trans('*');

                 //usart_trans('*');

                } 

            break;

            case 1:

                ORTD.7=1;

                 usart_trans(0x45);

                 usart_trans(0x53); 

                 usart_trans(0x02);

                 usart_trans(0x01); 

                 usart_trans(0x01);

                 usart_r_flag=1; 

                 GIFR|=0xe0;

                 GICR=0x20; 

                UCSRB=0x00; 

                break;

            case 2:

                ORTD.7=0;

                usart_trans(0x45);

                 usart_trans(0x53); 

                 usart_trans(0x02);

                 usart_trans(0x01); 

                 usart_trans(0x02);

                 usart_r_flag=1; 

                 GIFR|=0xe0;

                 GICR=0x20; 

                UCSRB=0x00;

                break;

            case 3:

                usart_r_flag=1;

                usart_trans(0x45);

                 usart_trans(0x53); 

                 usart_trans(0x02);

                 usart_trans(0x01); 

                 usart_trans(0x03); 

                GIFR|=0xe0;

                GICR=0x20; 

                UCSRB=0x00;

         }

    

    }

    usart_count=0;

    

}   

}

 

  

 

 adc_permm=0;//in INT2 service runtime,turns to 1

 l_delay(10);

 GIFR|=0xe0;

 GICR=0x20;

 UCSRB=0x00;

 while(!adc_permm); 

 

while (usart_r_flag)

      { 

       

      if(adc_permm)

      start_adc_n_c();

      _delay(2);

 

      if(adc_flag)

        {

             if(i<100 )

             {

             Volth=adch;

             Voltl=adcl;

             i++; 

             adc_flag=0;

             }

             else 

             {   

                 k=0;

                 adc_temp=0; 

                 if(channel_compl%2)

                   { 

                    UCSRB=0x98;

                    //usart_trans('/');

                    }

                 switch(channel_compl%2)

                 {

                  case 0:

                        adc_calcu(&Volt[0],0);break;

                  case 1: 

                        adc_calcu(&Curr[0],1);break;

                 }                 

                 

                   //trans_100byte(&Volth[0]);

                   //usart_l_int(adc_av);

                   if(channel_compl%2)

                   {

                        power_calcu(); 

                   }

//                 if(channel_compl%2)

//                   { 

//                    UCSRB=0x98;

//                    usart_trans('*');

//                    }

                  

             i=0;

             k=0;     

             channel_compl++;

             adc_mux_alter(channel_compl%2);

             l_delay(2);      

             adc_permm=0;//in INT2 service runtime,turns to 1

             GIFR|=0xe0;

             GICR=0x20;

             UCSRB=0x00; 

             

             

             while(!adc_permm);

             //UCSRB=0x00;

              }

 

            

       } 

        

      }

}

自己标注了一点程序,具体的不懂。无线模块给AVR发45 53 02 01 00,返回45 53 0D 01 00 00 00 00 5A 98 00 00 00 00 00 00 (什么都没插);45 53 0D 01 00 00 00 00 5A 16 00 11 00 00 00 EA 插充电器;45 53  0D  01 00 00 00 00 59 94 00 3B 00 00 01 86 插充电灯。不知道哪个是电压,哪个是电流,同学说U,I还要乘系数哦,但是不记得是多少了,有人能帮我看一下么???!!


安安静静做人,踏踏实实做事
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-6-7 00:32:53 | 显示全部楼层
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

13

主题

611

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1929
金钱
1929
注册时间
2014-10-6
在线时间
625 小时
发表于 2015-6-7 07:26:44 | 显示全部楼层
问你的同学就好了,他写的,他一看就知道了,别人怎么会理解呢!
回复

使用道具 举报

2

主题

4

帖子

0

精华

新手入门

积分
32
金钱
32
注册时间
2015-6-4
在线时间
0 小时
 楼主| 发表于 2015-6-8 15:25:07 | 显示全部楼层
回复【3楼】烟酒不沾:
---------------------------------
他说忘记了==我只能看懂一部分
安安静静做人,踏踏实实做事
回复

使用道具 举报

13

主题

611

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1929
金钱
1929
注册时间
2014-10-6
在线时间
625 小时
发表于 2015-6-8 15:30:57 | 显示全部楼层
回复【4楼】st893:
---------------------------------
你把他请到馆子里吃一顿他就记得了!别人都不知道你这个程序要实现目的,任何程序都是和相关的硬件联系的,你只给个不知道的程序,叫别人看看你的编程结构还是可以的!
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-6-8 16:20:27 | 显示全部楼层
回复【5楼】烟酒不沾:
---------------------------------
此楼甚是有理
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-21 10:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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