您好, 登录| 注册|
论坛导航
您好, 登录| 注册|
子站:
论坛首页    高校联盟/电子设计大赛
  •  发帖
  • 收藏

【我的毕设作品】电动自行车BLDC无刷电机控制保护的模拟仿真
阅读: 1270 |  回复: 30 楼层直达

2019/08/24 17:18:47
1
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

QQ截图20160321155901 内容精选】管理员精心选择的优质内容 快来讨论吧


感谢电源网和璐璐姐给我们提供这样一个平台,下面介绍一下我的毕设作品设计主要设计要求

主要指标:

1.对于无刷直流电机进行实物仿真搭建并通过模拟控制器采集主要参数信息

2.模拟控制器能够将数据传输出去并在主控面板上实时显示

3.主控制器和模拟控制可以进行数据传输,数据传输模式不限

4.主控制模块实现对采样数据的处理并显示

5.当电动自行车电机失压、负载过轻、超额定转速后控制器执行相应动作并让模拟器执行相应机构

下附原理图

2019/08/24 17:20:40
2
电源网-璐璐
电源币:1092 | 积分:76 主题帖:266 | 回复帖:1498
LV10
司令
楠楠好棒!
2019/08/24 23:20:59
3
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
马上更新
2019/08/24 23:25:22
4
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

本次毕业设计在电动自行车bldc直流电机的控制的基础上,主要利用BLDC无刷直流电机建立对电动自行车电机的仿真;通过各类传感器、信号调理电路以及AD转换电路等将采集量转换成数字量并送至模拟控制器中;模拟控制器将采集量记录并保存在EEPROM中并通过异步串口协议将采集量传输至终端控制器中;终端控制器处理模拟调节器发来的信息并下达保护控制信号,完成对发电机的控制检测显示和保护。

搭建模型如图所示

2019/08/24 23:30:58
5
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

为保障电动自行车电机性能的实时监测与维护,因此搭建模拟电动自行车的BLDC电机,模拟电动自行车电机模型如下图所示。

2019/08/24 23:31:46
6
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
型号是A2212航模BLDC无刷电机
2019/08/24 23:37:29
7
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

介绍一下电动自行车无刷直流电机仿真采样的硬件电路和具体实施方案

1.本系统需要对汽车车载三相发电机的电压、电流以及转速进行实时在线采集。针对此系统三相交流电压的采集,可通过DL-PT202G型电压互感器将电压变为低压可测的范围之内,将电压互感器二次侧得到的电压经过整流桥以及电解电容的整流滤波之后输出一个脉动较小的直流电压,这个直流电压由于在0~5V可被STC12C5A60S2单片机AD采样模块准确检测到。

2.针对此系统电流的采样,采用微电阻压降放大的间接采样法,主要原因是因为STC12C5A60S2单片机AD采样模只识别电压信号不识别电流等其他类型的信号。其具体做法是在系统主功率回路中串入一个阻值较小的康铜丝或者水泥电阻,在功率电流流向这个阻值较小的电阻时会产生一个微小的压降,通过类似LM358之类的运算放大器将其电压放大再送至STC12C5A60S2单片机AD采样模块,来实现对系统主回路电流的测量。

3.针对此系统汽车三相交流发电机的转速测量,在考虑到安装体积以及其他综合因素情况之下,本次采集选用电机码轮以及以LM393为核心的光电门检测模块作为检测发电机转速的传感器,通过间接测量光电门测速模块的下降沿频率来进一步测出发电机的转速。

下图是电压采样电路

下图是电流采样电路

下图是测速模块接线图

下图是测速电路

下图是测量传感电路实物

2019/08/24 23:38:31
8
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

此图是当时测得电机的两相波形

2019/08/24 23:41:22
9
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

总体设计方案

本系统利用DL-PT202G型电压互感器作为电动自行车电机电压采样传感器,采用码盘和基于宽电压比较器LM393的电机测速模块来实现对电机速度的测量。保护电路采用JQC-3F(T73)5VDC型继电器作为保护器件。显示报警电路由液晶显示屏LCD1604、LED发光二极管和有源蜂鸣器组成。模拟控制模块拟采用STC12C5A60S2作为电压调节电路的主控核心芯片并将采样回来的电机、电压、电流和速度参数进行数字化处理通过异步串口通信发送给主控制器。主控制电路核心控制芯片采用PIC18F2580单片机,通过PIC18F2580单片机将采样值进行处理并发出相应执行命令给相应被控元件。由于本系统需要模拟发电机以及要求负载三相相对对称的特殊性,现采用A2212无刷直流电机模拟电动自行车电机,通过简易电子负载电路实现负载的三相对称要求。

电子负载电路通过三相全桥整流电路和滤波电路将三相交流电压转化为直流电压,通过简易负载电路调节一路负载便可实现三相电流的均衡调节。

模拟电子负载电路是下图

下图是简易电子负载电路实物图

2019/08/24 23:55:22
10
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

保护电路是由JQC-3F(T73)5VDC型继电器作为主要器件构成的,继电器在高压高功率场合下可起到对控制回路以及单片机之间的隔离和驱动保护,其在125V交流电压条件下可承受10A的电流、在240V交流电压条件下可承受7A的电流,可满足本次毕业设计的需求。

下图保护电路

2019/08/24 23:57:31
11
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

显示模块采用lcd1604,用法和1602类似但是比之前多了俩行

原理图如下

报警电路采用有源蜂鸣器来作为主要报警器件,有源蜂鸣器配合一个NPN型三极管实现了单片机控制电路与蜂鸣器电路的隔离,等效增大了单片机的驱动能力。值得一提是单片机I/O接口与三极管基极之间一般需要增设一个1K左右的电阻,否则基极电流过大会影响单片机的正常工作。这主要是由于单片机I/O输出口灌电流比较弱的原因驱动不了较大负载,这也是在单片机和有源蜂鸣器之间需要三极管的主要原因。另外在此基础上加了绿、蓝、红色三路指示灯,所选LED发光二极管由于通过电流较分别在电小可用单片机直接进行控制。报警电路如图所示。

实物如下

2019/08/25 00:07:03
12
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

掉电储存模块

AT24C02作为掉电记忆8端口芯片,有2048bit的记忆容量。其可通过端口A0、A1、A2三个电平状态检测引脚组合成8种地址,可以让模拟电压调节模块最大识别8个AT24C02芯片。AT24C02记忆芯片通过IIC总线通信协议与模拟电压调节器进行同步通信,其供电电源可由系统辅助电源模块的5V供电。AT24C02外围电路电路如图所示。

2019/08/25 00:12:14
13
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

控制模块的硬件电路主要是针对通信协议选定的

STC12C5A60S2采用11.0592mhz晶振。

PIC18F2580采用22.1184mhz晶振

下图是硬件原理图

下图是实物图

2019/08/25 00:17:47
14
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

通信选择选异步串口通信主要是由于异步串口通信建立过程简便便于实施

核心:串口通信

串口通信的硬件联调,

介于对系统参数采样稳定的要求,本系统采用9600bps波特率的串口通信速率,最大可传输76米的直线距离。硬件需要外接11.0592MHz的外部无源晶振,由于无源晶振需要起振电容,故选30pF的瓷片电容作为起振电容。由于模拟电压调节器内部没有专用波特率生成的寄存器,因此,需要通过软件算法配置T1定时器和TMOD寄存器。

终端控制器主要是由PIC18F2580单片机组成,由于终端控制器仅有一个异步串口通信接口引脚,因此其终端控制器的工作仅负责对模拟电压调节器的信号进行处理,并控制显示和发出控制命令。终端控制器有内部自带的增强型USART模块,增强型USART的操作主要由三个寄存器控制,分别是传输状态和控制寄存器、接收状态和控制寄存器、波特率控制寄存器。EUSART串口控件将根据需要自动将引脚从输入端配置到输出端。

2019/08/25 00:22:46
15
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

这是当时对串口数据传输的调试照片

2019/08/25 00:35:57
16
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

接下来是介绍一下主要软件设计,主要的软件流程图

ad采样程序

按键程序

低速报警程序

轻载报警程序

串口传输程序

2019/08/25 00:38:56
17
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
这是数据采样的程序
#include <STC12C5A60S2.h>  
#include <intrins.h>
#include <stdio.h>
#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;
	}
}
2019/08/25 00:42:02
18
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
这是终端做显示,控制功能的程序

#include <xc.h>
#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);
}

uchar strHEX[3];//INT8UtostrHEX函数转换的字符串显示16进制

void play(uchar ch)
{

    int a,b,c,a1,b1,c1,a2,b2,c2;
    if(ch==1)
    {
        if(xz==0)Ucc++;
        if(xz==1)Scc++;
        if(xz==2)Icc++;
    }
    if(ch==2)
    {
        if(xz==0)Ucc--;
        if(xz==1)Scc--;
        if(xz==2)Icc--;
    }
    if(ch==3)
    {
        charfill(' ');                      //显示清屏
       
        xz=0;
    }    
    if(ch==4)
    {
        charfill(' ');                      //显示清屏

        xz=1;
    }   
    if(ch==5)
    {
        charfill(' ');
        xz=2;
    }
    a=Ucc/100;a1=Scc/100;a2=Icc/100;
    b=Ucc%100/10;b1=Scc%100/10;b2=Icc%100/10;
    c=Ucc%10;c1=Scc%10;c2=Icc%10;
    DisplayOneChar(0, 0, 'U');DisplayOneChar(1, 0, 'c');DisplayOneChar(2, 0, 'c');DisplayOneChar(3, 0, ' ');
    DisplayOneChar(4, 0, '=');DisplayOneChar(5, 0,'0'+a);DisplayOneChar(6, 0, '.');DisplayOneChar(7, 0, '0'+b);
    DisplayOneChar(8, 0, '0'+c);DisplayOneChar(9, 0, 'V');
        
    DisplayOneChar(0, 1, 'S');DisplayOneChar(1, 1, 'c');DisplayOneChar(2, 1, 'c');DisplayOneChar(3, 1, ' ');
    DisplayOneChar(4, 1, '=');DisplayOneChar(5, 1,'0'+a1);DisplayOneChar(6, 1, '0'+b1);
    DisplayOneChar(7, 1, '0'+c1);DisplayOneChar(8, 1, 'r');DisplayOneChar(9, 1, '/');DisplayOneChar(10, 1, 's');

    DisplayOneChar(0, 2, 'I');DisplayOneChar(1, 2, 'c');DisplayOneChar(2, 2, 'c');DisplayOneChar(3, 2, ' ');
    DisplayOneChar(4, 2, '=');DisplayOneChar(5, 2,'0'+a2);DisplayOneChar(6, 2, '.');DisplayOneChar(7, 2, '0'+b2);
    DisplayOneChar(8, 2, '0'+c2);DisplayOneChar(9, 2, 'A');
    DisplayOneChar(14, xz, '<');    DisplayOneChar(15, xz, '-');    
}

play_1(int abc)
{
    DisplayOneChar(8, 0, 'S');        //显示单个字符
    DisplayOneChar(9, 0, '=');        //显示单个字
    DisplayOneChar(13, 0, 'r');
    DisplayOneChar(14, 0, '/');
    DisplayOneChar(15, 0, 's');
    DisplayOneChar(10, 0, '0'+abc*1/25);
    DisplayOneChar(11, 0, '0'+abc*111/25%100/10);
    DisplayOneChar(12, 0, '0'+abc*111/25%10);
}


void main()
{ 
    lcdreset();                         //液晶显示控制器初始化
    charfill(' ');                      //显示清屏
    init();	
    UartInit();
    TRISB=0x00; 
    PORTB=0x00;
    INTCON=0x00; /* 关总中断 */
    ADCON1=0X07; /* 设置数字输入输出口,不用作模拟口 */
   
  
    xc=RCREG;   
	while(1)
    {
        if(1==SciReceiveFlag) /* 是否接收到8个通信数据 */
        {                 
            lcdreset();                         //液晶显示控制器初始化
            charfill(' ');                      //显示清屏
            if(receive232[9]==0x01|receive232[9]==0x02|receive232[9]==0x03|receive232[9]==0x04|receive232[9]==0x05)
                play(receive232[9]);
            else
            {
                for(int i=0;i<4;i++)
                    {    
                       
                aa_4=receive232[3];
                aa_5=receive232[5];
                play_1(aa_4);
                SciReceiveFlag=0; /* 清接收到8个通信数据标志 */
                
                if(aa_4>Ucc/20*9|aa_5>Icc/20*9)pd=1;
                else
                  

                    TXREG=pd; /* 发送第一个数据后,将发送指针加1 */
                    TXEN=1; /* 使能发送 */
                }
            }
        }     
     }     
}


//显示AD转换值
void display_AD_value(uint a,uint abc,uint v)
{
    
    int e0=0;
    if(a>3){e0=1;a=a-4;}
        int i=0;
        unsigned int temp=0;
        unsigned char str[3];
        unsigned int j=100;
        unsigned char k=0;
        unsigned int ge;unsigned int di;
        //0.演示前的准备,LCD液晶显示控制器初始化,所有显示全清零
        ge=nu[6]/100;di=nu[6]%10;


        {
               if(a!=3)
            {   
                DisplayOneChar(0, a, 'U');        //显示单个字符
                DisplayOneChar(1, a, '=');        //显示单个字
                DisplayOneChar(6, a, 'V');
            }
            if(a==3)
            {   
                DisplayOneChar(0, a, 'I');        //显示单个字符
                DisplayOneChar(1, a, '=');        //显示单个字
                DisplayOneChar(6, a, 'A');
            }
            if(v==0)
            {
                for(i=0; i<=2; i++)
                {
                    temp=abc/j;
                    abc=abc-j*temp;
                    str[i]=(unsigned char)(temp+0x30);
                    j/=10;
                }
                for(k=0,i=0; i<4; k++,i++)
                {
                        if(i==0)        
                               DisplayOneChar(k+2+8*e0, a, str[i]);        //显示单个字符
                        else if(i==1)        
                               DisplayOneChar(k+2+8*e0, a, '.');        //显示单个字符
                        else
                        {
                           DisplayOneChar(k+2+8*e0, a, str[i-1]);        //显示单个字符        
                        }

                }
            }
           else               //输出溢出标志为零
            {
                 temp=(abc+258)/j;
                 abc=abc+258-j*temp;
                 str[0]=(unsigned char)(temp+0x30);
                 j/=10;
               for(i=1; i<=2; i++)
                {
                        temp=abc/j;
                        abc=abc-j*temp;
                        str[i]=(unsigned char)(temp+0x30);
                        j/=10;
                }
                for(k=0,i=0; i<4; k++,i++)
                {
                        if(i==0)        
                               DisplayOneChar(k+2+8*e0, a, str[i]);        //显示单个字符
                        else if(i==1)        
                               DisplayOneChar(k+2+8*e0, a, '.');        //显示单个字符
                        else
                        {
                           DisplayOneChar(k+2+8*e0, a, str[i-1]);        //显示单个字符        
                        }

                }

            }
        }
        
}

void exsample(void)                     //演示程序
{   unsigned char i;unsigned int ge;unsigned int di;
//0.演示前的准备,LCD液晶显示控制器初始化,所有显示全清零
    ge=nu[6]/10;di=nu[6]%10;
    lcdreset();                         //液晶显示控制器初始化
    charfill(' ');                      //显示清屏

//1.字符串演示: 在(4,0)字符位置显示"SMC1604A"
    putstrxy(0,0,"*****IN PUT*****");           //在(4,0)位置开始显示字符串
     //exdelay(); exdelay();                          //延时约300mS
    putstrxy(0,1,"Ua=  .  V       ""Ub=  .  V       ""Uc=  .  V");           //在(4,0)位置开始显示字符串   Io= . A Ms=   . r/min
    putstrxy(0,1,"Ua=  .  V       ""Ub=  .  V       ""Uc=  .  V"); 
    exdelay();                            //延时约300mS
    exdelay();
    
    //putstrxy(2,1,"System  init");  //延时约300mS
}


void exsample1(void)                     //演示程序
{   unsigned char i;
//0.演示前的准备,LCD液晶显示控制器初始化,所有显示全清零
    lcdreset();                         //液晶显示控制器初始化
    charfill(' ');                      //显示清屏

//1.字符串演示: 在(4,0)字符位置显示"SMC1604A"
    putstrxy(0,0,"Welcome To Use");           //在(4,0)位置开始显示字符串
    exdelay();                          //延时约300mS
    exdelay();                          //延时约300mS
     putstrxy(2,1,"System  init");           //在(4,0)位置开始显示字符串
    exdelay();                          //延时约300mS
    exdelay();                          //延时约300mS

}
//------------------------------------------

void exdelay(void)                      //演示延时子程序
{ unsigned char i,j,k;                  //延时约300mS
  for(i=0;i<30;i++)
    for(j=0;j<64;j++)
      for(k=0;k<51;k++);
}

////--------------------




void charfill(unsigned char c)          //整屏显示A代表的ASCII字符子程序
{   for(CXPOS=CYPOS=0;1;)
    {   putchar(c);                     //定位写字符
        charcursornext();               //置字符位置为下一个有效位置
        if((CXPOS==0) && (CYPOS==0)) break;
    }
}
//------------------

//-------------------------------------------------------------------------------
//子程序名称:void putstrxy(unsigned char cx,unsigned char cy,unsigned char *s).
//功能:在(cx,cy)字符位置写字符串.
//修改日期:2009.08.11
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
void putstrxy(unsigned char cx,unsigned char cy,unsigned char  *s)
{                                       //在(cx,cy)字符位置写字符串子程序
    CXPOS=cx;                           //置当前X位置为cx
    CYPOS=cy;                           //置当前Y位置为cy
    for(;*s!=0;s++)                     //为零表示字符串结束,退出
    {   putchar(*s);                    //写1个字符
        charcursornext();               //字符位置移到下一个
    }
}
//-------------------------------------------------------------------------------
//子程序名称:void putstr(unsigned char *s).
//功能:在(CXPOS,CYPOS)字符位置写字符串.
//修改日期:2009.08.11
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
void putstr(unsigned char  *s)      //定位写字符串子程序
{   for(;*s!=0;s++)                     //为零表示字符串结束,退出
    {   putchar(*s);                    //写1个字符
        charcursornext();               //字符位置移到下一个
    }
}
//-------------------------------------------------------------------------------
//子程序名称:void putchar(unsigned char c).
//功能:在(CXPOS,CYPOS)字符位置写字符.
//修改日期:2009.08.11
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
void putchar(unsigned char c)           //在(CXPOS,CYPOS)字符位置写字符子程序
{
    charlcdpos();                       //设置(CXPOS,CYPOS)字符位置的DDRAM地址
    lcdwd(c);                           //写字符
}
//-------------------------------------------------------------------------------
//子程序名称:unsigned char getchar(void).
//功能:在(CXPOS,CYPOS)字符位置读字符.
//修改日期:2009.08.12
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
unsigned char getchar(void)             //在(CXPOS,CYPOS)字符位置读字符子程序
{
    charlcdpos();                       //设置(CXPOS,CYPOS)字符位置的DDRAM地址
    return lcdrd();                     //读字符
}
//-------------------------------------------------------------------------------
//以下charlcdpos,charcursornext,lcdreset为HD44780兼容芯片的液晶显示控制器的
//16字符X4行的SMC1604系列标准字符点阵型液晶显示模块的接口程序.
//-------------------------------------------------------------------------------
//子程序名称:void charlcdpos(void).
//功能:设置(CXPOS,CYPOS)字符位置的DDRAM地址.
//修改日期:2009.08.11
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
void charlcdpos(void)                   //设置(CXPOS,CYPOS)字符位置的DDRAM地址
{
    CXPOS&=0X0f;                        //X位置范围(0到15)
    CYPOS&=0X03;                        //Y位置范围(0到1)
    if(CYPOS==0)                        //(第一行)X: 第0----15个字符
        lcdwc(CXPOS|0x80);              //    DDRAM:   0----0FH
    else if (CYPOS==1)                  //(第二行)X: 第0----15个字符
        lcdwc(CXPOS|0xC0);              //    DDRAM:  40----4FH
    else if (CYPOS==2)                  //(第三行)X: 第0----15个字符
        lcdwc(CXPOS|0x90);              //    DDRAM:  10----1FH
    else                                //(第四行)X: 第0----15个字符
        lcdwc(CXPOS|0xD0);              //    DDRAM:  50----5FH
}
//-------------------------------------------------------------------------------
//子程序名称:void charcursornext(void).
//功能:置字符位置为下一个有效位置.
//修改日期:2009.08.11
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
void charcursornext(void)               //置字符位置为下一个有效位置子程序
{
    CXPOS++;                            //字符位置加1
    if(CXPOS>15)                        //字符位置CXPOS>15表示要换行
    {   CXPOS=0;                        //置列位置为最左边
        CYPOS++;                        //行位置加1
        CYPOS&=0X3;                     //字符位置CYPOS的有效范围为(0到3)
    }
}
//-------------------------------------------------------------------------------
//子程序名称:void lcdreset(void).
//功能:液晶显示控制器初始化.
//修改日期:2009.08.11
//修改人:chujianjun@sunman.cn,tanchao@sunman.cn
//-------------------------------------------------------------------------------
void lcdreset(void)                     //SMC1604系列液晶显示控制器初始化子程序
{                                       //1604的显示模式字为0x38
    lcdwc(0x38);                        //显示模式设置第一次
    delay3ms();                         //延时3MS
    lcdwc(0x38);                        //显示模式设置第二次
    delay3ms();                         //延时3MS
    lcdwc(0x38);                        //显示模式设置第三次
    delay3ms();                         //延时3MS
    lcdwc(0x38);                        //显示模式设置第四次
    delay3ms();                         //延时3MS
    lcdwc(0x08);                        //显示关闭
    lcdwc(0x01);                        //清屏
    delay3ms();                         //延时3MS
    lcdwc(0x06);                        //显示光标移动设置
    lcdwc(0x0C);                        //显示开及光标设置
}
void delay3ms(void)                     //延时3MS子程序
{ unsigned char i,j,k;
  for(i=0;i<3;i++)
    for(j=0;j<64;j++)
      for(k=0;k<51;k++);
}
2019/08/25 00:43:06
19
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
明天发一下此次毕业设计完成的状态,和感想吧
2019/08/25 14:12:17
20
不可说
电源币:87 | 积分:3 主题帖:3 | 回复帖:50
LV5
营长
挺厉害的
2019/08/25 15:01:50
21
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
谢谢夸奖
2019/08/25 15:13:18
22
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
自我感觉我的毕业设计难度适中,主要难点是学习pic单片机,尤其是他的配置位,设置错误程序根本不运行的。还有就是针对pic和stc一种哈佛结构另一种冯诺依曼结构的单片机进行数据的互传问题,涉及到硬件软件互相配合互相协调,尽管还是有几率会报错,但是已经做的把数据误差降到最低了。
2019/08/25 15:13:29
23
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
通过对pic单片机的学习,你会真正体会到stc所比不上的优势,pic型号各异各有各的功能,而且程序不容易被盗取,硬件功能丰富简化了许多不必要的麻烦。其次针对无刷电机的控制保护我也是头一次做,采样电路,显示报警电路以及简易负载电路都是靠着自己的一些经验做的,有不对的地方希望大佬们提出宝贵意见,批评指正。
2019/08/27 00:06:48
24
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

这是当时测试系统采样电路和电子负载

2019/08/27 00:08:26
25
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

当时进行双机的串口通信时候利用开发板做的测试试验

2019/08/27 00:09:50
26
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

显示电路写照,当时拍下做毕业答辩时候用的

2019/08/27 00:12:15
27
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

系统联合测试,利用串口助手可以看到很细微的数据变化

2019/08/30 22:28:51
28
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

 仿真系统搭建

当时搭建的显示仿真

通过查阅大量资料,最终确定了以PIC18F2580单片机为核心的汽车发电机智能控制系统的实施方案。由于之前对PIC18F2580单片机了解接触的较少,为研究其使用方法以及实现基础显示和数据传输。对终端控制器的显示以及数据传输做了如下仿真。图为PIC18F2580单片机显示仿真图,

图为数据传输结果。

2019/08/30 22:32:06
29
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长

系统调试下载工具‘

2019/09/10 09:50:26
30
薄浩楠
电源币:82 | 积分:7 主题帖:3 | 回复帖:50
LV4
连长
当时做毕设时,遇到最主要的问题就是单片机的操作问题。由于题目要求指定PIC型号单片机然后就从网上各个方面了解和学习,通过不断的尝试终于调通。遇到最麻烦的就是他的配置位,没有配置位程序即使烧录进去也不能用。之后就剩下另一个难点了,串口通信。串口简易通信较容易实现但是互发数组又的保证不出错误就比较难。在此我利用串口助手的功能分别对俩个主控模块进行串口的数据调试,这样出来的程序基本就是可用的。本次毕设最终基本完成,有点瑕疵地方就是在进行通信时仍会出现小几率的错误使得执行机构误动作。主要是由于硬件部分仍会有一点不匹配造成的,软件在串口助手上面已经调试到完美了,,这点仍待解决
客服热线
服务时间:周一至周五9:00-18:00
微信关注
免费技术研讨会
获取一手干货分享

互联网违法不良信息举报

Reporting Internet Illegal and Bad Information
editor@netbroad.com
400-003-2006