单片机编程课程(单片机编程培训)

2023-12-28 15:12:24 数码极客 bianji01

 

学单片机要学什么课程

给你两本书《爱上单片机》-作者杜洋

另外一本《单片机C语言程序设计实训100例基于8051+Proteus仿真》

留下QQ给你传一个PROTEUS仿真电路板,完全免费,不用买单片机学习板了。

QQ:794123566,非常感谢

本回答由提问者推荐

单片机课程设计(数字时钟) 麻烦大家不要发链接 直接帮我把程序写过来。

哈哈有个1602显示的不过程序太长贴不上给你个数码管的吧不行再联系

1302.c

#include

#include

ucharbit_ser[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};

ucharseven_seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

/***********************时间显示*****************/

voidtimer0_init(void)//T0初始化函数,用于时间的动态显示

TMOD=0x21;

TL0=(65536-5000)%256;

TH0=(65536-5000)/256;

EA=1;

ET0=1;

TR0=1;

voidtimer0_isr(void)interrupt1//T0断处理函数

charflag;//flag用于表示调整时闪烁的亮或灭

TR0=0;

TL0=(65536-5000)%256;

TH0=(65536-5000)/256;

TR0=1;

flag=x/100*0xff;//设置闪烁标志,如果x大于100则flag为0xff,小于100则为0x00

if(x>200)

switch(i)

case0:

P2=bit_ser[0];

if(setflag==3)//根据setflag的值判断当前位是否需要闪烁

P0=flag|seven_seg[dis_buffer[0]];

P0=seven_seg[dis_buffer[0]];

break;

case1:

P2=bit_ser[1];

if(setflag==3)

P0=flag|seven_seg[dis_buffer[1]];

P0=seven_seg[dis_buffer[1]];

break;

case2:

P2=bit_ser[2];

if(setflag==2)

P0=flag|seven_seg[dis_buffer[2]];

P0=seven_seg[dis_buffer[2]];

break;

case3:

P2=bit_ser[3];

if(setflag==2)

P0=flag|seven_seg[dis_buffer[3]];

P0=seven_seg[dis_buffer[3]];

break;

case4:

P2=bit_ser[4];

if(setflag==1)

P0=flag|seven_seg[dis_buffer[4]];

P0=seven_seg[dis_buffer[4]];

break;

case5:

P2=bit_ser[5];

if(setflag==1)

P0=flag|seven_seg[dis_buffer[5]];

P0=seven_seg[dis_buffer[5]];

break;

if(i>=6)

if(j==10)

if(setflag==0)

DS1302_GetTime(&Time);//如果setflag是0,就从1302中读出时间,因为setflag不是0时,说明处于调整状态,不需要读时间

dis_buffer[5]=Time.Second%10;//把当前时间放入显示缓冲区

dis_buffer[4]=Time.Second/10;

dis_buffer[3]=Time.Minute%10;

dis_buffer[2]=Time.Minute/10;

dis_buffer[1]=Time.Hour%10;

dis_buffer[0]=Time.Hour/10;

voidmain()

Initial_DS1302(Time);

timer0_init();

while(1)

set_down();

timer_down();

up_down();

down_down();

beepflag_down();

if(setflag==0&&Time.Hour==romhour&&Time.Minute==romminute&&Beepflag==1)//判断蜂鸣器是否要响

Beep=!Beep;

//key.c

#include

#defineucharunsignedchar

#defineuintunsignedint

uchari=0,j=0,x=0,setflag,flag_set,flag_timer;//setflag用来表示调整的位置,flag_set和flag_timer分别表示当前处于调整状态还是定时状态

SYSTEMTIMETime={0,20,15,3,30,6,10};//系统时间的初始值2010年6月30日星期三,15时20分0秒

chardis_buffer[6];//存放显示数据的缓冲区

sbitBeep_flag=P3^2;//蜂鸣器的接口

sbitkey_timer=P3^4;//定时按钮

sbitkey_set=P3^5;//调整按钮

sbitkey_up=P3^6;//增加按钮

sbitkey_down=P3^7;//减小按钮

charromhour,romminute,romsec;//分别存放定时的时,分,秒

bitBeepflag;//标记闹钟是否开启

//延时函数

voiddelays(ucharx)

while(x)x--;

//设置键的处理函数

voidset()

setflag++;

flag_set=1;

if(setflag>=4)

setflag=0;

flag_set=0;

Initial_DS1302(Time);

//定时间的处理函数

voidtimer()

setflag++;

flag_timer=1;

if(setflag==1)

Time.Hour=romhour;

Time.Minute=romminute;

Time.Second=romsec;

elseif(setflag>=4)

setflag=0;

flag_timer=0;

romhour=Time.Hour;

romminute=Time.Minute;

romsec=Time.Second;

//增加键的处理函数

voidup()

switch(setflag)

case0:

break;

case1:

Time.Second++;

if(Time.Second>=60)

Time.Second=0;

break;

case2:

Time.Minute++;

if(Time.Minute>=60)

Time.Minute=0;

break;

case3:

Time.Hour++;

if(Time.Hour>=24)

Time.Hour=0;

break;

//减小键的处理函数

voiddown()

switch(setflag)

case0:

break;

case1:

Time.Second--;

if(Time.Second<0)

Time.Second=59;

break;

case2:

Time.Minute--;

if(Time.Minute<0)

Time.Minute=59;

break;

case3:

Time.Hour--;

if(Time.Hour<0)

Time.Hour=23;

break;

//设置键的扫描函数

voidset_down()

if(key_set==0&&flag_timer==0)

delays(100);

if(key_set==0)

set();

while(!key_set);

//定时键的扫描函数

voidtimer_down()

if(key_timer==0&&flag_set==0)

delays(100);

if(key_timer==0)

timer();

while(!key_timer);

//增加键的扫描函数

voidup_down()

if(key_up==0&&setflag!=0)

delays(100);

if(key_up==0)

up();

while(!key_up);

//减少键的处理函数

voiddown_down()

if(key_down==0&&setflag!=0)

delays(100);

if(key_down==0)

down();

while(!key_down);

//定时开关的扫描处理函数

voidbeepflag_down()

if(Beep_flag==0)

delays(100);

Beepflag=!Beepflag;

while(!Beep_flag);

//ds1302.h

#ifndef_REAL_TIMER_DS1302

#define_REAL_TIMER_DS1302

#include

sbitDS1302_CLK=P1^1;//实时时钟时钟线引脚

sbitDS1302_IO=P1^2;//实时时钟数据线引脚

sbitDS1302_RST=P1^3;//实时时钟复位线引脚

sbitACC0=ACC^0;

sbitACC7=ACC^7;

sbitBeep=P2^7;

typedefstruct__SYSTEMTIME__

{charSecond;

charMinute;

charHour;

charWeek;

charDay;

charMonth;

charYear;

}SYSTEMTIME;//定义的时间类型

#defineAM(X)X

#definePM(X)(X+12)//转成24小时制

#defineDS1302_SECOND0x80//秒寄存器

#defineDS1302_MINUTE0x82//分寄存器

#defineDS1302_HOUR0x84

#defineDS1302_WEEK0x8A

#defineDS1302_DAY0x86

#defineDS1302_MONTH0x88

#defineDS1302_YEAR0x8C

#defineDS1302_RAM(X)(0xC0+(X)*2)//用于计算DS1302_RAM地址的宏

voidDS1302InputByte(unsignedchard)//实时时钟写入一字节(内部函数)

{unsignedchari;

ACC=d;

for(i=8;i>0;i--)

{DS1302_IO=ACC0;//相当于汇编中的RRC

DS1302_CLK=1;

DS1302_CLK=0;//发一个高跳变到低的脉冲

ACC=ACC>>1;

unsignedcharDS1302OutputByte(void)//实时时钟读取一字节(内部函数)

{unsignedchari;

for(i=8;i>0;i--)

{ACC=ACC>>1;//相当于汇编中的RRC

ACC7=DS1302_IO;

DS1302_CLK=1;

DS1302_CLK=0;//发一个高跳变到低的脉冲

return(ACC);

voidWrite1302(unsignedcharucAddr,unsignedcharucDa)//ucAddr:DS1302地址,ucData:要写的数据

{DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;

DS1302InputByte(ucAddr);//地址,命令

DS1302InputByte(ucDa);//写1Byte数据

DS1302_CLK=1;

DS1302_RST=0;//RST0->1->0,CLK0->1

unsignedcharRead1302(unsignedcharucAddr)//读取DS1302某地址的数据

{unsignedcharucData;

DS1302_RST=0;

DS1302_CLK=0;

DS1302_RST=1;//enable

DS1302InputByte(ucAddr|0x01);//地址,命令

ucData=DS1302OutputByte();//读1Byte数据

DS1302_CLK=1;//RST0->1->0,CLK0->1

DS1302_RST=0;

return(ucData);

voidDS1302_SetProtect(bitflag)//是否写保护

{if(flag)

Write1302(0x8E,0x80);//WP=1,不能写入

Write1302(0x8E,0x00);//WP=0,可以写入

voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)//设置时间函数

{DS1302_SetProtect(0);

Write1302(Address,((Value/10)<<4|(Value%10)));//高4位为十位,低4位为个位

DS1302_SetProtect(1);

//获取时间函数,从DS1302内读取时间然后存入Time内

voidDS1302_GetTime(SYSTEMTIME*Time)

{unsignedcharReadValue;

ReadValue=Read1302(DS1302_SECOND);

Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);//转换成10进制的秒

ReadValue=Read1302(DS1302_MINUTE);

Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_HOUR);

Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_DAY);

Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_WEEK);

Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_MONTH);

Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

ReadValue=Read1302(DS1302_YEAR);

Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

//利用STime初始化DS1302

voidInitial_DS1302(SYSTEMTIMESTime)

{unsignedcharSecond=Read1302(DS1302_SECOND);

if(Second&0x80)DS1302_SetTime(DS1302_SECOND,0);//如果第七为1(表明没有启动),则启动时钟

DS1302_SetTime(DS1302_SECOND,STime.Second);//设定起始时间

DS1302_SetTime(DS1302_MINUTE,STime.Minute);

DS1302_SetTime(DS1302_HOUR,STime.Hour);

DS1302_SetTime(DS1302_DAY,STime.Day);

DS1302_SetTime(DS1302_MONTH,STime.Month);

DS1302_SetTime(DS1302_YEAR,STime.Year);

DS1302_SetTime(DS1302_WEEK,STime.Week);

#endif

本回答由网友推荐

声明:易趣百科所有作品(图文、音视频)均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系315127732@qq.com
广告位招租
横幅广告