[51单片机]

毕业季回眸——没有开发板的51学习

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

电子时钟.rar

58.48 KB

相关帖子

lihui567|  楼主 | 2017-7-7 23:40 | 显示全部楼层
这是简化的额原理图 学2.png

使用特权

评论回复
巧克力娃娃| | 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 | 显示全部楼层
#include <STC12C5A60S2.h>
#include <intrins.h>

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

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

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

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

void IapIdle();
uchar IapReadunsigned_char(uint addr);
void IapProgramunsigned_char(uint addr, uchar dat);
void IapEraseSector(uint addr);
void Write_EEPROM();
//----------------------------
//关闭IAP,初始化函数
//---------------------------*/
void IapIdle()
{
        IAP_CONTR = 0;                  //关闭IAP功能
        IAP_CMD         = 0;              //清除命令寄存器
        IAP_TRIG         = 0;              //清除触发寄存器
        IAP_ADDRH = 0x80;            //将地址设置到非IAP区域
        IAP_ADDRL = 0;
}

//---------------------------
//从ISP/IAP/EEPROM区域读取一字节
//---------------------------
uchar IapReadunsigned_char(uint addr)
{
        uchar dat;                       //数据缓冲区

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

//----------------------------
//写一字节数据到ISP/IAP/EEPROM区域
//----------------------------
void IapProgramunsigned_char(uint addr, uchar dat)
{
        IAP_CONTR = ENABLE_IAP;         //使能IAP
        IAP_CMD         = CMD_PROGRAM;        //设置IAP命令
        IAP_ADDRL = addr;               //设置IAP低地址
        IAP_ADDRH = addr >> 8;          //设置IAP高地址
        IAP_DATA         = dat;                //写ISP/IAP/EEPROM数据
        IAP_TRIG         = 0x5a;               //写触发命令(0x5a)
        IAP_TRIG         = 0xa5;               //写触发命令(0xa5)
        _nop_();                        //等待ISP/IAP/EEPROM操作完成
        IapIdle();
}

//----------------------------
//扇区擦除
//---------------------------
void IapEraseSector(uint addr)
{
        IAP_CONTR = ENABLE_IAP;         //使能IAP
        IAP_CMD         = CMD_ERASE;          //设置IAP命令
        IAP_ADDRL = addr;               //设置IAP低地址
        IAP_ADDRH = addr >> 8;          //设置IAP高地址
        IAP_TRIG         = 0x5a;               //写触发命令(0x5a)
        IAP_TRIG         = 0xa5;               //写触发命令(0xa5)
        _nop_();                        //等待ISP/IAP/EEPROM操作完成
        IapIdle();
}


void Write_EEPROM()//将数据写入EEPROM
{
        IapEraseSector(IAP_ADDRESS);   //扇区擦除
        delay(2);                   //延时
        IapProgramunsigned_char(IAP_ADDRESS,Hour);//写入时
        delay(2);                   //延时
        IapProgramunsigned_char(IAP_ADDRESS+1,Min);//写入分
        delay(2);                   //延时
        IapProgramunsigned_char(IAP_ADDRESS+2,Sec); //写入秒
        
                                
}
void delay(uint k)
{
        uchar i;
        while((k--)!=0)
        {
        for(i=0;i<100;i++);
       
        }
}
void timechuli()
{
        if(Sec==60)
        {
                Sec=0;
                Min++;
                if(Min==60)
                {
                        Min=0;
                        Hour++;
                        if(Hour==24)
                        {Hour=0;}
                       
                }
        }
}
void delay123(uchar w)
{
        uchar n;
        for(n=0;n<w;n++)
        {
                timexianshi();
  }
}
               
void anjian()
{
        if(a1==0)
        {
                delay(500);//按键消抖  怎么改成显示的程序
                if(a1==0)
                {
                Sec++;
                        if(Sec==60)
                        {
                                Sec=0;
                                Min++;
                        }
        }
}
        if(a2==0)
        {
                delay(500);
                if(a2==0)
                {
                        P1=(xianshi[Min%10])|0x80;//显示分的个位
                P2=0x08;
                delay(5);
               
               
                P1=xianshi[Min/10];//显示分的十位
                P2=0x10;
                delay(5);
                        Min++;
                        if(Min==60)
                        {
                                Min=0;
                                Hour++;
                        }
        }
}
        if(a3==0)
        {
                delay(500);
                if(a3==0)
                {
                        Hour++;
                        if(Hour==24)
                        {
                                Hour=0;
                        }
                }
        }
}
        void timexianshi()         //P2口位选 P1口段选                       
        {
                P1=xianshi[Sec%10];//显示秒的个位
                P2=0x01;
                delay(5);
               
               
                P1=xianshi[Sec/10];//显示秒的十位
                P2=0x02;
                delay(5);
               
               
                P1=(xianshi[Min%10])|0x80;//显示分的个位
                P2=0x08;
                delay(5);
               
               
                P1=xianshi[Min/10];//显示分的十位
                P2=0x10;
                delay(5);
               
               
               
                P1=(xianshi[Hour%10])|0x80;//显示时的个位
                P2=0x40;
                delay(5);
               
               
               
                P1=xianshi[Hour/10];//显示时的个位
                P2=0x80;
                delay(5);
               
        }
        void timer0() interrupt 1
        {
                TH0=(65536-45872)/256;         //放入初值,11.0592M,50ms
          TL0=(65536-45872)%256;
                m++;
               
                if(m==20)
                {
                        m=0;
                        Sec++;
      cnt++;
                       
                        if(cnt==5)
                        {
                                Time_FLAG = 1;
                        cnt=0;
                        }
                }
        }
        void main()
        {
                P0=0xff;
                P2=0;
               
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TH0=(65536-45872)/256;         //放入初值,11.0592M,50ms
        TL0=(65536-45872)%256;
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        EA=1;                //开总中断
        EX0=1;
        ET0=1;                        //开定时器0中断
                //从EEPROM读取时间信息
                    Hour        = IapReadunsigned_char(IAP_ADDRESS);  //小时
                delay(2);
        Min        = IapReadunsigned_char(IAP_ADDRESS+1); //分钟
                delay(2);
        Sec        = IapReadunsigned_char(IAP_ADDRESS+2); //秒钟
                delay(2);
       
                        while(1)
                        {
                        timexianshi();//时间显示函数
                        anjian();//按键扫描函数
                        timechuli();//时间处理函数
                               
                                //每隔一段时间,将Time_FLAG置1,写一次EEPROM,这个时间看你自己需求了
                                       
                                if(Time_FLAG==1)
                {
                        Write_EEPROM();//写EEPROM
                        Time_FLAG = 0; //写完EEPROM将Time_FLAG标志清0
                                                                }
                       
                        }
                }
                                这是完整的一个电子时钟,带eeprom一个程序


使用特权

评论回复
cvgjhuor| | 2017-9-9 22:13 | 显示全部楼层
人人为我我为人人

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

54

主题

3739

帖子

20

粉丝