- /*
- * ade7758.c
- *
- * Created on: October 11, 2014
- * Author: Lzy
- */
- //#include
- #include "ade7758.h"
- #include "sys.h"
- #define ADE_CS_PIN PBout(12)
- #define ADE_RCC RCC_APB2Periph_GPIOB
- #define ADE_GPIO GPIOB
- #define ADE_PIN (GPIO_Pin_12)
- unsigned char bWorkModel=0; //Working mode flag 1: calibration mode; 0: normal working mode;
- unsigned char bit_1s=0; //1s clock flag, set in the clock interrupt function
- 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
- static unsigned int energy[9]; // used to accumulate energy value 36
- struct all_data working; //Electrical parameters stored in normal working mode 95
- static unsigned int vo_buffer[5][3]; //Integral filter for voltage 36
- static unsigned int io_buffer[5][3]; //Integral filter for current 36
- /**
- * Function: Chip select enable
- */
- void ADE_CS(unsigned char cs)
- {
- ADE_CS_PIN = cs;
- delay_ms(1);
- }
- /**
- * Function: Delay function 50us
- */
- void ADE_udelay(void)
- {
- delay_ms(1);
- }
- /**
- * Function: Write data to the chip via SPI
- * Entry parameters:
- * buf -> data buffer
- * len -> data length
- */
- void ADE_SPIWrite(unsigned char *buf, unsigned char len)
- {
- SPI2_Write(buf,len);
- }
- /**
- * Function: Read chip data via SPI
- * Input parameter: len -> data length
- * Output parameters: buf -> data buffer
- *
- */
- void ADE_SPIRead(unsigned char *buf, unsigned char len)
- {
- SPI2_Read(buf,len);
- }
- /**
- * Function: 7758 write data function
- * Entry parameters:
- * type: the address of the target register
- * wdata: content written into the register
- * databit: width of the target register
- * Exit parameter: NULL
- * Return value: NULL
- */
- void ADE_Write(unsigned char type,unsigned int wdata,unsigned char databit)
- {
- unsigned char data[4];
- ADE_CS(0);
- type = type | 0x80;
- data[0] = type;
- ADE_SPIWrite(data, 1);
- ADE_udelay();
- if(databit == 8)
- {
- data[0] = wdata;
- ADE_SPIWrite(data, 1);
- }
- else if(databit == 16)
- {
- data[0] = (wdata&0xff00) >> 8; /*high 8 bits*/
- data[1] = (wdata&0x00ff); /*bottom 8 bits*/
- ADE_SPIWrite(data, 2);
- }
- else if(databit == 24)
- {
- data[0] = (wdata&0xff0000) >> 16; /*high 8 bits*/
- data[1] = (wdata&0xff00)>>8;
- data[2] = (wdata&0xff);
- ADE_SPIWrite(data, 3);
- }
- else
- printf("ADE write databit Error:%d\n", databit);
- ADE_CS(1);
- }
- /**
- * Function: 7758 read register function
- * Entry parameters:
- * type: the address of the target register
- * databit: width of the target register
- * Export parameter: specifies the contents of the register
- * Return value: the contents of the specified register
- */
- unsigned int ADE_Read(unsigned char type,unsigned char databit)
- {
- unsigned char data[4]={0,0,0,0};
- unsigned int rtdata = 0;
- ADE_CS(0);
- type = type & 0x7F;
- data[0] = type;
- ADE_SPIWrite(data, 1);
- ADE_udelay();
- if(databit == 8)
- {
- ADE_SPIRead(data,1);
- rtdata = data[0];
- }
- else if(databit == 12)
- {
- ADE_SPIRead(data,2);
- rtdata = (data[0]&0x0f) << 8;
- rtdata += data[1];
- }
- else if(databit == 16)
- {
- ADE_SPIRead(data,2);
- rtdata = data[0] << 8;
- rtdata += data[1];
- }else if(databit == 24)
- {
- ADE_SPIRead(data,3);
- rtdata = data[0] << 16;
- rtdata += (data[1] << 8);
- rtdata += data[2];
- }
- else
- printf("ADE Read databit Error:%d\n", databit);
- ADE_CS(1);
- return(rtdata);
- }
- /**
- * Function: Detect anomalies
- */
- void ADE_AuCheck(void)
- {
- unsigned char i;
- unsigned int temp_data[5]; //Store intermediate variables in the calculation process
- unsigned int temp_v,temp_i;
- //Automatically detect whether ADE7758 has any abnormality
- if( working.voltage[ 0 ] > ERR_VOLTAGE ||
- working.voltage[ 1 ] > ERR_VOLTAGE ||
- working.voltage[ 2 ] > ERR_VOLTAGE )
- {
- // ADE_Check7758();
- printf("ADE Error\n" );
- }
- //Automatically set the size of the divider
- for( i = 0; i < 3 ; i++)
- {
- temp_v = working.voltage[ i ];
- temp_i = working.current[ i ];
- temp_data[i] = ( ( temp_v * temp_i ) / DIVI_VALUE ) & 0x000000ff;
- }
- temp_data[3] = ( temp_data[0] > temp_data[1] )?
- ( ( temp_data[0] > temp_data[2] )? temp_data[0] : temp_data[2] ) :
- ( ( temp_data[1] > temp_data[2] )? temp_data[1] : temp_data[2] ) ;
- if( divider != (char)temp_data[3] )
- {
- //write to ade7758
- divider = (char)temp_data[3] + 1;
- for(i = 0; i < 3; i++)
- ADE_Write( ADD_WDIV + i, ( (int) divider << 8 ), 8 );
- }
- }
- /**
- * Function: Read power every second
- */
- void ADE_ReadHR(void)
- {
- unsigned char i;
- unsigned int temp_data[9]; //Store intermediate variables in the calculation process
- //Workful
- temp_data[ADD_AWATTHR - 1 ] = ADE_Read(ADD_AWATTHR,16);
- temp_data[ADD_BWATTHR - 1 ] = ADE_Read(ADD_BWATTHR,16);
- temp_data[ADD_CWATTHR - 1 ] = ADE_Read(ADD_CWATTHR,16);
- //No use
- temp_data[ADD_AVARHR - 1 ] = ADE_Read(ADD_AVARHR,16);
- temp_data[ADD_BVARHR - 1 ] = ADE_Read(ADD_BVARHR,16);
- temp_data[ADD_CVARHR - 1 ] = ADE_Read(ADD_CVARHR,16);
- //Apparently
- temp_data[ADD_AVAHR - 1 ] = ADE_Read(ADD_AVAHR,16);
- temp_data[ADD_BVAHR - 1 ] = ADE_Read(ADD_BVAHR,16);
- temp_data[ADD_CVAHR - 1 ] = ADE_Read(ADD_CVAHR,16);
- for( i = 0; i < 9 ; i++)
- {
- if( temp_data[ i ] > 0x7fff )
- temp_data[ i ] = 0xffff - temp_data[ i ] + 1;
- }
- if( divider > 1)
- {
- for( i = 0; i < 9; i++)
- temp_data[ i ] = temp_data[ i ] * divider; //Multiply by the value of the divider
- }
- //Energy calculation
- for( i = 0; i < 9; i++)
- energy[i] += temp_data[i]; //Accumulate the energy value in WS (watt-seconds)
- //Convert to kWh
- for( i = 0; i < 3; i++)
- {
- working.watt_hour[i] += (energy[i] / 3600000); //Convert to kilowatt-hour
- energy[i] = energy[i] % 3600000;
- }
- working.watt_hour[3] = working.watt_hour[0] + working.watt_hour[1] + working.watt_hour[2];//总和
- //Convert to kVAh
- for( i = 0; i < 3; i++)
- {
- working.va_hour[i] += (energy[ i+6 ] / 3600000); //Convert to kilowatt-hour
- energy[ i+6 ] = energy[i+6] % 3600000;
- }
- working.va_hour[3] = working.va_hour[0] + working.va_hour[1] + working.va_hour[2];//总和
- for( working.watt[ 3 ] = 0, i = 0; i < 3; i++ )
- {
- working.watt[ i ] = temp_data[ i ]/1000;//千瓦
- working.watt[ 3 ] += working.watt[ i ];
- }
- for( working.var[ 3 ] = 0, i = 0; i < 3; i++ )
- {
- working.var[ i ] = temp_data[ i +3 ]/1000;
- working.var[ 3 ] += working.var[ i ];
- }
- for( working.va[ 3 ] = 0, i = 0; i < 3; i++ )
- {
- working.va[ i ] = temp_data[ i + 6 ] /1000; // kilovolt-ampere
- if(working.va[ i ] < working.watt[ i ])
- working.va[ i ] = working.watt[ i ];
- working.va[ 3 ] += working.va[ i ];
- }
- }
- /**
- * Function: Read current and voltage values in real time
- */
- void ADE_ReadVC(void)
- {
- unsigned char i, j;
- for( i = 0; i < 3; i++)
- {
- working.voltage[ i ] = 0;
- working.current[ i ] = 0;
- }
- for( i = 0; i < 3; i++)
- {
- for( j = 0; j < 5; j++)
- {
- working.voltage[ i ] += vo_buffer[j][i];
- working.current[ i ] += io_buffer[j][i];
- }
- }
- for( i = 0; i < 3; i++)
- {
- working.voltage[ i ] = working.voltage[ i ]/5;
- working.current[ i ] = working.current[ i ]/5;
- }
- //Three-phase average value of voltage and current
- working.voltage[ 3 ] = (working.voltage[ 0 ] + working.voltage[ 1 ] + working.voltage[ 2 ] ) / 3;
- working.current[ 3 ] = (working.current[ 0 ] + working.current[ 1 ] + working.current[ 2 ] ) / 3;
- printf("voltage=%x current=%x\n",working.voltage[ 0 ], working.current[ 0 ]);
- }
- /**
- * Function: Extract three-phase voltage, current, power and other electrical parameters from ADE7758
- */
- void ADE_Update(void)
- {
- static unsigned char sample_cycle = 0; //voltage sampling cycle, 5 times average
- static unsigned char bit_3s=0;
- unsigned char j;
- if( !bWorkModel ) // Normal working mode
- {
- if( bit_1s )
- {
- bit_1s = 0;
- ADE_ReadHR();
- if( (bit_3s++) >= 3 ) /*Detect an exception every three seconds*/
- {
- // ADE_AuCheck();
- bit_3s=0;
- }
- }
- for( j = 0; j < 3; j++)
- {
- vo_buffer[ sample_cycle ][j] = ADE_Read( ADD_AVRMS + j, 24 ) /*>> 12*/;//voltage
- io_buffer[ sample_cycle ][j] = ADE_Read( ADD_AIRMS + j, 24 ) /*>> 13*/;//current
- }
- if( sample_cycle == 4) /*Read 5 times and take the average value*/
- ADE_ReadVC();
- }
- if( sample_cycle < 4 )
- sample_cycle += 1;
- else
- sample_cycle = 0;
- }
- /**
- * Test whether the hardware connection is correct
- */
- u8 ADE_TestHard(void)
- {
- unsigned int rdata, wdata=0xaa5577; //AEHF=1,VAEHF=1, the lower 8 bits are useless
- u8 right=0;
- ADE_Write(ADD_MASK,wdata,24);
- rdata = ADE_Read(ADD_MASK,24); // Verify if there is any problem with communication
- if(rdata != wdata)
- printf("ADE error\r\n");
- else
- {
- right = 1;
- printf("ADE OK\r\n");
- }
- return right;
- }
- /**
- * Function: 7758 initialization function
- */
- void ADE_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(ADE_RCC, ENABLE);
- GPIO_InitStructure.GPIO_Pin =ADE_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //Push-pull output
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO port speed is 50MHz
- GPIO_Init(ADE_GPIO, &GPIO_InitStructure);
- ADE_CS(1);
- if(ADE_TestHard())
- {
- ADE_Write(ADD_OPMODE, 0x44,8); //Software reset
- ADE_udelay(); //Add delay to ensure reset success
- }
- }
- void ADE_thread_entry(void)
- {
- SPI2_Init();
- ADE_Heat();
- while(1)
- {
- ADE_Update();
- delay_ms( 50 ); /* Wait, give up CPU privileges, switch to other threads */
- }
- }
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]
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 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]
- Popular Resources
- Popular amplifiers
Latest Microcontroller Articles
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
MoreDaily News
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
Guess you like
- Playing with Zynq Serial 23 - Creation and packaging of user-defined IP cores
- [NXP Rapid IoT Review] Why can't data be updated to the screen?
- Antenna classification and selection
- Should I choose a single-ended or differential probe? .
- What is the function of R109 when this transistor is used as a switching tube?
- 2018 TI IoT Competition Development Board Application Approved List
- Qorvo to Acquire Active-Semi International
- DGUS implements Schneider PLC hardware and software connection guide
- German electrician VS Indian electrician, one has obsessive-compulsive disorder, the other drives the obsessive-compulsive disorder to death
- Analysis and Research on GSM Mobile Phone RF System (V)