Life Detector

功能需求:
正常模式:每次上电,指示灯亮一下,报警器响一声。报警指示灯约60s亮一下,大约每5s检测周围infrared signal。
低压模式:电池电压低于设定值时(例2.8V),报警器器每60s响一下,提醒电池欠压,更换电池。
Life模式:当infrared signal达到检测值时,指示灯快闪,报警器报警。
Test模式:长按test键,指示灯快闪,报警器报警,松开按键后,报警器恢复到正常模式。
消音模式:Life模式下,按下test键,报警器在90s内失去报警功能,如果一直在Life模式下,90s后报警器继续报警,若在消音模式下,再次检测到Life,报警器依然报警。
RF功能:在Life模式下,向服务器发送芯片滚码(2.5B地址+0.5B功能码)。
解决方案:
成本考虑,采用8pin的8位的OTP型MCU
1K* 14位一次性可编程ROM(OTP-ROM),64×8位的数据存储器(RAM),两组双向I/O口,2个8位定时 器/计数器,5路PWM,LVD检测。
原理图:
schematic diagram
software module:
学会使用demo例程代码,初始化IO、Timer、中断。先完成底层设计(当时我只会这个),在实现功能。
对单片机的输入输出来说,由外部控制单片机,配置为输入。由单片机控制外部电路,配置为输出。
首先先实现报警器能叫,灯能亮。灯亮很简单PB0输出0(一开始设置为输入,也会亮只是没哪么亮,硬件师傅说的)。报警器,利用的是无源蜂鸣器。通过PWM信号驱动。一开始这还没不简单想直接用PWM功能的,后面fae强烈建议直接利用IO取反方便多了,一开始我没采纳结果半天不叫,最终还是妥协使用IO取反。
后面用靠二三十分英语直译的水平一下就把代码写完了,结果灯一直亮,插电就亮,逻辑分析仪测了下,逻辑全都是乱的,麻了。请师傅一看,灯闪居然用delay,这堵塞CPU啊,如果我上家方案公司看到我这样写,肯定会骂死我,老师傅原话-,-
后面从头再来,IO没问题,Timer选择上出了问题。PWM实际上也是个Timer,该MCU就Timer0和Timer1两个,选择PWM的话 必须占用Timer1,然后Timer0用来定时基,但是后面TImer0和WDT又只能分频一个,所以综合考虑,Timer1时基,WDT唤醒,IO模拟PWM。
接下来就是实现功能函数了。首先实现慢闪,例如亮100ms、灭100ms,这样循环执行多少次。最开始亮灭用一个计数值对2取余来实现,结果效果不好、会出现亮完后最后灯还是亮着的,后面改用IO取反,每100ms进来一次,没进来之前保持上一次的状态,最后在计数值为0时,直接关闭灯。

void Led_blink(void)
{
	if(!flag_10ms)
	return;
	flag_10ms = 0;
	if(Led_100ms++ < 15)
	return;
	else
		Led_100ms = 0;
	if(Led_Cnt == 0)
	return;
	Led_Cnt--;
//	if(Led_Cnt%2 == 0)
//	{ 
//		LED_R=1;
//	}
//	else
//	{
//		LED_R=0;
//	}
	if(Led_Cnt > 0)
	{
		LED_R=!LED_R;
	}
	else 
		LED_R  = 1;	
}

接着是报警功能,最开始是直接放在中断里面取反。timer125us进一次中断 刚好配上4Khz的蜂鸣片,弄个计数值放在里面减减,然后要响久一点就把这个值舍得好大一开始一个8位值远远不够,就又弄了个值和这个相乘,搞得好麻烦,赋值在哪里都不合适每次进来都重新赋值,而且最致命的是 后面以为搞成了,接去测一直响根本不是报警声,简直就是噪音。
最后还是模仿灯亮灭的思想,直接在中断里判断标志位,满足就翻转BUZ1对应的IO,否者就关闭该IO。在解决一直响的问题,示波器测了下成品是500ms内响200ms停300ms,总的响的时间即次数还要另外设定个值,具体如下。(Beep_Time是放在20ms中断中减减,赋值250就是持续5s(理论值,实际值还得靠仿真器仿))

void Buz_ring()
{
 if(Beep_Time)
 {
	if(!flag_20ms)
	return;
	flag_20ms = 0;
//	Beep_Time--;
	if(Buz_Time++ <=12 && Beep_Time>0)		//500ms
	{
		if(Buz_Time <=5)		//200ms
			a=1;
		else
			a=0;
	}
	else
		Buz_Time = 0;
 }
}

之后就是按键功能,主要实现的就是短按和长按,这个是直接copy老师傅的就不发了,主要就是按键计数和短按长按标志位设定,小于40ms设定为短按,大于80ms为长按。
比较头痛的还是低功耗问题,后面才知道该成品为了省电,主旋律就是休眠状态,每5s来唤醒一次,一次就醒来几十个ms甚至几个ms,后面设标志位醒来后1s之后才能进休眠。醒1s就是1s后进入休眠,这个编程思想,作为小白的我是真的后面才接触到,就好像亮灭100ms,就是100ms之前保持原有的状态。后面的功能大部分都是if,标志位,中断 循环逻辑利用,就不详说说。要注意下,进休眠的条件要严谨,进休眠前的IO方向的IO电平要固定好,不然很影响休眠功耗(就是则个问题搞得我奔溃,这里只能一笔带过-。-),之前还有个比较头疼的问题,就是唤醒几次后怎么在第60s时灯亮一下,这个真的搞得我头疼,亲自跑到fae哪里,求他教我都不告诉我的,后面临近开项目会,自己一下子就想出来了,mmp,真不容易啊。(利用标志位实现)

总结下,这算是我人生第一个项目了吧,之前在大学实训的时候,真的实训月就是折磨,根本不想去,不去也不行,听也听不懂,做完之后最最最头痛的就是还写实训报告,每次都是各路求神仙,各取一段,然后CV大法。害,想不到今天自己居然还亲自来写个总结,真是少壮不努力,老大徒伤悲。当初要是能吃透两三个实训,现在也不是这个水平了,可是当时哪知道实训这东西这么重要,后面自己挤破头也想进研发,靠得就是项目经验,次次实训划水,项目经验为零。最讽刺的是毕业后的几个月,主动去翻出当年的实训报告来学习,发现自己做的比当年的实训也太简单了8。
做为第一个项目,我是真的很想搞出来,真的就是睡觉前都在想,需求怎么实现,需求怎么实现,这到底要怎样才能做出来!!(大学没码过代码,计算机毕业学生表示惭愧),后面老板施压做不出来就去测试打螺丝,再加上真的是很想弄出来 但是自己是真的水平太差了,导致自己出现畏难情绪,还特别怕老板 真的服了,最严重的时候怕的手抖,吃了没实力就没底气的亏。我深知自己学习了很多专业词汇,但是就是没有编程思想,只能充其量是个“理论大神”,所以这个亲自实操编码的项目对自己来说是何其重要。
很开心自己后面把功能都实现出来了,但是没达到产品量产要求,因为唤醒电流过大,这个真是超出自己的能力范围了,后面RF功能又因为RAM不够用也没实现成功,不过总的来说对于现在自己算是项目完成了!谢谢自己完成了人生的第一个项目,终于知道中断 定时器 标志位 看门狗 等等是个什么东西了,终于弄清了自己一直想弄清楚的东西 时钟源频率、系统时钟、指令时钟(如果 OPTION 选择 8M/2T,则 Fosc=16M,Fsys=8M,Fcpu=4M。)
每条C语句转换成Asm才可以计算每条语句执行的时间,这里的语句就是汇编语句,大部分一条汇编一个执行周期、有的需要两个周期,所以一条语句执行完的时间就是1/Fcpu,0.25us就执行完了(之前还去算了下例程延时是怎样才是延迟了1us 这个值怎么是这样的 原来这个不需要我去算 我不动他 直接拿来用他就是对的 这个是需要转换成汇编才算得出来的)
最重要的是有了点编程思想,谢谢你,感谢你顶住压力,加油!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值