语言学学习心得百度(精选4篇)
每当作文时,思绪总是喜欢飘回从前。
那时我还是一名初一新生。在小学时作文就极差的我,不禁有些担心起初中的作文了。虽然在我的作文中不乏有高分作文,但那一定是我从网上抄来的。小学老师只要一留作文,我回家的第一件事就是打开电脑,找一篇合适的,然后删一删,改一改,于是一篇作文就完成了。现在已经上初中了,我决定让我的作文有一些改观。
现在,我的作文水平有了一些提高,在这个提高的过程中,我总结出了一些经验,让我现在写作文不再发愁了,写作成了一种乐趣。我认为,要想写好作文,先要确定好中心。有了一个好的中心,其它的也就不是什么困难了。什么才是一个好的中心呢?首先这个中心是明确的,不能含含糊糊,中心是什么自己都不知道。其次,选的中心最好是一个好选材的,这样可以缩短思考时间,但却不能太俗气,如果真的没有好中心,选一个俗套的也没事,那么就要谈到下面一点了选材。选材在作文中也是一个很重要的部分。如果一个俗套的中心加上一个俗套的选材,那么这篇文章就绝对不可能成为一个好文的。选材好具体为:一定要新颖,不能够太大众化,要给老师一种眼前一亮的感觉。一个新颖的选材可以让你的文章提升一个档次,而不错的文字也能让你的文章增色不少。每个人的语言特点不同,有的人语言简洁朴实,有的人语言幽默风趣,有的人语言感人唯美,这也让每个人的文章有所不同。让作文提升最重要的一个途径就是要多练,等练到一定篇数时,就会量变引起质变,让你的作文提升一大个台阶。
正所谓:众里寻他千百度,默然回首,那人却在,灯火阑珊处。做事如此,作文也如此。|||fwJIA.COM/zUOweN教师频道编辑为参教师资格考试的考生搜集整理了:作文学习心得之众里寻他千百度等信息,祝愿广大考生取得满意的成绩。
每当作文时,思绪总是喜欢飘回从前。
那时我还是一名初一新生。在小学时作文就极差的我,不禁有些担心起初中的作文了。虽然在我的作文中不乏有高分作文,但那一定是我从网上抄来的。小学老师只要一留作文,我回家的第一件事就是打开电脑,找一篇合适的,然后删一删,改一改,于是一篇作文就完成了。现在已经上初中了,我决定让我的作文有一些改观。
现在,我的作文水平有了一些提高,在这个提高的过程中,我总结出了一些经验,让我现在写作文不再发愁了,写作成了一种乐趣。我认为,要想写好作文,先要确定好中心。有了一个好的中心,其它的也就不是什么困难了。什么才是一个好的中心呢?首先这个中心是明确的,不能含含糊糊,中心是什么自己都不知道。其次,选的中心最好是一个好选材的,这样可以缩短思考时间,但却不能太俗气,如果真的没有好中心,选一个俗套的也没事,那么就要谈到下面一点了选材。选材在作文中也是一个很重要的部分。如果一个俗套的中心加上一个俗套的选材,那么这篇文章就绝对不可能成为一个好文的。选材好具体为:一定要新颖,不能够太大众化,要给老师一种眼前一亮的感觉。一个新颖的选材可以让你的文章提升一个档次,而不错的文字也能让你的文章增色不少。每个人的语言特点不同,有的人语言简洁朴实,有的人语言幽默风趣,有的人语言感人唯美,这也让每个人的文章有所不同。让作文提升最重要的一个途径就是要多练,等练到一定篇数时,就会量变引起质变,让你的作文提升一大个台阶。
2011年金秋时节,我有幸来到北京语言大学,参加为期一年的学习。此次培训主要包括英语语言培训和对外汉语教学法培训。英语类课程包括听、说、读和写。北京语言大学是我国唯一一所,以对来华留学生进行汉语教育和中华文化教育为主要任务的国际型大学,素有“小联合国”的美誉;同时,北语还承担着对中国学生进行多种外语、对外汉语、汉语言文学、绘画、金融学、会计学、信息科学等专业教育,以及开展出国留学预备人员进行出国前外语培训的工作。现在,学校已形成了特色鲜明、优势明显、结构合理、内容充实的学科体系。从短期教育、速成教育、网络教育到本科生、硕士生、博士生教育,学科层次齐备,教育教学质量受到国内外普遍好评。一年的培训,让我体会最深的是以下几个方面:
一、北语校园印象
景色优美,绿化面积高,是一所漂亮精致的国际型大学。
春天,林荫路边粉红的桃花已盛开,陪衬着路边高大的法国梧桐。路上,各种肤色的学生川流不息,走上100米,就能听到多种语言。两名黄皮肤的女学生从身边走过,用英语和一位黑人学生打过招呼后,下一句从嘴里“蹦”出的却是韩语。然而,在白雪皑皑的冬季。在校园一角,一位满头银发的外籍教师带领若干中国学生正在搞“英语花园”活动,火热的学习景象让人记忆深刻。
这就是“色彩缤纷”素有“小联合国”美誉的北语。有人这样形容,在北语,呼吸的是法国的浪漫,感受的是巴西的奔放,体会的是中国的古典。在北语的任何一个角落,都有可能成为最新“韩流”服饰的展示台。在这里,亦不缺少阿拉伯式长袍、印度纱丽的点缀,纵使脚步匆匆,也能收获诸多风景。不用出国却有留学之感,这是历届北语中国学子的共识。经过北语独特的多元文化熏陶,让无数的中国毕业生在外交、商业、对外汉语教学等领域中如鱼得水。
二、万国墙、语伴和小奥运会
当和煦的春风夹杂着泥土芬芳拂过粉红的脸庞时,柳树早已迫不及待地吐出翠绿嫩芽。无论走在校园哪个角落,随时都能感受到扑面而来的盎然春意。
站在刻有“龙虎曲水”字样的小石潭和一弯小巧汉白玉石桥旁边,就能看见语言大学的标志性建筑——“万国墙”了。为什么叫“万国墙”呢?因为上面刻着160多个国家的名字。来自160多个国家的7000多名留学生在这所堪称国际型大学里学习汉语。
说起北语,大家的第一反应就是“美女多,老外多”。的确,据说北语的男女比例为1:7。瞧!两位抱着课本的金发碧眼、身材超棒的欧洲美女正边走边用流利的汉语聊天,一群衣着时尚,火辣、温柔的韩国少女们说着抑扬顿挫的韩语叽 1 叽喳喳地向教室走去。炎热夏天,印度少女便披上飘逸艳丽的纱丽,像一道流动的彩虹随风飘舞。操场上永远活跃一群对中国功夫深深着迷的老外。刀枪棍棒,剑术长拳,太极拳双节棍,一招一式打起来可是毫不含糊。草坪的石凳上总少不了一对对“语伴”的身影,一个中国学生一个外国学生,一个学习汉语一个学习英语,互相学习,共同进步。久而久之,“语伴”现象成为北语独特校园文化不可缺少的一部分。
北语运动会可说是“小奥运会”了。北语学子不仅能参与其中,与留学生同场竞技,过一把参加“奥运会”的瘾,还可以目睹留学生身着特色鲜明的民族服装接受检阅的精彩场面。韩国长裙、泰国筒裙、日本和服、墨西哥草帽、苏格兰裙、阿拉伯长袍等,让人眼花缭乱,目不暇接,体现了浓郁的国际特色。此外,各种语言类、体育类、文艺类社团让你有足够空间施展才华,发挥特长。
隔壁同学说,生活在北语和出国几乎没有什么两样。特色鲜明的校园文化,浓郁的国际化氛围是全中国其他任何一所大学都无法比拟的。寝室是标准4人间,还有电视,可以收到4个英文台,2个韩语台,以及西班牙语台,日语台等。校园小巧精致,鸟语花香,怪不得被誉为“中国最惬意的大学”。
三、话说北语
北京语言大学是教育部直属的公办全日制高等院校,是我国惟一一所以对来华留学生进行汉语和中华文化教育为主要任务的国际型大学。北京语言大学的前身——外国留学生高等预备学校,创办于1962年,1964年6月由国务院批准定名为北京语言学院,1996年6月更名为北京语言文化大学,2002年7月经教育部批准校名简化为北京语言大学。
在国内,北语是从事对外汉语和中华文化教育历史最长、规模最大和师资力量最雄厚的外语类院校。建校40多年来,已为世界上160多个国家和地区培养了十万余名懂汉语、熟悉中华文化的留学生。学校和世界上37个国家和地区的185所大学建立了良好的校际交流关系并在国内一些省市设立了联合办学点,还在韩国、新加坡、泰国等国家设立了办学机构。
北语承诺:不让学生因贫困辍学
为了帮助家庭经济困难的学生完成学业,北语有一项承诺:不让学生因贫困辍学。北语通过奖学金、勤工俭学、发放补助金等各种方式予以扶持,还为家庭经济困难的同学设有勤工助学工作岗位,学生可在业余时间通过劳动获取一定报酬;学校设有助学金,每月将120元打入学生饭卡,平时视学生困难情况还会发放一定数额生活补助金;少数学习特别优秀的贫困学生可减免学费;学校帮助家庭经济特别困难的学生申请国家助学贷款,解决学费和基本生活费。
四、思想的冲击
“大学之大,非谓有大楼之谓也,乃谓有大师之谓也。” 北京语言大学之所以大,不因为的校园面积很大,而是因为精英荟萃,大师辈出。我不得不说,在北语听课的感觉,真好。
(一)英语语言培训
这次英语培训涉及了教学中重点,从基础出发,深入浅出系统的让培训者更加体会了,语音是语言传播关健,让我们更好的正确的解读了课标,也就正确把握了教学的方向。教学不是唯一的以老师为主角的活动,她是师生间的双边活动,以至于学生是主角,老师是配角,如何让学生在知识的界面里不觉得的枯燥乏味,恰是这次培训中学习和体会到的教师的教学技能。转变了观念也就转变了教学技能,思想新了,办法也就有了,教学设计改变了课堂教学的模式。培训中,在教学传授中,老师渊博的知识,丰富的教学经验,高超的教学艺术,让我们饶有兴趣,深深不忘,深有启发。
有机会面对这么多的高水平的老师。在交流中,从他们身上我感悟到了很多新的教学方法和经验,还请教了我在教学中遇见的各种问题,感受颇为深刻。培训中,指导老师提出了许多非常好的做法,有很多是经验之谈,与我在实际中的实践反思相借鉴并变通使用别人成功的做法,进而形成自己的教学风格,对我来说都是弥足珍贵。一个人只有放开眼界去交流沟通才能丰富自己提高自己,学然后知不足。我觉得正是这次学习培训,让我看到了自己与他人的差距。但是正是这份带着对今后工作的遐想,让我内心蒙发了更高的自我期许,在今 后工作中将学到的能学以致用,我会学得更好,用的更好。
(二)对外汉语教学
北京语言大学对外汉语专业全国排名第一,所以,我很有幸在北语接受了对外汉语教学培训。
此次培训使我对对外汉语教学这门学科有了更多的认识和更大的信心。以前,很多教师认为,对外汉语教学不需要很高的技巧,套用一句话“只要是中国人就会教汉语”,经常把我们看作“二等公民”;我们老师在平时的教学中,也经常会感慨以前的一些知识(比如说古诗、经典文学)和教学的技巧在这里用不着了、慢慢地荒废了,给人感觉“学无所用”。
当然,有时候这些情况客观存在,其实它又是片面的。首先,会教汉语并不等于教得好汉语。有很多很优秀的老师初步接触对外汉语教学的时候,往往把外籍学生当中国学生来教,效果很不好。真正想把对外汉语教学钻研透(当然,从现在来看,在中国还没有一个人敢这么说),必须对学生的心理、文化、甚至的母语发音习惯都有很细的研究,这些比传统的语文教学要复杂得多,也由此可见对我们留学生部老师的教学技能和素养要求也要高得多;其次,从对外汉语教学 3 学科本身看,她如朝阳,正冉冉升起。
由于是教语言类课程,所以我比较注重课堂教学技巧的学习。课堂教学如果要细分,可以分为语音教学、词汇教学、语法教学、汉字教学、汉语写作教学、听力教学等。课堂教学技巧一类是教师在课堂教学中为使学生理解和掌握汉语技能所使用的手段,比如我们老师经常用的多媒体、图片、字词卡片等等,一类是学生在老师的指导下进行的课堂操练方式。(前一类主要是老师行为,后一类主要是教师指导下的学生行为)
总之,对外汉语教学的技能要求较高、技巧繁多,作为一名合格的对外汉语教师,仅一个月的学习是远远不够的,只是希望在今后的工作中与老师们共同摸索、提高。
五、名师讲坛
在北语学习的另外一大好处就是有机会听名师讲坛,可以和有些有名的智者面对面,聆听他们精彩的人生感悟。3月28日晚,由校团委、校学生会主办的“聆听智慧·启迪人生”北京语言大学名师讲坛之六小龄童专场在主楼209如期举行。
晚上7点整,家喻户晓的《西游记》孙悟空扮演者著名艺术家章金莱老师准时出现,座无虚席的现场顿时爆发出热烈的掌声。刚上台,章老师就向大家表达最诚挚的感谢。章老师先从自己的名字聊起,爆料自己是全国唯一拥有两张身份证的公民,的确六小龄童这个名字在中国几乎无人不知无人不晓。除了孙悟空,章老师还饰演过许多深入人心的角色,如吴承恩,周恩来,胡适,鲁迅等,但是正如章老师所说的,“一个人一生做好一件事”,他承认自己塑造得最成功的角色,还是孙悟空。《西游记》历时17年拍摄完成,充满了各种困难和艰辛。对章老师来说,各种受伤意外早已是家常便饭,但是他始终坚持着,专业并且敬业,才成就了神通广大的孙悟空。对于表演艺术,章老师认为“雅俗共赏,老少皆宜”是优秀艺术的标志,他强调表演要生动鲜活,栩栩如生。这几年,章老师一直致力于西游文化的弘扬与传播,他希望自己在后半生可以将猴文化发扬光大,使其走出国门,走向世界。
在随后的互动环节,同学们向齐天大圣踊跃提问。有同学问到章老师和猴子互相敬礼的故事,章老师风趣幽默的叙述让在场的观众忍俊不禁,也让大家从侧面了解章老师模仿猴子的神似,还有同学希望章老师对于文化传承提出建议,章老师用写毛笔字的例子告诉大家,文化需要继承创新发展,要做到人无我有,人有我好,人好我精,人精我绝,人绝我换。
在最后的表演环节,章老师邀请台下的同学上台,传授表演技巧,随后的耍金箍棒更是夺人眼球,不少女生大叫“好帅”,台下掌声经久不息。讲座最后,4 主持人发动全场观众预祝章老师生日快乐,学生会代表与章老师互赠礼物。章老师向大家致谢并送给大家一句话:苦练七十二变,笑对八十一难。
六、吾生有涯,而知无涯
“世界是同样的世界,人生是同样的人生”。但是同样的世界和同样的人生对于每个人的意义是不同的。北京语言大学有中国首屈一指的教授,也有中国优秀的学生。“山外有山、人外有人”的谚语在这里能充分的展现。十分佩服学者教授们的口才、自信、渊博、睿智。要达到这样的境界,让我领悟到才学和智慧对于一个人的一生是何等的重要,我们所拥有的一切如金钱、荣誉、美貌……在才学和智慧面前只不过是水中月,镜中花,终将如过眼云烟,随风而逝。一个人的才识和智慧决定了他的精神境界,有意义、有价值的才是精彩的人生。
“吾生有涯,而知无涯”,回来后,我辗转反侧,我对自己近些年来荒芜于学习感到非常羞愧,曾几何时,我是多么地喜欢看书学习。而今,我还是应该多在读书学习上下点工夫,博览群书,多关心国内外大事,多学习英语,提高语言能力,不断学习新的东西,才能在自己的脑子里多装点东西,内容丰富了,才识才会增强,才能更加适应新形势的需要。
北语一年的学习机会难得,感悟至深,培训虽然结束了,但我的学习并没有结束。我领悟这么多的新知识、新思想,有机会不断丰富自己,提高自己。我一定不辜负组织和领导的希望,用所学更好地为地区发展贡献自己的力量。
学习单片机也已经有几年了,藉此机会和大家聊一下我学习过程中的一些经历和想法吧。也感谢一线工人提供了这个机会。希望大家有什么好的想法和建议都直接跟帖说出来。毕竟只有交流才能够碰撞出火花来^_^。
。“卖弄”也好,“吹嘘”也罢,我只是想认真的写写我这一路走来历经的总总,把其中值得注意,以及经验的地方写出来,权当是我对自己的一个总结吧。而作为看官的你,如果看到了我的错误,还请一定指正,这样对我以及其它读者都有帮助,而至于你如果从中能够收获到些许,那便是我最大的欣慰了。姑妄言之,姑妄听之。如果有啥好的想法和建议一定要说出来。 几年前,和众多初学者一样,我接触到了单片机,立刻被其神奇的功能所吸引,从此不能自拔。很多个日夜就这样陪伴着它度过了。期间也遇到过非常多的问题,也一度被这些问题所困惑„„等到回过头来,看到自己曾经走过的路,唏嘘不已。经常混迹于论坛里,也看到了很多初学者发的求助帖子,看到他们走在自己曾走过的弯路上,忽然想到了自己的那段日子,心里竟然莫名的冲动,凡此总总,我总是尽自己所能去回帖。很多时候,都想写一点什么东西出来,希望对广大的初学者有一点点帮助。但总是不知从何处写起。今天借一线工人的台,唱一唱我的戏
一路学习过来的过程中,帮助最大之一无疑来自于网络了。很多时候,通过网络,我们都可以获取到所需要的学习资料。但是,随着我们学习的深入,我们会慢慢发现,网络提供的东西是有限度的,好像大部分的资料都差不多,或者说是适合大部分的初学者所需,而当我们想更进一步提高时,却发现能够获取到的资料越来越少,相信各位也会有同感,铺天盖地的单片机资料中大部分不是流水灯就是LED,液晶,而且也只是仅仅作功能性的演示。于是有些人选择了放弃,或者是转移到其他兴趣上面去了,而只有少部分人选择了继续摸索下去,结合市面上的书籍,然后在网络上锲而不舍的搜集资料,再从牛人的只言片语中去体会,不断动手实践,慢慢的,也摸索出来了自己的一条路子。当然这个过程必然是艰辛的,而他学会了之后也不会在网络上轻易分享自己的学习成果。如此恶性循环下去,也就不难理解为什么初级的学习资料满天飞,而深入一点的学习资料却很少的原因了。相较于其他领域,单片机技术的封锁更加容易。尽管已经问世了很多年了,有价值的资料还是相当的欠缺,大部分的资料都是止于入门阶段或者是简单的演示实验。但是在实际工程应用中却是另外一回事。有能力的高手无暇或者是不愿公开自己的学习经验。
很多时候,我也很困惑,看到国外爱好者毫不保留的在网络上发布自己的作品,我忽然感觉到一丝丝的悲哀。也许,我们真的该转变一下思路了,帮助别人,其实也是在帮助自己。啰啰嗦嗦的说了这么多,相信大家能够明白说的是什么意思。在接下来的一段日子里,我将会结合电子工程师之家举办的主题周活动写一点自己的想法。尽可能从实用的角度去讲述。希望能够帮助更多的初学者更上一层楼。而关于这个主题周的最大主题我想了这样的一个名字“从单片机初学者迈向单片机工程师”。名字挺大挺响亮,给我的压力也挺大的,但我会努力,争取使这样的一系列文章能够带给大家一点帮助,而不是看后大跌眼镜。这样的一系列文章主要的对象是初学者,以及想从初学者更进一步提高的读者。而至于老手,以及那些牛XX的人,希望能够给我们这些初学者更多的一些指点哈~@_@
我们首先来看第一章节
从这一章开始,我们开始迈入单片机的世界。在我们开始这一章具体的学习之前,有必要给大家先说明一下。在以后的系列文章中,我们将以51内核的单片机为载体,C语言为编程语言,开发环境为KEIL uv3。至于为什么选用C语言开发,好处不言而喻,开发速度快,效率高,代码可复用率高,结构清晰,尤其是在大型的程序中,而且随着编译器的不断升级,其编译后的代码大小与汇编语言的差距越来越小。而关于C语言和汇编之争,就像那个啥,每隔一段时间总会有人挑起这个话题,如果你感兴趣,可以到网上搜索相关的帖子自行阅读。不是说汇编不重要,在很多对时序要求非常高的场合,需要利用汇编语言和C语言混合编程才能够满足系统的需求。在我们学习掌握C语言的同时,也还需要利用闲余的时间去学习了解汇编语言。
1.从点亮LED(发光二极管)开始
在市面上众多的单片机学习资料中,最基础的实验无疑于点亮LED了,即控制单片机的I/O的电平的变化。
如同如下实例代码一般
void main(void){ LedInit();While(1){ LED = ON;DelayMs(500);LED = OFF;DelayMs(500);} }
程序很简单,从它的结构可以看出,LED先点亮500MS,然后熄灭500MS,如此循环下去,形成的效果就是LED以1HZ的频率进行闪烁。下面让我们分析上面的程序有没有什么问题。
看来看出,好像很正常的啊,能有什么问题呢?这个时候我们应该换一个思路去想了。试想,整个程序除了控制LED = ON ; LED = OFF; 这两条语句外,其余的时间,全消耗在了DelayMs(500)这两个函数上。而在实际应用系统中是没有哪个系统只闪烁一只LED就其它什么事情都不做了的。因此,在这里我们要想办法,把CPU解放出来,让它不要白白浪费500MS的延时等待时间。宁可让它一遍又一遍的扫描看有哪些任务需要执行,也不要让它停留在某个地方空转消耗CPU时间。
从上面我们可以总结出
(1)无论什么时候我们都要以实际应用的角度去考虑程序的编写。
(2)无论什么时候都不要让CPU白白浪费等待,尤其是延时(超过1MS)这样的地方。
下面让我们从另外一个角度来考虑如何点亮一颗LED。先看看我们的硬件结构是什么样子的。
我手上的单片机板子是电子工程师之家的开发的学习板。就以它的实际硬件连接图来分析吧。如下图所示
(原文件名:led.jpg)
引用图片
一般的LED的正常发光电流为10~20MA而低电流LED的工作电流在2mA以下(亮度与普通发光管相同)。在上图中我们可知,当Q1~Q8引脚上面的电平为低电平时,LED发光。通过LED的电流约为(VCC-Vd)/ RA2。其中Vd为LED导通后的压降,约为1.7V左右。这个导通压降根据LED颜色的不同,以及工作电流的大小的不同,会有一定的差别。下面一些参数是网上有人测出来的,供大家参考。红色的压降为1.82-1.88V,电流5-8mA,绿色的压降为1.75-1.82V,电流3-5mA,橙色的压降为1.7-1.8V,电流3-5mA 兰色的压降为3.1-3.3V,电流8-10mA,白色的压降为3-3.2V,电流10-15mA,(供电电压5V,LED直径为5mm)
74HC573真值表如下:
(原文件名:74hc573.jpg)
引用图片
通过这个真值表我们可以看出。当OutputEnable引脚接低电平的时候,并且LatchEnable引脚为高电平的时候,Q端电平与D端电平相同。结合我们的LED硬件连接图可以知道LED_CS端为高电平时候,P0口电平的变化即Q端的电平的变化,进而引起LED的亮灭变化。由于单片机的驱动能力有限,在此,74HC573的主要作用就是起一个输出驱动的作用。需要注意的是,通过74HC573的最大电流是有限制的,否则可能会烧坏74HC573这个芯片。
上面这个图是从74HC573的DATASHEET中截取出来的,从上可以看出,每个引脚允许通过的最大电流为35mA 整个芯片允许通过的最大电流为75mA。在我们设计相应的驱动电路时候,这些参数是相当重要的,而且是最容易被初学者所忽略的地方。同时在设计的时候,要留出一定量的余量出来,不能说单个引脚允许通过的电流为35mA,你就设计为35mA,这个时候你应该把设计的上限值定在20mA左右才能保证能够稳定的工作。
(设计相应驱动电路时候,应该仔细阅读芯片的数据手册,了解每个引脚的驱动能力,以及整个芯片的驱动能力)
了解了相应的硬件后,我们再来编写驱动程序。
首先定义LED的接口 #define LED P0 然后为亮灭常数定义一个宏,由硬件连接图可以,当P0输出为低电平时候LED亮,P0输出为高电平时,LED熄灭。
#define LED_ON()LED = 0x00 //所有LED亮 #define LED_OFF()LED = 0xff //所有LED熄灭
下面到了重点了,究竟该如何释放CPU,避免其做延时空等待这样的事情呢。很简单,我们为系统产生一个1MS的时标。假定LED需要亮500MS,熄灭500MS,那么我们可以对这个1MS的时标进行计数,当这个计数值达到500时候,清零该计数值,同时把LED的状态改变。unsigned int g_u16LedTimeCount = 0;//LED计数器
unsigned char g_u8LedState = 0;//LED状态标志, 0表示亮,1表示熄灭
void LedProcess(void){ if(0 == g_u8LedState)//如果LED的状态为亮,则点亮LED { LED_ON();} else //否则熄灭LED { LED_OFF();} }
void LedStateChange(void){ if(g_bSystemTime1Ms)//系统1MS时标到 { g_bSystemTime1Ms = 0;g_u16LedTimeCount++;//LED计数器加一
if(g_u16LedTimeCount >= 500)//计数达到500,即500MS到了,改变LED的状态。{ g_u16LedTimeCount = 0;g_u8LedState =!g_u8LedState;} } }
上面有一个变量没有提到,就是g_bSystemTime1Ms。这个变量可以定义为位变量或者是其它变量,在我们的定时器中断函数中对其置位,其它函数使用该变量后,应该对其复位(清0)。我们的主函数就可以写成如下形式(示意代码)void main(void){ while(1){ LedProcess();LedStateChange();} }
因为LED的亮或者灭依赖于LED状态变量(g_u8LedState)的改变,而状态变量的改变,又依赖于LED计数器的计数值(g_u16LedTimeCount,只有计数值达到一定后,状态变量才改变)所以,两个函数都没有堵塞CPU的地方。让我们来从头到尾分析一遍整个程序的流程。
程序首先执行LedProcess();函数
因为g_u8LedState 的初始值为0(见定义,对于全局变量,在定义的时候最好给其一个确定的值)所以LED被点亮,然后退出LedStateChange()函数,执行下一个函数LedStateChange()在函数LedStateChange()内部首先判断1MS的系统时标是否到了,如果没有到就直接退出函数,如果到了,就把时标清0以便下一个时标消息的到来,同时对LED计数器加一,然后再判断LED计数器是否到达我们预先想要的值500,如果没有,则退出函数,如果有,对计数器清0,以便下次重新计数,同时把LED状态变量取反,然后退出函数。
由上面整个流程可以知道,CPU所做的事情,就是对一些计数器加一,然后根据条件改变状态,再根据这个状态来决定是否点亮LED。这些函数执行所花的时间都是相当短的,如果主程序中还有其它函数,则CPU会顺次往下执行下去。对于其它的函数(如果有的话)也要采取同样的措施,保证其不堵塞CPU,如果全部基于这种方法设计,那么对于不是非常庞大的系统,我们的系统依旧可以保证多个任务(多个函数)同时执行。系统的实时性得到了一定的保证,从宏观上看来,就是多个任务并发执行。
好了,这一章就到此为止,让我们总结一下,究竟有哪些需要注意的吧。
(1)无论什么时候我们都要以实际应用的角度去考虑程序的编写。
(2)无论什么时候都不要让CPU白白浪费等待,尤其是延时(超过1MS)这样的地方。(3)设计相应驱动电路时候,应该仔细阅读芯片的数据手册,了解每个引脚的驱动能力,以及整个芯片的驱动能力
(4)最重要的是,如何去释放CPU(参考本章的例子),这是写出合格程序的基础。
附完整程序代码(基于电子工程师之家的单片机开发板)
#include
sbit LED_SEG = P1^4;//数码管段选 sbit LED_DIG = P1^5;//数码管位选 sbit LED_CS11 = P1^6;//led控制位 sbit ir=P1^7;#define LED P0 //定义LED接口
bit g_bSystemTime1Ms = 0;// 1MS系统时标 unsigned int g_u16LedTimeCount = 0;//LED计数器
unsigned char g_u8LedState = 0;//LED状态标志, 0表示亮,1表示熄灭
#define LED_ON()LED = 0x00;//所有LED亮 #define LED_OFF()LED = 0xff;//所有LED熄灭
void Timer0Init(void){ TMOD &= 0xf0;TMOD |= 0x01;//定时器0工作方式1 TH0 = 0xfc;//定时器初始值 TL0 = 0x66;TR0 = 1;ET0 = 1;} void LedProcess(void){ if(0 == g_u8LedState)//如果LED的状态为亮,则点亮LED { LED_ON();} else //否则熄灭LED { LED_OFF();} }
void LedStateChange(void){ if(g_bSystemTime1Ms)//系统1MS时标到 { g_bSystemTime1Ms = 0;g_u16LedTimeCount++;//LED计数器加一
if(g_u16LedTimeCount >= 500)//计数达到500,即500MS到了,改变LED的状态。{ g_u16LedTimeCount = 0;g_u8LedState =!g_u8LedState;} } }
void main(void){ Timer0Init();EA = 1;LED_CS11 = 1;//74HC595输出允许
LED_SEG = 0;//数码管段选和位选禁止(因为它们和LED共用P0口)LED_DIG = 0;while(1){ LedProcess();LedStateChange();} }
void Time0Isr(void)interrupt 1 { TH0 = 0xfc;//定时器重新赋初值 TL0 = 0x66;g_bSystemTime1Ms = 1;//1MS时标标志位置位 }
“从单片机初学者迈向单片机工程师”
第三章----模块化编程初识
好的开始是成功的一半
通过上一章的学习,我想你已经掌握了如何在程序中释放CPU了。希望能够继续坚持下去。一个良好的开始是成功的一半。我们今天所做的一切都是为了在单片机编程上做的更好。
在谈论今天的主题之前,先说下我以前的一些经历。在刚开始接触到C语言程序的时候,由于学习内容所限,写的程序都不是很大,一般也就几百行而矣。所以所有的程序都完成在一个源文件里面。记得那时候大一参加学校里的一个电子设计大赛,调试了一个多星期,所有程序加起来大概将近1000行,长长的一个文件,从上浏览下来都要好半天。出了错误简单的语法错误还好定位,其它一些错误,往往找半天才找的到。那个时候开始知道了模块化编程这个东西,也尝试着开始把程序分模块编写。最开始是把相同功能的一些函数(譬如1602液晶的驱动)全部写在一个头文件(.h)文件里面,然后需要调用的地方包含进去,但是很快发现这种方法有其局限性,很容易犯重复包含的错误。
而且调用起来也很不方便。很快暑假的电子设计大赛来临了,学校对我们的单片机软件编程进行了一些培训。由于学校历年来参加国赛和省赛,因此积累了一定数量的驱动模块,那些日子,老师每天都会布置一定量的任务,让我们用这些模块组合起来,完成一定功能。而正是那些日子模块化编程的培训,使我对于模块化编程有了更进一步的认识。并且程序规范也开始慢慢注意起来。此后的日子,无论程序的大小,均采用模块化编程的方式去编写。很长一段时间以来,一直有单片机爱好者在QQ上和我一起交流。有时候,他们会发过来一些有问题的程序源文件,让我帮忙修改一下。同样是长长的一个文件,而且命名极不规范,从头看下来,着实是痛苦,说实话,还真不如我重新给他们写一个更快一些,此话到不假,因为手头积累了一定量的模块,在完成一个新的系统时候,只需要根据上层功能需求,在底层模块的支持下,可以很快方便的完成。而不需要从头到尾再一砖一瓦的重新编写。藉此,也可以看出模块化编程的一个好处,就是可重复利用率高。下面让我们揭开模块化神秘面纱,一窥其真面目。C语言源文件 *.c 提到C语言源文件,大家都不会陌生。因为我们平常写的程序代码几乎都在这个XX.C文件里面。编译器也是以此文件来进行编译并生成相应的目标文件。作为模块化编程的组成基础,我们所要实现的所有功能的源代码均在这个文件里。理想的模块化应该可以看成是一个黑盒子。即我们只关心模块提供的功能,而不管模块内部的实现细节。好比我们买了一部手机,我们只需要会用手机提供的功能即可,不需要知晓它是如何把短信发出去的,如何响应我们按键的输入,这些过程对我们用户而言,就是是一个黑盒子。
在大规模程序开发中,一个程序由很多个模块组成,很可能,这些模块的编写任务被分配到不同的人。而你在编写这个模块的时候很可能就需要利用到别人写好的模块的借口,这个时候我们关心的是,它的模块实现了什么样的接口,我该如何去调用,至于模块内部是如何组织的,对于我而言,无需过多关注。而追求接口的单一性,把不需要的细节尽可能对外部屏蔽起来,正是我们所需要注意的地方。C语言头文件 *.h 谈及到模块化编程,必然会涉及到多文件编译,也就是工程编译。在这样的一个系统中,往往会有多个C文件,而且每个C文件的作用不尽相同。在我们的C文件中,由于需要对外提供接口,因此必须有一些函数或者是变量提供给外部其它文件进行调用。假设我们有一个LCD.C文件,其提供最基本的LCD的驱动函数 LcdPutChar(char cNewValue);//在当前位置输出一个字符 而在我们的另外一个文件中需要调用此函数,那么我们该如何做呢?
头文件的作用正是在此。可以称其为一份接口描述文件。其文件内部不应该包含任何实质性的函数代码。我们可以把这个头文件理解成为一份说明书,说明的内容就是我们的模块对外提供的接口函数或者是接口变量。同时该文件也包含了一些很重要的宏定义以及一些结构体的信息,离开了这些信息,很可能就无法正常使用接口函数或者是接口变量。但是总的原则是:不该让外界知道的信息就不应该出现在头文件里,而外界调用模块内接口函数或者是接口变量所必须的信息就一定要出现在头文件里,否则,外界就无法正确的调用我们提供的接口功能。因而为了让外部函数或者文件调用我们提供的接口功能,就必须包含我们提供的这个接口描述文件----即头文件。同时,我们自身模块也需要包含这份模块头文件(因为其包含了模块源文件中所需要的宏定义或者是结构体),好比我们平常所用的文件都是一式三份一样,模块本身也需要包含这个头文件。
下面我们来定义这个头文件,一般来说,头文件的名字应该与源文件的名字保持一致,这样我们便可以清晰的知道哪个头文件是哪个源文件的描述。
于是便得到了LCD.C的头文件LCD.h 其内容如下。#ifndef _LCD_H_ #define _LCD_H_ extern LcdPutChar(char cNewValue);#endif
这与我们在源文件中定义函数时有点类似。不同的是,在其前面添加了extern 修饰符表明其是一个外部函数,可以被外部其它模块进行调用。#ifndef _LCD_H_ #define _LCD_H_ #endif
这个几条条件编译和宏定义是为了防止重复包含。假如有两个不同源文件需要调用LcdPutChar(char cNewValue)这个函数,他们分别都通过#include “Lcd.h”把这个头文件包含了进去。在第一个源文件进行编译时候,由于没有定义过 _LCD_H_ 因此 #ifndef _LCD_H_ 条件成立,于是定义_LCD_H_ 并将下面的声明包含进去。在第二个文件编译时候,由于第一个文件包含时候,已经将_LCD_H_定义过了。因此#ifndef _LCD_H_ 不成立,整个头文件内容就没有被包含。假设没有这样的条件编译语句,那么两个文件都包含了extern LcdPutChar(char cNewValue);就会引起重复包含的错误。
不得不说的typedef 很多朋友似乎了习惯程序中利用如下语句来对数据类型进行定义 #define uint unsigned int #define uchar unsigned char 然后在定义变量的时候 直接这样使用 uint g_nTimeCounter = 0;不可否认,这样确实很方便,而且对于移植起来也有一定的方便性。但是考虑下面这种情况你还会 这么认为吗?
#define PINT unsigned int * //定义unsigned int 指针类型 PINT g_npTimeCounter, g_npTimeState;那么你到底是定义了两个unsigned int 型的指针变量,还是一个指针变量,一个整形变量呢?而你的初衷又是什么呢,想定义两个unsigned int 型的指针变量吗?如果是这样,那么估计过不久就会到处抓狂找错误了。
庆幸的是C语言已经为我们考虑到了这一点。typedef 正是为此而生。为了给变量起一个别名我们可以用如下的语句
typedef unsigned int uint16;//给指向无符号整形变量起一个别名 uint16 typedef unsigned int * puint16;//给指向无符号整形变量指针起一个别名 puint16 在我们定义变量时候便可以这样定义了:
uint16 g_nTimeCounter = 0;//定义一个无符号的整形变量 puint16 g_npTimeCounter;//定义一个无符号的整形变量的指针
在我们使用51单片机的C语言编程的时候,整形变量的范围是16位,而在基于32的微处理下的整形变量是32位。倘若我们在8位单片机下编写的一些代码想要移植到32位的处理器上,那么很可能我们就需要在源文件中到处修改变量的类型定义。这是一件庞大的工作,为了考虑程序的可移植性,在一开始,我们就应该养成良好的习惯,用变量的别名进行定义。如在8位单片机的平台下,有如下一个变量定义 uint16 g_nTimeCounter = 0;如果移植32单片机的平台下,想要其的范围依旧为16位。
可以直接修改uint16 的定义,即
typedef unsigned short int uint16;这样就可以了,而不需要到源文件处处寻找并修改。
将常用的数据类型全部采用此种方法定义,形成一个头文件,便于我们以后编程直接调用。文件名 MacroAndConst.h 其内容如下:
#ifndef _MACRO_AND_CONST_H_ #define _MACRO_AND_CONST_H_
typedef unsigned int uint16;typedef unsigned int UINT;typedef unsigned int uint;typedef unsigned int UINT16;typedef unsigned int WORD;typedef unsigned int word;typedef int int16;typedef int INT16;typedef unsigned long uint32;
typedef unsigned long UINT32;typedef unsigned long DWORD;typedef unsigned long dword;typedef long int32;typedef long INT32;typedef signed char int8;typedef signed char INT8;typedef unsigned char byte;typedef unsigned char BYTE;typedef unsigned char uchar;typedef unsigned char UINT8;typedef unsigned char uint8;typedef unsigned char BOOL;#endif
至此,似乎我们对于源文件和头文件的分工以及模块化编程有那么一点概念了。那么让我们趁热打铁,将上一章的我们编写的LED闪烁函数进行模块划分并重新组织进行编译。
在上一章中我们主要完成的功能是P0口所驱动的LED以1Hz的频率闪烁。其中用到了定时器,以及LED驱动模块。因而我们可以简单的将整个工程分成三个模块,定时器模块,LED模块,以及主函数 对应的文件关系如下
main.c Timer.hTimer.c--Led.hLed.c--在开始重新编写我们的程序之前,先给大家讲一下如何在KEIL中建立工程模板吧,这个模板是我一直沿用至今。希望能够给大家一点启发。
下面的内容就主要以图片为主了。同时辅以少量文字说明。我们以芯片AT89S52为例。
(原文件名:1.jpg)
引用图片
(原文件名:2.jpg)
引用图片
(原文件名:3.jpg)
引用图片
(原文件名:4.jpg)
引用图片
(原文件名:5.jpg)
引用图片
(原文件名:6.jpg)
引用图片
(原文件名:7.jpg)
引用图片
(原文件名:8.jpg)
引用图片
(原文件名:9.jpg)
引用图片
(原文件名:10.jpg)
引用图片
(原文件名:11.jpg)
引用图片
(原文件名:12.jpg)
引用图片
(原文件名:13.jpg)
引用图片
(原文件名:14.jpg)
引用图片
(原文件名:15.jpg)
引用图片
(原文件名:16.jpg)
引用图片
(原文件名:17.jpg)
引用图片
(原文件名:18.jpg)
引用图片
(原文件名:19.jpg)
引用图片
(原文件名:20.jpg)
引用图片
(原文件名:21.jpg)
引用图片
(原文件名:22.jpg)
引用图片
OK,到此一个简单的工程模板就建立起来了,以后我们再新建源文件和头文件的时候,就可以直接保存到src文件目录下面了。
下面我们开始编写各个模块文件。
首先编写Timer.c 这个文件主要内容就是定时器初始化,以及定时器中断服务函数。其内容如下。#include
bit g_bSystemTime1Ms = 0;// 1MS系统时标
void Timer0Init(void){ TMOD &= 0xf0;TMOD |= 0x01;//定时器0工作方式1 TH0 = 0xfc;//定时器初始值 TL0 = 0x66;TR0 = 1;ET0 = 1;}
void Time0Isr(void)interrupt 1 { TH0 = 0xfc;//定时器重新赋初值 TL0 = 0x66;g_bSystemTime1Ms = 1;//1MS时标标志位置位 }
由于在Led.c文件中需要调用我们的g_bSystemTime1Ms变量。同时主函数需要调用Timer0Init()初始化函数,所以应该对这个变量和函数在头文件里作外部声明。以方便其它函数调用。
Timer.h 内容如下。#ifndef _TIMER_H_ #define _TIMER_H_
extern void Timer0Init(void);extern bit g_bSystemTime1Ms;#endif
完成了定时器模块后,我们开始编写LED驱动模块。Led.c 内容如下:
#include
static uint16 g_u16LedTimeCount = 0;//LED计数器 static uint8 g_u8LedState = 0;//LED状态标志, 0表示亮,1表示熄灭
#define LED P0 //定义LED接口
#define LED_ON()LED = 0x00;//所有LED亮 #define LED_OFF()LED = 0xff;//所有LED熄灭
void LedProcess(void){ if(0 == g_u8LedState)//如果LED的状态为亮,则点亮LED { LED_ON();} else //否则熄灭LED { LED_OFF();} }
void LedStateChange(void){ if(g_bSystemTime1Ms)//系统1MS时标到 { g_bSystemTime1Ms = 0;g_u16LedTimeCount++;//LED计数器加一
if(g_u16LedTimeCount >= 500)//计数达到500,即500MS到了,改变LED的状态。{ g_u16LedTimeCount = 0;g_u8LedState =!g_u8LedState;} } }
这个模块对外的借口只有两个函数,因此在相应的Led.h 中需要作相应的声明。Led.h 内容: #ifndef _LED_H_ #define _LED_H_
extern void LedProcess(void);extern void LedStateChange(void);#endif
这两个模块完成后,我们将其C文件添加到工程中。然后开始编写主函数里的代码。如下所示:
#include
sbit LED_SEG = P1^4;//数码管段选 sbit LED_DIG = P1^5;//数码管位选 sbit LED_CS11 = P1^6;//led控制位
void main(void){ LED_CS11 = 1;//74HC595输出允许
LED_SEG = 0;//数码管段选和位选禁止(因为它们和LED共用P0口)LED_DIG = 0;Timer0Init();EA = 1;while(1){ LedProcess();LedStateChange();} }
整个工程截图如下:
至此,第三章到此结束。
一起来总结一下我们需要注意的地方吧
[color=#FF0000]1.C语言源文件(*.c)的作用是什么 2.C语言头文件(*.h)的作用是什么 3.typedef 的作用 4.工程模板如何组织
5.如何创建一个多模块(多文件)的工程
“从单片机初学者迈向单片机工程师”之KEY主题讨论
按键程序编写的基础
从这一章开始,我们步入按键程序设计的殿堂。在基于单片机为核心构成的应用系统中,用户输入是必不可少的一部分。输入可以分很多种情况,譬如有的系统支持PS2键盘的接口,有的系统输入是基于编码器,有的系统输入是基于串口或者USB或者其它输入通道等等。在各种输入途径中,更常见的是,基于单个按键或者由单个键盘按照一定排列构成的矩阵键盘(行列键盘)。我们这一篇章主要讨论的对象就是基于单个按键的程序设计,以及矩阵键盘的程序编写。◎按键检测的原理
常见的独立按键的外观如下,相信大家并不陌生,各种常见的开发板学习板上随处可以看到他们的身影。
(原文件名:1.jpg)
引用图片
总共有四个引脚,一般情况下,处于同一边的两个引脚内部是连接在一起的,如何分辨两个引脚是否处在同一边呢?可以将按键翻转过来,处于同一边的两个引脚,有一条突起的线将他们连接一起,以标示它们俩是相连的。如果无法观察得到,用数字万用表的二极管挡位检测一下即可。搞清楚这点非常重要,对于我们画PCB的时候的封装很有益。
它们和我们的单片机系统的I/O口连接一般如下:
(原文件名:2.jpg)
引用图片
对于单片机I/O内部有上拉电阻的微控制器而言,还可以省掉外部的那个上拉电阻。简单分析一下按键检测的原理。当按键没有按下的时候,单片机I/O通过上拉电阻R接到VCC,我们在程序中读取该I/O的电平的时候,其值为1(高电平);当按键S按下的时候,该I/O被短接到GND,在程序中读取该I/O的电平的时候,其值为0(低电平)。这样,按键的按下与否,就和与该按键相连的I/O的电平的变化相对应起来。结论:我们在程序中通过检测到该I/O口电平的变化与否,即可以知道按键是否被按下,从而做出相应的响应。一切看起来很美好,是这样的吗?
◎现实并非理想
在我们通过上面的按键检测原理得出上述的结论的时候,其实忽略了一个重要的问题,那就是现实中按键按下时候的电平变化状态。我们的结论是基于理想的情况得出来的,就如同下面这幅按键按下时候对应电平变化的波形图一样:
(原文件名:3.jpg)
引用图片
而实际中,由于按键的弹片接触的时候,并不是一接触就紧紧的闭合,它还存在一定的抖动,尽管这个时间非常的短暂,但是对于我们执行时间以us为计算单位的微控制器来说,它太漫长了。因而,实际的波形图应该如下面这幅示意图一样。
(原文件名:4.jpg)
引用图片
这样便存在这样一个问题。假设我们的系统有这样功能需求:在检测到按键按下的时候,将某个I/O的状态取反。由于这种抖动的存在,使得我们的微控制器误以为是多次按键的按下,从而将某个I/O的状态不断取反,这并不是我们想要的效果,假如该I/O控制着系统中某个重要的执行的部件,那结果更不是我们所期待的。于是乎有人便提出了软件消除抖动的思想,道理很简单:抖动的时间长度是一定的,只要我们避开这段抖动时期,检测稳定的时候的电平不久可以了吗?听起来确实不错,而且实际应用起来效果也还可以。于是,各种各样的书籍中,在提到按键检测的时候,总也不忘说道软件消抖。就像下面的伪代码所描述的一样。(假设按键按下时候,低电平有效)
If(0 == io_KeyEnter)//如果有键按下了 { Delayms(20);//先延时20ms避开抖动时期
If(0 == io_KeyEnter)//然后再检测,如果还是检测到有键按下 { return KeyValue;//是真的按下了,返回键值 } else { return KEY_NULL //是抖动,返回空的键值 } while(0 == io_KeyEnter);//等待按键释放 }
所以合理的分配好微控制的处理时间,是编写按键程序的基础。乍看上去,确实挺不错,实际中呢?在实际的系统中,一般是不允许这么样做的。为什么呢?首先,这里的Delayms(20), 让微控制器在这里白白等待了20 ms 的时间,啥也没干,考虑我在《学会释放CPU》一章中所提及的几点,这是不可取的。其次while(0 == io_KeyEnter);更是程序设计中的大忌(极少的特殊情况例外)。任何非极端情况下,都不要使用这样语句来堵塞微控制器的执行进程。原本是等待按键释放,结果CPU就一直死死的盯住该按键,其它事情都不管了,那其它事情不干了吗?你同意别人可不会同意
◎消除抖动有必要吗? 的确,软件上的消抖确实可以保证按键的有效检测。但是,这种消抖确实有必要吗?有人提出了这样的疑问。抖动是按键按下的过程中产生的,如果按键没有按下,抖动会产生吗?如果没有按键按下,抖动也会在I/O上出现,我会立刻把这个微控制器锤了,永远不用这样一款微控制器。所以抖动的出现即意味着按键已经按下,尽管这个电平还没有稳定。所以只要我们检测到按键按下,即可以返回键值,问题的关键是,在你执行完其它任务的时候,再次执行我们的按键任务的时候,抖动过程还没有结束,这样便有可能造成重复检测。所以,如何在返回键值后,避免重复检测,或者在按键一按下就执行功能函数,当功能函数的执行时间小于抖动时间时候,如何避免再次执行功能函数,就成为我们要考虑的问题了。这是一个仁者见仁,智者见智的问题,就留给大家去思考吧。所以消除抖动的目的是:防止按键一次按下,多次响应。
“从单片机初学者迈向单片机工程师”之KEY主题讨论
基于状态转移的独立按键程序设计)的那种,有一个小液晶屏,还有四个按键,功能是时钟,闹钟以及秒表。在调整时间的时候,短按+键每次调整值加一,长按的时候调整值连续增加。小的时候很好奇,这样的功能到底是如何实现的呢,今天就让我们来剖析它的原理吧。 本章所描述的按键程序要达到的目的:检测按键按下,短按,长按,释放。即通过按键的返回值我们可以获取到如下的信息:按键按下(短按),按键长按,按键连_发,按键释放。不知道大家还记得小时候玩过的电子钟没有,就是外形类似于CALL 机(CALL 机,好像是很古老的东西了 状态在生活中随处可见。譬如早上的时候,闹钟把你叫醒了,这个时候,你便处于清醒的状态,马上你就穿衣起床洗漱吃早餐,这一系列事情就是你在这个状态做的事情。做完这些后你会去等车或者开车去上班,这个时候你就处在上班途中的状态„..中午下班时间到了,你就处于中午下班的状态,诸如此类等等,在每一个状态我们都会做一些不同的事情,而总会有外界条件促使我们转换到另外一种状态,譬如闹钟叫醒我们了,下班时间到了等等。对于状态的定义出发点不同,考虑的方向不同,或者会有些许细节上面的差异,但是大的状态总是相同的。生活中的事物同样遵循同样的规律,譬如,用一个智能充电器给你的手机电池充电,刚开始,它是处于快速充电状态,随着电量的增加,电压的升高,当达到规定的电压时候,它会转换到恒压充电。总而言之,细心观察,你会发现生活中的总总都可以归结为一个个的状态,而状态的变换或者转移总是由某些条件引起同时伴随着一些动作的发生。我们的按键亦遵循同样的规律,下面让我们来简单的描绘一下它的状态流程转移图。
(原文件名:1.jpg)
引用图片
下面对上面的流程图进行简要的分析。首先按键程序进入初始状态S1,在这个状态下,检测按键是否按下,如果有按下,则进入按键消抖状态2,在下一次执行按键程序时候,直接由按键消抖状态进入按键按下状态3,在此状态下检测按键是否按下,如果没有按键按下,则返回初始状态S1,如果有则可以返回键值,同时进入长按状态S4,在长按状态下每次进入按键程序时候对按键时间计数,当计数值超过设定阈值时候,则表明长按事件发生,同时进入按键连_发状态S5。如果按键键值为空键,则返回按键释放状态S6,否则继续停留在本状态。在按键连_发状态下,如果按键键值为空键则返回按键释放状态S6,如果按键时间计数超过连_发阈值,则返回连_发按键值,清零时间计数后继续停留在本状态。
看了这么多,也许你已经有一个模糊的概念了,下面让我们趁热打铁,一起来动手编写按键驱动程序吧。
下面是我使用的硬件的连接图。
(原文件名:2.jpg)
引用图片
硬件连接很简单,四个独立按键分别接在P3^0------P3^3四个I/O上面。
因为51单片机I/O口内部结构的限制,在读取外部引脚状态的时候,需要向端口写1.在51单片机复位后,不需要进行此操作也可以进行读取外部引脚的操作。因此,在按键的端口没有复用的情况下,可以省略此步骤。而对于其它一些真正双向I/O口的单片机来说,将引脚设置成输入状态,是必不可少的一个步骤。下面的程序代码初始化引脚为输入。void KeyInit(void){ io_key_1 = 1;io_key_2 = 1;io_key_3 = 1;io_key_4 = 1;} 根据按键硬件连接定义按键键值
#define KEY_VALUE_1 0x0e #define KEY_VALUE_2 0x0d #define KEY_VALUE_3 0x0b #define KEY_VALUE_4 0x07 #define KEY_NULL 0x0f 下面我们来编写按键的硬件驱动程序。
根据第一章所描述的按键检测原理,我们可以很容易的得出如下的代码: static uint8 KeyScan(void){ if(io_key_1 == 0)return KEY_VALUE_1;if(io_key_2 == 0)return KEY_VALUE_2;if(io_key_3 == 0)return KEY_VALUE_3;if(io_key_4 == 0)return KEY_VALUE_4;return KEY_NULL;} 其中io_key_1等是我们按键端口的定义,如下所示: sbit io_key_1 = P3^0;sbit io_key_2 = P3^1;sbit io_key_3 = P3^2;sbit io_key_4 = P3^3;
KeyScan()作为底层按键的驱动程序,为上层按键扫描提供一个接口,这样我们编写的上层按键扫描函数可以几乎不用修改就可以拿到我们的其它程序中去使用,使得程序复用性大大提高。同时,通过有意识的将与底层硬件连接紧密的程序和与硬件无关的代码分开写,使得程序结构层次清晰,可移植性也更好。对于单片机类的程序而言,能够做到函数级别的代码重用已经足够了。在编写我们的上层按键扫描函数之前,需要先完成一些宏定义。//定义长按键的TICK数,以及连_发间隔的TICK数 #define KEY_LONG_PERIOD 100 #define KEY_CONTINUE_PERIOD 25
//定义按键返回值状态(按下,长按,连_发,释放)#define KEY_DOWN 0x80 #define KEY_LONG 0x40 #define KEY_CONTINUE 0x20 #define KEY_UP 0x10
//定义按键状态
#define KEY_STATE_INIT 0 #define KEY_STATE_WOBBLE 1 #define KEY_STATE_PRESS 2 #define KEY_STATE_LONG 3 #define KEY_STATE_CONTINUE 4 #define KEY_STATE_RELEASE 5
接着我们开始编写完整的上层按键扫描函数,按键的短按,长按,连按,释放等等状态的判断均是在此函数中完成。对照状态流程转移图,然后再看下面的函数代码,可以更容易的去理解函数的执行流程。完整的函数代码如下: void GetKey(uint8 *pKeyValue){ static uint8 s_u8KeyState = KEY_STATE_INIT;static uint8 s_u8KeyTimeCount = 0;static uint8 s_u8LastKey = KEY_NULL;//保存按键释放时候的键值 uint8 KeyTemp = KEY_NULL;
KeyTemp = KeyScan();//获取键值
switch(s_u8KeyState){ case KEY_STATE_INIT : { if(KEY_NULL!=(KeyTemp)){ s_u8KeyState = KEY_STATE_WOBBLE;} } break;
case KEY_STATE_WOBBLE : //消抖 { s_u8KeyState = KEY_STATE_PRESS;} break;
case KEY_STATE_PRESS : { if(KEY_NULL!=(KeyTemp)){ s_u8LastKey = KeyTemp;//保存键值,以便在释放按键状态返回键值 KeyTemp |= KEY_DOWN;//按键按下 s_u8KeyState = KEY_STATE_LONG;} else { s_u8KeyState = KEY_STATE_INIT;} } break;
case KEY_STATE_LONG : { if(KEY_NULL!=(KeyTemp)){ if(++s_u8KeyTimeCount > KEY_LONG_PERIOD){ s_u8KeyTimeCount = 0;KeyTemp |= KEY_LONG;//长按键事件发生 s_u8KeyState = KEY_STATE_CONTINUE;} } else { s_u8KeyState = KEY_STATE_RELEASE;} } break;
case KEY_STATE_CONTINUE : { if(KEY_NULL!=(KeyTemp)){ if(++s_u8KeyTimeCount > KEY_CONTINUE_PERIOD){ s_u8KeyTimeCount = 0;KeyTemp |= KEY_CONTINUE;} } else { s_u8KeyState = KEY_STATE_RELEASE;} } break;
case KEY_STATE_RELEASE : { s_u8LastKey |= KEY_UP;KeyTemp = s_u8LastKey;s_u8KeyState = KEY_STATE_INIT;} break;
default : break;} *pKeyValue = KeyTemp;//返回键值 } 关于这个函数内部的细节我并不打算花过多笔墨去讲解。对照着按键状态流程转移图,然后去看程序代码,你会发现其实思路非常清晰。最能让人理解透彻的,莫非就是将整个程序自己看懂,然后想象为什么这个地方要这样写,抱着思考的态度去阅读程序,你会发现自己的程序水平会慢慢的提高。所以我更希望的是你能够认认真真的看完,然后思考。也许你会收获更多。
不管怎么样,这样的一个程序已经完成了本章开始时候要求的功能:按下,长按,连按,释放。事实上,如果掌握了这种基于状态转移的思想,你会发现要求实现其它按键功能,譬如,多键按下,功能键等等,亦相当简单,在下一章,我们就去实现它。
在主程序中我编写了这样的一段代码,来演示我实现的按键功能。void main(void){ uint8 KeyValue = KEY_NULL;uint8 temp = 0;LED_CS11 = 1;//流水灯输出允许 LED_SEG = 0;LED_DIG = 0;Timer0Init();KeyInit();EA = 1;while(1){ Timer0MainLoop();KeyMainLoop(&KeyValue);
经常有一些好友问我选择二外应该学哪门语言比较好?或者是问法文难还是德文难?这些问题都另我非常头痛,因为确实无法给出一个公正并且客观的答案。于是我整理了一下自己的学习经历,和大家分享一下我对这些语言的看法和理解。
当然对于某一种语文的评价,是可以有各种不同的切入点的,比如:文学文化资源、经济实力、使用人口规模等等。我本人学的是文学,所以可能多少会往这方面倾斜。
牛人可忽略此文,本文不从语言哲学或者更高的视角去比较和分析。纯粹只是一些感性的理解,希望能帮助那些在不同语言中纠结的童鞋做出选择。
--------------------------------------------------------------------
正文前的一些基本概念:
综合语:
综合语主要通过句子中词的屈折形式来体现词与词之间的语法关系。也称为屈折语。典型的如:拉丁语,德语,俄语等
分析语:
分析语不通过词的屈折变化,而是通过句子中的词序来确定语法关系和句子含义。比如:英语,现代汉语等
屈折(inflection):
指单词拼法的改变,导致语法功能改变,进而使其代表的意义也有所改变。比如名词的性数格,动词的变位,形容词的比较级等等。具体举例为:thought, thinking, thinks皆为think的不同屈折形式;bigger,biggest均为big的不同屈折形式;boys为boy的屈折形式。
性(gender):
此处的性指的是语法上的性。大多数印欧语均有此特征。性分为阴阳,或者阴阳中,视具体语言而定。语法性原则上来说和生物性别无关,只是作为语法的一个手段而存在。
格(case):
表示一个词在句子中的不同成分,分为主格,所属格,与格,宾格,呼格,夺格等。英语,法语,西班牙语等现代语言的格大量简化,基本只存在与人称代词中。但德语和俄语等综合语仍保留格的语法特征。
动词变位(conjugation):动词在不同人称后根据时态而变化的不同屈折形式,称为动词的变位。英语的动词变位已经非常弱化,但仍保留第三人称单数后动词需要加s。而其他现代欧洲语言基本都保留了比较完整的变位,在每个人称之后都有不同的变化。
--------------------------------------
法文(母语人口约九千万,第二语言人口约两亿)
法文是主要的西罗曼语中比较难的语言,其他的主要西罗曼语包括葡萄牙文,西班牙文,意大利文等(还有加泰罗尼亚文等)。法文和英文归属于不同的语族,英文从语言分类上来说更接近德文,同属于西日耳曼语。但是很多同学会觉得从单词拼写,语序安排来看,法文似乎比德文更接近英文,甚至很多词是完全可以猜出来的。这是因为英国在1066年后为诺曼人所征服,法国贵族统治了英国将近三四百年,而在这时期里,也就是我们所说的中古英语,收到了主要来自法文的巨大影响,英文的拉丁化现象非常严重,古英语的格,性和其他大量的屈折形式明显减少。到了乔叟写《坎特伯雷故事集》的时候,乔叟的语言已经非常的法国化了。在加上英国国内崇尚说法文的风潮猛烈,导致英文出现两套不同的话语体系,如说羊为sheep,而羊肉则为mutton(来自法文的mouton),说猪为pig,而猪肉为pork(来自法文的porc),可见养这些活物的为底层使用英文的劳动阶层,而上桌后使用的语言则是英国国内的法裔贵族。这种分化现象在英文中屡见不鲜,几乎大部分词都会有两套语体,如help和aid,meet和encounter,watery和aquatic,yearly和annual,love和adore等等,前者都是和德文同源的日耳曼词(被称为low English),而后者则是来自法文的拉丁词(被称为high English)。
那么既然和法文那么接近,是不是学法文就很容易了呢?其实不然,英文更多的是从法文借词,但是本身的语法特征并未完全拉丁化,总体来说英文的时态多通过增加助动词来实现,而并不是拉丁化的动词本身发生屈折,这点仍和德文类似。不过从拼写上来说,法文就规则很多,一旦掌握了拼写和发音规则,原则上是可以脱离音标念出单词的。但注意,是原则上。法文的例外情况很多,远远超过西班牙文和德文,因此西文词典甚至德文词典可以不标注音标,而法文词典是不行的。法文的联诵(liaison)亦是初学者头疼之处,原则上(法文例外实在太多)前一单词辅音字母结尾,后一字母元音字母开头,都需要连读。这就导致往往一句法文句子,读起来是不停顿的,比如il habite à Paris,这里的il和habite,habite和à均可以联诵,最后听起来就像是一个很长的单词,这对一开始的听力理解有很大的考验。
从语法上来看,法文的繁琐或许主要体现在动词上。法文动词的变位应该是刚才所述的几门主要罗曼语中最复杂的。而名词的阴阳性,在通过一些规则和积累之后,并不会成为拦路虎。英文好的同学学法文是很有优势的,因为基本上tion结尾的词,英法两文是共通的,ty结尾的换成té就成了对应的法文词;句法顺序上,两门语言都已经是典型的靠词序来决定意义的分析语。除了罗曼语习惯把宾格代词前置以外,英法两文(包括汉语)的语序基本都是相同的,并不存在困难。
如果是英文专业学习文学的同学,我很建议选择法文为第二外语,因为学习法文对于提高英文是很有帮助的,它能使英文显得更为典雅和正式。另外法国文学对于英国文学的滋养是持续不断的,犹如学习日本文学追根溯源必得学习汉语。
如果是打算学习古英语,或者盎格鲁撒克逊时期文学,那么我会建议学习德文,而非法文。
---------------------------------------------
德文(母语人口约为1.1亿)
德文虽和英文同属于日耳曼语族西日耳曼语支,但是两者并没有我们想象的那么互通。荷兰语(Dutch)是德语和英语之间的过渡语,是目前较大语种里最接近英语的语言。古英语是和德文相当接近的,英文自从由欧洲大陆迁徙到大不列颠以后,千年里发生了相当大的变化,而欧洲大陆的德文则并未有如此根深蒂固的改变,于是隔海相望的两种兄弟语言,就逐步变得互相无法辨认了。
德文和古英文一样,有四个格,三种性,形容词有强弱变化,动词有变位。时态上要比罗曼语简单很多,和英文类似,经常通过助动词来表示时态。但是格和性,包括单复数不是以加S而是通过不规则词尾体现等语法点,均比法、西、意等罗曼语来得复杂。更需要注意的是,德文仍保持着千年来的综合语特征(古英语虽也是综合语,但近现代以后英语已经成为典型的分析语了),也就是说德文的.句子含义,并不通过词语顺序来体现,而是通过单个词的屈折形式(如变位,变格)来体现的,举个简单的例子来看ich liebe dich,ich是第一人称主格单数,liebe是lieben一般现在时第一人称单数的变位,dich是第二人称第四格(宾格)单数,所以每个词都严格体现了它在句子中的成分,即使改变顺序,如dich liebe ich,其意思也不改变,而不需要通过语序体现。(如英文的I love you, I限定了第一人称主格单数,但love可以是第一人称单数,复数,也可以是第二人称单数复数,或者第三人称复数,you可以是主格,也可以是宾格,那么这句句子只能通过语序来判定每个单词的成分)。
学习德文初期有如被各种语法点轰炸,非常苦恼。但是德文的规则性则远高于法文和英文,显得更为程式化和严谨。德文的拼写和发音是远容易于法文或者英文的(小舌音这种通过一定练习都可以拿下),总体来看,要达到一般交流水平的程度上,德文要难于法文。
------------------------------------------
西班牙文(约3.5亿人使用)
西班牙文在西班牙语中有两个词表示,一个是espanol, 一个是castellano(卡斯蒂利亚语),很多情况下拉丁美洲国家的人愿意使用后者,因为espanol听起来太具有地域性。西班牙文的在英文和法文前曾一度称霸欧洲,它的繁荣始于1492年,这一年成为西班牙历史上极为重要的一年。1492年有三件大事发生,第一是西班牙人重于将摩尔人赶出了伊比利亚半岛,同时卡斯蒂利亚的斐迪南和阿拉贡的伊莎贝拉女王联姻,统一了西班牙;其二,哥伦布在伊莎贝拉女王的赞助下发现了新大陆;其三,第一本西班牙语语法书《卡斯蒂利亚语语法》发行,为规范西班牙语语言奠定了基础。之后西班牙进入了黄金时期,西班牙语则被奉为欧洲的通用语言。
西班牙文同属于罗曼拉丁语族西罗曼语,同意大利文,法文,葡萄牙文一样,均最初为拉丁文在罗马各行省的通俗形式。西班牙文的发音要远比法文简单和整齐,通常几个小时就可以掌握所有的规则,并且几乎不存在例外(所以西语词典一般不标注音标)。至于西班牙文的大舌音,只是初学者没有掌握规律或者训练时间还过少,通常一两周时间90%的学习者都可以掌握。(个人觉得,判断一门语言的发音难易,更多是看它的元音,而不是辅音)
西班牙文和法文一样,有动词变位,有阴阳性。但是西文的阴阳性非常规则(偶有例外),如a结尾为阴性,o结尾为阳性,故基本可以忽略不计,只要在使用时稍加注意即可。而西班牙文的变位或许仍然是学习者最头疼的地方,但西文的变位比法文来的齐整,并且由于西语每个字母均要发音的缘故,导致只看一个动词的变位形式,就可以判断其主语(法语做不到,因为好几个人称的变位,读起来是一样的),也就使得西语的句子,往往是不需要出现主语的。比如Yo soy estudiante(I am a student), 动词ser的第一人称单数直陈式现在时的变位为soy,soy对应的只能是yo,因此这个句子往往就直接变为Soy estudiante,而不需要出现主语yo。这种情况也出现在意大利文中。
西班牙文也同法文一样,对于扩大英文词汇有很大帮助。因为同是拉丁语言,西班牙文的词汇从英语角度来看是非常典雅和华丽的。
西语由于使用地域广泛,且母国和当年的殖民国之间的经济对比不如法语国家那么悬殊,因此拉丁美洲西班牙文和西班牙西班牙文的关系有如美国英语和英国英语。拉美西语的发音和西班牙西语的发音有很明显的不同,比如gracias中的c,拉美是直接念成s,而西班牙则是咬舌尖,念出类似英语中的th;至于拉美各国间的区别,比如重音等,则更是百态了。马德里音从来就没有像巴黎音一样成为标准音的典范。
------------------------------
意大利文(使用人口约为7千万)
意大利文在形态上是保留罗曼语中保留拉丁文形式最完整的语言。动词词尾仍如同拉丁文一样,整齐保留了are,ire和ere结尾(少了一个长音的ere),而西文则演变成ar,ir,和er,法文则有更大的不同。
意大利文是文艺复兴时期最有声望的语言,并在这一时期取得了极大的辉煌。经历了Guido Cavalcanti,Dante,Petracha等人的探索,意大利文臻于完美,一大批的文学经典滋养了欧洲各国的语言和文学。Dante等人均来自托斯卡纳地区的弗洛伦撒,也使得这个地区的意大利文成为标准语言。当时的威尼斯方言也相当强势,包括后来的罗马方言,但直到现在托斯卡纳发言依然是意大利文的标准基础。
意大利文也如同西班牙文一样,有整齐易学的发音体系,同样也不需要音标就可以完全朗读出来。但相比较起来,意大利文的发音规则比西文稍显复杂,比如e音和o音有开闭之分,这在法文中也是同样出现的,但由于意大利文中并不标注开闭音符号,所以让初学者有些犯难。西班牙西班牙文里的e也曾一度分有开闭音,但近年来已经有合并趋势,所以一般已经不加区分。但意大利语则仍严格恪守。
意大利文的语法体系,总体来说是和西班牙文大致对应的。只是在细节处略显繁琐:比如阴阳性和单复数,意大利文不是简单的加S,或者以oa区分,e结尾的单词变化规则也是西语中所没有的。另外冠词部分,意大利文也稍显复杂,和法文相当。
其他的主要语法比如动词变位,主语省略,语序等皆可参考西班牙文。意大利文和西班牙文的差异,要远比意大利文和法文的差异小很多。也曾有人指出,意大利人和西班牙人互相操自己的母语沟通,是可以相互理解至少7成以上的,当然如果是葡萄牙人和西班牙人交流,可能理解程度更高。葡萄牙文有鼻音,发音上比意大利文和西班牙文都要复杂些。
意大利文的重音有明显的拖长和降调,和西班牙文截然不同,也导致听起来更富有音乐性。英语直接从意大利文的借词不如从法文来的多,但意大利文伟大的文化积淀和文学财富,非常值得学习。
-----------------------------------
俄文(使用人口约3亿)
鄙人上大学前的曾一度梦想将俄文作为自己的第一志愿。中学时期读了大量的俄国小说,心中一直对这个北方国度有强烈的情节。只是后来阴差阳错,学了别的专业,但俄语一直是心中的一个夙愿。俄文是我最近才开始学的,所以可能理解不够,只是大概说一下自己的感受。
俄文属于斯拉夫语族,虽然和上述语言同属于印欧语系,但由于采用了自古希腊文演变来的西里尔字母体系,所以感觉上和那些拉丁字母语言有很大的不同。实则非也,西里尔字母如果拉丁化以后,会发现俄文很多词汇和英文,法文都是一样的,完全是在一个文化体系中的。
不过西里尔字母多少还是成了学习俄文的一个拦路虎。上述语言至少不需要重新学习字母,但俄文不得不花一段时间从字母开始学期。如果你学过古希腊文,那你会觉得西里尔字母是非常好认的,否则就需要适应一段时间了。
俄文的发音算不上是特别难,但也相当不容易。元音字母ы我个人认为是最难发标准的,而硬辅和软辅也让初学者并不容易完全掌握。好在俄文也是规则拼音文字,这点和欧洲大多数语言一样,最悲惨的就属英文了。
俄文的文法无疑是目前总结下来的语言中最复杂的了。基本上之前出现过的文法现象,在俄文中进行了一次大聚会:变位,变格,单复数不规则,性。。。。俄文分为6格,比现代德文多了两个格,甚至比拉丁文都多了一个格,和德文拉丁文一样,俄文也是通过屈折来体现句意,并不按照语序安排来体现。由于古老的斯拉夫语在千年中的变化较小,所以语言并没有获得西欧语言那般的极度简化。俄文是几门大语种中保留印欧语语法特征最完备的语言。
好在普希金(Пушкин),陀思妥耶夫斯基(Достоевский),托尔斯泰(Толстой)等人的伟大作品能激励每一个热爱文学的人去克服学习俄语的艰深和枯燥。当你能用原文念一首普希金的短诗的时候,会是莫大的激动和宽慰。
----------------------------------
拉丁文
对于Latin这个单词多少觉得有些憧憬,就像之前看梁文道的文中说他有一次看见一位师兄在列车上读塞内加(Seneca)的原文剧作,顿时觉得这为师兄周身都开始发着金光,崇拜之情油然而生。
学欧洲语言的,或多或少总会和拉丁文牵扯上关系,不管是背词根的时候,或者是读原著时碰到的引用。拉丁文之于现代欧洲语言,就如同古汉语之于现代汉语,前者是取之不尽的宝库,滋养和哺乳着后者。
所以我不同意说“拉丁文已死”。
拉丁文明明还活在英文,德文,更不用说它的嫡亲后代法文,西班牙文,意大利文中,怎么说它死了呢?古汉语也没有死,它只是通俗化了,演变成了现代汉语,拉丁文亦然。
有人夸张的说古罗马留给后世最大的两个财富一个是罗马法,一个就是拉丁文。可见拉丁文的重要性。
国内始终没有古典学系,也鲜有拉丁文课程和教材(虽然大多数人都可以从不同渠道获得英文版的教材),可算是西学研究的一个缺憾。不过对拉丁文有兴趣,并且在埋头学习的朋友确也不少,我亦有所涉猎,虽然只是皮毛,也大致嗦几句。
很多历史语言学教材上都把拉丁文看成是proto-romance,也就是法文,意大利文,西班牙文等的原型罗曼语。只是拉丁文的这些子孙千年来变化太大,早已背离了拉丁语大部分的语法特征,只是形似而已了。现代罗曼语基本已经是分析语言,而拉丁语则是非常典型的综合语。和德文,俄文一样,拉丁文的语序安排非常灵活,比如
Pater amat fīlium.
Pater fīlium amat.
Fīlium amat pater.
Fīlium pater amat.
Amat pater fīlium.
Amat fīlium pater.
这句句子表示的都是Father loves the son, 由于有严格的屈折变化来限定每一个词在句子中的格,所以无论怎么颠倒语序,表达的意思都是不变的。
在这一点上,拉丁文比德文走得更远。拉丁文的动词屈折形式,不仅仅可以提示出主语,还能表示被动或者主动,时态等等信息,所有的语法信息都浓缩在一个动词的结尾变化上,而不需要借助外在的助词等去完成意思的表达,这导致表示同样的意思,拉丁文用的词数要远少于现代语言,是一门非常economic的语言。这点有点像古汉语。
动词变位,名词变格等等,拉丁文都比德文来得复杂得多,但和俄文不相上下。这些其实都是可以通过多多练习来习得的。很多人都跟我说,学习拉丁文一段时间以后,即便只是浅尝辄止,也回过头去发现原来觉得confusing的德文,俄文语法,突然变得豁然开朗。
拉丁文的发音规则也是非常规律的,伊拉斯莫曾经还原了古典拉丁文的发音,但目前比较流行的是意大利式发音和德式发音。比较麻烦的是拉丁文的元音也分长短音,并有此导致重音的位置不同,这点在记单词的时候也增加了不少麻烦。
拉丁文丰富的文献和伟大的文学作品是西方人绕不开的财富,我想也是对于喜欢欧洲语言和文化的朋友所无法回避的。
-------------------------------------
英文
最后我恕唠叨几句英文。
我一直不赞同说英文是最简单容易的语言。诚然,英文是上述语言里通过最短的时间就能够开始交流的语言,但是要把英文学好又谈何容易。
英文的发音和拼写规则是最复杂的。英文的元音音位远比德文,西文,意大利文,拉丁文什么的多,和法文不相上下。而英文的重音又是如此的不规则,大部分词还是得最终通过词典去确认发音和重音音节,否则误读的几率是最高的。
英文的拼写就是更大的杯具了。表示f音,除了ph和f,居然还能用gh(如enough),而gh音在though中又不发音。s什么时候发s什么时候发z,简直无规律可循,比如你能一下子区分possess,disease,release等词中s的发音吗?
其次,英文的词汇是一个大熔炉。在前面讲法文的段落里,已经谈到high English和low English了,这种不同语体的近义词数量,可能是其他欧洲语言所不及的。经常要根据不同情况去选择究竟是I help her, 还是I aid her, 抑或是I assist her....这就导致英文的近义词无与伦比的多,能表达出各种细微的情感变化。有意思的是,日耳曼词虽然不如拉丁词高贵,但在表达最原始和最直接的情感时,即使英国女王跌入水中,也只会喊help,而不是aid!
【语言学学习心得百度】推荐阅读:
语言学习策略课心得11-26
语言学习心得体会2001-28
C语言程序设计学习心得体会02-16
中国石油大学(华东)-C语言学习心得09-27
语言学习方案09-24
关于语言学习10-08
语言文字学习方法11-27
语言文字培训心得11-27
c语言编程心得07-22
语言活动培训心得体会12-26