51单片机-AT24C02-实行2-秒表实行(可参考上一节)

种地  论坛元老 | 2024-9-17 08:17:37 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1093|帖子 1093|积分 3279

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
利用定时器去对按键和数码管进行扫描(Whappy)
main.c
  1. #include <REGX52.H>
  2. #include "LCD1602.h"
  3. #include "AT24C02.h"
  4. #include "Delay.h"
  5. #include "Timer0.h"
  6. #include "Nixie.h"
  7. #include "Key.h"
  8. unsigned char KeyNum;
  9. unsigned char Min,Sec,MiniSec;
  10. unsigned char RunFlag;
  11. void main()
  12. {
  13.         Timer0_Init(); //初始化定时器
  14.        
  15.         while(1)
  16.         {
  17.                 KeyNum = Key();
  18.                
  19.                 if(KeyNum == 1)
  20.                 {
  21.                         RunFlag = !RunFlag;
  22.                 }
  23.                 Nixie_SetBuf(1,Min/10);
  24.                 Nixie_SetBuf(2,Min%10);
  25.                 Nixie_SetBuf(3,11);
  26.                 Nixie_SetBuf(4,Sec/10);
  27.                 Nixie_SetBuf(5,Sec%10);
  28.                 Nixie_SetBuf(6,11);
  29.                 Nixie_SetBuf(7,MiniSec/10);
  30.                 Nixie_SetBuf(8,MiniSec%10);
  31.                
  32.                                
  33.         }
  34.         Delay(1000);
  35. }
  36. void Sec_Loop(void)
  37. {
  38.         if(RunFlag)
  39.         {
  40.                 MiniSec++;
  41.                 if(MiniSec >= 100)
  42.                 {
  43.                         MiniSec = 0;
  44.                         Sec++;
  45.                         if(Sec >= 60)
  46.                         {
  47.                                 Sec = 0;
  48.                                 Min++;
  49.                                 if(Min >= 60)
  50.                                 {
  51.                                         Min = 0;
  52.                                 }
  53.                         }
  54.                 }
  55.                 }
  56.        
  57. }
  58. void Timer0_Rountine(void)  interrupt 1
  59. {
  60.         static unsigned int T0Count1,T0Count2,T0Count3;  //Timer0_Rountine(void) 函数结束之后T0Count保留其原来的值
  61.        
  62.         TL0 = 0x66;                //设置定时初值
  63.         TH0 = 0xFC;                //设置定时初值
  64.        
  65.         T0Count1++;
  66.         if(T0Count1 >= 20)
  67.         {
  68.                 T0Count1 = 0;
  69.                 Key_Loop();
  70.         }
  71.        
  72.         T0Count2++;
  73.         if(T0Count2 >= 2)
  74.         {
  75.                 T0Count2 = 0;
  76.                 Nixie_Loop();
  77.         }       
  78.        
  79.         T0Count3++;
  80.         if(T0Count3 >= 10)
  81.         {
  82.                 T0Count3 = 0;
  83.                 Sec_Loop();
  84.         }       
  85. }
复制代码
  1. #include <REGX52.H>
  2. #include "Timer0.h"
  3. #include "Key.h"
  4. #include "Nixie.h"
  5. #include "Delay.h"
  6. #include "AT24C02.h"
  7. unsigned char KeyNum;
  8. unsigned char Min,Sec,MiniSec;
  9. unsigned char RunFlag;
  10. void main()
  11. {
  12.         Timer0_Init();
  13.         while(1)
  14.         {
  15.                 KeyNum=Key();
  16.                 if(KeyNum==1)                        //K1按键按下
  17.                 {
  18.                         RunFlag=!RunFlag;        //启动标志位翻转
  19.                 }
  20.                 if(KeyNum==2)                        //K2按键按下
  21.                 {
  22.                         Min=0;                                //分秒清0
  23.                         Sec=0;
  24.                         MiniSec=0;
  25.                 }
  26.                 if(KeyNum==3)                        //K3按键按下
  27.                 {
  28.                         AT24C02_WriteByte(0,Min);        //将分秒写入AT24C02
  29.                         Delay(5);
  30.                         AT24C02_WriteByte(1,Sec);
  31.                         Delay(5);
  32.                         AT24C02_WriteByte(2,MiniSec);
  33.                         Delay(5);
  34.                 }
  35.                 if(KeyNum==4)                        //K4按键按下
  36.                 {
  37.                         Min=AT24C02_ReadByte(0);        //读出AT24C02数据
  38.                         Sec=AT24C02_ReadByte(1);
  39.                         MiniSec=AT24C02_ReadByte(2);
  40.                 }
  41.                 Nixie_SetBuf(1,Min/10);        //设置显示缓存,显示数据
  42.                 Nixie_SetBuf(2,Min%10);
  43.                 Nixie_SetBuf(3,11);
  44.                 Nixie_SetBuf(4,Sec/10);
  45.                 Nixie_SetBuf(5,Sec%10);
  46.                 Nixie_SetBuf(6,11);
  47.                 Nixie_SetBuf(7,MiniSec/10);
  48.                 Nixie_SetBuf(8,MiniSec%10);
  49.         }
  50. }
  51. /**
  52.   * @brief  秒表驱动函数,在中断中调用
  53.   * @param  无
  54.   * @retval 无
  55.   */
  56. void Sec_Loop(void)
  57. {
  58.         if(RunFlag)
  59.         {
  60.                 MiniSec++;
  61.                 if(MiniSec>=100)
  62.                 {
  63.                         MiniSec=0;
  64.                         Sec++;
  65.                         if(Sec>=60)
  66.                         {
  67.                                 Sec=0;
  68.                                 Min++;
  69.                                 if(Min>=60)
  70.                                 {
  71.                                         Min=0;
  72.                                 }
  73.                         }
  74.                 }
  75.         }
  76. }
  77. void Timer0_Routine() interrupt 1
  78. {
  79.         static unsigned int T0Count1,T0Count2,T0Count3;
  80.         TL0 = 0x18;                //设置定时初值
  81.         TH0 = 0xFC;                //设置定时初值
  82.         T0Count1++;
  83.         if(T0Count1>=20)
  84.         {
  85.                 T0Count1=0;
  86.                 Key_Loop();        //20ms调用一次按键驱动函数
  87.         }
  88.         T0Count2++;
  89.         if(T0Count2>=2)
  90.         {
  91.                 T0Count2=0;
  92.                 Nixie_Loop();//2ms调用一次数码管驱动函数
  93.         }
  94.         T0Count3++;
  95.         if(T0Count3>=10)
  96.         {
  97.                 T0Count3=0;
  98.                 Sec_Loop();        //10ms调用一次数秒表驱动函数
  99.         }
  100. }
复制代码
AT24C02.c
  1. #include <REGX52.H>
  2. #include "IIC.h"
  3. #define AT24C02_ADDRESS 0XA0 //1010 0000 前四位AT24C02地址不变,最后一位决定是写还是读 1:读,即接收 0:写,即发送
  4. //仿照帧格式去写(可参考上一节IIC时序介绍)
  5. //字节写:在WORD ADDRESS处写入数据DATA
  6. void AT24C02_WriteByte(unsigned char WordAddress,Data)
  7. {
  8.         IIC_Start();  //起始信号
  9.         IIC_SendByte(AT24C02_ADDRESS); //发送从机地址和写操作
  10.         IIC_ReceiveAck();  //接收应答位
  11.         IIC_SendByte(WordAddress); //字地址:指定在WORD ADDRESS处写入数据DATA
  12.         IIC_ReceiveAck();  //接收应答位
  13.         IIC_SendByte(Data); //写入数据到WordAddress中
  14.         IIC_ReceiveAck(); //接收应答位
  15.         IIC_Stop();//结束信号
  16.        
  17. }
  18. //Ack : 0:表示应答 1:表示非应答
  19. //随机读:读出在WORD ADDRESS处的数据DATA
  20. unsigned char AT24C02_ReadByte(unsigned char WordAddress)
  21. {
  22.         unsigned char Data;
  23.        
  24.         //写操作,就是先找到要通信的从机
  25.         IIC_Start();  //起始信号
  26.         IIC_SendByte(AT24C02_ADDRESS); //发送从机地址和写操作
  27.         IIC_ReceiveAck();  //接收应答位
  28.         IIC_SendByte(WordAddress); //字地址:指定在WORD ADDRESS处写入数据DATA
  29.         IIC_ReceiveAck();  //接收应答位
  30.        
  31.         //找到对应的从机之后,开始接收从机发过来的数据
  32.         IIC_Start();  //起始信号
  33.         IIC_SendByte(AT24C02_ADDRESS | 0X01); //发送从机地址和读操作
  34.         IIC_ReceiveAck();  //接收应答位
  35.         Data = IIC_ReceiveByte();  //接收一个字节的数据
  36.         IIC_SendAck(1);
  37.         IIC_Stop();//结束信号
  38.        
  39.        
  40.         return Data;
  41. }
复制代码

Nixie.c
  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. unsigned char Nixie_Buf[9] = {0,10,10,10,10,10,10,10,10}; //显示缓存区
  4. unsigned char NixieTable[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0X40};
  5. void Nixie_SetBuf(unsigned char Location,Number)
  6. {
  7.         Nixie_Buf[Location] = Number;
  8. }
  9. void Nixie_Scan(unsigned char Location,Number)
  10. {
  11.         P0 = 0X00;
  12.         switch(Location) //位选
  13.         {
  14.                 case 1: P2_4 = 1;P2_3 = 1; P2_2 = 1; break;
  15.                 case 2: P2_4 = 1;P2_3 = 1; P2_2 = 0; break;
  16.                 case 3: P2_4 = 1;P2_3 = 0; P2_2 = 1; break;
  17.                 case 4: P2_4 = 1;P2_3 = 0; P2_2 = 0; break;
  18.                 case 5: P2_4 = 0;P2_3 = 1; P2_2 = 1; break;
  19.                 case 6: P2_4 = 0;P2_3 = 1; P2_2 = 0; break;
  20.                 case 7: P2_4 = 0;P2_3 = 0; P2_2 = 1; break;
  21.                 case 8: P2_4 = 0;P2_3 = 0; P2_2 = 0; break;
  22.         }
  23.        
  24.         P0 = NixieTable[Number]; //段选
  25.        
  26.                
  27. }
  28. void Nixie_Loop(void)
  29. {
  30.         static unsigned char i = 1;
  31.         Nixie_Scan(i,Nixie_Buf[i]);
  32.         i++;
  33.         if(i >= 9) {i=1;}
  34. }
复制代码
  1. #include <REGX52.H>
  2. #include "Delay.h"
  3. //数码管显示缓存区
  4. unsigned char Nixie_Buf[9]={0,10,10,10,10,10,10,10,10};
  5. //数码管段码表
  6. unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x40};
  7. /**
  8.   * @brief  设置显示缓存区
  9.   * @param  Location 要设置的位置,范围:1~8
  10.   * @param  Number 要设置的数字,范围:段码表索引范围
  11.   * @retval 无
  12.   */
  13. void Nixie_SetBuf(unsigned char Location,Number)
  14. {
  15.         Nixie_Buf[Location]=Number;
  16. }
  17. /**
  18.   * @brief  数码管扫描显示
  19.   * @param  Location 要显示的位置,范围:1~8
  20.   * @param  Number 要显示的数字,范围:段码表索引范围
  21.   * @retval 无
  22.   */
  23. void Nixie_Scan(unsigned char Location,Number)
  24. {
  25.         P0=0x00;                                //段码清0,消影
  26.         switch(Location)                //位码输出
  27.         {
  28.                 case 1:P2_4=1;P2_3=1;P2_2=1;break;
  29.                 case 2:P2_4=1;P2_3=1;P2_2=0;break;
  30.                 case 3:P2_4=1;P2_3=0;P2_2=1;break;
  31.                 case 4:P2_4=1;P2_3=0;P2_2=0;break;
  32.                 case 5:P2_4=0;P2_3=1;P2_2=1;break;
  33.                 case 6:P2_4=0;P2_3=1;P2_2=0;break;
  34.                 case 7:P2_4=0;P2_3=0;P2_2=1;break;
  35.                 case 8:P2_4=0;P2_3=0;P2_2=0;break;
  36.         }
  37.         P0=NixieTable[Number];        //段码输出
  38. }
  39. /**
  40.   * @brief  数码管驱动函数,在中断中调用
  41.   * @param  无
  42.   * @retval 无
  43.   */
  44. void Nixie_Loop(void)
  45. {
  46.         static unsigned char i=1;
  47.         Nixie_Scan(i,Nixie_Buf[i]);
  48.         i++;
  49.         if(i>=9){i=1;}
  50. }
复制代码

Timer.c
  1. #include <REGX52.H>
  2. //由软件配置的定时器STC-ISP
  3. /**
  4. * @brief 定时器初始化(51单片机软件内置配置的定时器)
  5.   * @param 无
  6.   * @retval 无
  7.   */
  8. void Timer0_Init()                //1毫秒@11.0592MHz
  9. {
  10.        
  11.         TMOD &= 0xF0;                //设置定时器模式
  12.         TMOD |= 0x01;                //设置定时器模式
  13.         TL0 = 0x66;                //设置定时初值
  14.         TH0 = 0xFC;                //设置定时初值
  15.         TF0 = 0;                //清除TF0标志
  16.         TR0 = 1;                //定时器0开始计时
  17.        
  18.         //打开定时器中断
  19.         ET0  = 1;
  20.         EA = 1;
  21.         PT0 = 0;
  22. }
  23. //void Timer0_Init()
  24. //{
  25. //        /*
  26. //        采用与或式赋值法,可以把不可寻址的位进行寻址,改变其中几位而不影响其他位
  27. //        TMOD = TMOD & 0XF0; //低四位清零,高四位置一
  28. //        TMOD = TMOD | 0X01;//把TMOD的最低位置1,高四位保持不变
  29. //        如上,改变低四位而不改变高四位
  30. //       
  31. //        */
  32. //        //TMOD = 0x01;  //工作模式寄存器
  33. //        TMOD = TMOD & 0XF0; //低四位清零,高四位置一
  34. //        TMOD = TMOD | 0X01;//把TMOD的最低位置1,高四位保持不变
  35. //        //控制寄存器
  36. //        TF0  = 0;
  37. //        TR0 = 1;
  38. //       
  39. //        /*定时器赋初值  定时1ms,12Mhz的晶振,1us产生一个计数脉冲,
  40. //        而16位的计数器是0~65535个可能,也就是65536us,65536个脉冲
  41. //        如何差生一微秒(1ms=1000us)那么从64535开始记到65535产生一个中断
  42. //        通过配置TL0和TH0控制处置也就是把64535变成16进制TL0是低八位两个十六进制,TH0是高八位的两十六进制*/
  43. //       
  44. //        TL0  = 64535%56;
  45. //        TH0  = 64535/256;
  46. //       
  47. //        ET0  = 1;
  48. //        EA = 1;
  49. //        PT0 = 0;
  50. //       
  51. //}
  52. /*定时器中断函数模板
  53. void Timer0_Rountine(void)  interrupt 1
  54. {
  55.         static unsigned int T0Count ;  //Timer0_Rountine(void) 函数结束之后T0Count保留其原来的值
  56.        
  57.         TL0 = 0x66;                //设置定时初值
  58.         TH0 = 0xFC;                //设置定时初值
  59.        
  60.         T0Count++;
  61.         if(T0Count >= 1000)
  62.         {
  63.                 T0Count = 0;
  64.                 P2_0 = ~P2_0;
  65.         }       
  66. }
  67. */
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

种地

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表