国雄 的个人资料照片日志列表 工具 帮助

日志


11月6日

没有标题

从国庆开始就不停的忙碌着
又是工作又是司仪
可以说是做7休0
呵呵,这样的日子过得真的有点累
突然发现想在家休息都是一种奢求
不过每次看到新人那种幸福的表情
总有一种很欣慰的感觉
真的很为他们感到高兴
同时也真的有点羡慕他们
或许在不久的将来我也会有这种幸福的感觉吧
人的思维总是在身体空闲时特别活跃
忙忙碌碌的我总是有一种莫明其妙的平静
我已经不在群上到处吼了
或许真的静下心了吧
这种感觉挺好
习惯了这样的生活
发现一个人过过也挺开心的。
前两天姐姐到我家来
我们一起去吃了喜多屋
并不像想象中的这么好吃
也就这点食物,也就这个味道
或许因为我本来对这个就没有太大要求吧
谁叫我是杂食动物呢,哈哈
不过那里的环境,外边的风景和食物相比
我更倾向于前者吧
感觉挺舒服的
就是人多了点有点小乱
但总体还是不错的
那天,我发现原来女孩子的胃口可以这么好
当我已经吃饱着坐在那里的时候
姐姐和妹妹还在不停得吃着各种各样的甜点的时候
我突然意识到女孩子的话真的不能相信
特别是什么我要减肥
当我吃得已经不想动的时候
看到老姐和老妹还在拿着一大杯哈根达斯狂挖的时候
我彻底崩溃了
终于明白美食对于女孩子的诱惑是多么可怕
呵呵不过想想也好
总比那些整天为了减肥不吃不喝的好
健康的身体和灿烂的微笑就是最美丽的
接下来的日子仍然有些小小忙碌
更新日志也总是懒得写
就像上个礼拜天和寒寒聊天时说到的
我基本就这个样子了
一百年老样子
估计要等到哪天我有GF了
生活才会有所变化吧
哈哈,好好过好现在的小日子再说吧
 
 
 
8月7日

懒惰是可耻的

最近发现自己好懒啊
8。25又要黑带考试咯
恢复恢复
不然到时候就坍台了要
这次的集训班挺好的
比上次的团结多了
兄弟之间的感情就是让人这么心潮澎湃啊 ~~!
有点怀念当初的我们
呵呵,加油拉,兄弟们 
8月3日

NOW

室内:听着古典小提琴的音乐
   吹着空调
   喝着咖啡
   上着网
室外:闪电
   狂风
   暴雨
   污七麻黑的天
时不时看看窗外的闪电,伴随着小提琴声,雷声,和似乎近在咫尺的闪电
闻到了雨水的味道
我也不知道此刻的心情
应该说此刻我没有任何心情,不好不坏
好平静啊~~~~~~
就是应该有这种镇定自若的心
不管外面如何,我都不为所动
呵呵.赞
7月26日

PWM技术应用概述

采样控制理论中有一个重要结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。PWM控制技术就是以该结论为理论基础,对半导体开关器件的导通和关断进行控制,使输出端得到一系列幅值相等而宽度不相等的脉冲,用这些脉冲来代替正弦波或其他所需要的波形。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。

  PWM控制的基本原理很早就已经提出,但是受电力电子器件发展水平的制约,在上世纪80年代以前一直未能实现。直到进入上世纪80年代,随着全控型电力电子器件的出现和迅速发展,PWM控制技术才真正得到应用。随着电力电子技术、微电子技术和自动控制技术的发展以及各种新的理论方法,如现代控制理论、非线性系统控制思想的应用,PWM控制技术获得了空前的发展。到目前为止,已出现了多种PWM控制技术,根据PWM控制技术的特点,到目前为止主要有以下8类方法。

  1  相电压控制PWM

  1.1  等脉宽PWM

  VVVF(Variable Voltage Variable Frequency)装置在早期是采用PAM(Pulse Amplitude Modulation)控制技术来实现的,其逆变器部分只能输出频率可调的方波电压而不能调压。等脉宽PWM法正是为了克服PAM法的这个缺点发展而来的,是PWM法中最为简单的一种。它是把每一脉冲的宽度均相等的脉冲列作为PWM波,通过改变脉冲列的周期可以调频,改变脉冲的宽度或占空比可以调压,采用适当控制方法即可使电压与频率协调变化。相对于PAM法,该方法的优点是简化了电路结构,提高了输入端的功率因数,但同时也存在输出电压中除基波外,还包含较大的谐波分量。

  1.2  随机PWM

  在上世纪70年代开始至上世纪80年代初,由于当时大功率晶体管主要为双极性达林顿三极管,载波频率一般不超过5kHz,电机绕组的电磁噪音及谐波造成的振动引起了人们的关注。为求得改善,随机PWM方法应运而生。其原理是随机改变开关频率使电机电磁噪音近似为限带白噪声(在线性频率坐标系中,各频率能量分布是均匀的),尽管噪音的总分贝数未变,但以固定开关频率为特征的有色噪音强度大大削弱。正因为如此,即使在IGBT已被广泛应用的今天,对于载波频率必须限制在较低频率的场合,随机PWM仍然有其特殊的价值;另一方面则说明了消除机械和电磁噪音的最佳方法不是盲目地提高工作频率,随机PWM技术正是提供了一个分析、解决这种问题的全新思路。

  1.3  SPWM

  SPWM(Sinusoidal PWM)法是一种比较成熟的、目前使用较广泛的PWM法。前面提到的采样控制理论中的一个重要结论:冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。SPWM法就是以该结论为理论基础,用脉冲宽度按正弦规律变化而和正弦波等效的PWM波形即SPWM波形控制逆变电路中开关器件的通断,使其输出的脉冲电压的面积与所希望输出的正弦波在相应区间内的面积相等,通过改变调制波的频率和幅值则可调节逆变电路输出电压的频率和幅值。该方法的实现有以下几种方案。

  1.3.1  等面积法

  该方案实际上就是SPWM法原理的直接阐释,用同样数量的等幅而不等宽的矩形脉冲序列代替正弦波,然后计算各脉冲的宽度和间隔,并把这些数据存于微机中,通过查表的方式生成PWM信号控制开关器件的通断,以达到预期的目的。由于此方法是以SPWM控制的基本原理为出发点,可以准确地计算出各开关器件的通断时刻,其所得的的波形很接近正弦波,但其存在计算繁琐,数据占用内存大,不能实时控制的缺点。

  1.3.2  硬件调制法

  硬件调制法是为解决等面积法计算繁琐的缺点而提出的,其原理就是把所希望的波形作为调制信号,把接受调制的信号作为载波,通过对载波的调制得到所期望的PWM波形。通常采用等腰三角波作为载波,当调制信号波为正弦波时,所得到的就是SPWM波形。其实现方法简单,可以用模拟电路构成三角波载波和正弦调制波发生电路,用比较器来确定它们的交点,在交点时刻对开关器件的通断进行控制,就可以生成SPWM波。但是,这种模拟电路结构复杂,难以实现精确的控制。

  1.3.3  软件生成法

  由于微机技术的发展使得用软件生成SPWM波形变得比较容易,因此,软件生成法也就应运而生。软件生成法其实就是用软件来实现调制的方法,其有两种基本算法,即自然采样法和规则采样法。

  1.3.3.1  自然采样法

  以正弦波为调制波,等腰三角波为载波进行比较,在两个波形的自然交点时刻控制开关器件的通断,这就是自然采样法。其优点是所得SPWM波形最接近正弦波,但由于三角波与正弦波交点有任意性,脉冲中心在一个周期内不等距,从而脉宽表达式是一个超越方程,计算繁琐,难以实时控制。

  1.3.3.2  规则采样法

  规则采样法是一种应用较广的工程实用方法,一般采用三角波作为载波。其原理就是用三角波对正弦波进行采样得到阶梯波,再以阶梯波与三角波的交点时刻控制开关器件的通断,从而实现SPWM法。当三角波只在其顶点(或底点)位置对正弦波进行采样时,由阶梯波与三角波的交点所确定的脉宽,在一个载波周期(即采样周期)内的位置是对称的,这种方法称为对称规则采样。当三角波既在其顶点又在底点时刻对正弦波进行采样时,由阶梯波与三角波的交点所确定的脉宽,在一个载波周期(此时为采样周期的两倍)内的位置一般并不对称,这种方法称为非对称规则采样 

7月14日

没有题目

从今天开始
每两个星期六我要上半天的班
突然发现
一个人的办公室真的很爽
安静,自由,写意
原来我真的喜欢一个人的感觉
上次刘宁给我做了一个测试
说我的孤独感是100%
一种从态度上自然而然的选择孤独
是的
我真的挺喜欢一个人的
自由,真的很自由
虽然有时候觉得寂寞
但是在自由和寂寞中选择
我想我情愿寂寞得自由着
有人说上班是一件很无聊的事情
其实我挺喜欢上班的
虽然有时候因为一个难题没有解决
会让我很抓狂,很痛苦,很头晕,很郁闷
但是却让我觉得很充实,很满足
当看着自己的设计越来越靠近成功的时候
那种感觉真的很棒,好象飞起来了一样
下了班可以去空手道
可以和朋友去活动
可以去跑跑步
也可以在家休息
虽然在家休息的机会比较少,嘿嘿
怎么说呢
我的生活真的挺丰富
虽然偶尔一个人的时候有点寂寞
但是记得有人说过一句话
男人越孤独越优秀
女人越优秀越孤独
呵呵,我还是希望成为一个优秀的男人
另外我想对一个女孩子说对不起
我想我辜负了你
你是一个好姑娘
相信你会找到自己的幸福
我不是一个值得女孩子交往的人
我已经不是以前那个有冲劲的我了
对于现在的我来说,没有比事业成功更渴望的了
所以请原谅我,虽然你看不到,呵呵
BOTH 加油~~!
7月5日

瞎想想

世界上最幸福的事情莫过于你爱的人也爱你,然后幸福得过一生
但是往往无法达到如此的完美
所以我选择找一个我爱的人去爱
然后学会爱上一个人的感觉
包括喜悦和痛苦
然后找个爱我的人结婚
并且给她幸福
因为她选择了我
呵呵。 又无聊瞎想咯.嘿嘿
6月18日

失踪了

失踪了
应该说是从我的生活中消失了
不需寻找
相信一切都会好的
哈哈
6月5日

忙中偷闲。嘿嘿

吃完那顿牛难吃的中饭
坐在安静的办公室里
呼吸着雨后清新的空气
5月的忙碌终于结束
生活步入正轨
上班,减肥,空手道
把时间安排的那么充实
发现自己越来越喜欢忙碌的感觉
虽然工作有点让我头疼
减肥有点跑不动
空手道让我有点睡眠不足
但是这样的感觉真好
看来我的确是个贱人
劳碌命啊~~~!
最近对朋友们关心有点少
在此对大家说一句
不好意思拉
联系少并不是我忽略大家
如果你们真的需要我
我一定来到你们身边
不过,事先先说好
夜宵就8吃了
不然我的体重估计永远下不来了
哈哈
大家也要为小弟的终身大事考虑考虑啊
好咯。工作去咯
祝看我空间的朋友们每天好心情咯
5月15日

饭要一口一口吃,事要一件一件做

今天终于把论文的初稿像挤牙膏一样得挤出来了
不容易啊不容易
要做的事情真的很多
想想就会觉得烦了
就像标题说的
急也没有用
静下心来慢慢做吧
一个一个完成
今天晚上抽空去了趟寝室
我的床上已经被别人占据
我的台子上除了几本我的书外
也没有我的东西了
虽然走廊还是这么熟悉
偶尔还可以看见几个熟悉的面孔
虽然我从来不知道他们的名字
看着进进出出的同学
感觉总是如此熟悉
却又好像我置身事外
是啊,这里的一切都已经不属于我了
回想当年我也是这样
无忧无虑,自由快活
好像我的主业是休息
上课只是偶尔的调剂
呵呵
看着学弟学妹们无忧无虑的表情
不知道是应该羡慕还是担忧
我以前不也是这个样子嘛。
在等车的空隙
还是注意了下MM们
呵呵,突然发现原来我们学校可爱的MM不少
咋我以前没有这么觉得呢
可能是心态不一样了吧。
哎,可惜机会已经浪费掉
或许不完美的人生才值得回忆吧。^_^
 
4月27日

着魔了

发现自己越来越牛了,哈哈
昨天晚上睡觉
在朦朦胧胧之中
产生了我觉得是世界上最牛的幻觉
我突然觉得我的被子有电
而且似乎还有光
我脑中一个想法不断提醒着我
这个是一个带220V电压的物体
甚至我连它是个被子都没有意识到
然后我本能的远离它
结果我就什么也没盖了
最后被冻醒了
迷迷糊糊得醒来
还略有顾及的把它盖上
可是第二次我又把被子踢得远远的
哎~~~
看来我是真的想太多了
着魔了,着魔了
哈哈
 
4月23日

中英文对照

原理图常用库文件:
Miscellaneous Devices.ddb
Dallas Microprocessor.ddb
Intel Databooks.ddb
Protel DOS Schematic Libraries.ddb
PCB元件常用库:
Advpcb.ddb
General IC.ddb
Miscellaneous.ddb

部分 分立元件库元件名称及中英对照
AND 与门
ANTENNA 天线
BATTERY 直流电源
BELL 铃,钟
BVC 同轴电缆接插件
BRIDEG 1 整流桥(二极管)
BRIDEG 2 整流桥(集成块)
BUFFER 缓冲器
BUZZER 蜂鸣器
CAP 电容
CAPACITOR 电容
CAPACITOR POL 有极性电容
CAPVAR 可调电容
CIRCUIT BREAKER 熔断丝
COAX 同轴电缆
CON 插口
CRYSTAL 晶体整荡器
DB 并行插口
DIODE 二极管
DIODE SCHOTTKY 稳压二极管
DIODE VARACTOR 变容二极管
DPY_3-SEG 3段LED
DPY_7-SEG 7段LED
DPY_7-SEG_DP 7段LED(带小数点)
ELECTRO 电解电容
FUSE 熔断器
INDUCTOR 电感
INDUCTOR IRON 带铁芯电感
INDUCTOR3 可调电感
JFET N N沟道场效应管
JFET P P沟道场效应管
LAMP 灯泡
LAMP NEDN 起辉器
LED 发光二极管
METER 仪表
MICROPHONE 麦克风
MOSFET MOS管
MOTOR AC 交流电机
MOTOR SERVO 伺服电机
NAND 与非门
NOR 或非门
NOT 非门
NPN NPN三极管
NPN-PHOTO 感光三极管
OPAMP 运放
OR 或门
PHOTO 感光二极管
PNP 三极管
NPN DAR NPN三极管
PNP DAR PNP三极管
POT 滑线变阻器
PELAY-DPDT 双刀双掷继电器
RES1.2 电阻
RES3.4 可变电阻
RESISTOR BRIDGE ? 桥式电阻
RESPACK ? 电阻
SCR 晶闸管
PLUG ? 插头
PLUG AC FEMALE 三相交流插头
SOCKET ? 插座
SOURCE CURRENT 电流源
SOURCE VOLTAGE 电压源
SPEAKER 扬声器
SW ? 开关
SW-DPDY ? 双刀双掷开关
SW-SPST ? 单刀单掷开关
SW-PB 按钮
THERMISTOR 电热调节器
TRANS1 变压器
TRANS2 可调变压器
TRIAC ? 三端双向可控硅
TRIODE ? 三极真空管
VARISTOR 变阻器
ZENER ? 齐纳二极管
DPY_7-SEG_DP 数码管
SW-PB 开关

74系列:

74LS00     TTL      2输入端四与非门
74LS01     TTL      集电极开路2输入端四与非门
74LS02     TTL      2输入端四或非门
74LS03     TTL      集电极开路2输入端四与非门
74LS122    TTL     可再触发单稳态多谐振荡器
74LS123    TTL     双可再触发单稳态多谐振荡器
74LS125    TTL     三态输出高有效四总线缓冲门
74LS126    TTL     三态输出低有效四总线缓冲门
74LS13     TTL     4输入端双与非施密特触发器
74LS132    TTL     2输入端四与非施密特触发器
74LS133    TTL     13输入端与非门
74LS136    TTL     四异或门
74LS138    TTL     3-8线译码器/复工器
74LS139    TTL     双2-4线译码器/复工器
74LS14     TTL     六反相施密特触发器
74LS145    TTL     BCD—十进制译码/驱动器
74LS15     TTL     开路输出3输入端三与门
74LS150    TTL     16选1数据选择/多路开关
74LS151    TTL     8选1数据选择器
74LS153    TTL     双4选1数据选择器
74LS154    TTL     4线—16线译码器
74LS155    TTL     图腾柱输出译码器/分配器
74LS156    TTL     开路输出译码器/分配器
74LS157    TTL     同相输出四2选1数据选择器
74LS158    TTL     反相输出四2选1数据选择器
74LS16     TTL     开路输出六反相缓冲/驱动器
74LS160    TTL     可预置BCD异步清除计数器
74LS161    TTL     可予制四位二进制异步清除计数器
74LS162    TTL     可预置BCD同步清除计数器
74LS163    TTL     可予制四位二进制同步清除计数器
74LS164    TTL     八位串行入/并行输出移位寄存器
74LS165    TTL     八位并行入/串行输出移位寄存器
74LS166    TTL     八位并入/串出移位寄存器
74LS169    TTL     二进制四位加/减同步计数器
74LS17     TTL     开路输出六同相缓冲/驱动器
74LS170    TTL     开路输出4×4寄存器堆
74LS173    TTL     三态输出四位D型寄存器
74LS174    TTL     带公共时钟和复位六D触发器
74LS175    TTL     带公共时钟和复位四D触发器
74LS180    TTL     9位奇数/偶数发生器/校验器
74LS181    TTL     算术逻辑单元/函数发生器
74LS185    TTL     二进制—BCD代码转换器
74LS190    TTL     BCD同步加/减计数器
74LS191    TTL     二进制同步可逆计数器
74LS192    TTL     可预置BCD双时钟可逆计数器
74LS193    TTL     可预置四位二进制双时钟可逆计数器
74LS194    TTL     四位双向通用移位寄存器
74LS195    TTL     四位并行通道移位寄存器
74LS196    TTL     十进制/二-十进制可预置计数锁存器
74LS197    TTL     二进制可预置锁存器/计数器
74LS20     TTL     4输入端双与非门
74LS21     TTL     4输入端双与门
74LS22     TTL     开路输出4输入端双与非门
74LS221    TTL     双/单稳态多谐振荡器
74LS240    TTL     八反相三态缓冲器/线驱动器
74LS241    TTL     八同相三态缓冲器/线驱动器
74LS243    TTL     四同相三态总线收发器
74LS244    TTL     八同相三态缓冲器/线驱动器
74LS245    TTL     八同相三态总线收发器
74LS247    TTL     BCD—7段15V输出译码/驱动器
74LS248    TTL     BCD—7段译码/升压输出驱动器
74LS249    TTL     BCD—7段译码/开路输出驱动器
74LS251    TTL     三态输出8选1数据选择器/复工器
74LS253    TTL     三态输出双4选1数据选择器/复工器
74LS256    TTL     双四位可寻址锁存器
74LS257    TTL     三态原码四2选1数据选择器/复工器
74LS258    TTL     三态反码四2选1数据选择器/复工器
74LS259    TTL     八位可寻址锁存器/3-8线译码器
74LS26     TTL     2输入端高压接口四与非门
74LS260    TTL     5输入端双或非门
74LS266    TTL     2输入端四异或非门
74LS27     TTL     3输入端三或非门
74LS273    TTL     带公共时钟复位八D触发器
74LS279    TTL     四图腾柱输出S-R锁存器
74LS28     TTL     2输入端四或非门缓冲器
74LS283    TTL     4位二进制全加器
74LS290    TTL     二/五分频十进制计数器
74LS293    TTL     二/八分频四位二进制计数器
74LS295    TTL     四位双向通用移位寄存器
74LS298    TTL     四2输入多路带存贮开关
74LS299    TTL     三态输出八位通用移位寄存器
74LS30     TTL     8输入端与非门
74LS32     TTL     2输入端四或门
74LS322    TTL     带符号扩展端八位移位寄存器
74LS323    TTL     三态输出八位双向移位/存贮寄存器
74LS33     TTL     开路输出2输入端四或非缓冲器
74LS347    TTL     BCD—7段译码器/驱动器
74LS352    TTL     双4选1数据选择器/复工器
74LS353    TTL     三态输出双4选1数据选择器/复工器
74LS365    TTL     门使能输入三态输出六同相线驱动器
74LS365    TTL     门使能输入三态输出六同相线驱动器
74LS366    TTL     门使能输入三态输出六反相线驱动器
74LS367    TTL     4/2线使能输入三态六同相线驱动器
74LS368    TTL     4/2线使能输入三态六反相线驱动器
74LS37        TTL     开路输出2输入端四与非缓冲器
74LS373    TTL     三态同相八D锁存器
74LS374    TTL     三态反相八D锁存器
74LS375    TTL     4位双稳态锁存器
74LS377    TTL     单边输出公共使能八D锁存器
74LS378    TTL     单边输出公共使能六D锁存器
74LS379    TTL     双边输出公共使能四D锁存器
74LS38     TTL     开路输出2输入端四与非缓冲器
74LS380    TTL     多功能八进制寄存器
74LS39     TTL     开路输出2输入端四与非缓冲器
74LS390    TTL     双十进制计数器
74LS393    TTL     双四位二进制计数器
74LS40     TTL     4输入端双与非缓冲器
74LS42     TTL     BCD—十进制代码转换器
74LS352    TTL     双4选1数据选择器/复工器
74LS353    TTL     三态输出双4选1数据选择器/复工器
74LS365    TTL     门使能输入三态输出六同相线驱动器
74LS366    TTL     门使能输入三态输出六反相线驱动器
74LS367    TTL     4/2线使能输入三态六同相线驱动器
74LS368    TTL     4/2线使能输入三态六反相线驱动器
74LS37     TTL     开路输出2输入端四与非缓冲器
74LS373    TTL     三态同相八D锁存器
74LS374    TTL     三态反相八D锁存器
74LS375    TTL     4位双稳态锁存器
74LS377    TTL     单边输出公共使能八D锁存器
74LS378    TTL     单边输出公共使能六D锁存器
74LS379    TTL     双边输出公共使能四D锁存器
74LS38     TTL     开路输出2输入端四与非缓冲器
74LS380    TTL     多功能八进制寄存器
74LS39     TTL     开路输出2输入端四与非缓冲器
74LS390    TTL     双十进制计数器
74LS393    TTL     双四位二进制计数器
74LS40     TTL     4输入端双与非缓冲器
74LS42     TTL     BCD—十进制代码转换器
74LS447    TTL     BCD—7段译码器/驱动器
74LS45     TTL     BCD—十进制代码转换/驱动器
74LS450    TTL     16:1多路转接复用器多工器
74LS451    TTL     双8:1多路转接复用器多工器
74LS453    TTL     四4:1多路转接复用器多工器
74LS46     TTL     BCD—7段低有效译码/驱动器
74LS460    TTL     十位比较器
74LS461    TTL     八进制计数器
74LS465    TTL     三态同相2与使能端八总线缓冲器
74LS466    TTL     三态反相2与使能八总线缓冲器
74LS467    TTL     三态同相2使能端八总线缓冲器
74LS468    TTL     三态反相2使能端八总线缓冲器
74LS469    TTL     八位双向计数器
74LS47     TTL     BCD—7段高有效译码/驱动器
74LS48     TTL     BCD—7段译码器/内部上拉输出驱动
74LS490    TTL     双十进制计数器
74LS491    TTL     十位计数器
74LS498    TTL     八进制移位寄存器
74LS50     TTL     2-3/2-2输入端双与或非门
74LS502    TTL     八位逐次逼近寄存器
74LS503    TTL     八位逐次逼近寄存器
74LS51     TTL     2-3/2-2输入端双与或非门
74LS533    TTL     三态反相八D锁存器
74LS534    TTL     三态反相八D锁存器
74LS54     TTL     四路输入与或非门
74LS540    TTL     八位三态反相输出总线缓冲器
74LS55     TTL     4输入端二路输入与或非门
74LS563    TTL     八位三态反相输出触发器
74LS564    TTL     八位三态反相输出D触发器
74LS573    TTL     八位三态输出触发器
74LS574    TTL     八位三态输出D触发器


74LS645    TTL     三态输出八同相总线传送接收器
74LS670    TTL     三态输出4×4寄存器堆
74LS73     TTL     带清除负触发双J-K触发器
74LS74     TTL     带置位复位正触发双D触发器
74LS76     TTL     带预置清除双J-K触发器
74LS83     TTL     四位二进制快速进位全加器
74LS85     TTL     四位数字比较器
74LS86     TTL     2输入端四异或门
74LS90     TTL     可二/五分频十进制计数器
74LS93     TTL     可二/八分频二进制计数器
74LS95     TTL     四位并行输入\\输出移位寄存器
74LS97     TTL     6位同步二进制乘法器
CD系列::
CD4000 双3输入端或非门+单非门 TI
CD4001 四2输入端或非门 HIT/NSC/TI/GOL
CD4002 双4输入端或非门 NSC
CD4006 18位串入/串出移位寄存器 NSC
CD4007 双互补对加反相器 NSC
CD4008 4位超前进位全加器 NSC
CD4009 六反相缓冲/变换器 NSC
CD4010 六同相缓冲/变换器 NSC
CD4011 四2输入端与非门 HIT/TI
CD4012 双4输入端与非门 NSC
CD4013 双主-从D型触发器 FSC/NSC/TOS
CD4014 8位串入/并入-串出移位寄存器 NSC
CD4015 双4位串入/并出移位寄存器 TI
CD4016 四传输门 FSC/TI
CD4017 十进制计数/分配器 FSC/TI/MOT
CD4018 可预制1/N计数器 NSC/MOT
CD4019 四与或选择器 PHI
CD4020 14级串行二进制计数/分频器 FSC
CD4021 08位串入/并入-串出移位寄存器 PHI/NSC
CD4022 八进制计数/分配器 NSC/MOT
CD4023 三3输入端与非门 NSC/MOT/TI
CD4024 7级二进制串行计数/分频器 NSC/MOT/TI
CD4025 三3输入端或非门 NSC/MOT/TI
CD4026 十进制计数/7段译码器 NSC/MOT/TI
CD4027 双J-K触发器 NSC/MOT/TI
CD4028 BCD码十进制译码器 NSC/MOT/TI
CD4029 可预置可逆计数器 NSC/MOT/TI
CD4030 四异或门 NSC/MOT/TI/GOL
CD4031 64位串入/串出移位存储器 NSC/MOT/TI
CD4032 三串行加法器 NSC/TI
CD4033 十进制计数/7段译码器 NSC/TI
CD4034 8位通用总线寄存器 NSC/MOT/TI
CD4035 4位并入/串入-并出/串出移位寄存 NSC/MOT/TI
CD4038 三串行加法器 NSC/TI
CD4040 12级二进制串行计数/分频器 NSC/MOT/TI
CD4041 四同相/反相缓冲器 NSC/MOT/TI
CD4042 四锁存D型触发器 NSC/MOT/TI
CD4043 4三态R-S锁存触发器("1"触发) NSC/MOT/TI
CD4044 四三态R-S锁存触发器("0"触发) NSC/MOT/TI
CD4046 锁相环 NSC/MOT/TI/PHI
CD4047 无稳态/单稳态多谐振荡器 NSC/MOT/TI
CD4048 4输入端可扩展多功能门 NSC/HIT/TI
CD4049 六反相缓冲/变换器 NSC/HIT/TI
CD4050 六同相缓冲/变换器 NSC/MOT/TI
CD4051 八选一模拟开关 NSC/MOT/TI
CD4052 双4选1模拟开关 NSC/MOT/TI
CD4053 三组二路模拟开关 NSC/MOT/TI
CD4054 液晶显示驱动器 NSC/HIT/TI
CD4055 BCD-7段译码/液晶驱动器 NSC/HIT/TI
CD4056 液晶显示驱动器 NSC/HIT/TI
CD4059 “N”分频计数器 NSC/TI
CD4060 14级二进制串行计数/分频器 NSC/TI/MOT
CD4063 四位数字比较器 NSC/HIT/TI
CD4066 四传输门 NSC/TI/MOT
CD4067 16选1模拟开关 NSC/TI
CD4068 八输入端与非门/与门 NSC/HIT/TI
CD4069 六反相器 NSC/HIT/TI
CD4070 四异或门 NSC/HIT/TI
CD4071 四2输入端或门 NSC/TI
CD4072 双4输入端或门 NSC/TI
CD4073 三3输入端与门 NSC/TI
CD4075 三3输入端或门 NSC/TI
CD4076 四D寄存器
CD4077 四2输入端异或非门 HIT
CD4078 8输入端或非门/或门
CD4081 四2输入端与门 NSC/HIT/TI
CD4082 双4输入端与门 NSC/HIT/TI
CD4085 双2路2输入端与或非门
CD4086 四2输入端可扩展与或非门
CD4089 二进制比例乘法器
CD4093 四2输入端施密特触发器 NSC/MOT/ST
CD4094 8位移位存储总线寄存器 NSC/TI/PHI
CD4095 3输入端J-K触发器
CD4096 3输入端J-K触发器
CD4097 双路八选一模拟开关
CD4098 双单稳态触发器 NSC/MOT/TI
CD4099 8位可寻址锁存器 NSC/MOT/ST
CD40100 32位左/右移位寄存器
CD40101 9位奇偶较验器
CD40102 8位可预置同步BCD减法计数器
CD40103 8位可预置同步二进制减法计数器
CD40104 4位双向移位寄存器
CD40105 先入先出FI-FD寄存器
CD40106 六施密特触发器 NSC\\TI
CD40107 双2输入端与非缓冲/驱动器 HAR\\TI
CD40108 4字×4位多通道寄存器
CD40109 四低-高电平位移器CD4529 双四路/单八路模拟开关
CD4530 双5输入端优势逻辑门
CD4531 12位奇偶校验器
CD4532 8位优先编码器
CD4536 可编程定时器
CD4538 精密双单稳
CD4539 双四路数据选择器
CD4541 可编程序振荡/***
CD4543 BCD七段锁存译码,驱动器
CD4544 BCD七段锁存译码,驱动器
CD4547 BCD七段译码/大电流驱动器
CD4549 函数近似寄存器
CD4551 四2通道模拟开关
CD4553 三位BCD计数器
CD4555 双二进制四选一译码器/分离器
CD4556 双二进制四选一译码器/分离器
CD4558 BCD八段译码器
CD4560 "N"BCD加法器
CD4561 "9"求补器
CD4573 四可编程运算放大器
CD4574 四可编程电压比较器
CD4575 双可编程运放/比较器
CD4583 双施密特触发器
CD4584 六施密特触发器
CD4585 4位数值比较器
CD4599 8位可寻址锁存器
CD40110 十进制加/减,计数,锁存,译码驱动 ST
CD40147 10-4线编码器 NSC\\MOT
CD40160 可预置BCD加计数器 NSC\\MOT
CD40161 可预置4位二进制加计数器 NSC\\MOT
CD40162 BCD加法计数器 NSC\\MOT
CD40163 4位二进制同步计数器 NSC\\MOT
CD40174 六锁存D型触发器 NSC\\TI\\MOT
CD40175 四D型触发器 NSC\\TI\\MOT
CD40181 4位算术逻辑单元/函数发生器
CD40182 超前位发生器
CD40192 可预置BCD加/减计数器(双时钟) NSC\\TI
CD40193 可预置4位二进制加/减计数器 NSC\\TI
CD40194 4位并入/串入-并出/串出移位寄存 NSC\\MOT
CD40195 4位并入/串入-并出/串出移位寄存 NSC\\MOT
CD40208 4×4多端口寄存器

型号 器件名称 厂牌 备注

CD4501 4输入端双与门及2输入端或非门
CD4502 可选通三态输出六反相/缓冲器
CD4503 六同相三态缓冲器
CD4504 六电压转换器
CD4506 双二组2输入可扩展或非门
CD4508 双4位锁存D型触发器
CD4510 可预置BCD码加/减计数器
CD4511 BCD锁存,7段译码,驱动器
CD4512 八路数据选择器
CD4513 BCD锁存,7段译码,驱动器(消隐)
CD4514 4位锁存,4线-16线译码器
CD4515 4位锁存,4线-16线译码器
CD4516 可预置4位二进制加/减计数器
CD4517 双64位静态移位寄存器
CD4518 双BCD同步加计数器
CD4519 四位与或选择器
CD4520 双4位二进制同步加计数器
CD4521 24级分频器
CD4522 可预置BCD同步1/N计数器
CD4526 可预置4位二进制同步1/N计数器
CD4527 BCD比例乘法器
CD4528 双单稳态触发器


注:同型号的74系列、74HC系列、74LS系列芯片,逻辑功能上是一样的。74LSxx的使用说明如果找不到的话,可参阅74xx或74HCxx的使用说明。 有些资料里包含了几种芯片,如74HC161资料里包含了74HC160、74HC161、74HC162、74HC163四种芯片的资料。找不到某种芯片的资料时,可试着查看一下临近型号的芯片资料。

其他元件库
Protel Dos Schematic 4000 Cmos .Lib

40.系列CMOS管集成块元件库

4013 D 触发器
4027 JK 触发器
Protel Dos Schematic Analog Digital.Lib 模拟数字式集成块元件库

AD系列 DAC系列 HD系列 MC系列

Protel Dos Schematic Comparator.Lib 比较放大器元件库
Protel Dos Shcematic Intel.Lib INTEL公司生产的80系列CPU集成块元件库
Protel Dos Schematic Linear.lib 线性元件库
例555
Protel Dos Schemattic Memory Devices.Lib 内存存储器元件库
Protel Dos Schematic SYnertek.Lib SY系列集成块元件库
Protes Dos Schematic Motorlla.Lib 摩托罗拉公司生产的元件库
Protes Dos Schematic NEC.lib NEC公司生产的集成块元件库
Protes Dos Schematic Operationel Amplifers.lib 运算放大器元件库
Protes Dos Schematic TTL.Lib 晶体管集成块元件库 74系列
Protel Dos Schematic Voltage Regulator.lib 电压调整集成块元件库
Protes Dos Schematic Zilog.Lib 齐格格公司生产的Z80系列CPU集成块元件库

元件属性对话框中英文对照

Lib ref 元件名称
Footprint 器件封装
Designator 元件称号
Part 器件类别或标示值
Schematic Tools 主工具栏
Writing Tools 连线工具栏
Drawing Tools 绘图工具栏
Power Objects 电源工具栏
Digital Objects 数字器件工具栏
Simulation Sources 模拟信号源工具栏
PLD Toolbars 映象工具栏

4月11日

人总是在不停得解决问题中成长

这个礼拜我终于把程序写的七七八八了
回想开始的时候那许许多多的问题
那些让我有些抓狂的问题
终于基本都解决的差不多了
突然觉得轻松了许多
虽然离真正完成还有很多很多的路
但至少我跨出了第一步
就入我的标题上所写的
我觉得人总是在不停解决问题中成长
从刚开始的照大量参照书写
到后来的直接写
相信当突然有一天发现问题越来越少时
我会成为一个真正的高手
原来想要做出一样东西并不是那么简单的事情
要学的东西很多很多
到此为止,编程先告一段落
接下来我又要进入下一个阶段咯
又是一个完全没有接触过的东西  protel
它的大名我是早有耳闻拉,果然闻名不如见面啊~~!
哎,又要从头学了,看看这个书,复杂啊
万事开头难,我知道的.
安下心来,慢慢学吧.相信以后在一个方面我也可以成为一个小小的小~~~高手.哈哈
有人说工程师是实干家~~~
这句话我喜欢.哈哈
 
4月5日

重新振作

最近的我真的懒得可以
都已经好长时间没有去空手道咯
一方面是因为前段时间单位里的项目搞的我焦头烂额
郁闷到不行
另一个方面就是如果去练晚上回来可能比较晚
怕第二天吃不消
不过我后来仔细想想
其实这些都是借口
尽管要做的东西多
可是我回来并没有做
其实时间是一样的
如果按时结束回家
洗漱完毕也就11点
早上7点起来也有8个小时
应该是足够的
说到底就是我懒呗
有时候人活的真的不能太舒服了
好日子过多了在去过苦日子真的有点难
而且有时候就喜欢为自己的懒找上一些借口
让这个懒顺理成章
哎~~~~人性的弱点啊
所以为了磨练自己的意志
同时也为了磨练自己日趋飙升的体重
我决定每个周1,周3,周6去空手道
恩~~~我要找回那种感觉~~!!
我爱空手~~~!!!
对了,从这个礼拜开始
我每个周5晚上和周六白天都要去读中级口译咯
地点:上外,哈哈.上外的姑娘们,我来拉~~~~哈哈
保佑我在我那个班上能碰到让我心动的姑娘
争取做到读书,泡妞两不误~~~
哦~~~赞,想想我就那个高兴啊~~~!!
 
LOOP 哈哈
GOTO LOOP
(编程编疯拉~~~~~)
4月2日

参考

单片机学习指南 资料提供:上海齐济电子有限公司
.1.
第1章 PIC16F877 的外围功能模块
1.1.2 简单应用实例
该例用于令与PORTD 口相连的8 个发光二极管前4 个点亮,后4 个熄灭。在调试程序
前,应使与PORTD 口相连的8 位拔码开关拔向相应的位置。
例1.1 PORTD 输出
#include <pic.h>
main()
{
TRISD=0X00; /*TRISD寄存器被赋值,PORTD 每一位都为输出*/
while(1); /*循环执行点亮发光二极管的语句*/
{
PORTD=0XF0; /*向PORTD 送数据,点亮LED(由实验模板*/
/*的设计决定相应位置低时LED 点亮)。*/
}
}
1.2.1 MSSP 模块SPI 方式功能简介
下面是一段简单的SPI 初始化例程,用于利用SPI 工作方式输出数据的场合。
例1.2 SPI 初始化程序
/*spi 初始化子程序*/
void SPIINIT()
{
PIR1=0; /*清除SPI 中断标志*/
SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */
SSPSTAT=0xC0;
TRISC=0x00; /*SDO引脚为输出,SCK 引脚为输出*/
}
1.2.3 程序清单
下面给出已经在实验板上调试通过的一个程序,可作为用户编制其它程序的参考。
#include <pic1687x.h>
/*该程序用于在8 个LED 上依次显示1~8 等8 个字符*/
static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
volatile unsigned char data;
#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/
static bit PORTA_5 @ PORTAIT(PORTA,5);
/*spi 初始化子程序*/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */
SSPSTAT=0xC0;
TRISC=0x00; /*SDO引脚为输出,SCK 引脚为输出*/
}
/*系统各输入输出口初始化子程序*/
void initial()
{
TRISA=0x00; /*A口设置为输出*/
INTCON=0x00; /*关闭所有中断*/
PORTA_5=0; /*LACK送低电平,为锁存做准备*/
单片机学习指南 资料提供:上海齐济电子有限公司
.2.
}
/*SPI 发送子程序*/
void SPILED(int data)
{
SSPBUF=data; /*启动发送*/
do
{

}while(SSPIF==0); /*等待发送完毕*/
SSPIF=0; /*清除SSPIF 标志*/
}
/*主程序*/
main()
{
unsigned I;
initial(); /*系统初始化*/
SPIINIT() ; /*SPI初始化*/
for(i=8;i>0;i--) /*连续发送8 个数据*/
{
data=table[i]; /*通过数组的转换获得待显示的段码*/
SPILED(data); /*发送显示段码显示*/
}
PORTA_5=1; /*最后给锁存信号,代表显示任务完成*/
}
1.3.3 程序清单
下面给出已经在实验板上调试通过的程序,可作为用户编制其它程序的参考。有关
显示部分的SPI 初始化,请读者参考1.2 节。
#include <pic.h>
/*该程序用于按下相应的键时,在第一个8 段LED 上显示相应的1~4 的字符*/
#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/
static bit PORTA_5 @ PORTAIT(PORTA,5);
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/
static bit PORTB_5 @ PORTBIT(PORTB,5);
static bit PORTB_4 @ PORTBIT(PORTB,4);
static bit PORTB_1 @ PORTBIT(PORTB,1) ;
static bit PORTB_2 @ PORTBIT(PORTB,2) ;
unsigned int I;
unsigned char j;
int data;
/*spi 初始化子程序*/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
TRISC=0xD7; /*SDO引脚为输出,SCK 引脚为输出*/
}
/*系统各输入输出口初始化子程序*/
void initial()
{
TRISA=0xDF;
TRISB=0XF0; /*设置与键盘有关的各口的数据方向*/
INTCON=0x00; /*关闭所有中断*/
单片机学习指南 资料提供:上海齐济电子有限公司
.3.
data=0X00; /*待显示的寄存器赋初值*/
PORTB=0X00; /*RB1 RB2 先送低电平*/
j=0;
}
/*软件延时子程序*/
void DELAY()
{
for(i = 6553; --i ;)
continue;
}
/*键扫描子程序*/
int KEYSCAN()
{
while(1)
{
if ((PORTB_5==0)||(PORTB_4==0))
break;
} /*等待有键按下*/
DELAY(); /*软件延时*/
if ((PORTB_5==0)||(PORTB_4==0))
KEYSERVE(); /*如果仍有键按下,则调用键服务子程序*/
else j=0x00; /*如果为干扰,则令返回值为0*/
return(j);
}
/*键服务子程序*/
int KEYSERVE()
{
PORTB=0XFD ;
if(PORTB_5==0) j=0X01;
if(PORTB_4==0) j=0X03;
PORTB=0XFB;
if(PORTB_5==0) j=0X02;
if(PORTB_4==0) j=0X04;/*以上根据按下的键确定相应的键值*/
PORTB=0X00; /*恢复PORTB 的值*/
while(1)
{
if((PORTB_5==1)&&(PORTB_4==1)) break;/*等待键盘松开*/
}
return(j);
}
/*SPI 发送子程序*/
void SPILED(int data)
{
SSPBUF=data; /*启动发送*/
do
{

}while(SSPIF==0); /*等待发送完毕
SSPIF=0;
}
/*主程序*/
main()
{
单片机学习指南 资料提供:上海齐济电子有限公司
.4.
static int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
initial();/*系统初始化*/
SPIINIT() ;/*SPI 初始化*/
while(1)
{
KEYSCAN();
if(j!=0) /*如果j=0,证明先前的按键为干扰,则不予显示*/
{
data=table[j];
PORTA_5=0; /*LACK信号清0,为锁存做准备*/
SPILED(data);
PORTA_5=1; /*最后给锁存信号,代表显示任务完成*/
}
}
}
1.4.1 PORTB 端口“电平变化中断”简介
例1.3 PORTB 口“电平变化中断”初始化子程序
/*B 口“电平变化中断”初始化子程序*/
void PORTBINT( )
{
TRISB=0XF0; /*设置相应口的输入输出方式*/
OPTION=0x7F; /*B口弱上拉有效*/
PORTB=0X00; /*RB1,RB2 先送低电平*/
RBIE=1; /*B口变位中断允许 */
PORTB=PORTB; /*读B 口的值,以锁存旧值,为变位中断创造条件*/
}
1.4.3 程序清单
下面给出一个调试通过的例程,以供读者参考。有关显示的部分请读者参考前面章节。
该程序中寄存器的位都用头文件中定义的位,如RB5 表示PORTB 的第5 位,而不像前面几
节那样自己定义。
#include <pic.h>
/*该程序用于通过PORTB 的"电平变化中断"进行键盘的识别。*/
/*程序设置一个键值寄存器j,当按下S9 键时j=1,按下S11 键时 */
/*j=2,按下S10 键时,j=3,按下S12 键时j=4*/
unsigned char data;
unsigned int I;
unsigned char j;
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,
0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*B 口“电平变化中断”初始化子程序*/
void PORTBINT()
{
TRISB=0XF0; /*设置相应口的输入输出方式*/
OPTION=0x7F;
PORTB=0X00; /*RB1, RB2 先送低电平*/
RBIE=1; /*B口变位中断允许 */
PORTB=PORTB; /*读B 口的值,为变位中断创造条件*/
}
/*spi 初始化子程序*/
void SPIINIT()
{
单片机学习指南 资料提供:上海齐济电子有限公司
.5.
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
TRISC=0xD7; /*SDO引脚为输出,SCK 引脚为输出*/
}
/*系统各输入输出口初始化子程序*/
void initial()
{
TRISA=0xDF;
INTCON=0x00; /*关闭所有中断*/
data=0X00; /*待显示的寄存器赋初值*/
}
/*键服务子程序*/
void KEYSERVE()
{
PORTB=0XFD ;
if(RB5==0) j=0X01;
if(RB4==0) j=0X03;
PORTB=0XFB ;
if(RB5==0) j=0X02;
if(RB4==0) j=0X04; /*以上通过逐行逐列扫描,以确定是何键按下*/
PORTB=0X00; /*恢复PORTB 的值*/
}
/*软件延时子程序*/
void DELAY()
{
for(i = 6553; --i ;)
continue;
}
/*SPI 发送子程序*/
void SPILED(int data)
{
SSPBUF=data; /*启动发送*/
do
{

}while(SSPIF==0);
SSPIF=0;
}
void IDEDIS()
{
KEYSERVE(); /*进行键盘的识别*/
data=table[j]; /*获得需要送出显示的段码*/
RA5=0; /*LACK信号清0,为锁存做准备*/
SPILED(data);
RA5=1; /*最后给一个锁存信号,代表显示任务完成*/
}
/*中断服务程序*/
void interrupt keyint(void)
{
DELAY(); /*软件延时*/
if ((RB5==0)||(RB4==0)) /*该语句除了能够确认按键是否为干扰外,*/
/*还可以屏蔽一次键松开时引起的中断*/
单片机学习指南 资料提供:上海齐济电子有限公司
.6.
IDEDIS(); /*键识别和显示模块*/
PORTB=PORTB; /*读B 口的值,改变中断发生的条件,避免键*/
/*一直按下时,连续进行键识别*/
RBIF=0; /*键扫描时可能会产生"电平变化"而使RBIF*/
/*置1,再清除一次RBIF 以避免额外中断*/
}
main()
{
initial(); /*系统初始化*/
PORTBINT(); /*B口变位中断初始化*/
SPIINIT() ; /*利用SPI 显示初始化*/
ei(); /*总中断允许*/
while(1)
{

} /*等待中断*/
}
1.5.2 程序清单
下面给出一个调试通过的例程,可作为读者的参考。调试该程序把模板J7 上的短路跳
针拔下,以免产生冲突。
#include <pic1687x.h>
volatile unsigned char data;
/*spi 初始化子程序*/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */
SSPSTAT=0xC0;
TRISC=0x10; /*SDI引脚为输入,SCK 引脚为输出*/
}
/*系统各输入输出口初始化子程序*/
void initial()
{
TRISA=0x00;
TRISD=0x00; /*D口为输出方式*/
INTCON=0x00; /*关闭所有中断*/
}
/*SPI 接收子程序*/
int SPIIN()
{
RA4=0; /*74HC165 并行置数使能,将8 位开关量置入器件*/
/* (LOAD为低电平时8 位并行数据置入74HC165)*/
RA4=1; /*74HC165 移位置数使能(LOAD 为高电平时芯*/
/*片才能串行工作)*/
SSPBUF=0; /*启动SPI,此操作只用于清除SSPSTAT 的
*BF位,因此W 中的实际数据无关紧要*/
do{

}while(SSPIF==0); /*查询数据接收完毕否?*/
SSPIF=0;
data=SSPBUF;
return(data); /*返回接收到的数据*/
}
单片机学习指南 资料提供:上海齐济电子有限公司
.7.
/*把SPI 接收的数据通过D 口显示在8 个发光二极管上的子程序*/
void SPIOUT(int data)
{
PORTD=~data;
}
/*主程序*/
main( )
{
initial(); /*系统初始化*/
SPIINIT(); /*SPI初始化*/
while(1)
{
SPIIN(); /*SPI接收外部数据*/
SPIOUT(data); /*送出数据显示*/
}
}
1.2.1 CCP 模块的PWM 工作方式简介
下面给出一个CCP 模块设置为PWM 操作时的初始化程序
例1.4 CCP 模块设置为PWM 方式时的初始化程序
/*CCP1 模块的PWM 工作方式初始化子程序*/
void CCP1INIT()
{
CCPR1L=0X7F;
CCP1CON=0X3C; /*设置CCP1 模块为PWM 工作方式,且其工作循环
*的低2 位为11,高8 位为01111111=7F*/
INTCON=0X00; /*禁止总中断和外围中断*/
PR2=0XFF; /*设置PWM 的工作周期*/
TRISC=0XFB; /*设置CCP1 引脚为输出方式*/
}
该初始化子程序设置CCP1 模块输出分辨率为10 位的PWM 波形,且占空比为50%。
1.2.3 程序清单
下面给出一个调试通过的例程,可作为读者编制程序的参考。
#include <pic.h>
/*该程序用于使CCP1 模块产生分辨率为10 位的PWM 波形,占空比为50%*/
/*CCP1 模块的PWM 工作方式初始化子程序*/
void CCP1INIT()
{
CCPR1L=0X7F;
CCP1CON=0X3C; /*设置CCP1 模块为PWM 工作方式,且其工作
*循环的低2 位为11,高8 位为01111111=7F*/
INTCON=0X00; /*禁止总中断和外围中断*/
PR2=0XFF; /*设置PWM 的工作周期*/
TRISC=0XFB; /*设置CCP1 引脚为输出方式*/
}
/*主程序*/
main()
{
CCP1INIT(); /*CCP1模块的PWM 工作方式初始化*/
T2CON=0X04; /*打开TMR2,且使其前分频为0,
*同时开始输出PWM 波形*/
do
{
单片机学习指南 资料提供:上海齐济电子有限公司
.8.

}while(1); /*系统开始输出PWM 波形。如果系统是
*多任务的,则可以在此执行其它任务,而
*不会影响PWM 波形的产生*/
}
1.3.3 应用程序
2. 程序清单
#include <pic.h>
/*此程序实现"看门狗"WDT 的功能*/
unsigned long I;
/*系统初始化子程序*/
void initial()
{
OPTION = 0X0F; /*把前分频器分配给WDT,且分频倍率为1:128*/
TRISD = 0X00; /*D口设为输出*/
}
/*延时子程序*/
void DELAY()
{
for (i=19999;--i;)
continue;
}
/*主程序*/
main ()
{
initial(); /*初始化,设定看门狗的相关寄存器*/
PORTD = 0X00; /*D口送00H,发光二极管亮*/
DELAY(); /*给予一定时间的延时*/
PORTD = 0XFF; /*D口送FFH,发光二极管灭*/
while(1)
{

} /*死循环,等待看门狗溢出复位*/
}
1.4.3 程序清单
该例在PIC16F877 休眠前使8 个发光二极管的高4 个发光,然后进入休眠工作方式;若
按键引起的中断将其激活,则低4 个发光。用C 语言编写程序时,语句SLEEP()相当于
汇编语言中的语句“sleep”,使单片机进入休眠状态。
#include <pic.h>
/*该程序实现PIC16F877 的休眠工作方式,并由实验板上的按键产生"电平变化中断"将其*
从休眠状态中激活。休眠与激活的状态由与D 口相连的8 个LED 显示。休眠时高4 个
*LED 发光,低4 个LED 熄灭; 激活以后高4 个LED 熄灭,低4 个LED 发光*/
unsigned long i;
/*系统初始化子程序*/
void initial()
{
di(); /*全局中断禁止,"电平变化中断"只执行唤醒功能*/
RBIE=1; /*PORTB口电平变化中断允许*/
RBIF=0; /*清除B 口电平变化中断标志*/
TRISB4=1;
TRISB5=1;
TRISB2=0;
单片机学习指南 资料提供:上海齐济电子有限公司
.9.
TRISB1=0; /*设置与键盘有关的各I/O 口的输入输出方式*/
TRISD=0X00; /*D 口为输出*/
PORTB=0X00; /*键盘的行线送低电平,为“电平变化中断” 作准备*/
PORTB=PORTB; /*读PORTB 的值,锁存旧值,也为“电平变化
*中断”作准备*/
}
/*主程序*/
main ()
{
initial(); /*初始化*/
PORTD=0X0F; /*高4 个LED 灯亮*/
SLEEP(); /*单片机开始进入休眠状态*/
PORTD=0XF0; /*激活后,低4 个LED 灯亮*/
while(1)
{

}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.10.
第2章 模拟量输入与输出
2.1 A/D 转换的应用
例2.1 A/D 转换初始化程序
//A/D 转换初始化子程序
void adinitial( )
{
ADCON0 = 0x51; //选择A/D 通道为RA2,打开A/D 转换器
//在工作状态,且使AD 转换时钟为8tosc
ADCON1 = 0X80; //转换结果右移,及ADRESH 寄存器的高6 位为"0"
//且把RA2 口设置为模拟量输入方式
PIE1 = 0X00;
PIE2 = 0X00;
ADIE = 1; //A/D转换中断允许
PEIE = 1; //外围中断允许
TRISA2=1; //设置RA2 为输入方式
}
2.1.2 程序清单
下面给出一个调试通过的例程,可作为读者编制程序的参考。该程序中用共用体的方式
把A/D 转换的10 位结果组合在一起。有关共用体的详细资料请参考本书相关章节。
# include <pic.h>
union adres
{int y1;
unsigned char adre[2];
}adresult; //定义一个共用体,用于存放A/D 转换的结果
unsigned char i;
unsigned int j;
//系统各I/O 口初始化子程序
void initial()
{
TRISD=0X00; //D口为输出
i=0x00;
}
//A/D 转化初始化子程序
void adinitial()
{
ADCON0=0x51; //选择A/D 通道为RA2,打开A/D 转换器
//在工作状态,且使A/D 转换时钟为8tosc
ADCON1=0X80; //转换结果右移,及ADRESH 寄存器的高6 位为"0"
//且把RA2 口设置为模拟量输入方式
PIE1=0X00;
PIE2=0X00;
ADIE=1; //A/D转换中断允许
PEIE=1; //外围中断允许
TRISA2=1; //设置RA2 为输入方式
}
//延时子程序
void delay()
{
单片机学习指南 资料提供:上海齐济电子有限公司
.11.
for(j=5535;--j;) continue;
}
//报警子程序
void alarm()
{
i=i^0xFF; //通过异或方式每次把i 的各位值取反
PORTD=i; //D口输出i 的值
}
//中断服务程序
void interrupt adint(void)
{
ADIF=0; //清除中断标志
adresult.adre[0]=ADRESL;
adresult.adre[1]=ADRESH; //读取并存储A/D 转换结果,A/D 转换的结果通过共
//用体的形式放入了变量y1 中
if(adresult.y1>0x200)
{
alarm(); //如果输入的模拟量大于2.5V(对应数字量
//0X200h),则调用报警子程序
delay(); //调用延时子程序,使电压检测不要过于频繁
}
else PORTD=0XF0 ; //如果输入的模拟量小于2.5V,则与D 口相连的
//8个发光二极管的低4 个发亮,表示系统正常
ADGO=1; //启动下一次A/D 转换
}
//主程序
main()
{
adinitial(); //A/D转换初始化
initial(); //系统各I/O 口初始化
ei(); //总中断允许
ADGO=1; //启动A/D 转换
while(1)
{

} //等待中断,在中断中循环检测外部电压
}
2.2.2 I2C 总线工作方式相关子程序
1.C 语言编写的I2C 总线工作方式的初始化子程序
//I2C 初始化子程序
void i2cint()
{
SSPCON = 0X08; //初始化SSPCON 寄存器
TRISC3 =1; //设置SCL 为输入口
TRISC4 =1; //设置SDA 为输入口
TRISA4 = 0;
SSPSTAT=0X80; //初始化SSPSTAT 寄存器
SSPADD=0X02; //设定I2C 时钟频率
SSPCON2=0X00; //初始化SSPCON2 寄存器
di(); //关闭总中断
SSPIF=0; //清SSP 中断标志
RA4=0; //关掉74HC165 的移位时钟使能,以免74HC165 移位
单片机学习指南 资料提供:上海齐济电子有限公司
.12.
//数据输出与I2C 总线的数据线发生冲突(此操作与该
//实验板的特殊结构有关,不是通用的)
SSPEN=1; //SSP模块使能
}
2.C 语言编写的I2C 总线工作方式传输数据子程序
需要发送的数据在寄存器j 中。
//I2C 总线输出数据子程序
i2cout()
{
SEN=1; //产生I2C 启动信号
for(n=0x02;--n;) continue;//给予一定的延时,保证启动
do {
RSEN=1; //产生I2C 重启动信号
}while(SSPIF==0); //如果没能启动,则反复启动,直到启动为止
SSPIF=0; //SSPIF 标志清0
SSPBUF=0X58; //I2C 总线发送地址字节
do {

}while(SSPIF==0); //等待地址发送完毕
SSPIF=0; //SSPIF 标志清0
SSPBUF=0X01; //I2C 总线发送命令字节
do {

}while(SSPIF==0); //等待命令发送完毕
SSPIF=0; //SSPIF 标志清0
SSPBUF=j; //I2C 总线发送数据字节
do {

}while(SSPIF==0); //等待数据发送完毕
SSPIF=0; //SSPIF 标志清0
PEN=1; //产生停止条件
do {

}while(SSPIF==0); //等待停止条件产生
SSPIF=0; //SSPIF 标志清0
}
2.2.4 程序清单
下面给一个例程。该程序利用MAX518 进行D/A 转换,且从D/A0 引脚输出一个正弦
波形。可作为读者编制程序的参考。特别注意,在调试该程序时,把模板上的钮子开关S8
拔向高电平,以免发生资源冲突。
#include <pic.h>
//本程序将通过PIC16F877 的I2C 方式驱动D/A 转换器MAX518,使其D/A0 通道输出
//一个连续的正弦波形(注:本程序并没对正弦波的频率进行控制)
const char table[ ] = {0X80,0X86,0X8D, 0X93,0X99,0X9F,0XA5,0XAB,
0XB1,0XB7,0XBC,0XC2,0XC7,0XCC,0XD1,0XD6,0XDA,0XDF,0XE3,0XE7,
0XEA,0XEE,0XF1,0XF4,0XF6,0XF8,0XFA,0XFC,0XFD,0XFF,0XFF,0XFF,
0XFF,0XFF,0XFF,0XFE,0XFD,0XFB,0XF9,0XF7,0XF5,0XF2,0XEF,0XEC,
0XE9,0XE5,0XE1,0XDD,0XD8,0XD4,0XCF,0XCA,0XC5,0XBF,0XBA,0XB4,
0XAE,0XA8,0XA2,0X9C,0X96,0X90,0X89,0X83,0X80,0X79,0X72,0X6C,
0X66,0X60,0X5A,0X55,0X4E,0X48,0X43,0X3D,0X38,0X33,0X2E,0X29,
0X25,0X20,0X1C,0X18,0X15,0X11,0X0E,0X0B,0X09,0X07,0X05,0X03,0X02,
单片机学习指南 资料提供:上海齐济电子有限公司
.13.
0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X02,0X04,0X06,0X08,0X0A,0X0D,
0X10,0X13,0X16,0X1A,0X1E,0X22,0X27,0X2B,0X30,0X35,0X3A,0X40,
0X45,0X4C,0X51,0X57,0X5D,0X63,0X69,0X6F,0X76,0X7C};
//以上的数组用于存放正弦表,在定义数组时,前面应该加上 const,
//以使数组存放于ROM 中,而不至于占用太多的RAM
unsigned char i;
unsigned char j;
unsigned char n;
//I2C 初始化子程序
void i2cint()
{
SSPCON = 0X08; //初始化SSPCON 寄存器
TRISC3 =1; //设置SCL 为输入口
TRISC4 =1; //设置SDA 为输入口
TRISA4 = 0;
SSPSTAT=0X80; //初始化SSPSTAT 寄存器
SSPADD=0X02; //设定I2C 时钟频率
SSPCON2=0X00; //初始化SSPCON2 寄存器
di(); //关闭总中断
SSPIF=0; //清SSP 中断标志
RA4=0; //关掉74HC165 的移位时钟使能,以免74HC165
//移位数据输出与I2C 总线的数据线发生冲突
SSPEN=1; //SSP模块使能
}
//I2C 总线输出数据子程序
void i2cout()
{
SEN=1; //产生I2C 启动信号
for(n=0x02;--n;) continue;//给予一定的延时,保证启动
do {
RSEN=1; //产生I2C 启动信号
}while(SSPIF==0); //如果没能启动,则反复启动,直到启动为止
SSPIF=0; //SSPIF 标志清0
SSPBUF=0X58; //I2C 总线发送地址字节
do {

}while(SSPIF==0); //等待地址发送完毕
SSPIF=0; //SSPIF 标志清0
SSPBUF=0X01; //I2C 总线发送命令字节
do {

}while(SSPIF==0); //等待命令发送完毕
SSPIF=0; //SSPIF 标志清0
SSPBUF=j; //I2C 总线发送数据字节
do {

}while(SSPIF==0); //等待数据发送完毕
SSPIF=0; //SSPIF 标志清0
PEN=1; //产生停止条件
do {

}while(SSPIF==0); //等待停止条件产生
单片机学习指南 资料提供:上海齐济电子有限公司
.14.
SSPIF=0; //SSPIF 标志清0
}
//主程序
main ()
{
i2cint(); //I2C 初始化
while(1){
for(i=0x00;i<=127;++i)
{
j=table[i]; //从数组中得到需要传输的数据量
i2cout(); //利用I2C 总线方式送出数据
}
}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.15.
第3章 秒 表
3.2.2 程序清单
该源程序已在实验板上调试通过,读者可直接引用,并可利用软件编程的灵活性,加以
拓展,实现更为复杂的功能。
#include <pic.h>
#include <math.h>
//此程序实现计时秒表功能,时钟显示范围00.00~95.99 秒,分辨度:0.01 秒
unsigned char s0,s1,s2,s3;
//定义0.01 秒、0.1 秒、1 秒、10 秒计时器
unsigned char s[4];
unsigned char k ,data ,sreg;
unsigned int i;
const table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90};
//不带小数点的显示段码表
const table0[10]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
//带小数点的显示段码表
//TMR0 初始化子程序
void tmint()
{
T0CS=0; //TMR0工作于定时器方式
PSA=1; //TMR0不用分频
T0IF=0; //清除TMR0 的中断标志
T0IE=1; //TMR0中断允许
}
//spi 显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置SPI 的控制方式,允许SSP 方式,并且时钟下降沿发送。与"74HC595,当其
//SCLK 从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7; //SDO 引脚为输出,SCK 引脚为输出
TRISA5=0; //RA5引脚置为输出,输出显示锁存信号
}
//系统其它部分初始化子程序
void initial()
{
TRISB1=0;
TRISB2=0;
TRISB4=1;
TRISB5=1; //设置与键盘有关的各口的输入输出方式
RB1=0;
RB2=0; //建立键盘扫描的初始条件
}
//SPI 传输数据子程序
void SPILED(data)
{
SSPBUF=data; //启动发送
单片机学习指南 资料提供:上海齐济电子有限公司
.16.
do {

}while(SSPIF==0);
SSPIF=0;
}
//显示子程序,显示4 位数
void dispaly()
{
RA5=0; //准备锁存
for(k=4;k>0;k--)
{
data=s[k-1];
if(k==3) data=table0[data];//第二位需要显示小数点
else data=table[data];
SPILED(data); //发送显示段码
}
for(k=0;k<4;k++)
{
data=0xFF;
SPILED(data); //连续发送4 个DARK,使显示好看一些
}
RA5=1; //最后给锁存信号,代表显示任务完成
}
//软件延时子程序
void DELAY()
{
for(i = 3553; --i ;) continue;
}
//键扫描子程序
void KEYSCAN()
{
while(1){
while(1)
{
dispaly(); //调用一次显示子程序
if ((RB5==0)||(RB4==0)) break;
}
DELAY(); //若有键按下,则软件延时
if ((RB5==0)||(RB4==0)) break;//若还有键按下,则终止循环扫描,返回
}
}
//等键松开子程序
void keyrelax()
{
while(1){
dispaly(); //调用一次显示子程序
if ((RB5==1)&&(RB4==1)) break;
} //为防止按键过于灵敏,每次等键松开才返回
}
//系统赋值初始化子程序
void inizhi()
{
s0=0x00;
s[0]=s0;
单片机学习指南 资料提供:上海齐济电子有限公司
.17.
s1=0x00;
s[1]=s1;
s2=0x00;
s[2]=s2;
s3=0x00;
s[3]=s3; //s0=s1=s2=s3=0,并放入显示缓冲数组中
sreg=0x00; //tmr0 中断次数寄存器清0
}
//中断服务程序
void interrupt clkint(void)
{
TMR0=0X13; //对TMR0 写入一个调整值。因为写入TMR0 后接着的
//两个周期不能增量,中断需要3 个周期的响应时间,
//以及C 语言自动进行现场保护要消耗周期
T0IF=0; //清除中断标志
CLRWDT();
sreg=sreg+1; //中断计数器加1
if(sreg==40) //中断次数为40 后,才对S0,S1,S2,S3 操作
{
sreg=0;
s0=s0+1;
if(s0==10){
s0=0 ;
s1=s1+1;
if(s1==10){
s1=0 ;
s2=s2+1;
if(s2==10){
s2=0;
s3=s3+1;
if(s3==10) s3=0 ;
}
}
}
}
s[0]=s0;
s[1]=s1;
s[2]=s2;
s[3]=s3;
}
//主程序
main()
{
OPTION=0XFF;
tmint(); //TMR0初始化
SPIINIT(); //spi显示初始化
initial(); //系统其它部分初始化
di(); //总中断禁止
while(1) {
inizhi(); //系统赋值初始化
KEYSCAN(); //键扫描,直到开始键按下
keyrelax(); //等键松开
单片机学习指南 资料提供:上海齐济电子有限公司
.18.
ei(); //总中断允许
KEYSCAN(); //键扫描直到停止键按下,在键扫描时有显示
keyrelax() ; //等键松开
di(); //总中断禁止
KEYSCAN(); //键扫描到清0 键按下,在键扫描时有显示
keyrelax() ; //等键松开
}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.19.
第4 章 通用同步/异步通信的应用
4.1 单片机双机异步通信
4.1.1 单片机PIC1 编程(发送部分)
#include <pic.h>
/*该程序实现单片机双机异步通信功能,该程序是发送部分*/
unsigned char tran[8]; /*定义一个数组存储发送数据*/
unsigned char k,data; /*定义通用寄存器*/
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*不带小数点的显示段码表*/
/*spi 显示初始化子程序*/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
/*设置SPI 的控制方式,允许SSP 方式,并且时钟下降沿发送,与"74HC595,当其
*SCLK 从低到高跳变时,串行输入寄存器"的特点相对应*/
TRISC=0xD7; /*SDO引脚为输出,SCK 引脚为输出*/
TRISA5=0; /*RA5引脚设置为输出,以输出显示锁存信号*/
}
/*给数组赋初值子程序 */
void fuzhi()
{
for(k=0;k<8;k++) {
tran[k]=k+3;
}
}
/*SCI 部件初始化子程序*/
void sciint()
{
SPBRG=0X19; /*将传输的波特率设为约9 600 位/秒*/
TXSTA=0X04; /*选择异步高速方式传输8 位数据*/
RCSTA=0X80; /*允许同步串行口工作*/
TRISC6=1;
TRISC7=1; /*将RC6、RC7 设置为输入方式,对外部呈高阻状态*/
}
/*SPI 传输数据子程序*/
void SPILED(data)
{
SSPBUF=data; /*启动发送*/
do {

}while(SSPIF==0);
SSPIF=0;
}
/*显示子程序,显示8 位数*/
void display()
{
RA5=0; /*准备锁存*/
单片机学习指南 资料提供:上海齐济电子有限公司
.20.
for(k=0;k<8;k++) {
data=tran[k];
data=table[data]; /*查得显示的段码*/
SPILED(data); /*发送显示段码*/
}
RA5=1; /*最后给一个锁存信号,代表显示任务完成*/
}
/*主程序*/
main()
{
SPIINIT();
fuzhi(); /*给数组赋初值*/
sciint(); /*SCI部件初始化*/
di(); /*中断禁止*/
TXEN=1; /*发送允许*/
CREN=1; /*接收数据允许*/
for(k=0;k<8;k++){
TXREG=tran[k]; /*发出一个字符*/
while(1){
if(TXIF==1) break;
} /*等待写入完成*/
while(1){
if(RCIF==1) break;/*若收到响应字节,则终止等待*/
}
RCREG=RCREG; /*读响应字节,清RCIF*/
}
display(); /*显示发送的数据*/
while(1){

}
}
4.1.2 单片机PIC2 编程(接收部分)
#include <pic.h>
/*该程序实现单片机双机异步通信功能,该程序是接收部分,并把接收的数据显示在8
*个LED 上*/
unsigned char rece[8];/*定义一个数组存储接收数据*/
unsigned char k,data;/*定义通用寄存器*/
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*不带小数点的显示段码表*/
/*spi 显示初始化子程序*/
void SPIINIT()
{
;详细语句见发送程序
}
/*SCI 部件初始化子程序*/
void sciint()
{
SPBRG=0X19; /*波特率设置与PIC1 相同,为约9 600 位/秒*/
TXSTA=0X04; /*异步高速传输*/
RCSTA=0X80; /*串行口工作使能*/
TRISC6=1;
单片机学习指南 资料提供:上海齐济电子有限公司
.21.
TRISC7=1; /*将RC6、RC7 设置为输入方式,对外部呈高阻状态*/
}
/*SPI 传送数据子程序*/
void SPILED(data)
{
;详细语句与见发送程序
}
/*显示子程序,显示4 位数*/
void display()
{
RA5=0; /*准备锁存*/
for(k=0;k<8;k++){
data=rece[k];
data=table[data]; /*查得显示的段码*/
SPILED(data); /*发送显示段码*/
}
RA5=1; /*最后给一个锁存信号,代表显示任务完成*/
}
/*主程序*/
main()
{
SPIINIT(); /*spi显示初始化*/
sciint(); /*SCI部件初始化*/
di(); /*中断禁止*/
CREN=1; /*接收允许*/
TXEN=1; /*发送允许*/
for(k=0;k<8;k++){
while(1){
if(RCIF==1) break;
} /*等待接收数据*/
rece[k]=RCREG; /*读取接收数据,同时清掉RCIF*/
TXREG=rece[k]; /*发送接收到的数据*/
while(1){
if(TXIF==1) break;
} /*等待写入完成*/
}
display(); /*显示接收的数据*/
while(1){

}
}
4.2 单片机双机同步通信
4.2.1 单片机PIC1 编程(主控发送)
#include <pic.h>
/*该程序实现单片机双机同步通信功能,是主控发送部分。程序上电后显示
*相应的字符,表示系统正常工作。发送完毕后显示发送的数据*/
unsigned char tran[8]; /*定义一个数组存储发送数据*/
unsigned char k,data; /*定义通用寄存器*/
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,
0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*不带小数点的的显示段码表*/
/*spi 显示初始化子程序*/
单片机学习指南 资料提供:上海齐济电子有限公司
.22.
void SPIINIT()
{
;详细程序语句请参考本章4.5 节
}
/*给发送数组赋初值子程序 */
void fuzhi()
{
for(k=0;k<8;k++){
tran[k]=k;
} /*发送0~7 八个数据*/
}
/*SCI 部件初始化子程序*/
void sciint()
{
SPBRG=200 ; /*将传输的波特率设为约9600 位/秒*/
TXSTA=0X90; /*选择主控方式*/
RCSTA=0X80; /*允许同步串行口工作*/
TRISC6=1;
TRISC7=1; /*将RC6、RC7 设置为输入方式,对外部呈高阻状态*/
}
/*SPI 传送数据子程序*/
void SPILED(data)
{
;详细程序语句请参考本章4.5 节
}
/*显示子程序,显示8 位数*/
void display()
{
RA5=0; /*准备锁存*/
for(k=0;k<8;k++){
data=tran[k];
data=table[data]; /*查得显示的段码*/
SPILED(data); /*发送显示段码*/
}
RA5=1; /*最后给一个锁存信号,代表显示任务完成*/
}
/*显示子程序,显示8 位数*/
void display1()
{
RA5=0; /*准备锁存*/
for(k=0;k<8;k++){
data=0xf9; /*显示"1"表示系统正常工作*/
SPILED(data); /*发送显示段码*/
}
RA5=1; /*最后给一个锁存信号,代表显示任务完成*/
}
/*主程序*/
main()
{
SPIINIT(); /*spi显示初始化*/
fuzhi(); /*给发送数组赋发送初值*/
sciint(); /*SCI部件初始化*/
di(); /*中断禁止*/
单片机学习指南 资料提供:上海齐济电子有限公司
.23.
TXEN=1; /*发送允许*/
display1(); /*显示相应的字符,表示系统正常*/
while(1){
for(k=0;k<8;k++){
TXREG=tran[k];/*发出一个字符*/
while(1){
if(TXIF==1) break;
} /*等待上一个数据写入完成*/
}
display(); /*显示发送的数据*/
} /*循环发送*/
}
4.2.2 单片机PIC2 编程(从动接收)
#include <pic.h>
/*该程序实现单片机双机 同步通信功能,是从动接收部分,并把接收的数据显
*示在8 个LED 上*/
unsigned char rece[8]; /*定义一个数组存储接收数据*/
unsigned char k,data; /*定义通用寄存器*/
unsigned int i;
const char table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
/*不带小数点的显示段码表*/
/*spi 显示初始化子程序*/
void SPIINIT()
{
;详细程序语句请参考本章4.5 节
}
/*SCI 部件初始化子程序*/
void sciint()
{
TXSTA=0X10 ; /*选择同步从动方式*/
RCSTA=0X90; /*串行口工作使能*/
TRISC6=1;
TRISC7=1; /*将RC6、RC7 设置为输入方式对外部呈高阻状态*/
}
/*SPI 传送数据子程序*/
void SPILED(data)
{
;/*详细程序语句请参考本章4.5 节*/
}
/*显示子程序,显示4 位数*/
void display()
{
RA5=0; /*准备锁存*/
for(k=0;k<8;k++){
data=rece[k];
data=table[data]; /*查得显示的段码*/
SPILED(data); /*发送显示段码*/
}
RA5=1; /*最后给一个锁存信号,代表显示任务完成*/
}
/*主程序*/
单片机学习指南 资料提供:上海齐济电子有限公司
.24.
main()
{
SPIINIT(); /*spi显示初始化*/
sciint(); /*SCI部件初始化*/
di(); /*中断禁止*/
CREN=1; /*接收允许*/
for(k=0;k<8;k++) rece[k]=0x03;
display(); /*显示表示系统正常运行的数据*/
while(1) {
while(1){
CREN=1; /*允许连续接收*/
while(1){
if(RCIF==1) break;
} /*等待接收数据*/
k=0;
rece[k]=RCREG; /*读取接收数据*/
if(OERR==1) { /*如果有溢出错误,则处理*/
CREN=0;
CREN=1;
}
if(rece[k]==0x00) break;/*“0”为同步字符,只有接收到“0”时才进行下面的接收*/
}
for(k=1;k<8;k++){
while(1){
if(RCIF==1) break;
} /*等待接收数据*/
rece[k]=RCREG;/*读取接收数据*/
if(OERR==1) { /*如果有溢出错误,则处理*/
CREN=0;
CREN=1;
}
rece[k]=rece[k]&0x0F;/*屏蔽掉高位,防止干扰*/
}
CREN=0;
display(); /*显示接收的数据*/
for(i=65535;--i; )continue;
for(i=65535;--i; )continue;/*给予一定时间的延时,再进行下一轮接收*/
}
}
4.3 单片机与PC 机通信
4.3.1 PC 机编程
PC 采用Toubr C 进行编写。程序如下:
#include<stdio.h>
#define port 0x3f8 /*利用串口1 进行通信*/
int ch[15];
main ()
{
int a;
int i,j;
int b[6]={88,15,38,26,20,0};
char c;
单片机学习指南 资料提供:上海齐济电子有限公司
.25.
clrscr();
outportb(port+3,0x80); /*准备设置波特率*/
outportb(port,0x0C); /*波特率设置为9600bps*/
outportb(port+1,0x00);
outportb(port+3,0x03); /*8位数据,无奇偶检验,1 位停止位*/
outportb(port+1,0x00); /*关中断*/
inportb(port+5); /*读一次线路状态寄存器,使其复位*/
for(;;){
printf("\t\tsend data or receive data: (s or r?)\n\n\n");
c=getchar();
switch(c) {
case 's':
case 'S': {
while(!(inportb(port+5)&0x20));/*发送保持器满则等待*/
outportb(port,0x01); /*否则发送数据01,通知单片机准备接收*/
for(i=0;i<6;i++){ /*共发送6 个数据*/
a=b[i];
while(!(inportb(port+5)&0x20)) delay(100);/*发送保持器满,等待*/
outportb(port,a); /*发送a*/
printf("%d\n",a); /*显示a*/
while(!(inport(port+5)&1)); /*接收单片机送回的数据*/
ch[i]=inport(port); /*保存*/
}
delay(10);
for(j=0;j<8;j++) printf("\n%d\n",ch[j]);/*显示接收的回送数据*/
getch();
break;
}
case'r': /*接收数据*/
case'R':{
while(!(inportb(port+5)&0x20));
outportb(port,0x02); /*发送数据02,通知单片机发送数据*/
for(j=0;j<9;j++) { /*共接收9 个数据*/
while(!(inportb(port+5)&1));
ch[j]=inportb(port);
}
for(j=0;j<9;j++) printf("\n %d\n",ch[j]);
getch();
break;
}
}
}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.26.
第5章 PIC16F87X 在CAN 通信中的应用
5.1 软件清单
// ========CAN 通信程序=======
#include <pic.h>
#include <pic16f87x.h>
#include <mcp256.h> // MCP2510 寄存器定义
// =========常数和变量定义=========
#define READ 0x03 // 读MCP2510 指令代码
#define WRITE 0x02 // 写MCP2510 指令代码
#define RESET 0xC0 // 复位MCP2510 指令代码
#define RTS 0x80 // MCP2510 请求发送指令代码
#define STA2510 0xA0 // 读MCP2510 状态指令代码
#define BITMOD 0x05 // MCP2510 位修改指令代码
int a[12]; // SPI 发送或接收数据寄存器
int b[8]; // 发送或接收的数据
int c[8]; // 发送或接收的数据
int i; // 临时变量
int count; // 发送接收计数器
int count1=0; // for test
int RecID_H=0;
int RecID_L=0;
int DLC=8;
void SPIINT();
void TMR1INT();
void CCP1INT();
void SPIEXCHANGE(int count);
void WAIT_SPI();
void RESET2510();
int RD2510(int adress,int n);
void WR2510(int adress,int n);
void RTS2510(int RTSn);
int GETS2510();
void BM2510(int adress,int mask,int data);
void SETNORMAL();
void TXCOMPLETE(int adress);
void TXMSG(int DLC);
int RXMSG();
void INIT2510();
void INIT877();
void INITSPI();
void ACK();
void wait();
// ========主程序=======
main(void)
{
int l,detect=0;
SSPIE=1;
TMR1IE=1;
单片机学习指南 资料提供:上海齐济电子有限公司
.27.
CCP1IE=1;
CCP2IE=1;
PEIE=1;
ei(); // 开中断
INIT877(); // 初始化PIC16F877 芯片
INITSPI(); // 初始化SPI 接口
INIT2510(); // 初始化MCP2510 芯片
flag1=0;
flag2=0;
CCP1CON=0x05;
CCP2CON=0x04;
while(1) {
RXMSG();
TXMSG(8);
}
}
// ========中断服务程序=======
// SPI 中断服务子程序
void SPIINT()
{
SSPIF=0;
a[i++]=SSPBUF; // 数据暂存a[]中
count-=1;
if(count>0) SSPBUF=a[i];// 未发送完,继续
else RE2=1; // 否则,片选信号置高电平
return;
}
// TMR1 中断服务子程序
void TMR1INT()
{
TMR1IF=0;
T1CON=0;
if(!flag1){
TMR1H=0xfe; // 512 μs 脉冲宽度
TMR1L=0x00;
T1CON=0x01;
PORTD=0xff; // 输出所有通道
flag1=1;
}
else {
flag1=0;
PORTD=0;
T1CON=0;
}
return;
}
// CCP1 中断服务子程序
void CCP1INT()
{
CCP1IF=0;
T1CON=0x01;
单片机学习指南 资料提供:上海齐济电子有限公司
.28.
return;
}
// CCP2 中断服务子程序
void CCP2INT()
{
CCP2IF=0;
T1CON=0x01;
return;
}
// 中断入口,保护现场,判中断类型
void interrupt INTS()
{
di();
if(TMR1IF) TMR1INT(); // 定时器TMR1 中断
else if(CCP1IF) CCP1INT(); // 电压过零捕捉中断1
else if(CCP2IF) CCP2INT(); // 电压过零捕捉中断2
else if(SSPIF) SPIINT(); // SPI 接口中断
ei();
}
// ========子程序=======
// 启动SPI 传送
void SPIEXCHANGE(count)
int count;
{
if(count>0) { // 有数据可送?
i=0;
RE2=0; // 片选位置低电平
SSPBUF=a[i]; // 送数
}
else
; // 否则,空操作,并返回
return;
}
// 等待SPI 传送完成
void WAIT_SPI()
{
do{
;
}while(count>0); // 当count!=0 时,等待 to add "CLRWDT"
return;
}
// 对MCP2510 芯片进行复位
void RESET2510()
{
a[0]=RESET;
count=1;
SPIEXCHANGE(count); // 送复位指令
WAIT_SPI();
return;
}
// 读取从地址"adress"开始的寄存器中的数据,共n 个,存放在数组b[n]中
单片机学习指南 资料提供:上海齐济电子有限公司
.29.
int RD2510(adress,n)
int adress;
int n;
{
int j;
a[0]=READ;
a[1]=adress;
for(j=0;j<n;j++) a[j+2]=0;
count=n+2; // 指令、地址和要得到的数据量n
SPIEXCHANGE(count);
WAIT_SPI();
for(j=0;j<n;j++) b[j]=a[j+2];// 数据存到数组b[]中
return;
}
// 向从地址"adress"开始的寄存器写入数据,共n 个,数据存放数组b[n]中
void WR2510(adress,n)
int adress;
int n;
{
int j;
a[0]=WRITE;
a[1]=adress;
for(j=0;j<n;j++) a[j+2]=b[j];
count=n+2; // 指令、地址和要写入的数据量n
SPIEXCHANGE(count);
WAIT_SPI();
return;
}
// MCP2510 芯片请求发送程序
void RTS2510(RTSn)
int RTSn;
{
a[0]=RTS^RTSn;
count=1;
SPIEXCHANGE(count); // 发送MCP2510 芯片,请求发送指令
WAIT_SPI();
return;
}
// 读取MCP2510 芯片的状态
int GETS2510()
{
a[0]=STA2510;
a[1]=0;
count=2;
SPIEXCHANGE(count); // 读取MCP2510 芯片状态
WAIT_SPI();
b[0]=a[1]; // 状态存到数组b[]中
return;
}
// 对MCP2510 芯片进行位修改子程序
void BM2510(adress,mask,data)
单片机学习指南 资料提供:上海齐济电子有限公司
.30.
int adress;
int mask;
int data;
{
a[0]=BITMOD; // 位修改指令
a[1]=adress; // 位修改寄存器地址
a[2]=mask; // 位修改屏蔽位
a[3]=data; // 位修改数据
count=4;
SPIEXCHANGE(count);
WAIT_SPI();
return;
}
// 设置MCP2510 芯片为正常操作模式
void SETNORMAL()
{
int k=1;
BM2510(CANCTRL,0xe0,0x00); // 设置为正常操作模式
do {
RD2510(CANSTAT,1);
k=b[0]&0xe0;
}while(k); // 确认已进入正常操作模式
return;
}
// 对MCP2510 进行初始化
void INIT2510()
{
RESET2510(); // 使芯片复位
b[0]=0x02;
b[1]=0x90;
b[2]=0x07;
WR2510(CNF3,3); // 波特率为 125 kbps
b[0]=0x00;
b[1]=0x00;
WR2510(RXM0SIDH,2);
b[0]=0x00;
b[1]=0x00;
WR2510(RXF0SIDH,2); // RX0 接收,屏蔽位为0,过滤器为0
b[0]=0x00;
WR2510(CANINTE,1); // CAN 中断不使能
SETNORMAL(); // 设置为正常操作模式
return;
}
// MCP2510 芯片发送完成与否判断,邮箱号为adress
void TXCOMPLETE(adress)
int adress;
{
int k=1;
do {
RD2510(adress,1);
k=b[0]&0x08;
单片机学习指南 资料提供:上海齐济电子有限公司
.31.
}while(k); // 确认是否已发送完毕 to add CLRWDT
return;
}
// 初始化PIC16F877 芯片
void INIT877()
{
PORTA=0;
PORTB=0;
PORTC=0;
PORTD=0;
PORTE=0;
TRISA=0xff;
TRISB=0xfd;
TRISC=0xd7; // SCK, SDO:输出,SDI:输入
TRISD=0;
TRISE=0x03; // 片选CS 信号输出
PORTA=0xff;
PORTB=0x03; // RST=1
PORTC=0;
PORTD=0xff;
PORTE=0x04;
return;
}
// 初始化SPI 接口
void INITSPI()
{
SSPCON=0x11;
SSPEN=1; // SSP 使能
SSPSTAT=0;
return;
}
// 发送数据子程序
void TXMSG(int DLC)
{
for(i=0;i<DLC;i++) b[i]=c[i];
WR2510(TXB0D0,DLC);
b[0]=DLC;
WR2510(TXB0DLC,1);
b[0]=0x03;
b[1]=RecID_H;
b[2]=RecID_L;
WR2510(TXB0CTRL,3);
RTS2510(0x01); // 请求发送
TXCOMPLETE(TXB0CTRL); //等待发送完毕
return;
}
// 接收数据子程序
int RXMSG()
{
int k;
RD2510(CANINTF,1);
单片机学习指南 资料提供:上海齐济电子有限公司
.32.
k=b[0]&0x01;
if(k==1) {
BM2510(CANINTF,0x01,0x00);
RD2510(RXB0SIDH,2);
RecID_H=b[0];
RecID_L=b[1]&0xe0;
RD2510(RXB0DLC,1);
DLC=b[0]&0x0f;
RD2510(RXB0D0,DLC);
for(i=0;i<DLC;i++) c[i]=b[i];
return 1;
}
return 0;
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.33.
第6 章 利用CCP 模块设计频率计
6.1 程序设计
6.1.1 程序清单
#include <pic.h>
#include <stdio.h>
#include <math.h>
//本程序利用CCP1 模块实现一个“简易数字频率计”的功能
const char table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,
0xFF};
//不带小数点的显示段码表
const char table0[11]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,
0X10,0xFF};
//带小数点的显示段码表
bank3 int cp1z[11]; //定义一个数组,用于存放各次的捕捉值
union cp1
{int y1;
unsigned char cp1e[2];
}cp1u; //定义一个共用体
unsigned char COUNTW,COUNT; //测量脉冲个数寄存器
unsigned char COUNTER,data,k;
unsigned char FLAG @ 0XEF;
#define FLAGIT(adr,bit) ((unsigned)(&adr)*8+(bit)) //绝对寻址位操作指令
static bit FLAG1 @ FLAGIT(FLAG,0);
static bit FLAG2 @ FLAGIT(FLAG,1);
static bit FLAG3 @ FLAGIT(FLAG,2);
unsigned char s[4]; //定义一个显示缓冲数组
int T5 ,uo;
double RE5;
double puad5;
//spi 方式显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置SPI 的控制方式,允许SSP 方式,并且时钟下降沿发送,与"74HC595,当其
//SCLk 从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7; //SDO引脚为输出,SCK 引脚为输出
TRISA5=0; //RA5引脚设置为输出,以输出显示锁存信号
FLAG1=0 ;
FLAG2=0 ;
FLAG3=0 ;
COUNTER=0X01;
}
//CCP 模块工作于捕捉方式初始化子程序
void ccpint( )
{
CCP1CON=0X05; //首先设置CCP1 捕捉每个脉冲的上升沿
T1CON=0X00; //关闭TMR1 震荡器
单片机学习指南 资料提供:上海齐济电子有限公司
.34.
PEIE=1; //外围中断允许(此时总中断关闭)
CCP1IE=1; //允许CCP1 中断
TRISC2=1; //设置RC2 为输入
}
//系统其它部分初始化子程序
void initial( )
{
COUNT=0X0B; //为保证测试精度,测试5 个脉冲的参数后
//求平均值,每个脉冲都要捕捉其上升、下降沿,
//故需要有11 次中断
TRISB1=0;
TRISB2=0;
TRISB4=1;
TRISB5=1; //设置与键盘有关的各口的输入、输出方式
RB1=0;
RB2=0; //建立键盘扫描的初始条件
}
//SPI 传送数据子程序
void SPILED(data)
{
SSPBUF=data; //启动发送
do {

}while(SSPIF==0);
SSPIF=0;
}
//显示子程序,显示4 位数
void display( )
{
RA5=0; //准备锁存
for(COUNTW=0;COUNTW<4;COUNTW++){
data=s[COUNTW];
data=data&0x0F;
if(COUNTW==k) data=table0[data];//第二位需要显示小数点
else data=table[data];
SPILED(data); //发送显示段码
}
for(COUNTW=0;COUNTW<4;COUNTW++){
data=0xFF;
SPILED(data); //连续发送4 个DARK,使显示好看一些
}
RA5=1; //最后给一个锁存信号,代表显示任务完成
}
//键盘扫描子程序
void keyscan( )
{
if((RB4==0)||(RB5==0)) FLAG1=1 ;//若有键按下,则建立标志FLAG1
else FLAG1=0 ; //若无键按下,则清除标志FLAG1
}
//键服务子程序
void keyserve( )
{
PORTB=0XFD ;
单片机学习指南 资料提供:上海齐济电子有限公司
.35.
if(RB5==0) data=0X01;
if(RB4==0) data=0X03;
PORTB=0XFB;
if(RB5==0) data=0X02;
if(RB4==0) data=0X04; //以上确定是哪个键按下
PORTB=0X00; //恢复PORTB 的值
if(data==0x01) {
COUNTER=COUNTER+1; //若按下S9 键,则COUNTER 加1
if(COUNTER>4) COUNTER=0x01;//若COUNTER 超过4,则又从1 计起
}
if(data==0x02) {
COUNTER=COUNTER-1; //若按下S11 键,则COUNTER 减1
if(COUNTER<1) COUNTER=0x04;//若COUNTER 小于1,则又循环从4 计起
}
if(data==0x03) FLAG2=1 ; //若按下S10 键,则建立标志FLAG2
if(data==0x04) FLAG2=0 ; //若按下S12 键,则清除标志FLAG2
}
//中断服务程序
void interrupt cp1int(void)
{
CCP1IF=0; //清除中断标志
cp1u.cp1e[0]=CCPR1L;
cp1u.cp1e[1]=CCPR1H;
cp1z[data]=cp1u.y1; //存储1 次捕捉值
CCP1CON=CCP1CON^0X01; //把CCP1 模块改变成捕捉相反的脉冲沿
data++;
COUNT--;
}
//周期处理子程序
void PERIOD( )
{
T5=cp1z[10]-cp1z[0]; //求得5 个周期的值
RE5=(double)T5; //强制转换成双精度数
RE5=RE5/5; //求得平均周期,单位为μs
}
//频率处理子程序
void FREQUENCY( )
{
PERIOD( ); //先求周期
RE5=1000000/RE5; //周期值求倒数,再乘以1 000 000,得频率,
//单位为HZ
}
//脉宽处理子程序
void PULSE( )
{
int pu;
for(data=0,puad5=0;data<=9;data++) {
pu=cp1z[data+1]-cp1z[data];
puad5=(double)pu+puad5;
data=data+2;
} //求得5 个脉宽的和值
RE5=puad5/5; //求得平均脉宽
}
单片机学习指南 资料提供:上海齐济电子有限公司
.36.
//占空比处理子程序
void OCCUPATIONAL( )
{
PULSE( ); //先求脉宽
puad5=RE5; //暂存脉宽值
PERIOD(); //再求周期
RE5=puad5/RE5; //求得占空比
}
//主程序
main( )
{
SPIINIT( ); //SPI方式显示初始化
while(1) {
ccpint(); //CCP模块工作于捕捉方式初始化
initial(); //系统其它部分初始化
if(FLAG2==0) {
s[0]=COUNTER; //第一个存储COUNTER 的值
s[1]=0X0A;
s[2]=0X0A;
s[3]=0X0A; //后面的LED 将显示"DARK"
}
display( ); //调用显示子程序
keyscan(); //键盘扫描
data=0x00; //存储数组指针赋初值
TMR1H=0;
TMR1L=0; //定时器1 清0
CCP1IF=0; //清除CCP1 的中断标志,以免中断一打开就进入
//中断
ei( ); //中断允许
TMR1ON=1; //定时器1 开
while(1){
if(COUNT==0)break;
} //等待中断次数结束
di(); //禁止中断
TMR1ON=0; //关闭定时器
keyscan(); //键盘扫描
if(FLAG1==1) keyserve() ; //若确实有键按下,则调用键服务程序
if(FLAG2==0) continue; //如果没有按下确定键,则终止此次循环,
//继续进行测量
//如果按下了确定键,则进行下面的数值转换和显示工作
if(COUNTER==0x01) FREQUENCY(); //COUNTER=1,则需要进行频率处理
if(COUNTER==0x02) PERIOD(); //COUNTER=2,则需要进行周期处理
if(COUNTER==0x03) OCCUPATIONAL();//COUNTER=3,则需要进行占空比处理
if(COUNTER==0x04) PULSE(); //COUNTER=4,则需要进行脉宽处理
k=5;
if(RE5<1){
RE5=RE5*1000; //若RE5<1,则乘以1 000,保证小数点的精度
k=0x00;
}
else if(RE5<10){
RE5=RE5*1000; //若RE5<10,则乘以1 000,保证小数点的精度
单片机学习指南 资料提供:上海齐济电子有限公司
.37.
k=0x00;
}
else if(RE5<100){
RE5=RE5*100; //若RE5<100,则乘以100,保证小数点的精度
k=0x01;
}
else if(RE5<1000){
RE5=RE5*10; //若RE5<1000,则乘以10,保证小数点的精度
k=0x02;
}
else RE5=RE5 ;
uo=(int)RE5;
sprintf(s,"%4d",uo); //把需要显示的数据转换成4 位ASII 码,且放入数
//组S 中
display();
}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.38.
第7 章 交流电压测量
7.1.1 程序清单
该程序已在模板上调试通过,可作读者的参考。有关显示部分请读者参考本书相关章节,
有关A/D 转换的详细设置请参考前面章节。
#include <pic.h>
#include <math.h>
#include <stdio.h>
//该程序用于测电网的交流电压有效值,最后的结果将在4 个LED 上显示,保留
//1 位小数。
//为了保证调试时数据运算的精确性,需要将PICC 的double 型数据选成32 位
union adres
{
int y1;
unsigned char adre[2];
}adresult; //定义一个共用体
bank3 int re[40]; //定义存放A/D 转换结果的数组,在bank3 中
unsigned char k,data; //定义几个通用寄存器
double squ ,squad; //平方寄存器和平方和寄存器,squ 又通用为存储其
//它数值
int uo;
bank1 unsigned char s[4]; //此数组用于存储需要显示的字符的ASII 码
const char table[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,
0x90};
//不带小数点的显示段码表
const char table0[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,
0x10};//带小数点的显示段码表
//A/D 转换初始化子程序
void adinitial()
{
ADCON0=0x41; //选择A/D 通道为RA0,且打开A/D 转换器
//在工作状态,使A/D 转换时钟为8Tosc
ADCON1=0X8E; //转换结果右移,及ADRESH 寄存器的高6 位为"0"
//把RA0 口设置为模拟量输入方式
ADIE=1; //A/D转换中断允许
PEIE=1; //外围中断允许
TRISA0=1; //设置RA0 为输入方式
}
//spi 方式显示初始化子程序
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
//设置SPI 的控制方式,允许SSP 方式,并且时钟下降沿发送,与"74HC595,当其
//SCLK 从低到高跳变时,串行输入寄存器"的特点相对应
TRISC=0xD7; //SDO 引脚为输出,SCK 引脚为输出
TRISA5=0; //RA5引脚设置为输出,以输出显示锁存信号
}
//系统其它初始化子程序
单片机学习指南 资料提供:上海齐济电子有限公司
.39.
void initial()
{
CCP2IE=0; //禁止CCP 中断
SSPIE=0; //禁止SSP 中断
CCP2CON=0X0B; //初始化CCP2CON,CCP2 为特别事件触发方式
CCPR2H=0X01;
CCPR2L=0XF4; //初始化CCPR2 寄存器,设置采样间隔500 μs,
//一个周期内电压采40 个点
}
//中断服务程序
void interrupt adint(void)
{
CCP2IF=0;
ADIF=0; //清除中断标志
adresult.adre[0]=ADRESL;
adresult.adre[1]=ADRESH; //读取并存储A/D 转换结果,A/D 转换的结果
//通过共用体的形式放入了变量y1 中
re[k]=adresult.y1; //1 次A/D 转换的结果存入数组
k++; //数组访问指针加1
}
//SPI 传送数据子程序
void SPILED(data)
{
SSPBUF=data; //启动发送
do{

}while(SSPIF==0);
SSPIF=0;
}
//主程序
main( )
{
adinitial(); //A/D转换初始化
SPIINIT(); //spi方式显示初始化
initial(); //系统其它初始化
while(1){
k=0; //数组访问指针赋初值
TMR1H=0X00 ;
TMR1L=0X00; //定时器1 清0
ei(); //中断允许
T1CON=0X01; //打开定时器1
while(1){
if(k==40) break; //A/D 转换次数达到40,则终止
}
di(); //禁止中断
for(k=0;k<40;k++)re[k]=re[k]-0X199;//假设提升电压为2 V,对应十六进制数199H,
//则需在采样值的基础上减去该值
for(k=0,squad=0;k<40;k++) {
uo=re[k];
squ=(double)uo; //强制把采得的数据量转换成双精度数,以便运算
squ=squ*5/1023; //把每点的数据转换成实际数据
squ=squ*squ; //求一点电压的平方
单片机学习指南 资料提供:上海齐济电子有限公司
.40.
squad=squad+squ;
} //以上求得40 点电压的平方和,存于寄存器 squad 中
squ=squad/40; //求得平均值
squ=sqrt(squ); //开平方,求得最后的电压值
squ=squ*154.054; //通过变压器的变比和分压电阻分配确定该系数
//以上得到了实际电网的电压值
squ=squ*10; //为了保证显示的小数点的精度,先对电压值乘以10
uo=(int)squ; //强制把U 转换成有符号整型量
sprintf(s,"%4d",uo); //通过sprintf 函数把需要显示的电压数据转换成
//ASII码,并存于数组S 中
RA5=0; //准备锁存
for(k=0;k<4;k++){
data=s[k];
data=data&0X0F; //通过按位相与的形式把ASII 码转换成BCD 码
if(k==2) data=table0[data];//因为squ 已乘以10,则需在第2 位打小数点
else data=table[data]; // table0 存储带小数点的显示段码,
//table 存储不带小数点的显示段码
SPILED(data); //发送显示段码
}
for(k=0;k<4;k++) {
data=0xFF;
SPILED(data); //连续发送4 个DARK,使显示看起来好看一些,这点与
//该实验板的LED 分布结构有关
}
RA5=1; //最后给一个锁存信号,代表显示任务完成
}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.41.
第8 章 与PLC 接口的4 位LED 数字显示表
8.1 数显表头软件设计思路
8. 2 程序清单
#include <pic16F87x.h>
#include "mydefine.h"
#include <pic.h>
static int flag,flag0,flag1,flag3,led_d;
static int data1[5],data2[5];
static int data,data0,data_1,data_2,sdata;
//=====================子程序=========================
//端口初始化子程序
void initport( )
{
PORTA=0;
PORTB=0;
PORTC=0;
PORTD=0;
ADCON1=0x07;
TRISA=0x03; //设RA0,RA1 为输入
TRISB=0xE8; //设RB0,RB1,RB2,RB4 为输出
TRISC=0xFF; //设C 口为输入
TRISD=0; //设D 口为输出
}
//判断地址是否相同子程序
int adr_jud(int x)
{
int adress,y;
adress=PORTA&0x03;
x&=0x60;
adress=adress<<5;
if (adress==x) y=1;
else y=0;
CLRWDT();
return(y);
}
//显示初始化子程序
void initdis( )
{
PORTB=0xFE; //选通数码管1
PORTD=0xC0;
PORTB=0xFD; //选通数码管2
PORTD=0xC0;
PORTB=0xFB; //选通数码管3
PORTD&=0x7F; //选通小数位
PORTD=0xC0;
PORTB=0xEF; //选通数码管4
PORTD=0xC0;
单片机学习指南 资料提供:上海齐济电子有限公司
.42.
}
//读5 次数据判是否有4 次相等
int judge(arry)
int arry[5];
{
int i,j,k;
for(i=0;i<=4;i++){
k=0;
for(j=0;j<=4;j++)
{ if(arry[i]==arry[j]) k++;
if(k>=4) {
flag1=1;
data0=arry[i];
return(flag1);
}
else flag1=0;
}
}
return(flag1);
}
//数据转换子程序
int convert(int d1,int d2)
{
auto int dd1,dd2;
int i1,j1,k1,i2,j2,m;
dd1=d1;
dd2=d2;
j1=0x10;
k1=2048;
d1=0;
for(i1=1;i1<=5;i1++) {
if(j1==(dd1&j1)) m=1;
else m=0;
d1=d1+m*k1;
j1=j1/2;
k1=k1/2;
}
j2=0x40;
d2=0;
for(i2=1;i2<=7;i2++) {
if(j2==(dd2&j2)) m=1;
else m=0;
d2=d2+m*k1;
j2=j2/2;
k1=k1/2;
}
data=d1+d2;
return(data);
}
//显示子程序
int display(int x)
单片机学习指南 资料提供:上海齐济电子有限公司
.43.
{ int l1,l2,l3,l4;
l1=x/1000;
PORTB=0xFE; //选通数码管1
PORTD=led[l1];
l2=(x-l1*1000)/100;
PORTB=0xFD; //选通数码管2
PORTD=led[l2];
l3=(x-l1*1000-l2*100)/10;
PORTB=0xFB; //选通数码管3
PORTD=0x7F;
PORTD=led[l3];
l4=x-l1*1000-l2*100-l3*10;
PORTB=0xEF; //选通数码管4
PORTD=led[l4];
}
//中断服务子程序
void interrupt int_serve( )
{
PIR1=0;
TMR1L=0xE5;
TMR1H=0xBE;
di( );
sdata=PORTC&0x80;
ei( );
}
//开中断子程序
void int_open( )
{
inportc=PORTC&0x80;
if(inportc==1) return;
else data1[0]=~PORTC;
flag=adr_jud(data1[0]);
if(flag==0) return; //地址不同返回
else data1[1]=~PORTC;
data1[2]=~PORTC;
if(data1[0]==data1[1])
if(data1[0]==data1[2]) {
flag3=1;
PIR1=0; //开通总中断前,清所有中断标志位
TMR1IE=1; //TMR1 溢出中断使能
PEIE=1;
ei( );
TMR1L=0xE5;
TMR1H=0xBE; //20ms 中断1 次
T1CON=0x01; //设TMR1 为1 分频,计数器方式工作
}
else return;
}
//读第1 帧子程序
voidread_1( )
{ int j0;
单片机学习指南 资料提供:上海齐济电子有限公司
.44.
for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;
flag1=judge(data1);
if (flag1==1) {
data_1=data0;
flag0=1;
count1++;
}
flag=adr_jud(data1[0]);
if(flag==1) {
for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;
flag1=judge(data1);
if (flag1==1){
data_1=data0;
flag0=1;
count1++;
}
}
}
// 主程序
main( )
{ int i0,ii,i;
flag0=0; //帧标志位
flag1=0; //读5 次数据判有4 次相等标志位
flag3=1; //开中断标志位
count1=0; //读第1 帧计数单元
count2=0; //读第2 帧计数单元
data_1=0;
data_2=0;
led_d=0;
led[0]=0xc0; //0
led[1]=0xf9;
led[2]=0xa4;
led[3]=0xb0;
led[4]=0x99;
led[5]=0x92;
led[6]=0x82;
led[7]=0xf8;
led[8]=0x80;
led[9]=0x90; //9
initport( );
OPTION=0xFE; //开看门狗
initdis( );
while(1) {
if(flag3==0) int_open();
else{
if(sdata==0x80){ //第二帧数据到
if(flag0==1){
for(i0=0;i0<=4;i0++) data2[i0]=~PORTC;
flag1=judge(data2);
if (flag1==1) {
data_2=data0;
单片机学习指南 资料提供:上海齐济电子有限公司
.45.
flag0=0;
count2++;
}
}
}
else if(sdata==0) { //第一帧数据到
if(flag0==0) {
data1[0]=~PORTC;
flag=adr_jud(data1[0]);
if(flag==1) {
for(j0=1;j0<=4;j0++) data1[j0]=~PORTC;
flag1=judge(data1);
if (flag1==1) {
data_1=data0;
flag0=1;
count1++;
}
}
}
}
CLRWDT();
if(count1==count2) led_d=convert(data_1,data_2 );
}
display(led_d);
}
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.46.
第9章 单片机控制的电动自行车驱动系统
9.1 C 语言程序
#include <pic.h>
//电动车双闭环程序,采用双闭环方式控制电机,以得到最好的zh 转速性能,并且可以
//限制电机的最大电流。本应用程序用到两个CCP 部件,其中CCP1 用于PWM 输出,以控
//制电机电压;CCP2 用于触发AD,定时器TMR2、TMR1,INT 中断,RB 口电平变化中断,
//看门狗以及6 个通用I/O 口
#define AND 0xe0 //状态采集5,6,7 位
#define CURA 0X0a //电流环比例和积分系数之和
#define CURB 0X09 //电流环比例系数
#define THL 0X6400 //电流环最大输出
#define FULLDUTY 0X0FF //占空比为1 时的高电平时间
#define SPEA 0X1d //转速环比例和积分系数之和
#define SPEB 0X1c //转速环比例系数
#define GCURHILO 0X0330 //转速环最大输出
#define GCURH 0X33 //最大给定电流
#define GSPEH 0X67 //最大转速给定
#define TSON 0X38 //手柄开启电压1.1 V,TSON*2 为刹车后手柄开启电压,即
//2.2 V
#define VOLON 0X4c //低电压保护重开电压3.0 V 即33 V
#define VOLOFF 0X49 //低电压保护关断电压2.86 V 即31.5 V
volatile unsigned char DELAYH,DELAYL,oldstate,speed,
speedcount,tsh,count_ts,count_vol,gcur,currenth,
voltage; //寄存器定义
static bit sp1,spe,ts,volflag,spepid,lowpower,
off,shutdown,curpid; //标志位定义
static volatile unsigned char new[10]={0xaf,0xbe,0xff,0x7e,0xcf,
0xff,0xd7,0x77,0xff,0xff}; //状态寄存器表
//------------PIC16F877 初始化子程序------------
void INIT877()
{
PORTC=0X0FF; //关断所有MOSFET
TRISC=0X02; //设置C 口输出
PIE1=0X00; //中断寄存器初始化,关断所有中断
TRISA=0XCF; //设置RA4,RA5 输出
TRISB=0XEF; //RB 口高三位输入,采集电机三相的霍尔信号
PORTC=new[(PORTB&AND)>>5]; //采集第一次霍尔信号,并输出相应的信号,导通
//两个MOS 管
T2CON=0X01; //TMR2 4 分频
CCPR1L=0X0FF; //初始时PWM 输出全高
CCP1CON=0X0FF; //CCP1 设置为PWM 方式
CCP2CON=0X0B; //CCP2 设置为特殊方式,以触发AD
ADCON0=0X81; //AD 时钟为32 分频,且AD 使能,选择AN0 通道采集手
//柄电压
TMR2=0X00; //TMR2 寄存器初始化
TMR1H=0X00; //TMR1 寄存器初始化
TMR1L=0X00;
T1CON=0X00; //TMR1 为1 分频
单片机学习指南 资料提供:上海齐济电子有限公司
.47.
CCPR2H=0X08;
CCPR2L=0X00; //电流采样周期设置为TAD=512 μs
PR2=0XC7; //PWM 频率设置为5 kHz
ADCON1=0X02; //AD 结果左移
OPTION=0XFB; //INT 上升沿触发
TMR2ON=1; //PWM 开始工作
INTCON=0XD8; //中断设置GIE=1,PEIE=1,RBIE=1
ADIE=1; //AD中断使能
speedcount=0x00; //转速计数寄存器
speed=0x7f; //转速保持寄存器
spe=1; //低速标志位
sp1=1; //低速标志位
oldstate=0x0ff; //初始状态设置,区别于其他状态
count_ts=0x08; //电流采样8 次,采集1 次手柄
count_vol=0x00; //采样256 次手柄,采集1 次电池电压
ts=1; //可以采集手柄值的标志位
ADGO=1; //AD采样使能
TMR1ON=1; //CCP2 部件开始工作
}
//------------延时子程序---------------
#pragma interrupt_level 1
void DELAY1(x)
char x;
{
DELAYH=x; //延时参数设置
#asm
DELAY2 MOVLW 0X06
MOVWF _DELAYL
DELAY1 DECFSZ _DELAYL
GOTO DELAY1
DECFSZ _DELAYH
GOTO DELAY2
#endasm
}
//-----------状态采集子程序----------------------
void sample()
{
char state1,state2,state3,x;
do {
x=1;
state1=(PORTB&AND); //霍尔信号采集
DELAY1(x);
state2=(PORTB&AND);
}while(state1-state2); //当三次采样结果不相同时继续采集状态
if(state1-oldstate!=0) //看本次采样结果是否与上次相同,不同
//则执行
{oldstate=state1; //将本次状态设置为旧状态
state1=(oldstate>>5);
PORTC=new[state1]; //C 口输出相应的信号触发两个MOS 管
if(sp1==1){spe=1;sp1=0;}
else { //如果转速很低,则spe 置1
单片机学习指南 资料提供:上海齐济电子有限公司
.48.
spe=0;sp1=0;
speedcount<<=1;
state3=(TMR1H>>2); //否则,spe=0,计转速
speed=speedcount+state3; //speed 寄存器为每256 μs 加1
}
speedcount=0;
}
}
//-----------------AD 采样子程序----------------------
void AD()
{
char x;
ADIF=0; //清AD 中断标志位
if(ts==1){ //如果为手柄采样,则采样手柄值
CHS0=1; //选择电流采样通道
count_vol=count_vol+1; //电池采样计数寄存器
spepid=1; //置转速闭环运算标志
ts=0;tsh=ADRESH; //存手柄值
if(count_vol==0) { //如果电池采样时间到,则选择AN2 通道,采集电池电压
CHS0=0;CHS1=1;volflag=1;x=1;DELAY1(x);ADGO=1;
}
}
else if(volflag==1) { //电池采样完毕,进行相应的处理
CHS1=0;CHS0=1;volflag=0;voltage=ADRESH;lowpower=1;
}
else { //否则,中断为采样电流中断
speedcount=speedcount+1; //speedcount 寄存器加1,作为测量转速用
if(speedcount>0x3d) sp1=1; //如果转速低于1 000 000 μs/(512 μs*3eh*3)
// 则认为为低速状态
currenth=ADRESH;
curpid=1;
count_ts=count_ts-1;
if(count_ts==0) { //如果手柄时间到,则转入手柄采样通道
CHS0=0;count_ts=0x08;ts=1;x=1;DELAY1(x);ADGO=1;
}
}
}
//-------------刹车处理子程序------------------
void BREAKON()
{
char x;
off=0; //off清零,如果是干扰则不复位
shutdown=0;
if(RB0==1) { //如果刹车信号为真,则停止输出电压
ADIE=0; //关AD 中断
INTE=0; //关刹车中断
CCPR1L=FULLDUTY; //输出电压0
TMR1ON=0; //关CCP2,不再触发AD
for(;ADGO==1;) continue;//如正在采样,则等待采样结束
ADIF=0; //ADIF 位清零
CHS0=0; //选择通道0 采样手柄
单片机学习指南 资料提供:上海齐济电子有限公司
.49.
CHS1=0;
x=1;
DELAY1(x);
do {
ADGO=1;
for(;ADIF==0;)continue;
ADIF=0;
CCPR1L=FULLDUTY;
asm("CLRWDT");
tsh=(ADRESH>>1);
}while(tsh>TSON||RB0==1); //当手柄值大于2.2 V 或刹车仍旧继续时,执行以
//上语句
off=1; //置复位标志
}
}
//---------欠保护子程序-------------------
void POWER()
{
char x;
lowpower=0;
voltage>>=1; //电压值换为7 位,以利于单字节运算
if(voltage<VOLOFF) { //电池电压小于3*k(V)时保护
ADIE=0;
INTE=0;
TMR1ON=0;
CCPR1L=FULLDUTY;
for(;ADGO==1;)continue;
ADIF=0;
CHS0=0;CHS1=1;
x=1;
DELAY1(x);
do{ADGO=1;
for(;ADIF==0;)continue;
ADIF=0;
voltage=(ADRESH>>1);
CCPR1L=FULLDUTY;
asm("CLRWDT");
}while(voltage<VOLON); //电池电压小于35 V 时继续保护
off=1; //置复位标志
}
}
//------------电流环运算子程序-----------------
void CURPI()
{ static int curep=0x00,curek=0x00,curuk=0x00;
union data{int pwm;
char a[2];}b; //定义电流环运算寄存器
curpid=0; //清电流运算标志
curep=curek*CURB; //计算上一次偏差与比例系数的积
if(currenth<2)currenth=2; //如果采样电流为零,则认为有一个小电流以利于
//使转速下降
currenth>>=1;
单片机学习指南 资料提供:上海齐济电子有限公司
.50.
curek=gcur-currenth; //计算本次偏差
curuk=curuk+curek*CURA-curep; //按闭环PI 运算方式得到本次输出结果,下
//面对结果进行处理
if(curuk<0x00) { //如果输出小于零,则认为输出为零
curuk=0;CCPR1L=FULLDUTY;CCP1X=0;CCP1Y=0;
}
else if(curuk-THL>=0) { //如果输出大于限幅值,则输出最大电压
curuk=THL;CCPR1L=0;CCP1X=0;CCP1Y=0;
}
else { //否则,按比例输出相应的高电平时间到CCPR1 寄存器
b.pwm=THL-curuk;
b.pwm<<=1;
CCPR1L=b.a[1]; //CCPR1L=(b.pwm>>8)&0x0ff;将PWM 寄存器的高半字节
if(b.pwm&0x80!=0) CCP1X=1;
else CCP1X=0;
if(b.pwm&0x40!=0) CCP1Y=1;
else CCP1Y=0;
}
}
//---------------转速环运算子程序-----------------------
void SPEPI()
{ static int speep=0x00,speek=0x00,speuk=0x00;
int tsh1,speed1; //转速寄存器定义
spepid=0; //清转速运算标志
if(spe==1) speed1=0x00; //若转速太低,则认为转速为零
else speed1=0x7f-speed; //否则计算实际转速
if(speed1<0) speed1=0;
speep=speek*SPEB;
tsh1=tsh-0x38; //得到计算用的手柄值
speek=tsh1-speed1;
if(tsh1<0) {speuk=0;gcur=0;} //当手柄值低于1.1 V 时,则认为手柄给定为零
else { //否则,计算相应的转速环输出
if(tsh1>=GSPEH) //限制最大转速
tsh1=GSPEH;
speuk=speuk+speek*SPEA-speep; //计算得转速环输出
if(speuk<=0X00) {speuk=0x00;gcur=0x00;}//转速环输出处理
else if(speuk>GCURHILO) { //转速环输出限制,即限制最大电流约12 A
speuk=GCURHILO;gcur=GCURH;}
else { //调速状态时的输出
gcur=(speuk>>4)&0x0ff;
}
}
}
//-----------主程序-------------------------
main()
{
for(;;){
INIT877(); //单片机复位后,先对其进行初始化
off=0; //清复位标志
for(;off==0;) { //复位标志为零,则执行下面程序,否则复位
if(curpid==1) CURPI(); //电流PI 运算
单片机学习指南 资料提供:上海齐济电子有限公司
.51.
else if(spepid==1) SPEPI(); //转速PI 运算
else if(lowpower==1) POWER();
else if(shutdown==1) BREAKON();
asm("CLRWDT");
}
}
}
//---------中断服务子程序---------------------
#pragma interrupt_level 1
void interrupt INTS(void)
{
if(RBIF==1) {RBIF=0;sample();}
else if(ADIF==1) AD();
else if(INTF==1) {shutdown=1;INTF=0;} //刹车中断来,置刹车标志
}
NOTE:
单片机学习指南 资料提供:上海齐济电子有限公司
.52.
第10章 液晶显示模块编程
10.1 MG-12232 模块的编程
下面以图7.1 的接口电路为例。液晶显示区域分成E1 边和E2 边,下面只含E1 边的程
序(表7.1 中E1=1,E2=0),E2 边(表7.1 中E1=0,E2=1)类推。
在系统程序的初始化部分,应对程序中用到的寄存器和临时变量作说明,如:
unsigned char TRANS;
unsigned char PAGEADD; //存放页地址寄存器
unsigned char PAGENUM; //存放总页数寄存器
unsigned char CLMSUM; //存放总列数寄存器
unsigned char CLMADD; //存放列地址寄存器
unsigned char WRITE; //存放显示数据寄存器
unsigned char row; //存放显示起始行寄存器
unsigned char i,k; //通用寄存器
//系统各口的输入输出状态初始化子程序
void INITIAL()
{
ADCON1=0X87; //设置PORTA 口和PORTE 口为数字I/O 口
TRISA3=0;
TRISB0=0;
TRISE=0X00; //设置液晶的4 个控制脚为输出
}
//读液晶显示器状态子程序
void LCDSTA1()
{
while(1) {
TRISD=0XFF; //设置D 口为输入
RB0=1; //E1=1
RA3=0; //E2=0
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD7==0) break; //为忙状态,则继续等待其为空闲
}
}
//对液晶显示器发指令子程序(指令保存在TRANS 寄存器中)
void TRANS1()
{
LCDSTA1(); //判断液晶是否为忙
TRISD=0X00; //置D 口为输出
RB0=1; //E1=1
RA3=0; //E2=0
RE0=0; //R/W=0
RE1=0; //A0=0
PORTD=TRANS; //需要写入的命令字送入数据线
RB0=0; //E1=0写入指令
RE0=1; //R/W=1
}
//对液晶显示器写数据子程序(数据保存在WRITE 寄存器中)
void WRITE1()
{
TRANS=CLMADD; //设置列地址
单片机学习指南 资料提供:上海齐济电子有限公司
.53.
TRANS1();
LCDSTA1(); //查询液晶是否为空闲
TRISD=0X00; //D口为输出
RB0=1;//E1=1
RA3=0;//E2=0
RE0=0;//R/W=0
RE1=1;//A0=1
PORTD=WRITE; //需要写入的数据放入D 口
RB0=0; //E1=0,写入数据
CLMADD++; //列地址加1
RE0=1; //R/W=1
}
//开E1 显示子程序
void DISP1()
{
while(1)
{
TRANS=0XAF;
TRANS1(); //送出控制命令
LCDSTA1(); //判断液晶是否为空闲
TRISD=0XFF; //设置D 口为输入
RB0=1; //E1=1
RA3=0; //E2=0
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD5==0) break; //如果液晶没被关闭,则继续关
}
}
//E1 边清屏子程序
void CLEAR1()
{
PAGEADD=0xB8; //设置页地址代码
for(PAGENUM=0X04;PAGENUM>0;PAGENUM--){
TRANS=PAGEADD;
TRANS1();
CLMADD=0x00; //设置起始列
for(CLMSUM=0X50;CLMSUM>0;CLMSUM--){
LCDSTA1(); //判断液晶是否为空闲
WRITE=0X00;
WRITE1(); //写入00H 以清屏
}
PAGEADD++; //页号增1
}
}
//关 E1 显示子程序
void DISOFF1()
{
while(1)
{
TRANS=0XAE;
TRANS1(); //发出控制命令
LCDSTA1(); //判断液晶是否为空闲
TRISD=0XFF; //D口设置为输入
单片机学习指南 资料提供:上海齐济电子有限公司
.54.
RB0=1; //E1=1
RA3=0; //E2=0
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD5==1) break; //如果液晶没被关闭,则继续关
}
}
有了以上的通用子程序,就可以构造出各种显示程序,如字符、汉字、曲线等。执行
这些程序前,必须对液晶进行初始化。初始化的顺序为:关显示→正常显示驱动设置→占空
比设置→复位→ADC 选择→清屏→开显示,程序如下:
//E1 边初始化
void lcd1()
{
DISOFF1(); //关显示E1
TRANS=0XA4; //静态显示驱动
TRANS1(); //发出控制命令
TRANS=0XA9; //占空比为1/32
TRANS1(); //发出控制命令
TRANS=0XE2; //复位
TRANS1(); //发出控制命令
TRANS=0XA0; //ADC 选择正常输出
TRANS1(); //发出控制命令
CLEAR1(); //清屏
LCDSTA1(); //判断液晶是否为空闲
DISP1(); //开显示
}
10.2 程序清单
下面给出一个已经在模板上调试通过的程序。 注意在调试该程序时,需把模板上的
J9 跳针短接。
#include <pic.h>
//该程序用于液晶显示功能的演示
//运行程序后,液晶上显示"电流有效值 "和"电压有效值 "字样
//系统总的初始化子程序
unsigned char TRANS;
unsigned char PAGEADD; //存放页地址寄存器
unsigned char PAGENUM;//存放总页数寄存器
unsigned char CLMSUM; //存放总列数寄存器
unsigned char CLMADD; //存放列地址寄存器
unsigned char WRITE; //存放显示数据寄存器
unsigned char row; //存放显示起始行寄存器
unsigned char i,k; //通用寄存器
const char table[192]={0X00,0XF8,0X48,0X48,0X48,0X48,0XFF,0X48,
0X48,0X48,0X48,0XFC,0X08,0X00,0X00,0X00,
0X00,0X07,0X02,0X02,0X02,0X02,0X3F,0X42,
0X42,0X42,0X42,0X47,0X40,0X70,0X00,0X00,//"电"
0X00,0X00,0XFE,0X02,0X82,0X82,0X82,0X82,
0XFE,0X82,0X82,0X82,0XC3,0X82,0X00,0X00,
0X40,0X30,0X0F,0X40,0X40,0X40,0X40,0X40,
0X7F,0X40,0X42,0X44,0X4C,0X60,0X40,0X00,//"压"
单片机学习指南 资料提供:上海齐济电子有限公司
.55.
0X04,0X04,0X04,0X84,0XE4,0X3C,0X27,0X24,
0X24,0X24,0X24,0XF4,0X24,0X06,0X04 ,0X00,
0X4 ,0X2 ,0X1 ,0X0 ,0XFF,0X9,0X9 ,0X9,
0X9 ,0X49,0X89,0X7F,0X0,0X0,0X0 ,0X0, //"有"
0X88,0X48,0XB8,0X9,0XA,0X98,0X2C ,0X48,
0X20,0XD0,0X1F,0X10,0X10,0XF8,0X10 ,0X0,
0X40,0X20,0X18,0X5,0X2,0XD,0X30 ,0X80,
0X80,0X41,0X36,0X8,0X37,0XC0,0X40 ,0X0, //"效"
0X80,0X40,0X20,0XF8,0X7,0X4,0XE4,0XA4,
0XA4,0XBF,0XA4,0XA4,0XF6,0X24,0X0 ,0X0,
0X0,0X0,0X0,0XFF,0X40,0X40,0X7F,0X4A,
0X4A,0X4A,0X4A,0X4A,0X7F,0X40,0X40 ,0X0,//"值"
0X10,0X22,0X64,0XC,0X80,0X44,0X44,0X64,
0X55,0X4E,0X44,0X54,0X66,0XC4,0X0,0X0,
0X4,0X4,0XFE,0X1,0X0,0X80,0X40,0X3F,
0X0,0XFF,0X0,0X3F,0X40,0X40,0X70,0X0 //"流"
};
//系统各口的输入输出状态初始化子程序
void INITIAL()
{
ADCON1=0X87; //设置PORTA 口和PORTE 口为数字I/O 口
TRISA3=0;
TRISB0=0;
TRISE=0X00; //设置液晶的4 个控制脚为输出
}
//读液晶显示器状态子程序
void LCDSTA1()
{
while(1){
TRISD=0XFF; //设置D 口为输入
RB0=1; //E1=1
RA3=0; //E2=0
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD7==0) break; //为忙状态,则继续等待其为空闲
}
}
//对液晶显示器发指令子程序(指令保存在TRANS 寄存器中)
void TRANS1()
{
LCDSTA1(); //判断液晶是否为忙
TRISD=0X00; //D 口为输出
RB0=1; //E1=1
RA3=0; //E2=0
RE0=0; //R/W=0
RE1=0; //A0=0
PORTD=TRANS; //需要写入的命令字送入数据线
RB0=0; //E1=0写入指令
RE0=1; //R/W=1
}
//对液晶显示器写数据子程序(数据保存在WRITE 寄存器中)
void WRITE1()
单片机学习指南 资料提供:上海齐济电子有限公司
.56.
{
TRANS=CLMADD; //设置列地址
TRANS1();
LCDSTA1(); //查询液晶是否为空闲
TRISD=0X00; //D 口为输出
RB0=1; //E1=1
RA3=0; //E2=0
RE0=0; //R/W=0
RE1=1; //A0=1
PORTD=WRITE; //需要写入的数据放入D 口
RB0=0; //E1=0,写入数据
CLMADD++; //列地址加1
RE0=1; //R/W=1
}
//开E1 显示子程序
void DISP1()
{
while(1) {
TRANS=0XAF;
TRANS1(); //送出控制命令
LCDSTA1(); //判断液晶是否为空闲
TRISD=0XFF; //设置D 口为输入
RB0=1; //E1=1
RA3=0; //E2=0
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD5==0) break; //如果液晶没被关闭,则继续关
}
}
//E1 边清屏子程序
void CLEAR1()
{
PAGEADD=0xB8; //设置页地址代码
for(PAGENUM=0X04;PAGENUM>0;PAGENUM--){
TRANS=PAGEADD;
TRANS1();
CLMADD=0x00; //设置起始列
for(CLMSUM=0X50;CLMSUM>0;CLMSUM--) {
LCDSTA1(); //判断液晶是否为空闲
WRITE=0X00;
WRITE1(); //写入00H 以清屏
}
PAGEADD++; //页号增1
}
}
//关 E1 显示子程序
void DISOFF1()
{
while(1) {
TRANS=0XAE;
TRANS1(); //发出控制命令
LCDSTA1(); //判断液晶是否为空闲
单片机学习指南 资料提供:上海齐济电子有限公司
.57.
TRISD=0XFF; //D 口设置为输入
RB0=1; //E1=1
RA3=0; //E2=0
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD5==1) break; //如果液晶没被关闭,则继续关
}
}
//E1 边初始化
void lcd1()
{
DISOFF1(); //关显示E1
TRANS=0XA4; //静态显示驱动
TRANS1(); //发出控制命令
TRANS=0XA9; //占空比为1/32
TRANS1(); //发出控制命令
TRANS=0XE2; //复位
TRANS1(); //发出控制命令
TRANS=0XA0; //ADC 选择正常输出
TRANS1(); //发出控制命令
CLEAR1(); //清屏
LCDSTA1(); //判断液晶是否为空闲
DISP1(); //开显示
}
//E2 边的处理部分
//读液晶显示器状态子程序
void LCDSTA2()
{
while(1) {
TRISD=0XFF; //设置D 口为输入
RB0=0; //E1=0
RA3=1; //E2=1
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD7==0) break; //为忙状态,则继续等待其为空闲
}
}
//对液晶显示器发指令子程序指令保存在TRANS 寄存器中
void TRANS2()
{
LCDSTA2(); //判断液晶是否为忙
TRISD=0X00; //D 口为输出
RB0=0; //E1=0
RA3=1; //E2=1
RE0=0; //R/W=0
RE1=0; //A0=0
PORTD=TRANS; //需要写入的命令字送入数据线
RA3=0; //E2=0写入指令
RE0=1; //R/W=1
}
//对液晶显示器写数据子程序(数据保存在WRITE 寄存器中)
void WRITE2()
单片机学习指南 资料提供:上海齐济电子有限公司
.58.
{
TRANS=CLMADD; //设置列地址
TRANS2();
LCDSTA2(); //查询液晶是否为空闲
TRISD=0X00; //D 口为输出
RB0=0; //E1=0
RA3=1; //E2=1
RE0=0; //R/W=0
RE1=1; //A0=1
PORTD=WRITE; //需要写入的数据放入D 口
RA3=0; //E2=0,写入数据
CLMADD++; //列地址加1
RE0=1; //R/W=1
}
//开E2 显示子程序
void DISP2()
{
while(1) {
TRANS=0XAF;
TRANS2(); //送出控制命令
LCDSTA2(); //判断液晶是否为空闲
TRISD=0XFF; //设置D 口为输入
RB0=0; //E1=0
RA3=1; //E2=1
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD5==0) break; //如果液晶没被关闭,则继续关
}
}
//E2 边清屏子程序
void CLEAR2()
{
PAGEADD=0xB8; //设置页地址代码
for(PAGENUM=0X04;PAGENUM>0;PAGENUM--) {
TRANS=PAGEADD;
TRANS2();
CLMADD=0x00; //设置起始列
for(CLMSUM=0X50;CLMSUM>0;CLMSUM--) {
LCDSTA2(); //判断液晶是否为空闲
WRITE=0X00;
WRITE2(); //写入00H 以清屏
}
PAGEADD++; //页号增1
}
}
//关 E2 显示子程序
void DISOFF2()
{
while(1) {
TRANS=0XAE;
TRANS2(); //发出控制命令
LCDSTA2(); //判断液晶是否为空闲
单片机学习指南 资料提供:上海齐济电子有限公司
.59.
TRISD=0XFF; //D 口设置为输入
RB0=0; //E1=0
RA3=1; //E2=1
RE0=1; //R/W=1
RE1=0; //A0=0
if(RD5==1) break; //如果液晶没被关闭,则继续关
}
}
//E2 边初始化
void lcd2()
{
DISOFF2(); //关显示E1
TRANS=0XA4; //静态显示驱动
TRANS2(); //发出控制命令
TRANS=0XA9; //占空比为1/32
TRANS2(); //发出控制命令
TRANS=0XE2; //复位
TRANS2(); //发出控制命令
TRANS=0XA0; //ADC 选择正常输出
TRANS2(); //发出控制命令
CLEAR2(); //清屏
LCDSTA2(); //判断液晶是否为空闲
DISP2(); //开显示
}
//LCD 的E1 边显示函数,调用一次该函数,则在相应的位置显示相应的字
void dis1()
{
TRANS=row;
TRANS1();
TRANS=PAGEADD;
TRANS1();
i=i*32; //i变成数组指示指针
for(k=0;k<16;k++) {
WRITE=table[i+k]; //查得需要显示的字节
WRITE1(); //在WRITE1 子程序里面,列地址加1
}
CLMADD=CLMADD-16;//恢复列地址
PAGEADD=PAGEADD+1;//页地址加1
TRANS=PAGEADD;
TRANS1();
for(;k<32;k++) {
WRITE=table[i+k]; //查得需要显示的字节
WRITE1(); //在WRITE1 子程序里面,列地址已经加1
}
}
//LCD 的E2 边显示函数,调用一次该函数,则在相应的位置显示相应的字
void dis2()
{
TRANS=row;
TRANS2();
TRANS=PAGEADD;
TRANS2();
单片机学习指南 资料提供:上海齐济电子有限公司
.60.
i=i*32; //i变成数组指示指针
for(k=0;k<16;k++) {
WRITE=table[i+k]; //查得需要显示的字节
WRITE2(); //在WRITE1 子程序里面,列地址已经加1
}
CLMADD=CLMADD-16;//恢复列地址
PAGEADD=PAGEADD+1;//页地址加1
TRANS=PAGEADD;
TRANS2();
for(;k<32;k++) {
WRITE=table[i+k]; //查得需要显示的字节
WRITE2(); //在WRITE1 子程序里面,列地址已经加1
}
}
//主程序
main()
{
INITIAL(); //系统初始化
lcd1(); //E1边初始化
lcd2(); //E2边初始化
row=0XC0; //显示起始列为第0 行
//以下显示不同的字符
PAGEADD=0XB8; //显示起始页为第0 页
CLMADD=0X00; //起始列为第0 列
i=0; //显示数组中对应的第一个字
dis1(); //调用显示函数
PAGEADD=0XB8; //显示起始页为第0 页
CLMADD=16; //起始列为第16 列
i=1; //显示数组中对应的第二个字
dis1(); //调用显示函数
PAGEADD=0XB8; //显示起始页为第0 页
CLMADD=32; //起始列为第32 列
i=2; //显示数组中对应的第三个字
dis1(); //调用显示函数
PAGEADD=0XB8; //显示起始页为第0 页
CLMADD=48; //起始列为第48 列
i=3; //显示数组中对应的第四个字
dis1(); //调用显示函数
PAGEADD=0XB8; //显示起始页为第0 页
CLMADD=0; //起始列为第0 列
i=4; //显示数组中对应的第五个字
dis2(); //调用E2 边显示函数
PAGEADD=0XBA; //显示起始页为第2 页
CLMADD=0X00; //起始列为第0 列
i=0; //显示数组中对应的第一个字
dis1(); //调用显示函数
PAGEADD=0XBA; //显示起始页为第2 页
CLMADD=16; //起始列为第16 列
i=5; //显示数组中对应的第六个字
dis1(); //调用显示函数
PAGEADD=0XBA; //显示起始页为第2 页
单片机学习指南 资料提供:上海齐济电子有限公司
.61.
CLMADD=32; //起始列为第32 列
i=2; //显示数组中对应的第三个字
dis1(); //调用显示函数
PAGEADD=0XBA; //显示起始页为第2 页
CLMADD=48; //起始列为第48 列
i=3; //显示数组中对应的第四个字
dis1(); //调用显示函数
PAGEADD=0XBA; //显示起始页为第2 页
CLMADD=0; //起始列为第0 列
i=4; //显示数组中对应的第五个字
dis2(); //调用E2 边显示函数
while(1) {

}
}
NOTE:
3月27日

[转]一个光棍的呐喊

汽车渴望公路,
花草渴望雨露,
太监迫切渴望著雄性激素。

灵魂渴望超度,
心灵渴望归宿,
而我则迫切渴望著有个媳妇。

众里寻她千百度,
踏平脚下路。
蓦然回首细环顾,
大婶大娘无数。
偶有美女光顾,
还是有夫之妇,
余下大多数,
基本不堪入目。
时间犹如脱兔,
匆匆不肯停步。
转眼就把我拖到了该当爹岁数。

然而上天却挺可恶,
对我不管不顾。
把我培养的庸庸碌碌,
难以获得少女的爱慕。

我曾向月老求助,
求他将我单身的生涯结束。
而他给予我的眷顾,
竟是接踵而至的恶女和怨妇。

比起她们的飞扬跋扈,
以及对我精神上的无情屠戮,
我更愿意选择让步,
甘心走向黄泉之路。
无助,无助。

其实我并非一无是处。
我有很多的优点可以列举和陈述。
但我不知道是什么缘故,
我竟无法得到过别人的敬仰和拥护
我的爱心彰明较著,
最最热心于公益捐助。

为了祖国福利和体育事业的长足进步,、
我不知疲倦的奔波于体彩和福彩中心投注;
为了向世人体现优越的社会主义制度,
以及在party和国家的领导下我们小康的程度,

我毅然决然的增加了喝酒的次数,
终于练出了代表富足的啤酒肚;
我还坚持为人民服务,用我最大的热情为别人提供帮助。

为了让我这片心意落到实处,
我硬是把不愿过去的大娘也搀过了马路……
而我得到的赞扬却远远少于挨骂的次数。
我不明白我的努力换来的为何只是别人的不屑一顾甚至是愤怒。
 
是因为我过人的天赋,
让他们相形见绌,
还是我高尚的品格和气度,
让他们产生了深深的嫉妒?

我的优秀并没有让我自负,
更没有因为自己的伟大而恃才傲物。
本以为这样才能有女孩对我暗生情素,
谁知我等到现在也还没有一点迹象和眉目。

其实要把女人比做猎物,
我则是一个迷茫的猎户。
因为我实在是不懂狩猎的技术。
该跟著群雄逐鹿,
还是该继续著守株待兔,
思考了很久也没有整理出一条清晰的思路。
也许这便也成了我的桎梏,
成了我无法得到爱情的又一大因素。

或许曾经的某次时机被我奢侈的贻误,
就造成了现在的万劫不复。
咱们这个国度,
人口资源丰富。
但为何娶不到老婆的男人还是不计其数?
是因为封建思想的束缚,
打乱了男女的比例和数目,
还是因为社会的退步,
又重新开始了一夫多妻的制度?

有时想想也他妈愤怒,
你说凭啥大款就可以包养了N个情妇?
难道只为著权利和财富,
就可以不受道德的约束,
并置我们光棍于不顾,
抢占著资源无数?

怪也怪女人们过于世故,
对金钱和地位的趋之若鹜。
只知道花园洋房和别墅,
早把真情的概念颠覆。
冲动时我真恨不得变成动物,
哪怕只是头卖力的牲畜。
听凭主人的吩咐,
不用感受做人的无助。

或者干脆来个移花接木,
彻底的做个变性手术。
跑到人群中滥竽充数,
也好让同胞们多一条可以选择的出路。

街上的婚介星罗棋布。
我也曾幻想著他们能帮我打开销路。
然而最终的结果是让我明白了什么叫认贼作父,
并被婚托儿们榨干了我几年的收入。

吃不著猪蹄儿能看看猪跑也算对我心灵创伤的平复。
所以能看到美女的繁华地段成了我最爱的去处。
每当看著她们迈著款款的猫步,
在我的视线里出出入入,
我总是能感受到久违了的心跳并顺便痛心一下她们的已为人妇。

现实的打击让我鸡肠小肚。
我最看不惯情侣们当众亲密过度。
只要看到有人稍越雷池半步,
我就会上前阻止并提醒他们病出口入。
结果自然不必赘述,
我经常会体验到肢体语言的丰富。
尽管如此我也并没有减少对此事的关注,
反而更觉得有必要加大宣传的攻势和力度。
没有爱的倾注,
我如涸辙之鲋。

这样的生活确实很难让我安之若素。
看著朋友们已为人父,
小生活过的美满和睦,
我又何尝不是深深的羡慕,
并渴望著感情上的脱贫致富?

都说男儿有泪不扑簌,
但那绝对是未到伤心处。
有谁知道泪水已经多少次模糊了我心灵的窗户?
况且咱都是沧海一粟,
凭啥我就不能在爱情的海岸登陆?
只能一口一口的吃著干醋,
被动的尽著晚婚晚育的义务!

人生本来就短促,我又怎能就这样默默的虚度?
为了尽快给自己找一个归宿,
我决心不择手段的全力以赴。
错误,错误。

这种想法最终成了我难逃的劫数。
没想到我一时的慌不择路,
竟上演了那样惨绝人寰的一幕。

那是我走投无路,
勾引了有夫之妇。
谁知道罪行败露,
被人家当场抓住。
只后悔不会武术,
没能够杀出血路。
无奈的任人摆布,
惨遭了打击报复。

他们恼羞成怒,
打得义无反顾。
片刀循环往复,
板砖频频招呼。
我浑身血流如注,
俩腿还不住抽搐。
走错那罪恶一步,
差点就死不瞑目。
KB,KB。
真庆幸我还能把命保住。

那场我自导自演的前车之覆,
带给了我贼深贼深的感触。
往事历历在目,
我此刻一一追溯。

经历了苦痛挣扎后的觉悟,
终于上升到了前所未有的高度。
问世间情为何物,
我算是大彻大悟。
感情上的事儿看来还真不能过于盲目。
是你的挡不住,
不是你的留也留不住。

别人的老婆就是再好也不能轻易接触。
有道是皮之不存毛将焉附,
我要是OVER了还上哪儿去找我的贤内助?
更何况人生短促,
还有很多东西值得我们珍惜和呵护。
 
爱情的光环固然眩目,
也毕竟不是生命的全部。
岁月的痕迹无孔不入。
无有爱情的皮囊苍老的更加迅速。
看著我那用蒸汽熨斗都已无法熨平的面部,
真不知还有谁肯向我将她的终身托付。
等待著等待到行将就木,
持续著持续到人生落幕。

盼望吧盼望著解决光棍待遇的法规早日颁布,
但愿啊但愿我首先踏入的能够是婚姻的坟墓

3月26日

参考参考

1,事业永远第一
  虽然金钱不是万能的,但没有钱是万万不能的,虽然这句话很俗,但绝对有道理,所以30岁之前,请把你大部分精力放在你的事业上.
2,别把钱看得太重
  不要抱怨自己现在工资低,银行存款4位数以下,看不到前途,现在要做的就是努力学习,即使你文凭再高,怎么把理论运用到实践还是需要一个很长的锻炼过程,社会永远是一所最博大的大学,它让你学到的知识远比你在学校学到的重要得多,所以同样,你也别太介意学历低.30岁之前靠自己能力买车买房的人还是极少.
3,学会体谅父母
  别嫌他们唠叨,等你为人父了你就知道可怜天下父母心,在他们眼里你还是个孩子,但他们真的老了,现在得你哄他们开心了,也许只要你的一个电话,一点小礼物,就可以让他们安心,很容易做到.
4,交上好朋友
  朋友对你一生都影响重大,不要去结识太多酒肉朋友,至少得有一个能在关键时刻帮助你的朋友,如果遇到这么一个人,就好好把握,日后必定有用,不管他现在是富还是穷.
  5,别太相信爱情
  心中要有爱,但请别说也别相信那些琼瑶阿姨小说里面的山盟海誓,世上本无永恒,重要的是责任,但女人心海底针,心变了,一切都成枉然,你要做的就是该出手时就出手,该放手时别犹豫.30岁之前的爱情不是假的,但只是大多数人都没有能真正把握好的能力,所以学会量力而行.
  6,别担心至今还保留初吻
  爱情不在多而在精,别以为自己20多岁还没碰过女孩子就害怕自己永远找不到老婆.以后你会有很多机会认识女孩子,要知道这个社会虽然男人多于女人,但现实是女人其实比男人更担心这个问题.男人30一枝花,你在升值而不是贬值,成熟的爱情往往更美丽更长久,所以不要像疯狗一样看到女孩就想追,学会品味寂寞.
  7,不要沉迷于任何东西
  所谓玩物而丧志,网络游戏是你在出校门之前玩的,你现在没有多余的时间和精力花费到这上面,否则你透支的东西以后都得偿还.一个人要有兴趣,爱好,但请分清楚轻重.
  8,年轻没有失败
  不要遇到挫折就灰心,年轻人要时刻保持积极向上的态度.失败了,重来过;失去了,再争取别的。错过了,要分析,下次来,要把握;幼稚了,下次,成熟点。不要紧,会好的,哪怕到了极点,也不要放弃,相信一定可以挺过去。不要消极,会好的。曾经的错,过去了,总不能回味在过去。现在的,很好,累完了,很舒服。不要伤,总会有人在支撑你。
  9,不要轻易崇拜或者鄙视一个人
  人都有偶像,但请拥有你自己的个性.不要刻意去模仿一个人,因为你就是你,是唯一的,独一无二的,要有自信.也不要全盘否定一个人,每个人是有价值的,如果你不能理解他,也请学会接受.
  10,要有责任心.
  不管你曾经怎样,但请从现在开始做一个正直的人.男人要有责任心,无论是工作还是生活上,一个有责任心的人才能让别人有安全感,才能让别人觉得你是一个值得信赖的人.我们不要懦弱,但请不要伤害爱你的人和你爱的人,尤其是善良的女孩,因为这个世界善良的女孩不多了,即使不想拥有,但也请让她保持她美丽的心.
  11,男人的外貌并不重要.
  不要为自己的长相身高而过分担心,一个心地善良,为人正直的男人远比那些空有英俊相貌,挺拔身材但内心龌龊的男人要帅得多.如果有人以貌取人,请不要太在意,因为你不用去为一个低级趣味的人而难过.
  12,学会保护身体
  不要以为现在抽烟喝酒,熬夜通宵也没什么事.那是因为你的身体正处于你一生的黄金时段.30岁以后你就能明白力不从心这个词的意义了,身体是革命的本钱,没有好的身体什么也做不了,所以要尽量让自己过有规律的健康生活.
  13,别觉得一事无成.
  你现在还没有资格谈成功,当然如果你有千万资产的除外.一开始太固定的职业并不一定是好事,或许在不断的改行当中,你会学到更丰富的知识,而且可以挖掘出自己的潜能,找到最适合你的工作.
  14,请认真工作
  即使你现在的工作再怎么无聊再怎么低级,也请你认真去对待,要知道任何成功人士都是从最小的事做起,或许你现在学不到多么了不起的知识,但起码你要学会良好的工作态度和工作方法,这对以后很重要.
  15,请认真对待感情.
  不要羡慕那些换女人像换鞋一样的花花公子,逢场作戏的爱情只是让你浪费时间浪费精力,一个人最痛苦的不是找不到爱人,而是心中没有了爱,当你把我爱你3个字变成你最容易说的一句话时,那么你在爱情的世界里已经很难找到真正的幸福了.爱情没有公平,总有一个人比对方付出得多,即使没有结果,也别觉得不值,因为你的付出不光是为了她,也是为了你自己的爱,为爱付出是很可贵的,赞自己一下.
  16.请留一点童心
  在内心深处,哪怕只是一个很小的角落里,请保持一份童心,不是幼稚,但有的时候单纯一点会让你很快乐.所以不要太计较得失,生活本无完美.
  最后说一点,学会尊重别人,这样别人才会尊重你,所以上论坛看帖子请回个贴,这是美德,花不了你多少时间,哈哈,谢谢各位!
 
哎,帮我想的一样的嘛~~哈哈,原来我已经无敌拉
3月25日

(转载)做不了爱人,我们做什么

 男人试着去忘掉女人,让她不再去承受这份沉重的感情折磨,也还给自己一片自由的空间。女人面对着大海,想问大海要到答案,但是他们仍然逃脱不了残酷现实的折磨。

    终于,当两个人都精疲力尽的时候,最后的选择到了。
静静的调整好彼此的心情,小心的问对方,做不了爱人我们做什么?

   “我们做知己吧”!女人对男人说。男人说:“不,我承受不了那份永久的牵挂与思念,没有人能做好一辈子的知己。”

   “那我们做情人吧”!男人说:“不,因为你是善良的女人,尽管我们的感情没有阳光的青睐,但是这样暧昧的词语是对我们的玷污”。

   “那我们做兄妹吧”! 女人对男人说。男人说:“不,我们的爱早已越过了兄妹之间的亲情,会有哥哥用带着柔情爱意的目光看待妹妹的吗?我不会做这样的哥哥”。

   “那我们做朋友吧,我只能给你这个了。”男人说:“不,在我的心里你早已经是我的爱人了,做了朋友的身份,我无法面对你和你的另一半,也无法想像你和你另一半在一起的时候……我也无法抗拒和我的另一半同床共眠的时候不去想你。”

   “我们还是做仇人吧”!男人对女人说。既然我们都改变不了自己的命运,此生注定了没有相互厮守一生的幸福,与其这样相互的念着、痛着,仇恨的远离对方的视线,永远的找寻不到对方,也许会是一种最好的解脱。女人愕然了,男人哭了。无法想像最后能给与对方的竟然是这样的结局。但是他们明白,也只有这样选择,才可以保留住对方的那份善良与纯洁,也不再会去伤害更多的人。 

    从此,他们消失了,没有相互的祝福,就这样静静的消失在茫茫的人海中。两副柔弱的肩膀,承受不住另类的爱情
 

 
3月19日

最近有点烦

不知道怎么了,最近情绪有点低潮,心情有点差
老板要求的设计搞的我头哈大呀
现在就好象我面前有一大堆乱麻
要从当中找到头啊~~~
一开始我的个人感觉并不是这么复杂的
可是随着研究的深入
越来越多的问题出现了
I2C总线问题
CCP模块驱动AD转换问题
交流电压的采样问题
16位无符号的乘法
32位的加法
牛顿迭代法算有效值
定时器
EEPROM读写问题
跨页跳转问题
......
要死啊,怎么把这些东西拼起来啊~~~~
单位里没有人懂,唯一一个懂的还不是我们单位的
我一个人做真的很吃力哦.
天啊~~~~~
发发牢骚,嘿嘿.
继续努力,继续努力.......
设计的路没有这么好走的.一步一步走稳咯
我要压抑,克制.........
1月7日

good luck

我除了说GOOD LUCK之外
什么也做不了咯
愿幸运与你同在
祝福祝福~~~