感谢电源网给我们提供这样一个平台,下面介绍一下我的毕设作品设计主要设计要求
主要指标:
1.对于无刷直流电机进行实物仿真搭建并通过模拟控制器采集主要参数信息
2.模拟控制器能够将数据传输出去并在主控面板上实时显示
3.主控制器和模拟控制可以进行数据传输,数据传输模式不限
4.主控制模块实现对采样数据的处理并显示
5.当电动自行车电机失压、负载过轻、超额定转速后控制器执行相应动作并让模拟器执行相应机构
下附原理图
介绍一下电动自行车无刷直流电机仿真采样的硬件电路和具体实施方案
1.本系统需要对汽车车载三相发电机的电压、电流以及转速进行实时在线采集。针对此系统三相交流电压的采集,可通过DL-PT202G型电压互感器将电压变为低压可测的范围之内,将电压互感器二次侧得到的电压经过整流桥以及电解电容的整流滤波之后输出一个脉动较小的直流电压,这个直流电压由于在0~5V可被STC12C5A60S2单片机AD采样模块准确检测到。
2.针对此系统电流的采样,采用微电阻压降放大的间接采样法,主要原因是因为STC12C5A60S2单片机AD采样模只识别电压信号不识别电流等其他类型的信号。其具体做法是在系统主功率回路中串入一个阻值较小的康铜丝或者水泥电阻,在功率电流流向这个阻值较小的电阻时会产生一个微小的压降,通过类似LM358之类的运算放大器将其电压放大再送至STC12C5A60S2单片机AD采样模块,来实现对系统主回路电流的测量。
3.针对此系统汽车三相交流发电机的转速测量,在考虑到安装体积以及其他综合因素情况之下,本次采集选用电机码轮以及以LM393为核心的光电门检测模块作为检测发电机转速的传感器,通过间接测量光电门测速模块的下降沿频率来进一步测出发电机的转速。
总体设计方案
本系统利用DL-PT202G型电压互感器作为电动自行车电机电压采样传感器,采用码盘和基于宽电压比较器LM393的电机测速模块来实现对电机速度的测量。保护电路采用JQC-3F(T73)5VDC型继电器作为保护器件。显示报警电路由液晶显示屏LCD1604、LED发光二极管和有源蜂鸣器组成。模拟控制模块拟采用STC12C5A60S2作为电压调节电路的主控核心芯片并将采样回来的电机、电压、电流和速度参数进行数字化处理通过异步串口通信发送给主控制器。主控制电路核心控制芯片采用PIC18F2580单片机,通过PIC18F2580单片机将采样值进行处理并发出相应执行命令给相应被控元件。由于本系统需要模拟发电机以及要求负载三相相对对称的特殊性,现采用A2212无刷直流电机模拟电动自行车电机,通过简易电子负载电路实现负载的三相对称要求。
电子负载电路通过三相全桥整流电路和滤波电路将三相交流电压转化为直流电压,通过简易负载电路调节一路负载便可实现三相电流的均衡调节。
模拟电子负载电路是下图
保护电路是由JQC-3F(T73)5VDC型继电器作为主要器件构成的,继电器在高压高功率场合下可起到对控制回路以及单片机之间的隔离和驱动保护,其在125V交流电压条件下可承受10A的电流、在240V交流电压条件下可承受7A的电流,可满足本次毕业设计的需求。
下图保护电路
显示模块采用lcd1604,用法和1602类似但是比之前多了俩行
原理图如下
报警电路采用有源蜂鸣器来作为主要报警器件,有源蜂鸣器配合一个NPN型三极管实现了单片机控制电路与蜂鸣器电路的隔离,等效增大了单片机的驱动能力。值得一提是单片机I/O接口与三极管基极之间一般需要增设一个1K左右的电阻,否则基极电流过大会影响单片机的正常工作。这主要是由于单片机I/O输出口灌电流比较弱的原因驱动不了较大负载,这也是在单片机和有源蜂鸣器之间需要三极管的主要原因。另外在此基础上加了绿、蓝、红色三路指示灯,所选LED发光二极管由于通过电流较分别在电小可用单片机直接进行控制。报警电路如图所示。
实物如下
掉电储存模块
AT24C02作为掉电记忆8端口芯片,有2048bit的记忆容量。其可通过端口A0、A1、A2三个电平状态检测引脚组合成8种地址,可以让模拟电压调节模块最大识别8个AT24C02芯片。AT24C02记忆芯片通过IIC总线通信协议与模拟电压调节器进行同步通信,其供电电源可由系统辅助电源模块的5V供电。AT24C02外围电路电路如图所示。
通信选择选异步串口通信主要是由于异步串口通信建立过程简便便于实施
核心:串口通信
串口通信的硬件联调,
介于对系统参数采样稳定的要求,本系统采用9600bps波特率的串口通信速率,最大可传输76米的直线距离。硬件需要外接11.0592MHz的外部无源晶振,由于无源晶振需要起振电容,故选30pF的瓷片电容作为起振电容。由于模拟电压调节器内部没有专用波特率生成的寄存器,因此,需要通过软件算法配置T1定时器和TMOD寄存器。
终端控制器主要是由PIC18F2580单片机组成,由于终端控制器仅有一个异步串口通信接口引脚,因此其终端控制器的工作仅负责对模拟电压调节器的信号进行处理,并控制显示和发出控制命令。终端控制器有内部自带的增强型USART模块,增强型USART的操作主要由三个寄存器控制,分别是传输状态和控制寄存器、接收状态和控制寄存器、波特率控制寄存器。EUSART串口控件将根据需要自动将引脚从输入端配置到输出端。
这是数据采样的程序
#include#include #include #define uint unsigned int #define uchar unsigned char #define ADC_FLAG 0X10 #define VCC 220 uchar code SMGduan[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,}; //数码管位选码 uchar code SMGwei[] = {0xfe, 0xfd, 0xfb}; unsigned char pdata bufRxd[64]; //接收字节缓冲区 /***********************延时函数*******************************/ void delay(uint z) { uint x,y; for(x = z; x > 0; x--) for(y = 114; y > 0 ; y--); } /************************采用器初始化******************************/ void InitADC(void) { P1M1=0xff; //1^012开启高阻态 P1M0=0x00; //其余端口当普通端口使用 P1ASF=0Xff; //P^1 DC_V ADC_RES=0; ADC_CONTR=0X80; //1000 0000 开电源,最低速 delay(50); } /**************************采样函数******************************/ uint GetADC(uchar ch) { uint result=0; ADC_CONTR=0x88|ch; //选择通道 开始AD转换e8 ADC最快,88,ADC最慢 _nop_(); _nop_(); _nop_(); _nop_(); while(!(ADC_CONTR&ADC_FLAG)); //查询ADC_FLOG是否置位1 转换结束 ADC_CONTR&=!ADC_FLAG; //清除ADC中断标志 result=ADC_RES; //(ADC_RES<<2)+ADC_RESL (<<2)+ADC_RESL; aa[ss++]= ADC_RES; if(ss==6)ss=2; return(result); } /**********************定时器0初始化****************************/ void timer0Init() { EA = 1; //打开总中断 ET0 = 1;//打开定时器0中断 TR0 = 1; //启动定时器0 REN = 1;//允许串口接收 TMOD |= 0X01; //定时器工作模式1,16位定时模式 TH0 = 0xED; TL0 = 0xFF; //定时5ms } /***********************串口初始化*********************************/ void UARTInit() { EA = 1; //打开总中断 ES = 1; //打开串口中断 SM0 = 0; SM1 = 1;//串口工作方式1,8位UART波特率可变 } void main()//main函数自身会循环 { InitADC(); //采样初始化 timer0Init();//定时器0初始化 UARTInit();//串口初始化 bb=0; while(mode) { } } while(mode==0) { EA=0; //关总中断 bb=0; while(sw_up==1&sw_down==1&sw_mune0==1&sw_mune1==1&sw_mune2==1)if(mode)break; if(sw_mune1==0) aa[9]=4; if(sw_mune2==0) aa[9]=5; while(sw_up==0|sw_down==0|sw_mune0==0|sw_mune1==0|sw_mune2==0)if(mode)break; if(mode)break; else EA=1; //开总中断 delay(300); } } /****************************串口通信中断*****************************/ void UART() interrupt 4 { SBUF=0xff; if(TI)//判断是否发送完成 { bb++; if(bb>=10&&aa[9]==0xff) { bb=0; delay(1000); } } if(RI==1)//判断接收是否完成 { int nu; nu =SBUF ;//读SBUF,读出串口接收到的数据 //第0号数据不是帧头,跳过 switch(nu) { case 1:{LED2=1;LED1=0;LED0=1;wmq=0;JDQ=0;}break; //过压 case 2:{LED2=1;LED1=0;LED0=1;wmq=0;JDQ=0;}break; //过流 case 3:{LED2=0;LED1=1;LED0=1;wmq=1;JDQ=1;}break; //低速 case 0:{LED2=1;LED1=1;LED0=0;wmq=1;JDQ=1;}break; //正常 } RI = 0;//软件清零接收标志位 cc++; if(cc==1)cc=0; } }
这是终端做显示,控制功能的程序 #include#include "pic18.h" /* PIC18系列的头文件 */ #define MAIN_Fosc 22118400L //定义主时钟 #define e RC5 //LCD使能IO #define rs RC3 //LCD写数据或命令控制IO #define rw RC4 //LCD读写控制IO #define AT24C02_ADDR 0xa0 //AT24C02地址 #define PCF8591_ADDR 0x90 //PCF8591地址 #define VCC 500 unsigned char CXPOS; //列方向地址指针(用于CHARLCDPOS子程序) unsigned char CYPOS; //行方向地址指针(用于CHARLCDPOS子程序) unsigned char receive232[10]={0xfc,0xfc,3,4,5,6,7,8}; /* 接收数据数组 */ unsigned char send232[10]={0xfc,0xfc,3,4,5,6,7,8}; /* 发送数据数组 */ unsigned char receive_count=0; /* 接收数据个数计数 */ unsigned char send_count=1; /* 发送数据个数计数 */ unsigned char *pointer; /* 发送数据指针 */ unsigned char i; /* 程序中用到的循环变量 */ unsigned char SciReceiveFlag; /* =1,接收到8个数据 */ unsigned char Send_Mode=1; /* 不为0,中断方式发送;=0,非中断方式发送 */ //#define key RC0 typedef unsigned char uchar; typedef unsigned int uint; //------变量定义 uchar nu[6]={34,06,52,44,66,66,} ; uchar aa[11]; //数字量接收数组 uchar aa1[11]; //数字量溢出标志位 uchar bc[9];uchar xc=0; //={34,06,52,44,66,66,44,66,66,} uchar a=0; uchar bb=0; char web[] = {"Ua"}; uchar U[] = {"****Voltage*****"}; uchar Uv[] = {"V"}; uchar Ua[] = {"Ua="}; uchar Ub[] = {"Ub="}; uchar Uc[] = {"Uc="}; int iu; int result=0x38; int Ucc=500; int Scc=200; int Icc=500; int xz; int pd; void WriteDataLCD(unsigned char WDLCD) { PORTB = WDLCD; RC3 = 1; RC4 = 0; RC5 = 0; //若晶振速度太高可以在这后加小的延时 RC5 = 0; //延时 RC3 = 1; }*/ void sciinitial() /* 串行通讯初始化子程序 */ { TXSTA=0x04; /* 选择异步高速方式传输8位数据 */ RCSTA=0x80; /* 允许串行口工作使能 */ TRISC=TRISC|0X80; /* :将RC7(RX)设置为输入方式 */ TRISC=TRISC&0Xbf; /* RC6(TX)设置为输出 */ SPBRG=143; /* 4M晶振且波特率为9600时,SPBRG设置值为25 */ PIR1=0x00; /* 清中断标志 */ PIE1=PIE1|0x20; /* 允许串行通讯接口接收中断使能 */ RCIP=0; /* 设置SCI接收中断为低优先级中断 */ CREN=1; /* 允许串口连续接收数据 */ if(0==Send_Mode) TXEN=1; /* Send_Mode=0,非中断方式发送,串口发送数据使能 */ else /* Send_Mode=1,中断方式发送 */ { PIE1=PIE1|0x10; /* 允许中断发送 */ TXIP=0; /* 发送低优先级中断 */ } } void interrupt low_priority LOW_ISR() /* 低优先级中断子程序 */ { if(RCIF==1) /* RS232接收中断 */ { RCIF=0; /* 清中断标志 */ receive232[receive_count]=RCREG; send232[receive_count]=RCREG; /* 接收数据存放到发送缓冲数组 */ receive_count++; /* 接收计数器加1 */ if(receive232[0]==0xfc&&receive232[1]==0xfc);//前两位是否为0xfc else {receive_count=0;return;}//不是则重新加载数据 if(receive_count==10) /* 如果已经接收到8个数据 */ { receive_count=0; /* 接收计数器清0 */ SciReceiveFlag=1; /* 置接收到8个数据标志 */ } } else if((0!=Send_Mode)&&(TXIF==1)) /* 中断发送数据方式且为发送中断 */ { if(send_count==1) /* 已经发送完8个数 */ { TXEN=0; /* 发送不使能 */ return; } else { TXREG=pd; /* 发送当前应发送数据,发送指针加1 */ send_count++; /* 发送计数器加1 */ } } } void init() { TRISC3=0;TRISB=0x00; TRISA=0xFF; TRISC4=0; TRISC5=0; PORTB=0x00;//LATA=0xFF; RCSTA=0X90; } void UartInit(void)//初始化函数 { INTCONbits.GIEL = 1; //使能外设中断 } void lcdwc(unsigned char c) //送控制字到液晶显示控制器子程序 { lcdwaitidle(); //HD44780液晶显示控制器忙检测 RC3=0; //RS=0 RW=0 E=高电平 RC4=0; PORTB=c; RC5=1; RC5=0; } //------------------------------------------------------------------------------- //子程序名称:void lcdwd(unsigned char d). //功能:送数据到液晶显示控制器. //修改日期:2009.08.12 //修改人:chujianjun@sunman.cn,tanchao@sunman.cn //------------------------------------------------------------------------------- void lcdwd(unsigned char d) //送控制字到液晶显示控制器子程序 { lcdwaitidle(); //HD44780液晶显示控制器忙检测 RC3=1; //RS=1 RW=0 E=高电平 RC4=0; PORTB=d; RC5=1; RC5=0; } //------------------------------------------------------------------------------- //子程序名称:unsigned char lcdrd(void). //功能:读数据到液晶显示控制器. //------------------------------------------------------------------------------- unsigned char lcdrd(void) //读数据子程序 { unsigned char d; lcdwaitidle(); //HD44780液晶显示控制器忙检测 PORTB=0xff; RC3=1; //RS=1 RW=1 E=高电平 RC4=1; RC5=1; d=PORTB; RC5=0; return d; } //------------------------------------------------------------------------------- //子程序名称:void lcdwaitidle(void). //功能:忙检测. //------------------------------------------------------------------------------- void lcdwaitidle(void) //忙检测子程序 { unsigned char i; PORTB=0xff; RC3=0; //RS=0 RW=1 E=高电平 RC4=1; RC5=1; for(i=0;i<20;i++) if((PORTB&0x80) == 0) break; //D7=0 表示LCD控制器空闲,则退出检测 RC5=0; } void Delay_Ms(unsigned int ms) { unsigned int i; do{ i = MAIN_Fosc / 96000; while(--i) ; //96T per loop }while(--ms); } void delay() { int i; for (i=0;i<5000;i++); } void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) { X&=0X0f; //X位置范围(0到15) Y&=0X03; //Y位置范围(0到1) if(Y==0) //(第一行)X: 第0----15个字符 lcdwc(X|0x80); // DDRAM: 0----0FH else if (Y==1) //(第二行)X: 第0----15个字符 lcdwc(X|0xC0); // DDRAM: 40----4FH else if (Y==2) //(第三行)X: 第0----15个字符 lcdwc(X|0x90); // DDRAM: 10----1FH else //(第四行)X: 第0----15个字符 lcdwc(X|0xD0); lcdwd(DData); }