查看:
14065
回复: 11 |
参赛作品《井上无纸记录仪》
|
|||
陈臻
3
主题
9
回复 |
发表于2017-06-22 08:40:14
|
显示全部楼层
1#
电梯直达
1. 参赛者姓名(必填项): 陈臻 2. 单位或学校名称(必填项): 宁波精丰测控技术有限公司 3. 当前职务或职称(必填项): 工程师 4. 参赛作品的名字(必填项): 井上无纸记录仪 5. 简要陈述您的idea和作品(必填项): 井上无纸记录仪与井下传感器组成油井井下测量系统,完成对井下压力、温度信号的实时采集与记录。主要可以完成以下功能: ● 井下压力、温度信号的实时采集 ● 程序可通过u盘进行在线升级 6. 拟用到的立创商城在售物料(必填项): EL357N(B)(TA)-G 7. 拟用到的非立创商城物料或其它补充(必填项): FTC359B AMC1200BDWVR 【作品正式发表(报名成功后进入设计阶段)需要填写的内容】 一、作品简介 例如,可以包括但不局限于以下内容: 作品外观:
主板部分
显示板反面 显示板正面
整机图 该作品的主要功能是利用单通道通过一定的时序和电源方向来采集2-4通道的压力温度信号,并进行长时间的数据存储,内部存储器最大可扩展到32G,至少可以采集10年以上的数据 以上并不重要,个人感觉重要的是下面部分,在此先吐槽下立创社区帖子编辑功能,之前一口气全部写完了,写的非常非常多,结果点击保存帖子,马上回到了解放前,心有多累阿,能不能加个即时保存的功能,向腾讯QQ空间学习学习,体验真的很差!现在没办法,只能写一段,保存一下,保存前还得复制一下,尽量降低损失。 这个作品里面有些方面可以拿出来共享下,在其他地方都可以借鉴应用,高手可忽略。 1.大容量数据快速存储方案:简单的说是把采集的数据往铁电中存,存到一定空间时(大概是4k),马上转移到U盘,或者大容量的flash中,主要考虑到u盘,flash擦写次数越多,速度上会下降,也有可能会写坏,因此使用FRAM来进行过渡 2.隔离电流4-20mA采集方案:以前的方案相对比较奢侈,采用磁隔离器+AD芯片+微功率隔离电源方案,成本比较高,也浪费了MCU内部的ADC,现在应用了新的方案,采用隔离放大器+仪表运放+微功率隔离电源的方式,成本能有所下降,可靠性还是后者比较可靠些。 3.隔离485通讯方案:在作品中有2种方案,一种是金升阳的TD系列方案,另外一种是ADI的ADM2582E方案,后者体积更小,属于芯片级,隔离电源也设计在内部,成本也是后者低一些,实际测试下来,ADI方案距离1km误码率相对TD方案要低,建议大家采用ADI的方案。 4.通过U盘或者485总线升级程序。这个功能的思路是这样的,首先需要写一段引导代码,代码起始地址设置为0x8000000,大小设置64K,它的主要功能是复制u盘或者通讯中的数据写入到起始地址为0x8010000的用户程序区,将用户程序覆盖。这里也会引发很多问题,比如升级过程中u盘拔出导致升级失败了怎么办?外部u盘一直插着,忘拔了,开机就升级程序如何处理?等等这些都需要一整套的机制在处理,下面会慢慢提到,这个功能用的好,可以解决因为开发周期短导致有BUG,而客户无法对程序进行升级的困难,如果用的不好,升级失败了,反而成了板砖,客户的心理阴影肯定会很大,毕竟这个板砖比较大。 5.触摸式输入方案,相比按键式或者轻触式,寿命更长,结构更简单,按键没有抖动,MCU处理起来会简单许多,这里采用的是FTC359B芯片的设计方案。使用起来感觉还是挺不错的
二、系统构架图
三、硬件部分的描述 1.电源部分 ACDC EMC电源,采用的是金升阳的模块电源,其中有一款电压比较宽,现在还不是很成熟,并没有进行测试 2.内部存储部分 usb部分采用南京沁恒CH376的芯片方案 3.隔离485部分 上面的EMC电路是金升阳推荐电路 4. PWM转4-20mA或0-20mA电路 这个电路推荐给大家,非常稳定 5.隔离电流采集(5-10mA) 6.继电器驱动电路 虽然简单,但经常会有工程师设计出问题 四、材料清单(BOM列表) EL357N(B)(TA)-G C6649
五、软件部分的描述(选填) 软件部分因为保密,只能把Bootloader写的过程发出来,仅供交流学习
1. Bootloader的设置 在正常配置工程的基础上,根据boot工程文件的大小来设定需要用到的程序空间大小,如图,在红色方框内将原本0x80000(512K)的size大小改为0x10000(64K),剩余的空间用于存放在实际应用中需要运行的代码 ,在Debug设置中也需修改
2. APP 程序地址修改 在APP程序中,将flash起始地址设为boot程序的末尾地址(0x801000),代码空间(size)可选择范围最大为0x70000(448K),Debug中做同样设置
3.APP程序生成.bin文件方法 APP程序中在user选项下勾选 After Build/Rebuild中的Run#1 并配置其路径 D:\Keil_v5\ARM\ARMCC\bin\fromelf.exe --bin -o ..\..\Output\BH-F103.bin ..\..\Output\Template.axf
D:\Keil_v5\ARM\ARMCC\bin\fromelf.exe为本地安装Keil软件的fromelf.exe文件的路径,通过右侧打开文件方式直接选择 ..\..\Output\Template.axf为生成bin文件的依赖文件,其路径和文件名在编译工程时可看到
--bin -o ..\..\Output\BH-F103.bin用于生成bin文件,其中--bin –o为生成bin文件的指令,..\..\Output为文件路径,需和axf文件保持一致 BH-F103.bin为生成的bin文件的文件名,用于通过U盘升级程序
3.在boot程序中关闭中断 在最后一条跳转指令之前加入关闭中断指令__disable_irq();
3.给APP中的中断向量做偏移 在程序开始运行前加入: SCB->VTOR = 0x8000000 | 0x10000; __enable_irq(); 中断向量的偏移用SCB->VTOR = 0x8000000 | 0x10000;或NVIC_SetVectorTable (NVIC_VectTab_FLASH, 0x10000);都可以 关于中断跳转后可能出现的死机的情况,在某些情况下光用__disable_irq();和__enable_irq();两条语句无法完全规避,具体情况可访问网站http://www.eeworld.com.cn/mcu/article_2017020533639.html解决 Boot程序的flash擦出设置为安全起见可设置为全部擦出
void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; //PC5 作为模拟通道10输入引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure USART1 Tx (PA.09) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART1 Rx (PA.10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); } //系统中断管理 void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif /* Enable the USARTy Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } //配置系统时钟,使能各外设时钟 void RCC_Configuration(void) { SystemInit(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO |RCC_APB2Periph_SPI1, ENABLE ); } void InitDis(void) { /* LCD Module init */ } //配置所有外设 void Init_All_Periph(void) { RCC_Configuration(); GPIO_Configuration(); NVIC_Configuration(); USART1_Configuration(); CH376_Init(); mInitCH376Host(); LCD12864_GPIO_Config(OUTPUT);//LCD12864 IO口配置 Init_LCD12864(); } void BootLoader_Jump(uint32_t Sect, uint32_t Msp, uint32_t Reset) { uint32_t base; uint32_t offset; iapfun jump2app; base = (Sect > NVIC_VectTab_FLASH ) ? NVIC_VectTab_FLASH : NVIC_VectTab_RAM; //中断向量表基地址 offset = Sect - base; //中断向量表偏移 NVIC_SetVectorTable( base, offset ); //重定位中断向量表 jump2app=(iapfun)*(uint32_t*)(Sect+4); //用户代码区第二个字为程序开始地址(复位地址) __set_MSP(*(uint32_t*)Sect); //初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); } int main(void) { mDelaymS( 200 ); mDelaymS( 200 ); mDelaymS( 200 );//CH376建立需要时间 Init_All_Periph(); Flash_Init(); //初始化Flash BootLoader_FromUSB(); //Bootloader从USB更新固件 } 六、作品演示 请上传您的作品的功能演示到腾讯视频,并编辑到本楼(或附上视频链接)。按要求上传视频可获得5分,具体详见活动规则。 七、总结 感谢主办方给予这次机会,这个项目也是刚立项不久,历时近2个月,在过程中遇到的困难也是不少,电路上出现过32k晶振不起振的情况,虽然后面通过引脚加焊的方式让它振荡了,但这应该不是真正的原因,负载电容和走线布线可能是主要问题,留着下一版本解决。在升级程序上也摸索了好几天,现在才比较稳定,经过各种意外测试,比如升级过程中断电,升级过程中电压不稳定,升级过程中加强干扰等等。 |
|||
陈臻
3
主题
9
回复 |
发表于2017-07-25 20:32:57
|
显示全部楼层
6#
嗯,测试通过了
|
|