74hc595和74hc165级连c51程序
- 格式:doc
- 大小:330.50 KB
- 文档页数:3
************************** Copyright(C)CaKe ******************************* **********=============================================================================== =======================**文件名: main.c ============================**作者: CaKen ============================**版本号: V1.0 ============================**时间: 2014.08.16 ============== ==============**功能描述: 74HC165实验测试============================================================================================= =========******************************************************************************* *********#include <reg52.h>#include <intrins.h>//SPI 接口sbit CLK = P3^6; //串行时钟sbit IN_PL = P1^6; //把数据加载到锁存器中sbit IN_Dat = P1^7; //数据通过P1.7脚移进单片机内处理sbit RELAY = P1^4; //继电器sbit BEEP = P1^5; //蜂鸣器unsigned char bdata Key;sbit K0=Key^0; //位定义sbit K1=Key^1; //位定义sbit K2=Key^2; //位定义sbit K3=Key^3; //位定义sbit K4=Key^4; //位定义sbit K5=Key^5; //位定义sbit K6=Key^6; //位定义sbit K7=Key^7; //位定义bit M0 ,K0J; //位定义******************************************************************************* **********函数名:调用:beep();参数:返回值:结果:备注:蜂鸣器 (让蜂鸣器发出动听声音)******************************************************************************* **********void beep(){unsigned char i,j;for (i=0;i<2;i++){for (j = 0; j<255; j++){_nop_();}BEEP=!BEEP; //BEEP取反}BEEP=1; //关闭蜂鸣器}******************************************************************************* *********函数名:74HC165函数初始化调用:HC165_Init();参数:返回值:结果:备注:IN_PL上升沿,CLK上升沿******************************************************************************* *********unsigned long HC165_Init(void){unsigned char i;unsigned int indata;IN_PL=0; //上升沿_nop_(); //短暂延时产生一定宽度的脉冲IN_PL=1; //将外部信号全部读入锁存器中_nop_();indata=0; //保存数据的变量清0for(i=0; i<8; i++){indata=indata<<1; //左移一位if(IN_Dat==1)indata=indata+1; //如果IN_Dat检测到高电平保存数据的变量加1CLK=0; //时钟置0_nop_(); //上升沿CLK=1; //时钟置1}return(~indata); //将保存数据的变量取反后返回}******************************************************************************* **********函数名:主函数调用:main参数:返回值:结果:备注:74HC165控制八个按键******************************************************************************* **********main(){while(1){unsigned long Input=HC165_Init(); //调用165驱动程序Key=Input&0xff; //将数据传给位变量RELAY = 1;P2 = 0xff; //清除if(K0&K0J)M0=~M0; //实现脉冲输入大家仔细体会K0J=~K0;if(M0) {RELAY = 0; P2 = 0x7f; } //实现脉冲输入if(K1) {beep(); P2 = 0xbf; } //K1 为1时开启蜂鸣器和2个灯if(K2) {beep(); P2 = 0xdf; }if(K3) {beep(); P2 = 0xef; }if(K4) {beep(); P2 = 0xf7; }if(K5) {beep(); P2 = 0xfb; }if(K6) {beep(); P2 = 0xfd; }if(K7) {beep(); P2 = 0xfe; }}}。
74hc165接收函数支持联级/**************************************************** 74hc165intn();//初始化74hc165satin();//开始输入接收单级数据:dat=inpute();//接收返回值到dat使用数组保存多级:hc165pinsav(d)//d为接收个数,联级个数。
******************************************************/ #ifndef __74hc165_H__#define __74hc165_H__#include "A T89X52.h"#include <intrins.h>#include<stdio.h>unsigned char hc165insav[4];//保存接收数据联极sbit ck=P1^1;//时钟2引脚。
sbit sd=P1^0;//数据9引脚。
sbit sh=P1^2;//开始输入1引脚。
//SI联级10引脚,连接下级的9引脚。
/****************************************************五个机器周期******************************************************/ void nop(){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/****************************************************74hc165初始化******************************************************/void hc165intn() //初始化{sh=1;sd=1;ck=1;}/****************************************************74hc165开始输人******************************************************/ void hc165satin(){sh=0; //起始接收脉冲开始接收。
74HC595按键显示程序#include<reg51.h>#include<intrins.h>sbit DS=P1^1;sbit SH_CP=P1^2;sbit ST_CP=P1^3;sbit K1=P1^4;sbit K2=P1^5;sbit K3=P1^6;sbit K4=P1^7;unsigned char code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc6}; unsigned char code wei[]={0xfe,0xfd,0xfb,0xf7};char num1,num2,num3,num4,su,D,C,num_1,num_2;int A;void delay(int x)//延时{int a,b;for(a=0;a<=x;a++)for(b=0;b<=110;b++);}void num_in(char su)//数据输入{int j;for(j=0;j<8;j++){SH_CP=0;DS=su&0x80;su<<=1;SH_CP=1;_nop_();}}void num_out()//数据输出{ST_CP=0;ST_CP=1;_nop_();}void display()//显示子程序{num_in(wei[0]);num_in(duan[num_1]);num_out();delay(3);num_in(wei[1]);num_in(duan[num_2]);num_out();delay(3);num_in(wei[2]);num_in(duan[num3]);num_out();delay(3);num_in(wei[3]);num_in(duan[num4]);num_out();delay(3);}void display_1()//显示子程序1 {num_in(wei[0]);num_in(duan[num1]);num_out();delay(3);num_in(wei[1]);num_in(duan[num2]);num_out();delay(3);num_in(wei[2]);num_in(duan[num3]);num_out();delay(3);num_in(wei[3]);num_in(duan[num4]);num_out();delay(3);}void menu()//菜单程序0~9{switch(D){case 1: {num_1=10; num_2=10; num3=1; num4=11;};break;case 2: {num_1=10; num_2=10; num3=2; num4=11;};break;case 3: {num_1=10; num_2=10; num3=3; num4=11;};break;case 4: {num_1=10; num_2=10; num3=4; num4=11;};break;case 5: {num_1=10; num_2=10; num3=5; num4=11;};break;case 6: {num_1=10; num_2=10; num3=6; num4=11;};break;case 7: {num_1=10; num_2=10; num3=7; num4=11;};break;case 8: {num_1=10; num_2=10; num3=8; num4=11;};break;case 9: {num_1=10; num_2=10; num3=9; num4=11;};break;case 0: {num_1=10; num_2=10; num3=0; num4=11;};break;}}void xiugai() //修改按键{if(K2==0){delay(3);if(num1==10)num1=0;if(K2==0)num1++;while(!K2)display();}}void tuichu(){if(K1==0){delay(3);if(K1==0)A=!A;while(!K1)display();}}void shezhi() //设置按键{while(K1==1){int c,d;for(c=0;c<20;c++){xiugai();display_1();}for(d=0;d<20;d++){xiugai();display();}}}void xianshi()//显示按键{if(K1==0){delay(3);if(K1==0){while(K4==1)display_1();}while(!K1)display();}}unsigned char keyuse()//按键程序{if(K1==0){delay(3);if(K1==0)A=!A;while(!K1)display();}if(K2==0){delay(3);if(K2==0);while(!K2)display();}if(K3==0){delay(3);if(K3==0)shezhi();while(!K3)display();}if(K4==0){delay(3);if(K4==0){if(D==10)D=0;menu();D++;}while(!K4)display();}}void main()//主程序{while(1){keyuse();display();xianshi();}}。
51单片机驱动两片74HC595级联动态驱动8位数码管功能: 用2片74HC595驱动8位数码管, 级联的最低1片595控制位选,那么第一片控制段选平台: STC89C52 11.0592MHz现象: 8位数码管从第一位开始从0计数,满10进位版本说明: 第0版本没有使用定时器中断,同时定义了一个unsigned long int 变量计数,再把这个数的每位分离出来显示,所以导致有点闪屏,此版本使用定时器中断,而且没有用unsigned long int 之类的变量,而是用数组Val[8] 来计数,主函数只负责显示,其它的在中断函数里面处理,这样显示一点都不闪屏,备注: 可以用ULN2003A 接在数码管的com 口来提高驱动能力,ULN2003A里面有7个NPN三极管, 可以大大提高驱动能力#include <reg52.h>sbit SCK = P1^1; // 数据输入时钟线,脉冲sbit SI = P1^0; // 数据线sbit RCK = P1^2; // 锁存unsigned char code SMG[10] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; // 段码unsigned char code Wei[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; // 位选unsigned char Val[8] = {0}; // 要显示的数据************************ 函数声明************************void interrupt_init(void);void timer_init(void);控制74HC595输出数据void Output(void){RCK = 0;RCK = 1;}向74HC595中写入一字节数据void Write_Byte(unsigned char dat){unsigned char i = 0;for(i=0; i<8; i++){SCK = 0;SI = dat & 0x80;SCK = 1;dat <<= 1;}}显示函数void Display(unsigned char * p) {unsigned char * pt = Wei;Write_Byte(*(pt+0));Write_Byte(SMG[*(p+7)]);Output();Write_Byte(*(pt+1));Write_Byte(SMG[*(p+6)]);Output();Write_Byte(*(pt+2));Write_Byte(SMG[*(p+5)]);Output();Write_Byte(*(pt+3));Write_Byte(SMG[*(p+4)]);Output();Write_Byte(*(pt+4));Write_Byte(SMG[*(p+3)]);Output();Write_Byte(*(pt+5));Write_Byte(SMG[*(p+2)]);Output();Write_Byte(*(pt+6));Write_Byte(SMG[*(p+1)]);Output();Write_Byte(*(pt+7));Write_Byte(SMG[*(p+0)]);Output();}int main(void){timer_init();interrupt_init();while(1){Display(Val);}return 0;}void interrupt_init(void){EA = 1; //开总中断ET0 = 1; //开定时器0中断ET1 = 1; //开定时器1中断}void timer_init(void){TMOD = TMOD | 0x01; //定时器0工作方式1TMOD = TMOD & 0xFD;TH0 = 0x4B; //装初值,50ms计数TL0 = 0xFF;TR0 = 1; //开启定时器0}void timer0() interrupt 1{static unsigned char counter0 = 0;counter0++;TH0 = 0x4B; //重新装入初值,定时器0从头开始计数,计数50ms TL0 = 0xFF;if(2 == counter0) //2*50 ms = 100ms = 0.1s{counter0 = 0; //counter0置零,定时器0从头开始计数Val[0]++;if(10==Val[0]){Val[0] = 0;Val[1]++;if(10==Val[1]){Val[1] = 0;Val[2]++;if(10==Val[2]){Val[2] = 0;Val[3]++;if(10==Val[3]){Val[3] = 0;Val[4]++;if(10==Val[4]){Val[4] = 0;Val[5]++;if(10==Val[5]){Val[5] = 0;Val[6]++;if(10==Val[6]){Val[6] = 0;Val[7]++;if(10==Val[7]){Val[7] = 0;}}}}}}}}}}。
PIC系列单片机简单I/O口扩展技术摘要在实际应用当中当单片机的I/O口资源无法满足系统设计需要时,为了节省成本,常通过外部I/O扩展芯片来达到设计要求。
74系列TTL电路是一种简单实用的I/O扩展技术,介绍了74HC165和74HC595芯片的工作原理,给出了该芯片与PIC系列单片机的接口硬件电路及软件代码。
关键词单片机 I/O口扩展 TTL电路引言当单片机的I/O口资源无法满足系统设计需要时,为了节省成本,常通过外部I/O扩展芯片来达到设计要求。
通常的办法是设计之初就选用I/O口丰富的单片机来实现,但如果外围设备较多时,也只能进行外部扩展了。
另外,使用一款新的单片机,开发者还有一个熟悉、学习过程,因此这并不是最经济的办法。
常用的I/O口扩展方法有:(1)专用扩展芯片,如可编程并口扩展芯片8255,通过3个外部地址,扩展出3个并口;又如可通过串入并出、并入串出、并入并出进行I/O口扩展的GM8166芯片等。
(2)单片机I/O口扩展法,在系统中设计多个单片机,利用单片机自身I/O口资源进行扩展。
(3)TTL移位寄存器法,通过移位寄存器,来扩展无穷个输出或者输入I/O口。
(4)最简单的I/O口扩展法,如采用74373做多个锁存器进行输出扩展,采用74245做多个总线收发器进行输入扩展。
上述几种方法都有其一定的应用条件和适用范围,并不一定能分出个孰优孰劣,但从最经济角度来说,设计者往往希望能缩短开发周期、降低开发成本。
而TTL移位寄存器方法是一种简单实用的I/O扩展技术,芯片控制简单、编程容易,应用十分广泛。
本文介绍了74HC165和74HC595芯片的工作原理,给出了与PIC系列单片机的接口硬件电路及软件代码。
芯片介绍(1)8位并入/互补串出移位寄存器74HC165。
74HC165是一款高速CMOS器件,8位并行读取或串行输入移位寄存器,可在末级得到互补的串行输出(P0和P7)。
当移位/并行置入控制(/PL)输入为低时,从P0到P7口输入的并行数据将被异步地读取进寄存器内。
51单片机控制74HC595驱动的编程要点51单片机编程要点51单片机控制74HC595驱动的编程要点:74595外形图______QB--|1 16|--VccQC--|2 15|--QAQD--|3 14|--SIQE--|4 13|--/GQF--|5 12|--RCKQG--|6 11|--SCKQH--|7 10|--/SCLRGND-|8 9|--QH'|_____|74595的数据端:QA--QH: 八位并行输出端,可以直接控制数码管的8个段。
QH': 级联输出端。
我将它接下一个595的SI端。
SI: 串行数据输入端。
74595的控制端说明:/SCLR(10脚): 低点平时将移位寄存器的数据清零。
通常我将它接Vcc。
SCK(11脚):上升沿时数据寄存器的数据移位。
QA-->QB-->QC-->...-->QH;下降沿移位寄存器数据不变。
(脉冲宽度:5V时,大于几十纳秒就行了。
我通常都选微秒级)RCK(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。
通常我将RCK置为低点平,当移位结束后,在RCK端产生一个正脉冲(5V时,大于几十纳秒就行了。
我通常都选微秒级),更新显示数据。
/G(13脚): 高电平时禁止输出(高阻态)。
如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。
比通过数据端移位控制要省时省力。
注1)74164和74595功能相仿,都是8位串行输入转并行输出移位寄存器。
74164的驱动电流(25mA)比74595(35mA)的要小,14脚封装,体积也小一些。
2)74595的主要优点是具有数据存储寄存器,在移位的过程中,输出端的数据可以保持不变。
这在串行速度慢的场合很有用处,数码管没有闪烁感。
3)595是串入并出带有锁存功能移位寄存器,它的使用方法很简单,在正常使用时SCLR为高电平,G为低电平。