[51单片机] 毕业季回眸——没有开发板的51学习

[复制链接]
 楼主| lihui567 发表于 2017-7-7 23:33 | 显示全部楼层 |阅读模式
   回想起上大学,感觉自己后悔莫及啊,那个时候没有自己的职业规划,晕晕乎乎就上完了,感觉啥也没学,记得上学时连c语言都没学,学的VB和汇编,当时老师让用汇编写的一个跑马灯,自己把电路板焊接完了,程序不会写,去网上找程序,抄抄完事,啥也没想,结果毕业后啥也不会,到处碰壁,况且用c语言编程自己一点也不懂
    毕业后几个月内自己决定学习C语言,学习单片机编程,真的后悔当初没在学校买个开发板学习编程,没有基础一点一点啃吧,学习也没人教,只能一个人慢慢的去网上找资料,遇到问题问度娘,有时候笨的实在找不到问题,就加了个STC单片机的群,当时学习的单片机STC89C52  ,stc12c5A60S2,那个时候非常感谢群主的解答,慢慢的懂了点程序,也不舍得买开发板,就自己 焊接一个
这是一个电子时钟电路,其实这个板子都改过好几次了,从开始点亮LED,到流水灯、串口通讯,按键,595驱动数码管,最终才变成现在的样子,那个小板当时有245芯片,没有适合的板子焊接,就找了个引脚不一样板子焊接上了,线一条一条焊接到引脚上去,怕调试时线掉就用胶带缠住了,大板子上用的373驱动,电子时钟带掉电**,但是也是为了学习eeprom,把这段程序加上了,能把程序调通,还的真的感谢当时有个版主不厌其烦的解答。虽说没见过面但是真心感谢您,

本帖子中包含更多资源

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

×
 楼主| lihui567 发表于 2017-7-7 23:40 | 显示全部楼层
这是简化的额原理图

本帖子中包含更多资源

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

×
巧克力娃娃 发表于 2017-7-10 17:08 | 显示全部楼层
那个版主是谁呀,哈哈哈,
 楼主| lihui567 发表于 2017-7-11 08:17 | 显示全部楼层
巧克力娃娃,哈哈
 楼主| lihui567 发表于 2017-7-11 08:26 | 显示全部楼层
我真正来咱论坛才两年了,我毕业都好几年了,那个时候就对硬件电路熟悉,c语言就是从零学起
JY-DX-JY 发表于 2017-7-11 15:44 | 显示全部楼层
顶版主
 楼主| lihui567 发表于 2017-7-11 16:24 | 显示全部楼层

程序这块还的向您学习啊,特别是linux这块
JY-DX-JY 发表于 2017-7-12 17:01 | 显示全部楼层
lihui567 发表于 2017-7-11 16:24
程序这块还的向您学习啊,特别是linux这块

我linux不行
 楼主| lihui567 发表于 2017-7-12 17:55 | 显示全部楼层
学内核移植,stm32方面的问题等等
 楼主| lihui567 发表于 2017-7-16 21:39 | 显示全部楼层
  1. #include <STC12C5A60S2.h>
  2. #include <intrins.h>

  3. //宏定义,11.0592M晶振
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define ulong unsigned long
  7. //位定义
  8. sbit a1=P0^0;// 秒按键
  9. sbit a2=P0^1;//分按键
  10. sbit a3=P0^2;//时按键
  11. //数码管显示数组
  12. uchar code xianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
  13.         0x80,0x90};//共阳数码管0到9显示BCD码
  14. //变量声明
  15. bit Time_FLAG=0;//定义一个时间间隔标志,用来控制写EEPROM间隔时间
  16. bit Yanshi_FLAG=0;
  17. uchar Sec;//秒计数定义并初始化变量
  18. uchar Min;//分计数
  19. uchar Hour;//时计数

  20. uchar m=0;//中断计数
  21. uchar cnt=0;
  22. //定义IAP/ISP/EEPROM命令
  23. #define CMD_IDLE    0               //空闲模式
  24. #define CMD_READ    1             //IAP字节读命令
  25. #define CMD_PROGRAM 2         //IAP字节编程命令
  26. #define CMD_ERASE   3             //IAP扇区擦除命令

  27. #define ENABLE_IAP  0x82        //if SYSCLK<20MHz

  28. #define IAP_ADDRESS 0x0000           //定义EEPROM地址
  29. void delay(uint k);//延时函数
  30. void timechuli();//时间处理函数
  31. void anjian();//按键扫描函数
  32. void timexianshi();//时间显示函数

  33. void IapIdle();
  34. uchar IapReadunsigned_char(uint addr);
  35. void IapProgramunsigned_char(uint addr, uchar dat);
  36. void IapEraseSector(uint addr);
  37. void Write_EEPROM();
  38. //----------------------------
  39. //关闭IAP,初始化函数
  40. //---------------------------*/
  41. void IapIdle()
  42. {
  43.         IAP_CONTR = 0;                  //关闭IAP功能
  44.         IAP_CMD         = 0;              //清除命令寄存器
  45.         IAP_TRIG         = 0;              //清除触发寄存器
  46.         IAP_ADDRH = 0x80;            //将地址设置到非IAP区域
  47.         IAP_ADDRL = 0;
  48. }

  49. //---------------------------
  50. //从ISP/IAP/EEPROM区域读取一字节
  51. //---------------------------
  52. uchar IapReadunsigned_char(uint addr)
  53. {
  54.         uchar dat;                       //数据缓冲区

  55.         IAP_CONTR = ENABLE_IAP;         //使能IAP
  56.         IAP_CMD         = CMD_READ;      //设置IAP命令
  57.         IAP_ADDRL = addr;               //设置IAP低地址
  58.         IAP_ADDRH = addr >> 8;          //设置IAP高地址
  59.         IAP_TRIG         = 0x5a;               //写触发命令(0x5a)
  60.         IAP_TRIG         = 0xa5;               //写触发命令(0xa5)
  61.         _nop_();                        //等待ISP/IAP/EEPROM操作完成
  62.         dat = IAP_DATA;                 //读ISP/IAP/EEPROM数据
  63.         IapIdle();                      //关闭IAP功能
  64.         return dat;                     //返回
  65. }

  66. //----------------------------
  67. //写一字节数据到ISP/IAP/EEPROM区域
  68. //----------------------------
  69. void IapProgramunsigned_char(uint addr, uchar dat)
  70. {
  71.         IAP_CONTR = ENABLE_IAP;         //使能IAP
  72.         IAP_CMD         = CMD_PROGRAM;        //设置IAP命令
  73.         IAP_ADDRL = addr;               //设置IAP低地址
  74.         IAP_ADDRH = addr >> 8;          //设置IAP高地址
  75.         IAP_DATA         = dat;                //写ISP/IAP/EEPROM数据
  76.         IAP_TRIG         = 0x5a;               //写触发命令(0x5a)
  77.         IAP_TRIG         = 0xa5;               //写触发命令(0xa5)
  78.         _nop_();                        //等待ISP/IAP/EEPROM操作完成
  79.         IapIdle();
  80. }

  81. //----------------------------
  82. //扇区擦除
  83. //---------------------------
  84. void IapEraseSector(uint addr)
  85. {
  86.         IAP_CONTR = ENABLE_IAP;         //使能IAP
  87.         IAP_CMD         = CMD_ERASE;          //设置IAP命令
  88.         IAP_ADDRL = addr;               //设置IAP低地址
  89.         IAP_ADDRH = addr >> 8;          //设置IAP高地址
  90.         IAP_TRIG         = 0x5a;               //写触发命令(0x5a)
  91.         IAP_TRIG         = 0xa5;               //写触发命令(0xa5)
  92.         _nop_();                        //等待ISP/IAP/EEPROM操作完成
  93.         IapIdle();
  94. }


  95. void Write_EEPROM()//将数据写入EEPROM
  96. {
  97.         IapEraseSector(IAP_ADDRESS);   //扇区擦除
  98.         delay(2);                   //延时
  99.         IapProgramunsigned_char(IAP_ADDRESS,Hour);//写入时
  100.         delay(2);                   //延时
  101.         IapProgramunsigned_char(IAP_ADDRESS+1,Min);//写入分
  102.         delay(2);                   //延时
  103.         IapProgramunsigned_char(IAP_ADDRESS+2,Sec); //写入秒
  104.         
  105.                                 
  106. }
  107. void delay(uint k)
  108. {
  109.         uchar i;
  110.         while((k--)!=0)
  111.         {
  112.         for(i=0;i<100;i++);
  113.        
  114.         }
  115. }
  116. void timechuli()
  117. {
  118.         if(Sec==60)
  119.         {
  120.                 Sec=0;
  121.                 Min++;
  122.                 if(Min==60)
  123.                 {
  124.                         Min=0;
  125.                         Hour++;
  126.                         if(Hour==24)
  127.                         {Hour=0;}
  128.                        
  129.                 }
  130.         }
  131. }
  132. void delay123(uchar w)
  133. {
  134.         uchar n;
  135.         for(n=0;n<w;n++)
  136.         {
  137.                 timexianshi();
  138.   }
  139. }
  140.                
  141. void anjian()
  142. {
  143.         if(a1==0)
  144.         {
  145.                 delay(500);//按键消抖  怎么改成显示的程序
  146.                 if(a1==0)
  147.                 {
  148.                 Sec++;
  149.                         if(Sec==60)
  150.                         {
  151.                                 Sec=0;
  152.                                 Min++;
  153.                         }
  154.         }
  155. }
  156.         if(a2==0)
  157.         {
  158.                 delay(500);
  159.                 if(a2==0)
  160.                 {
  161.                         P1=(xianshi[Min%10])|0x80;//显示分的个位
  162.                 P2=0x08;
  163.                 delay(5);
  164.                
  165.                
  166.                 P1=xianshi[Min/10];//显示分的十位
  167.                 P2=0x10;
  168.                 delay(5);
  169.                         Min++;
  170.                         if(Min==60)
  171.                         {
  172.                                 Min=0;
  173.                                 Hour++;
  174.                         }
  175.         }
  176. }
  177.         if(a3==0)
  178.         {
  179.                 delay(500);
  180.                 if(a3==0)
  181.                 {
  182.                         Hour++;
  183.                         if(Hour==24)
  184.                         {
  185.                                 Hour=0;
  186.                         }
  187.                 }
  188.         }
  189. }
  190.         void timexianshi()         //P2口位选 P1口段选                       
  191.         {
  192.                 P1=xianshi[Sec%10];//显示秒的个位
  193.                 P2=0x01;
  194.                 delay(5);
  195.                
  196.                
  197.                 P1=xianshi[Sec/10];//显示秒的十位
  198.                 P2=0x02;
  199.                 delay(5);
  200.                
  201.                
  202.                 P1=(xianshi[Min%10])|0x80;//显示分的个位
  203.                 P2=0x08;
  204.                 delay(5);
  205.                
  206.                
  207.                 P1=xianshi[Min/10];//显示分的十位
  208.                 P2=0x10;
  209.                 delay(5);
  210.                
  211.                
  212.                
  213.                 P1=(xianshi[Hour%10])|0x80;//显示时的个位
  214.                 P2=0x40;
  215.                 delay(5);
  216.                
  217.                
  218.                
  219.                 P1=xianshi[Hour/10];//显示时的个位
  220.                 P2=0x80;
  221.                 delay(5);
  222.                
  223.         }
  224.         void timer0() interrupt 1
  225.         {
  226.                 TH0=(65536-45872)/256;         //放入初值,11.0592M,50ms
  227.           TL0=(65536-45872)%256;
  228.                 m++;
  229.                
  230.                 if(m==20)
  231.                 {
  232.                         m=0;
  233.                         Sec++;
  234.       cnt++;
  235.                        
  236.                         if(cnt==5)
  237.                         {
  238.                                 Time_FLAG = 1;
  239.                         cnt=0;
  240.                         }
  241.                 }
  242.         }
  243.         void main()
  244.         {
  245.                 P0=0xff;
  246.                 P2=0;
  247.                
  248.         AUXR &= 0x7F;                //定时器时钟12T模式
  249.         TMOD &= 0xF0;                //设置定时器模式
  250.         TMOD |= 0x01;                //设置定时器模式
  251.         TH0=(65536-45872)/256;         //放入初值,11.0592M,50ms
  252.         TL0=(65536-45872)%256;
  253.         TF0 = 0;                //清除TF0标志
  254.         TR0 = 1;                //定时器0开始计时
  255.         EA=1;                //开总中断
  256.         EX0=1;
  257.         ET0=1;                        //开定时器0中断
  258.                 //从EEPROM读取时间信息
  259.                     Hour        = IapReadunsigned_char(IAP_ADDRESS);  //小时
  260.                 delay(2);
  261.         Min        = IapReadunsigned_char(IAP_ADDRESS+1); //分钟
  262.                 delay(2);
  263.         Sec        = IapReadunsigned_char(IAP_ADDRESS+2); //秒钟
  264.                 delay(2);
  265.        
  266.                         while(1)
  267.                         {
  268.                         timexianshi();//时间显示函数
  269.                         anjian();//按键扫描函数
  270.                         timechuli();//时间处理函数
  271.                                
  272.                                 //每隔一段时间,将Time_FLAG置1,写一次EEPROM,这个时间看你自己需求了
  273.                                        
  274.                                 if(Time_FLAG==1)
  275.                 {
  276.                         Write_EEPROM();//写EEPROM
  277.                         Time_FLAG = 0; //写完EEPROM将Time_FLAG标志清0
  278.                                                                 }
  279.                        
  280.                         }
  281.                 }
  282.                                 这是完整的一个电子时钟,带eeprom一个程序


cvgjhuor 发表于 2017-9-9 22:13 | 显示全部楼层
人人为我我为人人
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:您的嵌入式应用将得益于意法半导体领先的产品架构、技术、多源产地和全方位支持。意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。

54

主题

3745

帖子

20

粉丝
快速回复 在线客服 返回列表 返回顶部
认证:意法半导体(中国)投资有限公司
简介:您的嵌入式应用将得益于意法半导体领先的产品架构、技术、多源产地和全方位支持。意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器。

54

主题

3745

帖子

20

粉丝
快速回复 在线客服 返回列表 返回顶部