光伏电子工程的设计与实施2022——单片机力控部分实现思路
目录
一、串口屏
1.1、接收数据
1.2、发送数据
1.3、显示曲线
1.4、改变亮度
二、EG8010
2.1、接收发送数据
2.2、读电压电流温度频率
2.3、改变输出电压频率
三、RS485
3.1、485初始化
3.2、接收数据响应函数
四、WiFi
4.1、模拟串口流程图
4.2、模拟串口部分代码
五、EEPROM(断电数据保护)
六、力控(vb代码)
6.1、用到的函数
6.2、登录窗口
6.3、顶部窗口
6.4、监视窗口
七、视频演示
7.1、串口屏单片机
7.2、力控
八、离网硬件
8.1、逆变升压
8.2、驱动部分
九、呼吸灯
主控IAP15W4K61S4,外设有串口屏,8010,485,WiFi,都是通过串口实现通讯。EEPROM实现断电数据保护。
一、串口屏
单片机使用串口2接收和发送数据
实现功能有:改变屏幕的亮度,采集输出电压电流(adc)频率(eg8010)显示在串口屏,改变输出频率电压(接收串口屏数据,通过8010改变)。
1.1、接收数据
接收串口屏数据,因为数据字节数是无规律的,所以接收数据使用到了队列方式接收。
- 队列
用了比较简单的方式,循环队列。
大体思路就是:结构体变量(数组,头尾变量作为数组的下标)
typedef struct _QUEUE
{u16 _head; //数据栈头指针u16 _tail; //数据栈尾指针u8 _data[QUEUE_MAX_SIZE]; //#define QUEUE_MAX_SIZE 80 ,队列长度
}QUEUE;
- 数据放入
void queue_push(u8 _data)//数据一个一个放入FIFO,串口屏
{u16 pos;pos = (que._tail+1)%QUEUE_MAX_SIZE; //if(pos!=que._head)//非满状态 {que._data[que._tail]=_data;que._tail = pos;}
}
- 数据取出
static void queue_pop(u8* _data)
{if(que._tail!=que._head)//非空状态{*_data = que._data[que._head];que._head = (que._head+1)%QUEUE_MAX_SIZE; //栈尾指向下一个指令头部? ? ? ? }
}
1.2、发送数据
- 单片机发送给串口屏数据很简单,代码如下发送一个字节数据
void Uart2_SendData(unsigned char dat) //串口2发送数据
{S2BUF = dat;//写数据到UART2数据寄存器while(!(S2CON&S2TI));//等待串口发送完成S2CON&=~S2TI;//发送中断标志位置0
}
- 发送2字节数据,把int拆分开高8位低8位分别发送
void SendDatas(u16 str)
{Uart2_SendData((u8)((str>>8)&0xff));Uart2_SendData((u8)(str&0xff));
}
- 串口屏显示的是文本,使用有时候要把整形数转为字符串,然后发送
sprintf(Text_buf,"%d",dat); //把整型dat转为字符串Text_buf
1.3、显示曲线
1、采集2个ad(电压 电流)
2、比较2ad,判断是否从曲线零点开始
3、循环采集屏的宽度+5个ad(滤波需要多出5个值)
4、滤波(取5个连续ad的平均值),比较出峰值谷值
5、发送数据给串口屏显示
1.4、改变亮度
接收串口屏的数据指令,发送改变亮度指令
二、EG8010
使用的串口3,数据接收到数组里面,因为数据很固定,都是发送2字节返回4字节数据
注:eg需要初始化
2.1、接收发送数据
- 接收
void UART3_Routine(void) interrupt 17 //串口3中断
{if(S3CON&S3RI) //等待串口接收完成{ S3CON&=~S3RI; //手动清零接收中断标志位 eg8010_buf[eg_count++]=S3BUF;//压入到指令缓冲区}
}
- 发送
void Uart3_SendData(u8 dat)//串口3发送1个字节数据
{S3BUF=dat;//写数据到UART3数据寄存器while(!(S3CON&S3TI));//等待发送中断标志位置1S3CON&=~S3TI;//将发送中断标志位置0
}
2.2、读电压电流温度频率
1、发送读取指令
2、等待数据接收完成
3、读取接收到的数据,4字节,分别是电压电流温度频率
2.3、改变输出电压频率
1、接收到串口屏的改变电压(频率)命令
2、发送给eg8010改变电压命令改变输出电压,控制数据命令改变输出频率
三、RS485
3.1、485初始化
使能脚定义,串口4初始化
sbit EN_485=P0^4; //485使能脚
void RS485_init()//485初始化
{Uart4_init();EN_485 = 0;//接收状态
}
3.2、接收数据响应函数
- 完整函数
接收到数据,根据功能码去处理,如果5ms还没有处理就摒弃掉这次数据
void check_modbus(void)
{unsigned int crcData,tempData,temp;timeProc();//定时处理,数据保留5msif(receCount>4) //如果接收到数据{if(receBuf[0]==LocalAddr) //核对地址{if(receBuf[1]<10){if(receCount>=8) //数据大于8个进入,地址1 功能码1 4 校验码2{crcData = CRC16_Check(receBuf,6); //核对校验码temp = (receBuf[7]<<8)+receBuf[6];if(temp==crcData){switch(receBuf[1]) //读取功能码{case 1: readCoils(); break; //读取线圈输出状态(一个或多个) case 2: readInPutCoils(); break; //读取线圈输入(只读寄存器)状态case 3: readRegisters(); break; //读取多个寄存器值case 5: forceSingleCoil(); break; //强制单个线圈case 6: presetSingleRegister(); break; //设置单个寄存器default:break; }}}} else if(receBuf[1]==16){tempData = (receBuf[4]<<8) + receBuf[5]; //设置寄存器个数tempData = tempData * 2; //数据个数= 寄存器*2tempData += 9; //从询问数据包格式可知,receCount应该等于9+byteCountif(receCount>=tempData){crcData = CRC16_Check(receBuf,tempData-2);if(crcData==((receBuf[tempData-1]<<8)+ receBuf[tempData-2]))if(receBuf[1]==16)presetMultipleRegisters(); receCount=0;} }} }
}
- 定时处理
从接收到最后一个数据开始计时,5ms后数据清理
void timeProc(void)
{if(bt1ms) //每1ms进入{bt1ms = 0;if(receTimeOut>0) //接收到数据赋值5,每接收一个数据receTimeOut赋值5{receTimeOut--; //等待5msif(receTimeOut==0 && receCount>0) //判断通讯接收是否超时{EN_485 = 0; //将485置为接收状态 receCount = 0;// //将接收地址偏移寄存器清零} }}
}
- 数据接收中断
receTimeOut决定数据处理等待最大时间,5就是5ms清零,与定时处理函数相关
void Uart4_485(void) interrupt 18 //串口4中断
{if(S4CON&S4RI){ S4CON&=~S4RI; //手动清零接收中断标志位 receTimeOut=5; //处理等待时间receBuf[receCount++] = S4BUF; //保存接收字节,并递增计数器}
}
- 设置单个寄存器函数
读出寄存器地址,和设置的内容,调用设置寄存器函数,最后数据发回plc
/****************fuction:06设置单个寄存器ok**********************************************************/
//主机发送:从机地址 + 功能码 + 寄存器地址(2个字节,先寄存器高位,在寄存器低位)+数据写入值(2个字节,先高位再低位)+ CRC16校验(低位再高位)
//从机返回:从机地址 + 功能码 + 寄存器地址(2个字节,先寄存器高位,在寄存器低位)+数据写入值(2个字节,先高位再低位)+ CRC16校验(低位再高位)
/****************************************************************************************************/
void presetSingleRegister(void) //fuction:06设置单个寄存器
{unsigned int addr;unsigned int tempAddr;unsigned int tempData;unsigned char i;addr = (receBuf[2]<<8)+receBuf[3]; //读取初始地址 tempAddr = addr+40000;//读取地址tempData = (receBuf[4]<<8) + receBuf[5];//设置寄存器写入值setRegisterVal(tempAddr,tempData); //设置寄存器内容for(i=0;i<receCount;i++) //回发,把数据发送回plcsendBuf[i] = receBuf[i];RS485_Send(sendBuf,8);
}
- 设置寄存器函数
根据地址,设置不同的寄存器
void setRegisterVal(unsigned int addr,unsigned int tempData) //设置寄存器内容函数
{switch(addr){ case RWDAT3: EG_OUTDY(tempData); break; //电压 180-220case RWDAT4: EG_OUTPL(tempData); break; //频率 0:50 1:60default:break;}
}
四、WiFi
使用的是模拟串口的方式,定时器1
4.1、模拟串口流程图
大致流程就是:中断中4个判断(3个有关接收,1个发送)
r被拉低,说明开始接收,就去接收8位,接收完就放入数组。
t拉低,起始位开始发送,发送8位+1停止位
4.2、模拟串口部分代码
void TIM0() interrupt 3
{if(REND) //接收是否完成{ REND=0; //清零接收完成wifi_buf[r]=RBUF; //数据放入接收数组r++; //存储位+1uart_flag=1; //置位数据存放完成flag}if(RING) //是否开始接收{if(--RCNT == 0){RCNT = 3; //重置接收波特计数器if (--RBIT == 0){RBUF = RDAT; 将数据保存到 RBUFRING = 0; 停止接收REND = 1; //设置接收已完成标志}else{RDAT >>= 1;if (RXB) RDAT |= 0x80; ///将数据一位一位放入缓冲区}}}if ((!RXB)&&(RING==0)) //RXB(P3.6)==0,接收起始位{RING = 1; 设置开始接收标志RCNT = 4; ///初始接收波特计数器RBIT = 9; //初始接收位数 (8 数据位 + 1 停止位)}if (--TCNT == 0) //波特计数{TCNT = 3; //重置发送波特计数器if(TING) //判断是否发送,开始发送标志位{if (TBIT == 0){TXB = 0; //发送起始位TDAT = TBUF; //将数据从 TBUF 加载到 TDATTBIT = 9; //初始发送位数 (8 数据位 + 1 停止位)}else //数据未发送完{TDAT >>= 1; //shift data to CYif (--TBIT == 0) //是否发送完{TXB = 1; //P3.7 == 1TING = 0; //停止发送TEND = 1; //设置发送完成标志}else //未发送完{TXB = CY; //write CY to TX port}}}}
}
void UART_Send(u8 dat)
{if(TEND) //发送完成{TEND=0;TBUF=dat;TING=1; //置位开始发送}delay_ms(5);
}
五、EEPROM(断电数据保护)
当每次智能离网微逆变系统信号源开机时,将“开机”的“次数”加1;
单片机上电初始化程序完成后读取EEPROM里的开机次数到变量a+1,并且显示在串口屏。
EEPROM程序实现参考STC——EEPROM(断电数据保护)_dz小伟的博客-CSDN博客
六、力控(vb代码)
6.1、用到的函数
#TextControl.Text //文本框内容,获取,更改
Display("顶部窗口"); //打开窗口,切换窗口
MsgBox("密码错误"+ setten +"次"); //弹出提示框
Exit(2); //退出程序应用01234
CloseWindow(); //关闭窗口,关闭弹出式窗口用
IntToStr($Day,10); //整数转字符串,返回值字符串
StrRight(string,2); //截取字符串右边个字符
Rand(10000); //随机数
#ComboBox1.GetWindowsText(); //获取编辑框内容,下拉框
#Text1.Show(1); //隐藏控件,图形目标
#TreeMenu.GetSelItemData(); //获取树形菜单数值
strlen(); //返回字符串长度
StrRepeate("#",5); // 重复形成的字符串。密码隐藏用//数据报表使用
#Report.AddRow(0,2,1);//插入一行
//#Report.SetCellDouble(0,2,1,123.1,1);//输出变量
#Report.SetCellString(0,2,1,$Time,1);//输出字符串
6.2、登录窗口
- 密码错误次数提示框
点击“登录”按钮后,若账号密码错误则弹窗提示“密码错误X次”
实现方法:定义一个整型变量,错误后加一,然后变量转字符串,用函数MsgBox显示
- 密码隐藏(***)和显示
1.设有“隐藏”按钮,点击后可将密码隐藏(显示的密码更换为‘#’)再次点击后可将隐藏额密码恢复显示。
按钮改变变量a(是否显示密码),窗口脚本判断是否显示密码:是并且flag为0把文本框内容赋值给密码变量mm,flag为1(密码隐藏切换回显示后执行一次),把mm赋值给文本框显示,flag清零。否隐藏密码并且flag为0(密码显示切换隐藏后执行一次),把flag置1,求出变量mm长度,把文本框赋值为长度len个#,flag置1。flag为1(密码隐藏循环执行的语句),判断mm和文本框内容长度是否一致,一致什么都不执行,否则变量len2=文本框-mm,把文本框的右len2个字符加到mm上,重新给文本框赋值len+len2个#。
2.设有“隐藏”按钮,点击后可将密码隐藏(显示的密码更换为‘*’)再次点击后可将隐藏额密码恢复显示。
做2文本框(属性设置为一个密码显示一个密码隐藏),2文本框切换显示(按钮改变变量完成切换)(切记2文本框内容必须一样且同步,在窗口脚本中同步)
- 验证码
设有4位验证码显示、可刷新验证码。
使用rand产生随机数。点击刷新,产生随机数并赋值给文本(不是4位数则重新随机)
- 自动判断账号和密码错误
账号输入正确时,弹窗提示“账号正确”,若账号输入超过4个字符且错误时弹窗提示“账号错误”并清空输入的账号;当密码输入正确时,弹窗提示“密码正确”,若密码输入超过6个字符且错误时弹窗提示“密码错误”并清空输入的密码;
定义flag和flag2(账号密码标志位,正确则置1),窗口脚本,进入后分别判断flag和flag2是否为0,为0后继续判断账号正确(flag置1),账号错误(账号不等于并且长度大于4)。
清空文本框:给文本框赋值""
- 账号锁定
一个变量,1表示锁定账户,解锁清空0
- 延迟2s
点击“登录”按钮后,若管理员账号密码正确,则等待2秒后,弹窗提示“管理员账号登录”并打开“顶部窗口”和“操作界面”;
密码正确后一个变量a置1,窗口脚本另一个变量b++,直到b加到2s后,弹窗和打开指定窗口。
6.3、顶部窗口
- 切换窗口(树形菜单)
读取树形菜单数值到变量a,根据a切换窗口,(切换窗口之前加一个判断是否和上次变量shu1一样),注:要在进入窗口的时候先给shu1赋初始值(不赋值会直接进入到树形菜单的初始值界面)
- 切换窗口(切换控件)
一个变量a++,一个a--,然后切换根据a数值切换。
- 显示时间(格式:XX日XX月XX年—上午/下午XX时XX分—星期X)
读取出变量,按格式赋值给文本框。
6.4、监视窗口
- 下拉框切换组合表
判断下拉内容然后隐藏显示表
单选
判断3中间变量状态是否和开关状态相等
不相等在判断中间变量是0还是1
0把开关状态置1,其他2个置0
1把开关状态置0
IF cs11 == cs111 THENELSEIF cs11 == 0 THENcs111 = 1;cs112 = 0;cs113 = 0;cs11 = cs111;cs12 = cs112;cs13 = cs113;ELSEcs111 = 0;cs11 = cs111;cs12 = cs112;cs13 = cs113;flagcs==0;ENDIFENDIF IF cs12 == cs112 THENELSEIF cs12 == 0 THENcs111 = 0;cs112 = 1;cs113 = 0;cs11 = cs111;cs12 = cs112;cs13 = cs113;ELSEcs112 = 0;cs11 = cs111;cs12 = cs112;cs13 = cs113;flagcs==0;ENDIFENDIFIF cs13 == cs113 THENELSEIF cs13 == 0 THENcs111 = 0;cs112 = 0;cs113 = 1;cs11 = cs111;cs12 = cs112;cs13 = cs113;ELSEcs113 = 0;cs11 = cs111;cs12 = cs112;cs13 = cs113;flagcs==0;ENDIFENDIF
七、视频演示
7.1、串口屏单片机
2022光伏电子单片机部分
7.2、力控
全国技能大赛(光伏电子工程)力控用到vb脚本部分
八、离网硬件
分为2块电路板
8.1、逆变升压
升压,逆变,前后级检测保护
- 前级升压到400v
- 后级逆变,LR滤波输出交流220v
8.2、驱动部分
前级升压驱动,后级逆变驱动,故障检测通信控制
- 前级SG3525升压驱动(pwm12),过压过流欠压保护
- 后级EG8010逆变驱动(spwm1234),IR2110隔离放大5-15v
- 单片机通信控制电路
九、呼吸灯
利用定时器1中断,模拟PWM,使led呈现呼吸灯效果
//定时器1中断,2us定时器
void timer1(void) interrupt 3
{s++;if(s>=500) //1ms{s=0;if(fx==0){ //a相当于占空比a++;if(a>=500){fx=1;}}else{a--;if(a<=0){fx=0;}}}if(s<=a){ //通过改变1ms内,低电平的时间(a相当于占空比)Led=0;}else{Led=1;}
}
//1ms定时器
void time1_sssww() interrupt 3
{ls++;//150ms改变一次占空比if(lflag==10){lflag=0;if(fx==0){la++;if(la>=15){fx=1;}}else{la--;if(la<=0){fx=0;}}}//15ms为一个PWM周期if(ls>=15){ls=0;lflag++;}if(ls<la){LED1=0;}else{LED1=1;}
}
光伏电子工程的设计与实施2022——单片机力控部分实现思路相关推荐
- uel结果输出_数电电子脉搏计设计报告与Multisim仿真工程
课程名称:数字电子技术课程设计 题 目:电子脉搏计设计 目录 电子脉搏计设计 3 一.设计任务与要求 3 二.方案设计与论证 ...
- 中国科学技术大学电子工程与信息科学系、先进技术研究院、科学岛篇|2022年(23届)电子信息/通信工程夏令营保研/考研复试经验贴
一.个人简介 学校及专业:四非通信工程 绩点排名:1/170 CET6:487 CET4:554 科研经历:二区SCI论文1篇,主持重点领域支持国家级大创1项 竞赛奖项:互联网+国铜.挑战杯国铜.节能 ...
- 游戏行业的人工智能设计:AI的设计和实施
文 / Donald Kehoe 在过去的几十年中,游戏行业取得了巨大发展. 从 Pong* 和Pac-Man*等让游戏玩家短暂逃离现实的简单游戏发展为魔兽世界* 和使命召唤 4*这样让游戏玩家真正喜 ...
- 一位电子工程师从学校到工作岗位的项目经历,或许你可以借鉴
正式从事电子硬件设计工作四年多了,回忆起接触电子的这几年,感触很多--虽然经历了很多酸甜苦辣,但也给我的生活增添了很多色彩-- 第一次真正意义上的接触电子应当算是高中的时候.当时很喜欢学校图书馆里的一 ...
- 电子工程术语和定义列表
按字母顺序排列: 电子工程术语和定义列表,按字母顺序排列 1-Wire 单线(加地线)通信协议. 更多信息,请参考: 1-Wire存储器产品 1-Wire接口方案 1-Wire软件工具 1-Wire ...
- 普渡大学电子计算机专业,普渡大学电子工程(EE)专业介绍
普渡大学(Purdue University)的ECE系(School of Electrical and Computer Engineering)有600多名研究生,超过2/3的学生是在读PhD, ...
- 电子与计算机工程导论,BGPLUS科研荟萃 | 杜克大学 | 电子工程、计算机工程:电子与计算机工程导论...
原标题:BGPLUS科研荟萃 | 杜克大学 | 电子工程.计算机工程:电子与计算机工程导论 课题名称 = 电子与计算机工程导论 = 课题简介 本课题涵盖数字硬件设计.电子与计算机工程和5G网络的基本概 ...
- kcl计算机通信专业,KCL伦敦国王学院计算机和电子工程介绍
原标题:KCL伦敦国王学院计算机和电子工程介绍 KCL国王学院本科很多学生都会选择计算机科学,但是这门课程竞争十分激烈,如果本身条件不是十分突出的话,立思辰留学360建议申请电子与信息工程学士取代!能 ...
- 计算机无限办公网络应用与推广论文,无线办公局域网的设计与实施(毕业论文终稿).doc...
办公无线局域网的设计与实施 PAGE 设计(论文)题目 办公无线局域网的设计与实施 学 院: 电子与信息工程学院 学生姓名: 曾桂晃 专业班级: 20008级计算机网络3班 学 号: 20082043 ...
最新文章
- Android Studio 3.5 之后导入第三方Library 库的方法
- ubuntu live cd修复grub引导项
- unity 200.8m yoy_【Unity文档】Realtime GI介绍(一)
- python类型转换异常捕捉_Java中的异常
- 大整数加法(信息学奥赛一本通-T1168)
- PostgreSQL9.6+PostGIS2.3学习笔记(一)导入shp文件
- 李国庆夺章后“发配”俞渝,当当网上线“从摔杯到抢章”专题,书目亮了
- 中欧 PHP 开发者大会因多元化争议而取消
- c语言:使用main函数的参数,实现一个整数计算器
- 新手学编程必会的100个代码
- 使用官网支持工具制作富士施乐打印机一键安装的程序
- 哈佛幸福课个人使用精华
- 【Seedlabs】Local DNS Attack Lab
- VB模拟满天星空闪烁的效果
- 机器学习学习笔记(3)——量纲与无量纲,标准化、归一化、正则化
- c语言小鱼的游泳时间,信息学奥林匹克竞赛-小鱼的游泳时间
- cyusb3014数据传输出错和蓝屏的问题
- 基于单片机智能数字温度采集报警器系统设计-毕设课设资料
- ARM之S5pv210的USB刷机
- 1T和12T单片机的区别,移动app开发
热门文章
- 3d打印技术应用实例_3D打印(工作,优势和应用)
- P13: * Component组件拆分、子组件向父组件传递数据
- Python递归学习6 涂格子问题
- SpringBoot + MyBatis-Plus + Shiro授权认证
- Python网络数据爬取及分析-智联招聘
- 3.2 语音和语言处理简史
- epub格式电子书剖析 .
- Codeforces Round #670 (Div. 2) C D E
- 三国演义人物出场顺序统计(文本词频统计)
- 苹果XS怎么截屏_苹果发布iOS14,有哪些值得一说的亮点