找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2641|回复: 3
收起左侧

基于STC12C5604AD+TM1640+DS3231数码管时钟程序

[复制链接]
ID:39072 发表于 2022-3-24 10:13 | 显示全部楼层 |阅读模式
IMG_20220324_101047.jpg

单片机源程序如下:
  1. #include<reg52.h>
  2. #include<intrins.h>

  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. #define u8  uint8_t
  6. #define u16 uint16_t
  7. #define u32 uint32_t
  8. typedef unsigned char    uint8_t;
  9. typedef unsigned short   uint16_t;
  10. typedef unsigned long    uint32_t;
  11. #define DS3231_WriteAddress                0xD0   
  12. #define DS3231_ReadAddress                0xD1
  13. #define Delay(us) {_nop_();_nop_();_nop_();_nop_();}
  14. typedef struct
  15. {
  16.         u8        hour;
  17.         u8        min;
  18.         u8        sec;                       
  19.         u32 w_year;
  20.         u8  w_month;
  21.         u8  w_date;
  22.         u8  week;               
  23.         u8        temper_H;
  24.         u8        temper_L;
  25. }Calendar_OBJ;
  26. extern Calendar_OBJ calendar;        //日历结构体
  27. extern u8 const mon_table[12];        //月份日期数据表
  28. //*******GPIO 定义********************************************************
  29. sbit TM1640_DIN=P1^3; //TM1640数据线
  30. sbit TM1640_SCLK=P1^4; //TM1640时钟线
  31. sbit SDA=P3^3; //IIC数据线
  32. sbit SCL=P3^4; //IIC时钟线
  33. sbit SDA_read=P3^3;
  34. sbit SCL_read=P3^4;
  35. //************************************************************************************************
  36. #define TM1640MEDO_ADD  0x44         //地址模式的设置0x40自动加一模式 0x44固定地址模式
  37. #define TM1640MEDO_DISPLAY  0x8C     //设置亮度小:0x88 0x89 0x8a 0x8b 0x8c 0x8d 0x8f最大0x80关闭
  38. #define TM1640MEDO_DISPLAY_OFF  0x80  //宏定义 关亮度设置
  39. //**************************************************************************************************
  40. //功能:延时1毫秒 ,入口参数:x  ,说明:当晶振为12M时,j<112;当晶振为11.0592M时,j<122*/
  41. //***************************************************************************************************
  42. void Delay_xms(uint x)
  43. {
  44.   uint i,j;
  45.   for(i=0;i<x;i++)
  46.     for(j=0;j<112;j++);
  47. }
  48. //功能:12us延时,STC89C52为1T单片机,即1个时钟/机器周期,速度为AT89C52的12倍
  49. void Delay_us(uint t)                                          
  50. {
  51.   for(;t>0;t--)
  52.    {
  53.          _nop_();
  54.    }
  55. }

  56. //*********TM1640驱动函数  START***************
  57. //功能:12us延时
  58. //***************************************************************************************
  59. //通信时序 启始
  60. void TM1640_start()
  61.         {
  62.         TM1640_DIN=1;
  63.         TM1640_SCLK=1;
  64.         Delay_us(1);
  65.         TM1640_DIN=0;
  66.         Delay_us(1);
  67.         TM1640_SCLK=0;
  68.         Delay_us(1);
  69. }
  70. //通信时序 结束       
  71. void TM1640_stop()
  72.         {
  73.         TM1640_DIN=0;
  74.         TM1640_SCLK=1;
  75.         Delay_us(1);
  76.         TM1640_DIN=1;
  77.         Delay_us(1);
  78. }
  79. //写数据       
  80. void TM1640_write(u8 date)
  81.         {       
  82.         u8 i;
  83.         u8 aa;
  84.         aa=date;
  85.         TM1640_DIN=0;
  86.         TM1640_SCLK=0;
  87.         for(i=0;i<8;i++){
  88.                 TM1640_SCLK=0;
  89.                 Delay_us(1);
  90.                 if(aa&0x01){
  91.                         TM1640_DIN=1;
  92.                         Delay_us(1);
  93.                 }else{
  94.                         TM1640_DIN=0;
  95.                         Delay_us(1);
  96.                 }
  97.                 TM1640_SCLK=1;
  98.                 Delay_us(1);
  99.                 aa=aa>>1;
  100.    }
  101.          TM1640_DIN=0;
  102.          TM1640_SCLK=0;
  103. }
  104. //TM1640接口初始化函数//TM1640设置
  105. void TM1640_Init(void)
  106.         {   
  107.           TM1640_start();
  108.           TM1640_write(TM1640MEDO_ADD); //设置工作模式
  109.           TM1640_stop();
  110.           TM1640_start();
  111.           TM1640_write(TM1640MEDO_DISPLAY);//设置显示亮度
  112.           TM1640_stop();                                       
  113. }
  114. //固定地址模式的显示输出函数
  115. void TM1640_display(u8 address,u8 date)
  116.         {
  117.         const u8 buff[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x00};//数字0~9及”-“”无”显示段码表
  118.                  //--   0    1    2    3    4    5    6    7    8    9     -   无   
  119.    TM1640_start();
  120.    TM1640_write(0xc0+address);             //传显示数据对应的地址,0-15位数码管
  121.    TM1640_write(buff[date]);                                 //传1BYTE显示数据,对应显示buff[12]数组0-11
  122.    TM1640_stop();
  123. }
  124. //**************************************tm1640函数*end***********************************
  125.   
  126. /**************************************IIC函数************************************  
  127. * 函数名: void I2C_delay(void)
  128. * 描述  : 短暂延时
  129. * 说明  : 内部定义的i可以优化速度,经测试最低到5还能写入
  130. ***************************************************************************/
  131. /*
  132. static void I2C_delay(void)  
  133. {     
  134.     u8 i=5;   
  135.     while(i)   
  136.     {   
  137.         i--;   
  138.     }   
  139. }
  140. */

  141. /**************************************************************************
  142. * 函数名: void I2C_Start(void)
  143. * 描述  : 起始信号
  144. ***************************************************************************/
  145. void I2C_Start(void)
  146. {
  147.         SCL=1;        Delay_us(5);
  148.         SDA=1;        Delay_us(5);
  149.         SDA=0;        Delay_us(5);
  150.         SCL=0;        Delay_us(5);
  151. }
  152. /**************************************************************************
  153. * 函数名: I2C_Stop(void)
  154. * 描述  : 终止信号
  155. ***************************************************************************/
  156. void I2C_Stop(void)
  157. {
  158.         SDA=0;        Delay_us(5);
  159.         SCL=1;        Delay_us(5);
  160.         SDA=1;        Delay_us(5);
  161. }
  162. /**************************************************************************
  163. * 函数名: void I2C_Ack(void)
  164. * 描述  : 应答信号
  165. ***************************************************************************/
  166. void I2C_Ack(void)  
  167. {     
  168.     SCL=0;  Delay_us(5);
  169.     SDA=0;  Delay_us(5);  
  170.     SCL=1;  Delay_us(5);
  171.     SCL=0;  Delay_us(5);
  172. }
  173. /**************************************************************************
  174. * 函数名: void I2C_NoAck(void)
  175. * 描述  : 无应答信号
  176. ***************************************************************************/
  177. void I2C_NoAck(void)  
  178. {     
  179.     SCL=0;  Delay_us(5);  
  180.     SDA=1;  Delay_us(5);  
  181.     SCL=1;  Delay_us(5);  
  182.     SCL=0;  Delay_us(5);
  183. }  
  184. /**************************************************************************
  185. * 函数名: u8 I2C_WaitAck(void)
  186. * 描述  : 等待应答信号
  187. * 输出  : TRUE : 有应答  FALSE : 无应答
  188. ***************************************************************************/
  189. u8 I2C_WaitAck(void)     
  190. {  
  191.         u8 ucErrTime=0;
  192.     SCL=0;  Delay_us(5);
  193.     SDA=1;  Delay_us(5);  
  194.     SCL=1;  Delay_us(5);  
  195.     while(SDA_read)  
  196.     {  
  197.         ucErrTime++;
  198.                 if(ucErrTime>250)
  199.                 {
  200.                         I2C_Stop();
  201.                         return 0;
  202.                 }
  203.     }  
  204.     SCL=0;  
  205.     return 1;  
  206. }  
  207. /**************************************************************************  
  208. * 函数名: void I2C_SendByte(u8 SendByte)  
  209. * 描述  : 发送一个字节
  210. * 输入  : SendByte : 字节数据 ,说明 : 数据从高位到低位
  211. ***************************************************************************/
  212. void I2C_SendByte(u8 SendByte)   
  213. {  
  214.     u8 i=8;  
  215.     while(i--)  
  216.     {  
  217.         SCL=0;  
  218.         Delay_us(5);
  219.                
  220.         if(SendByte & 0x80)  
  221.             SDA=1;   
  222.         else  
  223.             SDA=0;     
  224.         SendByte<<=1;  
  225.         Delay_us(5);
  226.                
  227.         SCL=1;  
  228.         Delay_us(3);  
  229.     }  
  230.     SCL=0;  
  231. }
  232. /**************************************************************************
  233. * 函数名: u8 I2C_ReceiveByte(void)  
  234. * 描述  : 读取一个字节
  235. * 输出  : 字节数据
  236. * 说明  : ReceiveByte : 数据从高位到低位
  237. ***************************************************************************/
  238. u8 I2C_ReceiveByte(void)   
  239. {   
  240.     u8 i=8;  
  241.     u8 ReceiveByte=0;  
  242.            
  243.     SDA=1;               
  244.     while(i--)  
  245.     {  
  246.         ReceiveByte<<=1;        
  247.         SCL=0;  
  248.         Delay_us(5);
  249.         SCL=1;
  250.         Delay_us(5);     
  251.         if(SDA_read)  
  252.         {  
  253.             ReceiveByte|=0x01;  
  254.         }  
  255.     }  
  256.     SCL=0;  
  257.     return ReceiveByte;  
  258. }
  259. //**************************IIC END*****************************************************************

  260. //****************ds3231函数*******************************************************************
  261. Calendar_OBJ calendar;
  262. //bcd转hex
  263. u8 BCD2HEX(u8 val)
  264. {
  265.     u8 i;
  266.     i= val&0x0f;
  267.     val >>= 4;
  268.     val &= 0x0f;
  269.     val *= 10;
  270.     i += val;
  271.    
  272.     return i;
  273. }

  274. u16 B_BCD(u8 val)
  275. {
  276.         u8 i,j,k;
  277.         i=val/10;
  278.         j=val%10;
  279.         k=j+(i<<4);
  280.         return k;
  281. }

  282. void DS3231_WR_Byte(u8 addr,u8 bytedata)
  283. {
  284.         I2C_Start();
  285.         I2C_SendByte(DS3231_WriteAddress);
  286.         I2C_WaitAck();
  287.         I2C_SendByte(addr);
  288.         I2C_WaitAck();
  289.         I2C_SendByte(bytedata);
  290.         I2C_WaitAck();
  291.         I2C_Stop();
  292. }       

  293. u8 DS3231_RD_Byte(u8 addr)
  294. {
  295.         u8 Dat=0;
  296.           I2C_Start();
  297.         I2C_SendByte(DS3231_WriteAddress);
  298.         I2C_WaitAck();
  299.         I2C_SendByte(addr);
  300.         I2C_WaitAck();
  301.         I2C_Start();
  302.         I2C_SendByte(DS3231_ReadAddress);
  303.         I2C_WaitAck();
  304.         Dat=I2C_ReceiveByte();
  305.         I2C_Stop();
  306.         return Dat;
  307. }
  308. //ds3231初始化函数
  309. void DS3231_Init(void)
  310. {
  311.         //I2C_GPIO_Config();
  312.         DS3231_WR_Byte(0x0e,0);
  313.     DS3231_WR_Byte(0x0f,0x0);
  314. }

  315. //DS3231初始化设置函数( 年 月 日 时 分 秒 周)
  316. void Set_DS3231_Time(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec,u8 week)
  317. {
  318.         u8 temp=0;
  319.           temp=B_BCD(yea);
  320.         DS3231_WR_Byte(0x06,temp);  
  321.         temp=B_BCD(mon);
  322.         DS3231_WR_Byte(0x05,temp);  
  323.         temp=B_BCD(da);
  324.         DS3231_WR_Byte(0x04,temp);
  325.         temp=B_BCD(hou);
  326.         DS3231_WR_Byte(0x02,temp);
  327.         temp=B_BCD(min);
  328.         DS3231_WR_Byte(0x01,temp);  
  329.         temp=B_BCD(sec);
  330.         DS3231_WR_Byte(0x00,temp);
  331.         temp=B_BCD(week);
  332.         DS3231_WR_Byte(0x03,temp);
  333. }
  334. void Get_DS3231_Time(void)
  335. {
  336.         calendar.w_year=DS3231_RD_Byte(0x06);  
  337.         calendar.w_year=BCD2HEX(calendar.w_year);
  338.         calendar.w_month=DS3231_RD_Byte(0x05);
  339.         calendar.w_month=BCD2HEX(calendar.w_month);
  340.         calendar.w_date=DS3231_RD_Byte(0x04);  
  341.         calendar.w_date=BCD2HEX(calendar.w_date);
  342.          
  343.         calendar.hour=DS3231_RD_Byte(0x02);
  344.         calendar.hour&=0x3f;                  
  345.         calendar.hour=BCD2HEX(calendar.hour);
  346.         calendar.min=DS3231_RD_Byte(0x01);
  347.         calendar.min=BCD2HEX(calendar.min);
  348.         calendar.sec=DS3231_RD_Byte(0x00);
  349.         calendar.sec=BCD2HEX(calendar.sec);

  350.         calendar.week=DS3231_RD_Byte(0x03);
  351.         calendar.week=BCD2HEX(calendar.week);       
  352.         DS3231_WR_Byte(0x0e,0x20);
  353.         calendar.temper_H=DS3231_RD_Byte(0x11);
  354.         calendar.temper_L=(DS3231_RD_Byte(0x12)>>6)*25;
  355. }
  356. //****************ds3231函数*********end*******************************************************************

  357. int main(void)
  358. {       
  359.        
  360.     //Set_DS3231_Time(22,03,24,09,53,00,4);//22年03月23号17点55分00秒周3 .第1次初始化DS3231使用后注销  
  361.         Delay_us(100);
  362.         DS3231_Init();
  363.         TM1640_Init(); //TM1640初始化       
  364.         while(1)
  365.         {
  366.                 Get_DS3231_Time();
  367.                 {                       
  368.                         TM1640_display(0,calendar.hour/10);        //第1个数码管显示时十位
  369.                         TM1640_display(1,calendar.hour%10);        //第2个数码管显示时个位
  370.                         TM1640_display(2,10); //此位数码管显示"-"
  371.                         TM1640_display(3,calendar.min/10);  //第4个数码管显示分十位                               
  372.                         TM1640_display(4,calendar.min%10);  //第5个数码管显示分个位
  373.                         TM1640_display(5,10); //此位数码管显示"-"
  374.                         TM1640_display(6,calendar.sec/10);        //第7个数码管显示秒十位
  375.                         TM1640_display(7,calendar.sec%10);  //第8个数码管显示秒个位       
  376.                 }
  377.         }
  378. }       
复制代码
51hei.png
Keil代码下载: Keil代码.7z (21.58 KB, 下载次数: 80)

评分

参与人数 1黑币 +50 收起 理由
admin + 50

查看全部评分

回复

使用道具 举报

ID:334781 发表于 2022-12-19 14:02 | 显示全部楼层
TM1640这款芯片,用着还可以,用STC单片机驱动的程序是我想要的,谢谢楼主
回复

使用道具 举报

ID:894868 发表于 2023-2-10 15:36 | 显示全部楼层
我都是为了学习一下驱动显示而来··谢谢分享··
回复

使用道具 举报

ID:1112603 发表于 2024-4-16 08:18 | 显示全部楼层
51单片机TM1640驱动数码管,正是我需要的,谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表