实例1
74HC164是串行输入,并行输出接口器件,可用在单向的并行输出/并行地址锁存等. 74HC164因为价格便宜,容易使用特别适合使用在在需要用到数码管显示IO口又比较紧张的电子产品中,下面浅谈使用方法:
1. 首先先了解他的引脚功能和逻辑图,如下图:
图1 引脚名称和用途
图2 真值表
通过真值表我们可以了解到,A,B两个输入端是互锁的,CLK上升沿时数据移入移位寄存器中,CLEAR为清零用的,接低电平时所有端口都输出低电平,了解了真值表之后开始运用了,先给出如下原理图:
图3 原理图
图中,采用义隆的EM78P153作为控制芯片,P50作为CLK时钟信号,注意平时数据不传输时,时钟信号是不发送的应一直保持低电平或者高电平,数据需要传输的时候才输出时钟信号^_^ ,继续P51作为移位数据输出端,接到74HC164的B端,A端接高电平,当然也可以AB端短路,然后连接到DATA移位数据端,P52作为数码管的选通信号(也可以叫消隐^_^), 作用是使数据传输过程暂时关闭显示,以免显示出不需要的数据,原因是应为164不带锁存功能,数据传输过程是一位一位的向高位移位输出的,所以要等数据全部移入后才打开始点亮数码管.
注意了哦,通过查看164的规格书发现,164输出高电平电流比输出低电平电流要小,亦称灌电流大,扇出电流弱,所以适合选用共阳数码管,如图,本人偷懒没有画出那个数码管的8字
该介绍的介绍的差不多了,废话少说,该开始干活了,任务是: 显示0-9 每秒+1 ,到9后又返回0,一直循环显示,根据任务得到如下流程图:
1. 显示部分:
将需要显示的数值送入A ==> 查表求得显示段码==>将段码逐位移入164==>8位移完后点亮数码管==>延时==>返回第一步执行
2. 中断部分:
进入中断==>保存现场(以备调查取证,送你入狱^_^)==>重置TCC==>够1秒钟将需要显示的数据+1,并重置,不够就退出;
根据以上要求就开始写代码调试了,要注意一点,数据移位时一定要记得高位在前哦,否则显示错误别怪我没有说清楚,我当年实验时就因为这个数据移位方向反了排查了半天,甚至以为是时钟频率不对,又以为时许不对.....搞了半天,NND后来重看DATASHEET才发现,原来是低级错误啊,呜呼哀哉.......,希望你不要重蹈我覆辙,哎哟!! 谁! 谁! 谁扔砖头上来? 啥? 你扔的? 我废话太多.........,那俺少来两句,继续上菜, 咦好像没啥可说的了,上源程序吧
- ;中断部分:
- ;;;;;;;;;;中断;;;;;;;;
- INTPUT:
- MOV TEMPA, A;
- MOV A,@130;
- MOV TCC,A;255-130=125
- CLR RF;
- ;;;;;此处填写250Us处理程序
- BS WKREG,T500US
- ;;;;;;;;;;;;;;;;;;;;;;;;;
- DJZ R1MS
- JMP INTEXT;
- MOV A,@4
- MOV R1MS,A;重置
- BS WKREG,T1MS
- ;;;;;;;此处填写1ms处理程序
- ;;;;;;;;;;;;;;;;;;;;;;;;;;
- DJZ R20MS
- JMP INTEXT;
- MOV A,@20
- MOV R20MS,A;重置
- ;;;此处填写1秒处理程序
- BS WKREG,T20MS
- ;;;;;;;;;;;;;;
- DJZ R1S
- JMP INTEXT;
- MOV A,@50
- MOV R1S,A;
- ;;;;;;;;;
- INC NUMBER
- MOV A,NUMBER
- SUB A,@10
- JBS SR,2
- JMP INTEXT
- MOV A,@0
- MOV NUMBER,A
- INTEXT:
- MOV A,TEMPA;
- RETI;;;;;;;;;;;;;;;;;;;;;
- ;显示部分:
- ;==============TXDATA==============
- TXDATA:
- BS P5,CC1
- MOV A,@8
- MOV DATALOP,A;
- TXLOP:
- BC WKREG,T500US
- BS P5,CLK;clk=高
- NOP;
- NOP
- JBS DATA_BUF,7
- JMP $+3
- BS P5,DATA;
- JMP $+2
- BC P5,DATA
- DD1MS: JBS WKREG,T500US
- JMP $-1
- BC P5,CLK
- BC WKREG,T500US
- JBS WKREG,T500US
- JMP $-1;
- RLC DATA_BUF
- DJZ DATALOP
- JMP TXLOP
- ;;;;;;;;;;
- BC WKREG,T500US
- BS P5,CLK;clk=高
- BC WKREG,T500US
- JBS WKREG,T500US
- JMP $-1;
- BC P5,CLK
- ;;;;;;;;
- BC P5,CC1
- RET;;;;;;;
- ;数据查表
- ;===============DSPTBL============
- DSPTBL: ADD PC,A
- RETL @0B01000000;0
- RETL @0B01111001;1
- RETL @0B00100100;2
- RETL @0B00110000;3
- RETL @0B00011001;4
- RETL @0B00010010;5
- RETL @0B00000010;6
- RETL @0B01111000;7
- RETL @0B00000000;8
- RETL @0B00010000;9
- ;循环体部分;
- ;;;;;;;;;;主程序;;;;;;;;;;;
- MLOOP:
- MOV A,NUMBER
- CALL DSPTBL
- MOV DATA_BUF,A
- CALL TXDATA
- BC WKREG,T1MS
- JBS WKREG,T1MS
- JMP $-1
- NOP;
- JMP MLOOP;;;;;;;;;;;;;;;;;;;;
实例2
在实际应用中驱动数码管常用的方式分动态扫描和静态驱动。动态扫描方式需要x+y个IO(x*y个数码管的情况,一般x=8,y=位数)这种方法很浪费MPU的IO端口对于2051等20脚的芯片就很难实现。静态显示驱动法,即是指每一个LED灯分别对应一个独立的IO驱动口,这种方法适用较少LED的驱动,不适合数码管驱动。
驱动要点:
1、上升沿写入串行数据:
3、 程序源代码:
- //共阴数码管74HC164串行驱动
- #include<AT892051.H>
- #define uint unsigned int
- #define uchar unsigned char
- sbit DAT=P3^7; //模拟串口数据发送端
- sbit CLK=P3^4;//模拟时钟控制端
- uchar code tab[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xff,0xf6};//0-9,-,全灭
- void sendbyte(uchar byte)
- {
- uchar num,c;
- num=tab[byte];
- for(c=0;c<8;c++)
- {
- CLK=0;
- DAT=num&0x01;
- CLK=1;
- num>>=1;
- }
- }
- void delay_50ms(unsigned int t)
- {
- unsigned int j;
- for(;t>0;t--)
- for(j=6245;j>0;j--)
- {;}
- }
- main()
- {
- unsigned char h;
- while(1){
- for(h=0;h<10;h++){
- delay_50ms(1);
- sendbyte(h);
- delay_50ms(4);
- }
- h=0;
- }
- }