📄 74hc595.c
字号:
#include<absacc.h>
#include<stdlib.h>
#include <reg52.h>
#include <intrins.h> /*used for _nop_() function*/
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit SDATA_595 =P1^0 ;/*串行数据输入*/
sbit SCLK_595 = P1^1;/*移位时钟脉冲*/
sbit RCK_595 =P1^2 ; /*输出锁存器控制脉冲*/
sbit YELLOW=P2^0; //黄色
sbit ALARM=P2^1; //报警
sbit RED=P2^2; //红色
sbit CS=P2^6;
bit b_flash;
sbit SCLK=P0^6;//时钟输入.
sbit IO=P0^7;//读写数据.
sbit RST=P0^5;//芯片复位.
uchar bdata dat;//
sbit dat0=dat^0;//
sbit dat7=dat^7;
uchar arr_RTC[7];
uchar counter;
bit b_flash;
uchar scan;
uchar Temp;
uchar Dis_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; /*0~9的共阴极段码表*/
uchar Dis_Date[5];
int countv;
int count,countv;
uchar bdata dat;
void delay(int i)
{
for(i=1000;i>0;i--)
{
_nop_();
}
}
/***************************
初始化(定时器0为定时器,定时器1为计数器)
***************************/
void Init()
{
TMOD=0x51;
TL0 = -50000%256;
TH0 = -50000/256; //50ms定时
TR0 = 1; //"T0运行控制"
ET0 = 1; //1"定时器0中断允许"
TR1 = 1; //"T1运行控制"
TH1=TL1=0;
EA=1; //总中断允许
counter=0; //计数器清零
}
void UPdate()
{
// int TM_hour=12;
// int TM_minute=23;
// float data temp2;//定义存放计算得到的速度值
//temp2=3.6*t*0.6*counter;
// Temp=(unsigned int)temp2;//强制转型
Temp=19;
Dis_Date[5]=Temp%10;
Dis_Date[4]=Temp/10;
}
/*写数据到74HC595函数*/
void WR_595(unsigned char data num2 )
{
unsigned char data count1;
for(count1=0;count1<=7;count1++)
{
num2<<=1; /*右移位*/
SDATA_595=CY;
_nop_();
_nop_();
SCLK_595=0;
_nop_();
_nop_();
SCLK_595=1; /*产生上生沿*/
}
}
/****************************************************************/
/*更新74HC595输出数据函数void Out_595(void)*/
void Out_595(void)
{
RCK_595=0;
_nop_();
_nop_();
RCK_595=1; /*上升沿锁存数据*/
}
void Led_Drive(void)
{
int i;
{
for(i=0;i<=5;i++)//一次输出六位
{
WR_595(Dis_Tab[Dis_Date[i]]);
}
{
Out_595();
delay(1000);
}
TL1=0;
}
}
/*****************************
功能:往DS1302写入1Byte数据
输入:wr_data写入的数据
返回值:无
*******************************/
void wr_1302(uchar wr_data)
{
uchar i;
RST=1;//启动数据传送.
SCLK=0;
_nop_(); _nop_();_nop_();
dat=wr_data;//读数据.
for(i=8;i>0;i--)//循环8次,写入数据.从低位到高位.
{
IO=dat0;//将dat0的值赋给时钟数据线.
_nop_();
_nop_();
SCLK=1;//时钟上升沿写入数据.
_nop_();
SCLK=0;
dat=dat>>1;//将高位数据移至dat0;
}
}
/*****************************
功能:从DS1302读出1Byte数据
返回值:dat
*******************************/
uchar rd_1302(void)
{
uchar i;//
RST=1;//启动数据传送.
_nop_();
for(i=8;i>0;i--)// //循环8次,读出数据.从低位到高位.
{
dat=dat>>1;//右移一位
dat7=IO;//读时钟数据总线
_nop_();
SCLK=1;
_nop_();
SCLK=0;//时钟下降沿读出数据
_nop_();
}
return (dat);
}
/********************************************************************
* 名称: uc_R1302
* 说明: 先写地址,后读命令/数据
* 功能: 读取DS1302某地址的数据
* 调用: v_RTInputByte() , uc_RTOutputByte()
* 输入: ucAddr: DS1302地址
* 返回值: ucDa :读取的数据
***********************************************************************/
uchar uc_R1302(uchar ucAddr)
{
uchar ucDa;
RST = 0;
SCLK = 0;
RST = 1;
wr_1302 (ucAddr); // 地址,命令
ucDa=rd_1302 (); //读1Byte数据
SCLK = 1;
RST =0;
return (ucDa);
}
/********************************************************************
* 名称: v_W1302
* 说明: 先写地址,后写命令/数据
* 功能: 往DS1302写入数据
* 调用: v_RTInputByte()
* 输入: ucAddr: DS1302地址, ucDa: 要写的数据
* 返回值: 无
***********************************************************************/
void v_W1302(uchar ucAddr, uchar ucDa)
{
RST = 0;
SCLK = 0;
RST = 1;
wr_1302(ucAddr); // 地址,命令
wr_1302(ucDa); // 写1Byte数据
SCLK = 1;
RST =0;
}
void RTC_RD_Time ()
{
uchar i,add = 0x81;
for (i=0;i<7;i++)
{
arr_RTC[i] = uc_R1302(add); //读秒
add += 2;
}
/*
arr_RTC[0] 秒
arr_RTC[1] 分
arr_RTC[2] 时
arr_RTC[3] 日
arr_RTC[4] 月
arr_RTC[5] 星期
arr_RTC[6] 年
*/
}
void RTC_initial ()
{
v_W1302(0x8e,0x00); //使能
v_W1302(0x80,0x80); //停止晶振
v_W1302(0x90,0x00); //关闭充电
v_W1302(0x8c,0x07); //设置年
v_W1302(0x8a,0x06); //设置周
v_W1302(0x88,0x01); //设置月
v_W1302(0x86,0x13); //设置日
v_W1302(0x84,0x18); //设置小时
v_W1302(0x82,0x05); //设置分
v_W1302(0x80,0x00); //启动晶振,设置秒
v_W1302(0x8e,0x80); //使能
}
void RTC_set_time ()
{
v_W1302(0x8e,0x00); //使能
v_W1302(0x80,0x80); //停止晶振
v_W1302(0x90,0x00); //关闭充电
v_W1302(0x8c,arr_RTC[6]); //设置年
v_W1302(0x8a,arr_RTC[5]); //设置周
v_W1302(0x88,arr_RTC[4]); //设置月
v_W1302(0x86,arr_RTC[3]); //设置日
v_W1302(0x84,arr_RTC[2]); //设置小时
v_W1302(0x82,arr_RTC[1]); //设置分
arr_RTC[0] &= 0x7f;
v_W1302(0x80,arr_RTC[0]); //启动晶振,设置秒
v_W1302(0x8e,0x80); //使能
}
void Sys_initial ()
{
//sbit SCLK=P1^6;//时钟输入.
//sbit IO=P1^7;//读写数据.
//sbit RST=P3^3;//芯片复位.
//P3^4 = 0;
// BEEP=0;
SCLK=0; RST=0;
ET0=1;
TMOD=0x01;
EA=1;
TH0=-(20000/256);// TH0=0xB1;22118
TL0=-(20000%256);// TL0=0xDF; // 20000nS(20ms)
TR0=1;
}
/*void Time0 (void) interrupt 1
{
TH0=-(22000/256);//20ms //18432
TL0=-(22000%256);//20ms
//b_disp = ~b_disp;
counter++;
if (counter>=25)
{
counter=0;
b_flash = ~b_flash;
}
} */
void main (void)
{
Sys_initial ();
RTC_initial ();
// EPIN=0;
while (1)
{
if (b_flash)
{ b_flash=0;
RTC_RD_Time ();
delay(10);
// display ();
}
}
}
/****************************************************************/
/* main()
{
SCON = 0x00;
CS=0;
// In12887();
Init();
while(1)
{
Dis_Date[3]=arr_RTC[0]%10;
Dis_Date[2]=arr_RTC[0]/10;
Dis_Date[1]=arr_RTC[1]%10;
Dis_Date[0]=arr_RTC[1]/10;
//if(scan==0)
// scan = 0;
// counter=TL1;
// UPdate();
// Led_Drive();
//把定时器的数据传给计数器
}
} */
void Time0 (void) interrupt 1
{
//uchar scan;
TR0=0;
delay(1000);
scan++;
if(scan==20)
{ scan = 0;
counter=TL1;
UPdate();
Led_Drive();
}
TL0 = -50000%256;
TH0 = -50000/256; //50ms定时
TR0=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -