STM32_ADE7758 driver

Publisher:数字驿站Latest update time:2016-07-30 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
  1. /*
  2.  * ade7758.c
  3.  *
  4.  * Created on: October 11, 2014
  5.  * Author: Lzy
  6.  */
  7. //#include 
  8. #include "ade7758.h"
  9. #include "sys.h"
  10.  
  11. #define ADE_CS_PIN     PBout(12)
  12.  
  13. #define ADE_RCC RCC_APB2Periph_GPIOB
  14. #define ADE_GPIO GPIOB
  15. #define ADE_PIN (GPIO_Pin_12)
  16.  
  17.  
  18. unsigned char bWorkModel=0; //Working mode flag 1: calibration mode; 0: normal working mode;
  19. unsigned char bit_1s=0; //1s clock flag, set in the clock interrupt function
  20.  
  21. static unsigned char divider = 1; //Energy divider, the default value is zero, when the apparent power exceeds a certain value, the value is automatically increased
  22. static unsigned int energy[9]; // used to accumulate energy value 36
  23.  
  24. struct all_data working; //Electrical parameters stored in normal working mode 95
  25. static unsigned int vo_buffer[5][3]; //Integral filter for voltage 36
  26. static unsigned int io_buffer[5][3]; //Integral filter for current 36
  27.  
  28.  
  29. /**
  30.  * Function: Chip select enable
  31.  */
  32. void ADE_CS(unsigned char cs)
  33. {
  34.     ADE_CS_PIN = cs;
  35.     delay_ms(1);
  36. }
  37.  
  38. /**
  39.  * Function: Delay function 50us
  40.  */
  41. void ADE_udelay(void)
  42. {
  43.     delay_ms(1);
  44. }
  45.  
  46. /**
  47.  * Function: Write data to the chip via SPI
  48.  * Entry parameters:
  49.  * buf -> data buffer
  50.  * len -> data length
  51.  */
  52. void ADE_SPIWrite(unsigned char *buf, unsigned char len)
  53. {
  54.     SPI2_Write(buf,len);
  55. }
  56.  
  57.  
  58. /**
  59.  * Function: Read chip data via SPI
  60.  * Input parameter: len -> data length
  61.  * Output parameters: buf -> data buffer
  62.  *
  63.  */
  64. void ADE_SPIRead(unsigned char *buf, unsigned char len)
  65. {
  66.     SPI2_Read(buf,len);
  67. }
  68.  
  69. /**
  70.  * Function: 7758 write data function
  71.  * Entry parameters:
  72.  * type: the address of the target register
  73.  * wdata: content written into the register
  74.  * databit: width of the target register
  75.  * Exit parameter: NULL
  76.  * Return value: NULL
  77.  */
  78. void ADE_Write(unsigned char type,unsigned int wdata,unsigned char databit)
  79. {
  80.     unsigned char data[4];
  81.  
  82.     ADE_CS(0);
  83.     type = type | 0x80;
  84.  
  85.     data[0] = type;
  86.     ADE_SPIWrite(data, 1);
  87.     ADE_udelay();
  88.  
  89.     if(databit == 8)
  90.     {
  91.         data[0] = wdata;
  92.         ADE_SPIWrite(data, 1);
  93.     }
  94.     else if(databit == 16)
  95.     {
  96.         data[0] = (wdata&0xff00) >> 8; /*high 8 bits*/
  97.         data[1] = (wdata&0x00ff); /*bottom 8 bits*/
  98.         ADE_SPIWrite(data, 2);
  99.     }
  100.     else if(databit == 24)
  101.     {
  102.         data[0] = (wdata&0xff0000) >> 16; /*high 8 bits*/
  103.         data[1] = (wdata&0xff00)>>8;
  104.         data[2] = (wdata&0xff);
  105.         ADE_SPIWrite(data, 3);
  106.     }
  107.     else
  108.         printf("ADE write databit Error:%d\n", databit);
  109.     ADE_CS(1);
  110. }
  111.  
  112. /**
  113.  * Function: 7758 read register function
  114.  * Entry parameters:
  115.  * type: the address of the target register
  116.  * databit: width of the target register
  117.  * Export parameter: specifies the contents of the register
  118.  * Return value: the contents of the specified register
  119.  */
  120. unsigned int ADE_Read(unsigned char type,unsigned char databit)
  121. {
  122.     unsigned char data[4]={0,0,0,0};
  123.     unsigned int rtdata = 0;
  124.  
  125.     ADE_CS(0);
  126.     type = type & 0x7F;
  127.     data[0] = type;
  128.     ADE_SPIWrite(data, 1);
  129.     ADE_udelay();
  130.  
  131.     if(databit == 8)
  132.     {
  133.         ADE_SPIRead(data,1);
  134.         rtdata = data[0];
  135.     }
  136.     else if(databit == 12)
  137.     {
  138.         ADE_SPIRead(data,2);
  139.         rtdata = (data[0]&0x0f) << 8;
  140.         rtdata += data[1];
  141.     }
  142.     else if(databit == 16)
  143.     {
  144.         ADE_SPIRead(data,2);
  145.         rtdata = data[0] << 8;
  146.         rtdata += data[1];
  147.     }else if(databit == 24)
  148.     {
  149.         ADE_SPIRead(data,3);
  150.         rtdata = data[0] << 16;
  151.         rtdata += (data[1] << 8);
  152.         rtdata += data[2];
  153.     }
  154.     else
  155.         printf("ADE Read databit Error:%d\n", databit);
  156.     ADE_CS(1);
  157.     return(rtdata);
  158. }
  159.  
  160.  
  161. /**
  162.  * Function: Detect anomalies
  163.  */
  164. void ADE_AuCheck(void)
  165. {
  166.     unsigned char i;
  167.     unsigned int temp_data[5]; //Store intermediate variables in the calculation process
  168.     unsigned int temp_v,temp_i;
  169.  
  170.     //Automatically detect whether ADE7758 has any abnormality
  171.     if( working.voltage[ 0 ] > ERR_VOLTAGE ||
  172.             working.voltage[ 1 ] > ERR_VOLTAGE ||
  173.             working.voltage[ 2 ] > ERR_VOLTAGE )
  174.     {
  175.         //        ADE_Check7758();
  176.         printf("ADE Error\n" );
  177.     }
  178.  
  179.     //Automatically set the size of the divider
  180.     for( i = 0; i < 3 ; i++)
  181.     {
  182.         temp_v = working.voltage[ i ];
  183.         temp_i = working.current[ i ];
  184.         temp_data[i] = ( ( temp_v * temp_i ) / DIVI_VALUE ) & 0x000000ff;
  185.     }
  186.  
  187.     temp_data[3] = ( temp_data[0] > temp_data[1] )?
  188.             ( ( temp_data[0] > temp_data[2] )? temp_data[0] : temp_data[2] ) :
  189.             ( ( temp_data[1] > temp_data[2] )? temp_data[1] : temp_data[2] ) ;
  190.  
  191.     if( divider != (char)temp_data[3] )
  192.     {
  193.         //write to ade7758
  194.         divider = (char)temp_data[3] + 1;
  195.  
  196.         for(i = 0; i < 3; i++)
  197.             ADE_Write( ADD_WDIV + i, ( (int) divider << 8 ), 8 );
  198.     }
  199. }
  200.  
  201. /**
  202.  * Function: Read power every second
  203.  */
  204. void ADE_ReadHR(void)
  205. {
  206.     unsigned char i;
  207.     unsigned int temp_data[9]; //Store intermediate variables in the calculation process
  208.  
  209.     //Workful
  210.     temp_data[ADD_AWATTHR - 1 ] = ADE_Read(ADD_AWATTHR,16);
  211.     temp_data[ADD_BWATTHR - 1 ] = ADE_Read(ADD_BWATTHR,16);
  212.     temp_data[ADD_CWATTHR - 1 ] = ADE_Read(ADD_CWATTHR,16);
  213.     //No use
  214.     temp_data[ADD_AVARHR - 1 ] = ADE_Read(ADD_AVARHR,16);
  215.     temp_data[ADD_BVARHR - 1 ] = ADE_Read(ADD_BVARHR,16);
  216.     temp_data[ADD_CVARHR - 1 ] = ADE_Read(ADD_CVARHR,16);
  217.     //Apparently
  218.     temp_data[ADD_AVAHR - 1 ] = ADE_Read(ADD_AVAHR,16);
  219.     temp_data[ADD_BVAHR - 1 ] = ADE_Read(ADD_BVAHR,16);
  220.     temp_data[ADD_CVAHR - 1 ] = ADE_Read(ADD_CVAHR,16);
  221.  
  222.     for( i = 0; i < 9 ; i++)
  223.     {
  224.         if( temp_data[ i ] > 0x7fff )
  225.             temp_data[ i ] = 0xffff - temp_data[ i ] + 1;
  226.     }
  227.  
  228.     if( divider > 1)
  229.     {
  230.         for( i = 0; i < 9; i++)
  231.             temp_data[ i ] = temp_data[ i ] * divider; //Multiply by the value of the divider
  232.     }
  233.  
  234.     //Energy calculation
  235.     for( i = 0; i < 9; i++)
  236.         energy[i] += temp_data[i]; //Accumulate the energy value in WS (watt-seconds)
  237.  
  238.     //Convert to kWh
  239.     for( i = 0; i < 3; i++)
  240.     {
  241.         working.watt_hour[i] += (energy[i] / 3600000); //Convert to kilowatt-hour
  242.         energy[i] = energy[i] % 3600000;
  243.     }
  244.  
  245.     working.watt_hour[3] = working.watt_hour[0] + working.watt_hour[1] + working.watt_hour[2];//总和
  246.  
  247.     //Convert to kVAh
  248.     for( i = 0; i < 3; i++)
  249.     {
  250.         working.va_hour[i] += (energy[ i+6 ] / 3600000); //Convert to kilowatt-hour
  251.         energy[ i+6 ] = energy[i+6] % 3600000;
  252.     }
  253.  
  254.     working.va_hour[3] = working.va_hour[0] + working.va_hour[1] + working.va_hour[2];//总和
  255.  
  256.     for( working.watt[ 3 ] = 0, i = 0; i < 3; i++ )
  257.     {
  258.         working.watt[ i ] = temp_data[ i ]/1000;//千瓦
  259.         working.watt[ 3 ] += working.watt[ i ];
  260.     }
  261.  
  262.     for( working.var[ 3 ] = 0, i = 0; i < 3; i++ )
  263.     {
  264.         working.var[ i ] = temp_data[ i +3 ]/1000;
  265.         working.var[ 3 ] += working.var[ i ];
  266.     }
  267.  
  268.     for( working.va[ 3 ] = 0, i = 0; i < 3; i++ )
  269.     {
  270.         working.va[ i ] = temp_data[ i + 6 ] /1000; // kilovolt-ampere
  271.  
  272.         if(working.va[ i ] < working.watt[ i ])
  273.             working.va[ i ] = working.watt[ i ];
  274.  
  275.         working.va[ 3 ] += working.va[ i ];
  276.     }
  277.  
  278.  
  279. }
  280.  
  281. /**
  282.  * Function: Read current and voltage values ​​in real time
  283.  */
  284. void ADE_ReadVC(void)
  285. {
  286.     unsigned char i, j;
  287.  
  288.     for( i = 0; i < 3; i++)
  289.     {
  290.         working.voltage[ i ] = 0;
  291.         working.current[ i ] = 0;
  292.     }
  293.  
  294.     for( i = 0; i < 3; i++)
  295.     {
  296.         for( j = 0; j < 5; j++)
  297.         {
  298.             working.voltage[ i ] += vo_buffer[j][i];
  299.             working.current[ i ] += io_buffer[j][i];
  300.         }
  301.     }
  302.  
  303.     for( i = 0; i < 3; i++)
  304.     {
  305.         working.voltage[ i ] = working.voltage[ i ]/5;
  306.         working.current[ i ] = working.current[ i ]/5;
  307.     }
  308.  
  309.     //Three-phase average value of voltage and current
  310.     working.voltage[ 3 ] = (working.voltage[ 0 ] + working.voltage[ 1 ] + working.voltage[ 2 ] ) / 3;
  311.     working.current[ 3 ] = (working.current[ 0 ] + working.current[ 1 ] + working.current[ 2 ] ) / 3;
  312.  
  313.     printf("voltage=%x current=%x\n",working.voltage[ 0 ], working.current[ 0 ]);
  314. }
  315.  
  316.  
  317. /**
  318.  * Function: Extract three-phase voltage, current, power and other electrical parameters from ADE7758
  319.  */
  320. void ADE_Update(void)
  321. {
  322.     static unsigned char sample_cycle = 0; //voltage sampling cycle, 5 times average
  323.     static unsigned char bit_3s=0;
  324.     unsigned char j;
  325.  
  326.     if( !bWorkModel ) // Normal working mode
  327.     {
  328.         if( bit_1s )
  329.         {
  330.             bit_1s = 0;
  331.             ADE_ReadHR();
  332.  
  333.             if( (bit_3s++) >= 3 ) /*Detect an exception every three seconds*/
  334.             {
  335.                 //                ADE_AuCheck();
  336.                 bit_3s=0;
  337.             }
  338.         }
  339.  
  340.         for( j = 0; j < 3; j++)
  341.         {
  342.             vo_buffer[ sample_cycle ][j] = ADE_Read( ADD_AVRMS + j, 24 ) /*>> 12*/;//voltage
  343.             io_buffer[ sample_cycle ][j] = ADE_Read( ADD_AIRMS + j, 24 ) /*>> 13*/;//current
  344.         }
  345.  
  346.         if( sample_cycle == 4) /*Read 5 times and take the average value*/
  347.             ADE_ReadVC();
  348.     }
  349.  
  350.     if( sample_cycle < 4 )
  351.         sample_cycle += 1;
  352.     else
  353.         sample_cycle = 0;
  354.  
  355. }
  356.  
  357. /**
  358.  * Test whether the hardware connection is correct
  359.  */
  360. u8 ADE_TestHard(void)
  361. {
  362.     unsigned int rdata, wdata=0xaa5577; //AEHF=1,VAEHF=1, the lower 8 bits are useless
  363.     u8 right=0;
  364.  
  365.     ADE_Write(ADD_MASK,wdata,24);
  366.     rdata = ADE_Read(ADD_MASK,24); // Verify if there is any problem with communication
  367.  
  368.     if(rdata != wdata)
  369.         printf("ADE error\r\n");
  370.     else
  371.     {
  372.         right = 1;
  373.         printf("ADE OK\r\n");
  374.     }
  375.  
  376.     return right;
  377. }
  378.  
  379. /**
  380.  * Function: 7758 initialization function
  381.  */
  382. void ADE_Init(void)
  383. {
  384.     GPIO_InitTypeDef GPIO_InitStructure;
  385.  
  386.     RCC_APB2PeriphClockCmd(ADE_RCC, ENABLE);
  387.     GPIO_InitStructure.GPIO_Pin =ADE_PIN;
  388.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //Push-pull output
  389.     GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz; //IO port speed is 50MHz
  390.     GPIO_Init(ADE_GPIO, &GPIO_InitStructure);
  391.     ADE_CS(1);
  392.  
  393.     if(ADE_TestHard())
  394.     {
  395.         ADE_Write(ADD_OPMODE, 0x44,8); //Software reset
  396.         ADE_udelay(); //Add delay to ensure reset success
  397.     }
  398. }
  399.  
  400.  
  401.  
  402. void ADE_thread_entry(void)
  403. {
  404.     SPI2_Init();
  405.     ADE_Heat();
  406.  
  407.     while(1)
  408.     {
  409.         ADE_Update();
  410.         delay_ms( 50 ); /* Wait, give up CPU privileges, switch to other threads */
  411.     }
  412. }
Keywords:STM32 Reference address:STM32_ADE7758 driver

Previous article:STM32 View System Clock
Next article:STM32 External SRAM

Recommended ReadingLatest update time:2024-11-23 13:49

STM32 IO port initialization process
First initialize the clock APB2 1. Configure input/output mode and pin speed (GPIOx_CRL or GPIOx_CRH) 2. Read or write IO port data     2.1 Read IO port data (GPIOx_IDR)     2.2 Write IO port data (GPIOx_ODR, GPIOx_BSRR, GPIOx_BRR)      3. Lock the IO port data until the next reset (GPIOx_LCKR)
[Microcontroller]
Summary of the advantages of STM32 over 51 microcontrollers
STM32  8051 Core Cortex-M3, 32Bit@72MHz 51 Core, 8Bit@2MHz Max (after frequency division) 1.25DMIPS 0.06DMIPS Address space 4GB 64KB On-chip memory ROM: 20K-1MB 2K-64K RAM:8K-256K 128B-1K Peripherals AD, DA, Timer, WWDG, IWDG, three timers and one serial port CRC, DMA, IIC, SPI, USART, etc. Development
[Microcontroller]
stm32 RTC_WaitForSynchro() dead loop
1.RTC_WaitForSynchro() dead loop, found that RTC_Configuration() was not executed, added function, but don't know what effect it will have on the clock accuracy later /******************************************************************************* * Function Name  : RTC_Configuration * Description    : Configures t
[Microcontroller]
STM32 file system fatfs transplantation notes detailed explanation
1. Introduction to memory and Flash The flash address of stm32 starts at 0x0800 0000 and ends at 0x0800 0000 plus the actual flash size of the chip. The flash size of different chips is different. The RAM start address is 0x2000 0000, and the end address is 0x2000 0000 plus the RAM size of the chip. The RAM of dif
[Microcontroller]
STM32 file system fatfs transplantation notes detailed explanation
How to get its own ID number in stm32
1. Function. void STM32_GetChipID(unsigned int *cID) {     cID =*(vu32*)(0x1ffff7e8);     cID =*(vu32*)(0x1ffff7ec);     cID =*(vu32*)(0x1ffff7f0); } 2. You can print it out using the serial port. Printf( "\r\nChip ID: %d, %d, %d\r\n", cID , cID , cID );
[Microcontroller]
stm32 clock related
I quoted some content from another blogger based on the original .    The clock system is the core of the processor, so before learning all the peripherals of STM32, it is necessary to carefully study the clock system, which helps to have a deep understanding of STM32.  The following is an STM32 clock block diagram
[Microcontroller]
stm32 clock related
STM32 Flash erase, read and write successfully
Reference: http://download.csdn.net/detail/my_friend_ship/4166970 Key points: Before writing data into the flash, you must erase it each time, otherwise the writing will fail and the error status will be: FLASH_Status=FLASH_ERROR_PG After writing the data successfully, you can view the data just written in Memory. S
[Microcontroller]
Design of full-color LED display system based on STM32
As a new display device, LED display screen has been widely used in recent years. With the continuous updating of technology, LED display screen is developing towards full color. A LED display screen control system is designed. The system uses the ARMCortex-M3 core chip STM32F103ZET6 as the control center, completes
[Microcontroller]
Design of full-color LED display system based on STM32
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号