Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7687468
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2014-10-21 14:45:38


点击(此处)折叠或打开

  1. /*
  2.  * ade7758.c
  3.  *
  4.  * Created on: 2014年10月11日
  5.  * Author: Lzy
  6.  */
  7. //#include <rtthread.h>
  8. #include "ade7758.h"
  9. #include "sys.h"

  10. #define ADE_CS_PIN     PBout(12)

  11. #define ADE_RCC RCC_APB2Periph_GPIOB
  12. #define ADE_GPIO GPIOB
  13. #define ADE_PIN (GPIO_Pin_12)


  14. unsigned char bWorkModel=0;//工作模式标志位 1:校准模式;0:正常工作模式;
  15. unsigned char bit_1s=0; //1s钟标志,在时钟中断函数中置位

  16. static unsigned char divider = 1;//电能分频器,默认值为零,视在功率超出一定值时,自动将该值提高
  17. static unsigned int energy[9];//用于累加电能值 36

  18. struct all_data working;//正常工作模式下存放的电参量 95
  19. static unsigned int vo_buffer[5][3];//用于电压的积分虑波 36
  20. static unsigned int io_buffer[5][3];//用于电流的积分虑波 36


  21. /**
  22.  * 功能:片选使能
  23.  */
  24. void ADE_CS(unsigned char cs)
  25. {
  26.     ADE_CS_PIN = cs;
  27.     delay_ms(1);
  28. }

  29. /**
  30.  * 功能:延时函数 50us
  31.  */
  32. void ADE_udelay(void)
  33. {
  34.     delay_ms(1);
  35. }

  36. /**
  37.  * 功能:通过SPI写入数据至芯片
  38.  * 入口参数:
  39.  *         buf -> 数据缓冲区
  40.  *         len -> 数据长度
  41.  */
  42. void ADE_SPIWrite(unsigned char *buf, unsigned char len)
  43. {
  44.     SPI2_Write(buf,len);
  45. }


  46. /**
  47.  * 功能:通过SPI读芯片数据
  48.  * 入口参数:len -> 数据长度
  49.  * 出口参数:    buf -> 数据缓冲区
  50.  *
  51.  */
  52. void ADE_SPIRead(unsigned char *buf, unsigned char len)
  53. {
  54.     SPI2_Read(buf,len);
  55. }

  56. /**
  57.  * 功能:7758写数据函数
  58.  * 入口参数:
  59.  * type:目标寄存器的地址
  60.  * wdata:写进寄存器的内容
  61.  * databit:目标寄存器的宽度
  62.  * 出口参数:NULL
  63.  * 返回值:NULL
  64.  */
  65. void ADE_Write(unsigned char type,unsigned int wdata,unsigned char databit)
  66. {
  67.     unsigned char data[4];

  68.     ADE_CS(0);
  69.     type = type | 0x80;

  70.     data[0] = type;
  71.     ADE_SPIWrite(data, 1);
  72.     ADE_udelay();

  73.     if(databit == 8)
  74.     {
  75.         data[0] = wdata;
  76.         ADE_SPIWrite(data, 1);
  77.     }
  78.     else if(databit == 16)
  79.     {
  80.         data[0] = (wdata&0xff00) >> 8; /*高8位*/
  81.         data[1] = (wdata&0x00ff); /*底8位*/
  82.         ADE_SPIWrite(data, 2);
  83.     }
  84.     else if(databit == 24)
  85.     {
  86.         data[0] = (wdata&0xff0000) >> 16; /*高8位*/
  87.         data[1] = (wdata&0xff00)>>8;
  88.         data[2] = (wdata&0xff);
  89.         ADE_SPIWrite(data, 3);
  90.     }
  91.     else
  92.         printf("ADE write databit Error:%d\n", databit);
  93.     ADE_CS(1);
  94. }

  95. /**
  96.  * 功能:7758读寄存器函数
  97.  * 入口参数:
  98.  *          type:目标寄存器的地址
  99.  * databit:目标寄存器的宽度
  100.  * 出口参数:指定寄存器的内容
  101.  * 返回值:指定寄存器的内容
  102.  */
  103. unsigned int ADE_Read(unsigned char type,unsigned char databit)
  104. {
  105.     unsigned char data[4]={0,0,0,0};
  106.     unsigned int rtdata = 0;

  107.     ADE_CS(0);
  108.     type = type & 0x7F;
  109.     data[0] = type;
  110.     ADE_SPIWrite(data, 1);
  111.     ADE_udelay();

  112.     if(databit == 8)
  113.     {
  114.         ADE_SPIRead(data,1);
  115.         rtdata = data[0];
  116.     }
  117.     else if(databit == 12)
  118.     {
  119.         ADE_SPIRead(data,2);
  120.         rtdata = (data[0]&0x0f) << 8;
  121.         rtdata += data[1];
  122.     }
  123.     else if(databit == 16)
  124.     {
  125.         ADE_SPIRead(data,2);
  126.         rtdata = data[0] << 8;
  127.         rtdata += data[1];
  128.     }else if(databit == 24)
  129.     {
  130.         ADE_SPIRead(data,3);
  131.         rtdata = data[0] << 16;
  132.         rtdata += (data[1] << 8);
  133.         rtdata += data[2];
  134.     }
  135.     else
  136.         printf("ADE Read databit Error:%d\n", databit);
  137.     ADE_CS(1);
  138.     return(rtdata);
  139. }


  140. /**
  141.  * 功能:检测异常
  142.  */
  143. void ADE_AuCheck(void)
  144. {
  145.     unsigned char i;
  146.     unsigned int temp_data[5];//存放运算过程的中间变量
  147.     unsigned int temp_v,temp_i;

  148.     //自动检测ADE7758是否出现异常
  149.     if( working.voltage[ 0 ] > ERR_VOLTAGE ||
  150.             working.voltage[ 1 ] > ERR_VOLTAGE ||
  151.             working.voltage[ 2 ] > ERR_VOLTAGE )
  152.     {
  153.         //        ADE_Check7758();
  154.         printf("ADE Error\n" );
  155.     }

  156.     //自动设置分频器的大小
  157.     for( i = 0; i < 3 ; i++)
  158.     {
  159.         temp_v = working.voltage[ i ];
  160.         temp_i = working.current[ i ];
  161.         temp_data[i] = ( ( temp_v * temp_i ) / DIVI_VALUE ) & 0x000000ff;
  162.     }

  163.     temp_data[3] = ( temp_data[0] > temp_data[1] )?
  164.             ( ( temp_data[0] > temp_data[2] )? temp_data[0] : temp_data[2] ) :
  165.             ( ( temp_data[1] > temp_data[2] )? temp_data[1] : temp_data[2] ) ;

  166.     if( divider != (char)temp_data[3] )
  167.     {
  168.         //write to ade7758
  169.         divider = (char)temp_data[3] + 1;

  170.         for(i = 0; i < 3; i++)
  171.             ADE_Write( ADD_WDIV + i, ( (int) divider << 8 ), 8 );
  172.     }
  173. }

  174. /**
  175.  * 功能:每秒读取功率
  176.  */
  177. void ADE_ReadHR(void)
  178. {
  179.     unsigned char i;
  180.     unsigned int temp_data[9];//存放运算过程的中间变量

  181.     //有功
  182.     temp_data[ADD_AWATTHR - 1 ] = ADE_Read(ADD_AWATTHR,16);
  183.     temp_data[ADD_BWATTHR - 1 ] = ADE_Read(ADD_BWATTHR,16);
  184.     temp_data[ADD_CWATTHR - 1 ] = ADE_Read(ADD_CWATTHR,16);
  185.     //无功
  186.     temp_data[ADD_AVARHR - 1 ] = ADE_Read(ADD_AVARHR,16);
  187.     temp_data[ADD_BVARHR - 1 ] = ADE_Read(ADD_BVARHR,16);
  188.     temp_data[ADD_CVARHR - 1 ] = ADE_Read(ADD_CVARHR,16);
  189.     //视在
  190.     temp_data[ADD_AVAHR - 1 ] = ADE_Read(ADD_AVAHR,16);
  191.     temp_data[ADD_BVAHR - 1 ] = ADE_Read(ADD_BVAHR,16);
  192.     temp_data[ADD_CVAHR - 1 ] = ADE_Read(ADD_CVAHR,16);

  193.     for( i = 0; i < 9 ; i++)
  194.     {
  195.         if( temp_data[ i ] > 0x7fff )
  196.             temp_data[ i ] = 0xffff - temp_data[ i ] + 1;
  197.     }

  198.     if( divider > 1)
  199.     {
  200.         for( i = 0; i < 9; i++)
  201.             temp_data[ i ] = temp_data[ i ] * divider;//乘上分频器的值
  202.     }

  203.     //能量的计算
  204.     for( i = 0; i < 9; i++)
  205.         energy[i] += temp_data[i];//累加电能值,单位为 WS(瓦秒)

  206.     //转换成千瓦时
  207.     for( i = 0; i < 3; i++)
  208.     {
  209.         working.watt_hour[i] += (energy[i] / 3600000);//转换成千瓦时
  210.         energy[i] = energy[i] % 3600000;
  211.     }

  212.     working.watt_hour[3] = working.watt_hour[0] + working.watt_hour[1] + working.watt_hour[2];//总和

  213.     //转换成千伏安时
  214.     for( i = 0; i < 3; i++)
  215.     {
  216.         working.va_hour[i] += (energy[ i+6 ] / 3600000);//转换成千瓦时
  217.         energy[ i+6 ] = energy[i+6] % 3600000;
  218.     }

  219.     working.va_hour[3] = working.va_hour[0] + working.va_hour[1] + working.va_hour[2];//总和

  220.     for( working.watt[ 3 ] = 0, i = 0; i < 3; i++ )
  221.     {
  222.         working.watt[ i ] = temp_data[ i ]/1000;//千瓦
  223.         working.watt[ 3 ] += working.watt[ i ];
  224.     }

  225.     for( working.var[ 3 ] = 0, i = 0; i < 3; i++ )
  226.     {
  227.         working.var[ i ] = temp_data[ i +3 ]/1000;
  228.         working.var[ 3 ] += working.var[ i ];
  229.     }

  230.     for( working.va[ 3 ] = 0, i = 0; i < 3; i++ )
  231.     {
  232.         working.va[ i ] = temp_data[ i + 6 ] /1000;//千伏安

  233.         if(working.va[ i ] < working.watt[ i ])
  234.             working.va[ i ] = working.watt[ i ];

  235.         working.va[ 3 ] += working.va[ i ];
  236.     }


  237. }

  238. /**
  239.  * 功能:实时读取电流电压值
  240.  */
  241. void ADE_ReadVC(void)
  242. {
  243.     unsigned char i, j;

  244.     for( i = 0; i < 3; i++)
  245.     {
  246.         working.voltage[ i ] = 0;
  247.         working.current[ i ] = 0;
  248.     }

  249.     for( i = 0; i < 3; i++)
  250.     {
  251.         for( j = 0; j < 5; j++)
  252.         {
  253.             working.voltage[ i ] += vo_buffer[j][i];
  254.             working.current[ i ] += io_buffer[j][i];
  255.         }
  256.     }

  257.     for( i = 0; i < 3; i++)
  258.     {
  259.         working.voltage[ i ] = working.voltage[ i ]/5;
  260.         working.current[ i ] = working.current[ i ]/5;
  261.     }

  262.     //电压电流的三相平均值
  263.     working.voltage[ 3 ] = (working.voltage[ 0 ] + working.voltage[ 1 ] + working.voltage[ 2 ] ) / 3;
  264.     working.current[ 3 ] = (working.current[ 0 ] + working.current[ 1 ] + working.current[ 2 ] ) / 3;

  265.     printf("voltage=%x current=%x\n",working.voltage[ 0 ], working.current[ 0 ]);
  266. }


  267. /**
  268.  * 功能:从ADE7758中取出三相电压电流功率等电参量
  269.  */
  270. void ADE_Update(void)
  271. {
  272.     static unsigned char sample_cycle = 0; //电压采样周期,5次取平均
  273.     static unsigned char bit_3s=0;
  274.     unsigned char j;

  275.     if( !bWorkModel )    //正常工作模式
  276.     {
  277.         if( bit_1s )
  278.         {
  279.             bit_1s = 0;
  280.             ADE_ReadHR();

  281.             if( (bit_3s++) >= 3 ) /*三秒检测一次异常*/
  282.             {
  283.                 //                ADE_AuCheck();
  284.                 bit_3s=0;
  285.             }
  286.         }

  287.         for( j = 0; j < 3; j++)
  288.         {
  289.             vo_buffer[ sample_cycle ][j] = ADE_Read( ADD_AVRMS + j, 24 ) /*>> 12*/;//voltage
  290.             io_buffer[ sample_cycle ][j] = ADE_Read( ADD_AIRMS + j, 24 ) /*>> 13*/;//current
  291.         }

  292.         if( sample_cycle == 4) /*读取5次取平均值*/
  293.             ADE_ReadVC();
  294.     }

  295.     if( sample_cycle < 4 )
  296.         sample_cycle += 1;
  297.     else
  298.         sample_cycle = 0;

  299. }

  300. /**
  301.  * 测试硬件连接是否正确
  302.  */
  303. u8 ADE_TestHard(void)
  304. {
  305.     unsigned int rdata, wdata=0xaa5577;//AEHF=1,VAEHF=1,低8位无用
  306.     u8 ret=0;

  307.     ADE_Write(ADD_MASK,wdata,24);
  308.     rdata = ADE_Read(ADD_MASK,24); // 验证通讯是否有问题

  309.     if(rdata != wdata)
  310.         printf("ADE error\r\n");
  311.     else
  312.     {
  313.         ret = 1;
  314.         printf("ADE OK\r\n");
  315.     }

  316.     return ret;
  317. }

  318. /**
  319.  * 功能:7758初始化函数
  320.  */
  321. void ADE_Init(void)
  322. {
  323.     GPIO_InitTypeDef GPIO_InitStructure;

  324.     RCC_APB2PeriphClockCmd(ADE_RCC, ENABLE);
  325.     GPIO_InitStructure.GPIO_Pin =ADE_PIN;
  326.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
  327.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
  328.     GPIO_Init(ADE_GPIO, &GPIO_InitStructure);
  329.     ADE_CS(1);

  330.     if(ADE_TestHard())
  331.     {
  332.         ADE_Write(ADD_OPMODE, 0x44,8); //软件复位
  333.         ADE_udelay(); //添加延时 确保复位成功
  334.     }
  335. }



  336. void ADE_thread_entry(void)
  337. {
  338.     SPI2_Init();
  339.     ADE_Init();

  340.     while(1)
  341.     {
  342.         ADE_Update();
  343.         delay_ms( 50 ); /* 等待,让出cpu权限,切换到其他线程 */
  344.     }
  345. }
STM32_ADE7758驱动.rar
阅读(6971) | 评论(0) | 转发(3) |
0

上一篇:ADE7758驱动程序

下一篇:Linux C 邮件发送

给主人留下些什么吧!~~