单片机源程序如下:- #include<reg52.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define u8 uint8_t
- #define u16 uint16_t
- #define u32 uint32_t
- typedef unsigned char uint8_t;
- typedef unsigned short uint16_t;
- typedef unsigned long uint32_t;
- #define DS3231_WriteAddress 0xD0
- #define DS3231_ReadAddress 0xD1
- #define Delay(us) {_nop_();_nop_();_nop_();_nop_();}
- typedef struct
- {
- u8 hour;
- u8 min;
- u8 sec;
- u32 w_year;
- u8 w_month;
- u8 w_date;
- u8 week;
- u8 temper_H;
- u8 temper_L;
- }Calendar_OBJ;
- extern Calendar_OBJ calendar; //日历结构体
- extern u8 const mon_table[12]; //月份日期数据表
- //*******GPIO 定义********************************************************
- sbit TM1640_DIN=P1^3; //TM1640数据线
- sbit TM1640_SCLK=P1^4; //TM1640时钟线
- sbit SDA=P3^3; //IIC数据线
- sbit SCL=P3^4; //IIC时钟线
- sbit SDA_read=P3^3;
- sbit SCL_read=P3^4;
- //************************************************************************************************
- #define TM1640MEDO_ADD 0x44 //地址模式的设置0x40自动加一模式 0x44固定地址模式
- #define TM1640MEDO_DISPLAY 0x8C //设置亮度小:0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8f最大0x80关闭
- #define TM1640MEDO_DISPLAY_OFF 0x80 //宏定义 关亮度设置
- //**************************************************************************************************
- //功能:延时1毫秒 ,入口参数:x ,说明:当晶振为12M时,j<112;当晶振为11.0592M时,j<122*/
- //***************************************************************************************************
- void Delay_xms(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<112;j++);
- }
- //功能:12us延时,STC89C52为1T单片机,即1个时钟/机器周期,速度为AT89C52的12倍
- void Delay_us(uint t)
- {
- for(;t>0;t--)
- {
- _nop_();
- }
- }
- //*********TM1640驱动函数 START***************
- //功能:12us延时
- //***************************************************************************************
- //通信时序 启始
- void TM1640_start()
- {
- TM1640_DIN=1;
- TM1640_SCLK=1;
- Delay_us(1);
- TM1640_DIN=0;
- Delay_us(1);
- TM1640_SCLK=0;
- Delay_us(1);
- }
- //通信时序 结束
- void TM1640_stop()
- {
- TM1640_DIN=0;
- TM1640_SCLK=1;
- Delay_us(1);
- TM1640_DIN=1;
- Delay_us(1);
- }
- //写数据
- void TM1640_write(u8 date)
- {
- u8 i;
- u8 aa;
- aa=date;
- TM1640_DIN=0;
- TM1640_SCLK=0;
- for(i=0;i<8;i++){
- TM1640_SCLK=0;
- Delay_us(1);
- if(aa&0x01){
- TM1640_DIN=1;
- Delay_us(1);
- }else{
- TM1640_DIN=0;
- Delay_us(1);
- }
- TM1640_SCLK=1;
- Delay_us(1);
- aa=aa>>1;
- }
- TM1640_DIN=0;
- TM1640_SCLK=0;
- }
- //TM1640接口初始化函数//TM1640设置
- void TM1640_Init(void)
- {
- TM1640_start();
- TM1640_write(TM1640MEDO_ADD); //设置工作模式
- TM1640_stop();
- TM1640_start();
- TM1640_write(TM1640MEDO_DISPLAY);//设置显示亮度
- TM1640_stop();
- }
- //固定地址模式的显示输出函数
- void TM1640_display(u8 address,u8 date)
- {
- const u8 buff[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};//数字0~9及”-“”无”显示段码表
- //-- 0 1 2 3 4 5 6 7 8 9 - 无
- TM1640_start();
- TM1640_write(0xc0+address); //传显示数据对应的地址,0-15位数码管
- TM1640_write(buff[date]); //传1BYTE显示数据,对应显示buff[12]数组0-11
- TM1640_stop();
- }
- //**************************************tm1640函数*end***********************************
-
- /**************************************IIC函数************************************
- * 函数名: void I2C_delay(void)
- * 描述 : 短暂延时
- * 说明 : 内部定义的i可以优化速度,经测试最低到5还能写入
- ***************************************************************************/
- /*
- static void I2C_delay(void)
- {
- u8 i=5;
- while(i)
- {
- i--;
- }
- }
- */
- /**************************************************************************
- * 函数名: void I2C_Start(void)
- * 描述 : 起始信号
- ***************************************************************************/
- void I2C_Start(void)
- {
- SCL=1; Delay_us(5);
- SDA=1; Delay_us(5);
- SDA=0; Delay_us(5);
- SCL=0; Delay_us(5);
- }
- /**************************************************************************
- * 函数名: I2C_Stop(void)
- * 描述 : 终止信号
- ***************************************************************************/
- void I2C_Stop(void)
- {
- SDA=0; Delay_us(5);
- SCL=1; Delay_us(5);
- SDA=1; Delay_us(5);
- }
- /**************************************************************************
- * 函数名: void I2C_Ack(void)
- * 描述 : 应答信号
- ***************************************************************************/
- void I2C_Ack(void)
- {
- SCL=0; Delay_us(5);
- SDA=0; Delay_us(5);
- SCL=1; Delay_us(5);
- SCL=0; Delay_us(5);
- }
- /**************************************************************************
- * 函数名: void I2C_NoAck(void)
- * 描述 : 无应答信号
- ***************************************************************************/
- void I2C_NoAck(void)
- {
- SCL=0; Delay_us(5);
- SDA=1; Delay_us(5);
- SCL=1; Delay_us(5);
- SCL=0; Delay_us(5);
- }
- /**************************************************************************
- * 函数名: u8 I2C_WaitAck(void)
- * 描述 : 等待应答信号
- * 输出 : TRUE : 有应答 FALSE : 无应答
- ***************************************************************************/
- u8 I2C_WaitAck(void)
- {
- u8 ucErrTime=0;
- SCL=0; Delay_us(5);
- SDA=1; Delay_us(5);
- SCL=1; Delay_us(5);
- while(SDA_read)
- {
- ucErrTime++;
- if(ucErrTime>250)
- {
- I2C_Stop();
- return 0;
- }
- }
- SCL=0;
- return 1;
- }
- /**************************************************************************
- * 函数名: void I2C_SendByte(u8 SendByte)
- * 描述 : 发送一个字节
- * 输入 : SendByte : 字节数据 ,说明 : 数据从高位到低位
- ***************************************************************************/
- void I2C_SendByte(u8 SendByte)
- {
- u8 i=8;
- while(i--)
- {
- SCL=0;
- Delay_us(5);
-
- if(SendByte & 0x80)
- SDA=1;
- else
- SDA=0;
- SendByte<<=1;
- Delay_us(5);
-
- SCL=1;
- Delay_us(3);
- }
- SCL=0;
- }
- /**************************************************************************
- * 函数名: u8 I2C_ReceiveByte(void)
- * 描述 : 读取一个字节
- * 输出 : 字节数据
- * 说明 : ReceiveByte : 数据从高位到低位
- ***************************************************************************/
- u8 I2C_ReceiveByte(void)
- {
- u8 i=8;
- u8 ReceiveByte=0;
-
- SDA=1;
- while(i--)
- {
- ReceiveByte<<=1;
- SCL=0;
- Delay_us(5);
- SCL=1;
- Delay_us(5);
- if(SDA_read)
- {
- ReceiveByte|=0x01;
- }
- }
- SCL=0;
- return ReceiveByte;
- }
- //**************************IIC END*****************************************************************
- //****************ds3231函数*******************************************************************
- Calendar_OBJ calendar;
- //bcd转hex
- u8 BCD2HEX(u8 val)
- {
- u8 i;
- i= val&0x0f;
- val >>= 4;
- val &= 0x0f;
- val *= 10;
- i += val;
-
- return i;
- }
- u16 B_BCD(u8 val)
- {
- u8 i,j,k;
- i=val/10;
- j=val%10;
- k=j+(i<<4);
- return k;
- }
- void DS3231_WR_Byte(u8 addr,u8 bytedata)
- {
- I2C_Start();
- I2C_SendByte(DS3231_WriteAddress);
- I2C_WaitAck();
- I2C_SendByte(addr);
- I2C_WaitAck();
- I2C_SendByte(bytedata);
- I2C_WaitAck();
- I2C_Stop();
- }
- u8 DS3231_RD_Byte(u8 addr)
- {
- u8 Dat=0;
- I2C_Start();
- I2C_SendByte(DS3231_WriteAddress);
- I2C_WaitAck();
- I2C_SendByte(addr);
- I2C_WaitAck();
- I2C_Start();
- I2C_SendByte(DS3231_ReadAddress);
- I2C_WaitAck();
- Dat=I2C_ReceiveByte();
- I2C_Stop();
- return Dat;
- }
- //ds3231初始化函数
- void DS3231_Init(void)
- {
- //I2C_GPIO_Config();
- DS3231_WR_Byte(0x0e,0);
- DS3231_WR_Byte(0x0f,0x0);
- }
- //DS3231初始化设置函数( 年 月 日 时 分 秒 周)
- void Set_DS3231_Time(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec,u8 week)
- {
- u8 temp=0;
- temp=B_BCD(yea);
- DS3231_WR_Byte(0x06,temp);
- temp=B_BCD(mon);
- DS3231_WR_Byte(0x05,temp);
- temp=B_BCD(da);
- DS3231_WR_Byte(0x04,temp);
- temp=B_BCD(hou);
- DS3231_WR_Byte(0x02,temp);
- temp=B_BCD(min);
- DS3231_WR_Byte(0x01,temp);
- temp=B_BCD(sec);
- DS3231_WR_Byte(0x00,temp);
- temp=B_BCD(week);
- DS3231_WR_Byte(0x03,temp);
- }
- void Get_DS3231_Time(void)
- {
- calendar.w_year=DS3231_RD_Byte(0x06);
- calendar.w_year=BCD2HEX(calendar.w_year);
- calendar.w_month=DS3231_RD_Byte(0x05);
- calendar.w_month=BCD2HEX(calendar.w_month);
- calendar.w_date=DS3231_RD_Byte(0x04);
- calendar.w_date=BCD2HEX(calendar.w_date);
-
- calendar.hour=DS3231_RD_Byte(0x02);
- calendar.hour&=0x3f;
- calendar.hour=BCD2HEX(calendar.hour);
- calendar.min=DS3231_RD_Byte(0x01);
- calendar.min=BCD2HEX(calendar.min);
- calendar.sec=DS3231_RD_Byte(0x00);
- calendar.sec=BCD2HEX(calendar.sec);
- calendar.week=DS3231_RD_Byte(0x03);
- calendar.week=BCD2HEX(calendar.week);
- DS3231_WR_Byte(0x0e,0x20);
- calendar.temper_H=DS3231_RD_Byte(0x11);
- calendar.temper_L=(DS3231_RD_Byte(0x12)>>6)*25;
- }
- //****************ds3231函数*********end*******************************************************************
- int main(void)
- {
-
- //Set_DS3231_Time(22,03,24,09,53,00,4);//22年03月23号17点55分00秒周3 .第1次初始化DS3231使用后注销
- Delay_us(100);
- DS3231_Init();
- TM1640_Init(); //TM1640初始化
- while(1)
- {
- Get_DS3231_Time();
- {
- TM1640_display(0,calendar.hour/10); //第1个数码管显示时十位
- TM1640_display(1,calendar.hour%10); //第2个数码管显示时个位
- TM1640_display(2,10); //此位数码管显示"-"
- TM1640_display(3,calendar.min/10); //第4个数码管显示分十位
- TM1640_display(4,calendar.min%10); //第5个数码管显示分个位
- TM1640_display(5,10); //此位数码管显示"-"
- TM1640_display(6,calendar.sec/10); //第7个数码管显示秒十位
- TM1640_display(7,calendar.sec%10); //第8个数码管显示秒个位
- }
- }
- }
复制代码
Keil代码下载:
Keil代码.7z
(21.58 KB, 下载次数: 102)
|