本设计是基于STM32与ATT7022E多功能电力监测仪的电路方案设计
程序编译器:keil 5
编程语言:C语言
【腾讯文档】C0016 网盘链接
近年来随着我国国民经济的高速发展,先进嵌入式处理器技术、微电子技术及测控技术也得到了快速发展 ,为了适应新形势的发展和需求,政府对智能电网的不断推进,对电力监测仪的实时性、可靠性、精确性,提出了更高的要求。
传统电力监测仪广泛采用AD+MCU模式,即外部模数A/D转换芯片与8位、 16位单片机进行对三相电网数据进行采集,存在许多的弊端,如芯片功能单一,需要进行外围扩展诸多器件,软件程序算法复杂,测量精度不高等问题。
而以DSP+MCU双CPU模式,很好的解决了复杂数据的处理问题,但存在开发成本过高,且造成MCU资源的一定浪费。
本系统通过采用高性能 32位ARMCortex-M3内核为处理器STM32F103ZE作为主控芯片与多功能高精度的三相电能专用计量芯片ATT7022E ,使系统整体硬件的设计更加简洁,与以往电力监测仪系统处理性能力得到明显提高,同时也降低程序算法复杂度。
原理图(提供PDF):
模块底板原理图(提供PDF):
PCB(提供PDF):
模块底板PCBS(提供PDF):
源程序:
//
///文件:main.c
///说明:
///用途:系统入口函数
///版本:Alpha0.0
//
#include “sys.h”
#include “delay.h”
#include “db_timer.h”
#include “db_init.h”
#include “db_usart.h”
#include “includes.h”
#include “db_amme.h”
#include “ucos_ii.h”
#include “sd_lcd.h”
OS_MEM * ptr;
//u8 ReadAmmeterData_sec; //
u32 CpuID[3];
u32 OldID[3]={0x05DCFF30,0x3132594D,0x51048325};//u32 OldID[3]={0x05D9FF37,0x33325943,0x43228423}
/*******/
//说 明:UCOSII任务函数声明区
//
//SingleBurner:创建UCOSII的启动任务
#define START_TASK_PRIO 30 //开始任务的优先级,最低
#define START_STK_SIZE 128 //开始任务堆栈的长度
OS_STK START_TASK_STK[START_STK_SIZE]; //开始任务堆栈空间
void start_task(void *pdata); //开始任务的声明
//SingleBurner:创建UCOSII的主任务
#define MAIN_TASK_PRIO 6 //主任务的优先级
#define MAIN_STK_SIZE 1024 //主任务堆栈的长度
OS_STK MAIN_TASK_STK[MAIN_STK_SIZE]; //主任务堆栈空间
void main_task(void *pdata); //主任务的声明
//SingleBurner:创建UCOSII的RTC任务
#define RTC_TASK_PRIO 4 //RTC任务的优先级
#define RTC_STK_SIZE 512 //RTC任务堆栈的长度
OS_STK RTC_TASK_STK[RTC_STK_SIZE]; //RTC任务堆栈空间
void rtc_task(void *pdata); //RTC任务的声明
OS_EVENT * sem_rtc; //RTC信号量指针
/****************************/
//函数名:main()
//说 明:主函数
//参 数:系统入口
//返回值:无返回
//
int main(void)
{
SCB->VTOR = FLASH_BASE;
System_Init(); //底层初始化
OSInit(); //UCOSII初始化
OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO); //创建开始任务
OSStart(); //启动UCOSII多任务管理
}
/****************************/
//函数名:start_task()
//说 明:起始函数
//参 数:UCOSII函数入口
//返回值:无返回
//
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=0;
pdata=pdata;
sem_rtc =OSSemCreate(0); //创建一个信号量用于RTC时钟
OSStatInit(); //初始化统计任务
OS_ENTER_CRITICAL(); //进入临界区
OSTaskCreate(main_task,(void *)0,(OS_STK *)&MAIN_TASK_STK[MAIN_STK_SIZE-1],MAIN_TASK_PRIO); //创建主任务
// OSTaskCreate(rtc_task,(void *)0,(OS_STK *)&RTC_TASK_STK[RTC_STK_SIZE-1],RTC_TASK_PRIO); //创建RTC任务
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务
OS_EXIT_CRITICAL(); //退出临界区
}
/****************************/
//函数名:main_task()
//说 明:UCOSII主函数,处理杂事
//参 数:无参数
//返回值:无返回
//
void main_task(void *pdata)
{
while(1)
{
DisposeKey(); //读取按键
key_scan(); //按键扫描处理
if(TimingMark == 10) //500ms定时标志位
{
TimingMark=0;
ReadAmmeterData(); //读取内部电表数据
UpdateLcdMark = 1;
}
if(UpdateLcdMark == 1) //判断是否要更新数据
{
clear_screen(); //清屏
Display_lcd(); //更新显示数据
UpdateLcdMark = 0;
}
}
}
/****************************/
//函数名:rtc_task()
//说 明:UCOSII的RTC任务,处理时间
//参 数:无参数
//返回值:无返回
//
void rtc_task(void *pdata)
{
u8 err;
while(1)
{
OSSemPend(sem_rtc,0,&err); //请求信号量
delay_ms(20); //延迟一下
}
}
/****************************/
//函数名:RTC_IRQHandler()
//说 明:RTC中断服务函数
//参 数:无参数
//返回值:无返回
//
void RTC_IRQHandler(void)
{
if(RTC_GetITStatus(RTC_IT_SEC) != RESET) //秒钟中断
{
OSSemPost(sem_rtc); //发送信号量
}
RTC_ClearITPendingBit(RTC_IT_SEC); //清秒钟中断
RTC_WaitForLastTask(); //等待最近一次对RTC操作完成
}