网站建设合同附件明细,哪里有学网页设计,网站上的办公网站怎么做,中国网站排名题目要求#xff1a;
一、基本要求 1.1 使用 CT107D 单片机竞赛板#xff0c;完成“电子钟”功能的程序设计与调试#xff1b; 1.2 设计与调试过程中#xff0c;可参考组委会提供的“资源数据包”#xff1b; 1.3 Keil 工程文件以准考证号命名#xff0c;保存在…题目要求
一、基本要求 1.1 使用 CT107D 单片机竞赛板完成“电子钟”功能的程序设计与调试 1.2 设计与调试过程中可参考组委会提供的“资源数据包” 1.3 Keil 工程文件以准考证号命名保存在以准考证号命名的考生文件夹中。 二、硬件框图 三、功能描述
3.1 初始化 1 关闭蜂鸣器、继电器等无关外设 2 设备初始化时钟为 23 时 59 分 50 秒闹钟提醒时间 0 时 0 分 0 秒。 3.2 显示功能 1) 时间显示格式 2) 温度显示格式 3.3 按键功能 1 按键 S7 定义为“时钟设置”按键通过该按键可切换选择待调整的 时、分、秒当前选择的显示单元以 1 秒为间隔亮灭时、分、秒 的调整需注意数据边界属性。 2 按键 S6 定义为“闹钟设置”按键通过该按键可进入闹钟时间设置 功能数码管显示当前设定的闹钟时间。 3 按键 S5 定义为“加”按键在“时钟设置”或“闹钟设置”状态下 每次按下该按键当前选择的单元时、分或秒增加 1 个单位。 4 按键 S4 定义为“减”按键在“时钟设置”或“闹钟设置”状态下 每次按下该按键当前选择的单元时、分或秒减少 1 个单位。 5 按键功能说明 按键 S4 、 S5 的“加”、“减”功能只在“时钟设置”或“闹钟设置” 状态下有效 在 “时钟显示”状态下按下 S4 按键显示温度数据松开按键 返回“时钟显示”界面。 3.4 闹钟提示功能 1 指示灯 L1 以 0.2 秒为间隔闪烁持续 5 秒钟 2 闹钟提示状态下按下任意按键关闭闪烁提示功能。 底层函数内容 1.初始化底层驱动专用文件 比如先用3个IO口控制74HC138译码器控制Y4为低电平当Y4为低电平时或非门74HC02控制Y4C为高电平使74HC573的OE端口有效OE端口有效时可使用P0口控制LED的亮灭。 可以去多了解74HC138译码器74HC02或非门74HC573八路输出透明锁存器的相关内容会更好理解 #include Init.h//关闭外设
void System_Init()
{P0 0xff;P2 P2 0x1f | 0x80;P2 0x1f;P0 0x00;P2 P2 0x1f | 0xa0;P2 0x1f;
} //头文件 #include STC15F2K60S2.H void System_Init(); 2.Led底层驱动专用文件 与初始化底层驱动专用文件同理需要了解对应的锁存器控制可以在使用的芯片数据手册查看 #include Led.hvoid Led_Disp(unsigned char addr,enable)
{static unsigned char temp 0x00;static unsigned char temp_old 0xff;if(enable)temp | 0x01 addr;elsetemp ~(0x01 addr);if(temp ! temp_old){P0 ~temp;P2 P2 0x1f |0x80;P2 0x1f;temp_old temp;}
} //头文件 #include STC15F2K60S2.H void Led_Disp(unsigned char addr,enable); 3.按键底层驱动专用文件 板子上的按键从按键4开始到按键19可根据实际硬件修改 #include Key.h
unsigned char Key_Read()
{unsigned char temp 0;if(P33 0)temp 4;if(P32 0)temp 5;if(P31 0)temp 6;if(P30 0)temp 7;return temp;
} //头文件 #include STC15F2K60S2.H unsigned char Key_Read(); 4.数码管底层驱动专用文件 这个板子使用的为共阳数码管若使用的为共阴数码管要更换对应的段码表和位选表与初始化底层驱动专用文件同理需要了解对应的锁存器控制可以在使用的芯片数据手册查看 #include Seg.h
code unsigned char Seg_Dula[]
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff,
//0x88, //A
//0x83, //b
//0xc6, //C
//0xa1, //d
//0x86, //E
//0x8e //F
0xbf, //-
0xc6
};
unsigned char Seg_Wela[] {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
void Seg_Disp(unsigned char wela,dula,point)
{P0 0xff;P2 P2 0x1f | 0xe0;P2 0x1f;P0 Seg_Wela[wela];P2 P2 0x1f | 0xc0;P2 0x1f;P0 Seg_Dula[dula];if(point)P0 0x7f;P2 P2 0x1f | 0xe0;P2 0x1f;
} //头文件 #include STC15F2K60S2.H void Seg_Disp(unsigned char wela,dula,point); 5.//温度底层驱动专用头文件 /* # 单总线代码片段说明 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 2. 参赛选手可以自行编写相关代码或以该代码为基础根据所选单片机类型、运行速度和试题 中对单片机时钟频率的要求进行代码调试和修改。 */ /* # 单总线代码片段说明 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 2. 参赛选手可以自行编写相关代码或以该代码为基础根据所选单片机类型、运行速度和试题 中对单片机时钟频率的要求进行代码调试和修改。 */ #include onewire.h sbit DQ P1^4; //单总线内部延时函数 void Delay_OneWire(unsigned int t) { unsigned char i; while(t--){ for(i0;i12;i); } } //单总线写操作 void Write_DS18B20(unsigned char dat) { unsigned char i; for(i0;i8;i) { DQ 0; DQ dat0x01; Delay_OneWire(5); DQ 1; dat 1; } Delay_OneWire(5); } //单总线读操作 unsigned char Read_DS18B20(void) { unsigned char i; unsigned char dat; for(i0;i8;i) { DQ 0; dat 1; DQ 1; if(DQ) { dat | 0x80; } Delay_OneWire(5); } return dat; } //DS18B20初始化 bit init_ds18b20(void) { bit initflag 0; DQ 1; Delay_OneWire(12); DQ 0; Delay_OneWire(80); DQ 1; Delay_OneWire(10); initflag DQ; Delay_OneWire(5); return initflag; } //函数名读取温度函数 //入口参数无 //函数功能完成温度转换并返回转换之后的温度数据 float Read_Temperature()
{unsigned char high,low;//返回温度数据的低八位和高八位init_ds18b20();//初始化Write_DS18B20(0xcc);//跳过ROMWrite_DS18B20(0x44);//开始温度转换init_ds18b20();//初始化Write_DS18B20(0xcc);//跳过ROMWrite_DS18B20(0xbe);//读取温度low Read_DS18B20();//读取低位high Read_DS18B20();//读取高位return ((high 8) |low) / 16.0;//返回温度保留后两位精度数据} //头文件 #include STC15F2K60S2.H float Read_Temperature(); 6.//时钟底层驱动专用头文件 /* # DS1302代码片段说明 1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。 2. 参赛选手可以自行编写相关代码或以该代码为基础根据所选单片机类型、运行速度和试题 中对单片机时钟频率的要求进行代码调试和修改。 */ #include ds1302.h #include intrins.h //引脚定义 sbit SCK P1^7; sbit SDA P2^3; sbit RST P1^3; //写字节 void Write_Ds1302(unsigned char temp) { unsigned char i; for (i0;i8;i) { SCK 0; SDA temp0x01; temp1; SCK1; } } //向DS1302寄存器写入数据 void Write_Ds1302_Byte( unsigned char address,unsigned char dat ) { RST0; _nop_(); SCK0; _nop_(); RST1; _nop_(); Write_Ds1302(address); Write_Ds1302(dat); RST0; } //从DS1302寄存器读出数据 unsigned char Read_Ds1302_Byte ( unsigned char address ) { unsigned char i,temp0x00; RST0; _nop_(); SCK0; _nop_(); RST1; _nop_(); Write_Ds1302(address); for (i0;i8;i) { SCK0; temp1; if(SDA) temp|0x80; SCK1; } RST0; _nop_(); SCK0; _nop_(); SCK1; _nop_(); SDA0; _nop_(); SDA1; _nop_(); return (temp); } //设置时钟可以根据数据手册调整要设置的时钟状态这里设置的为时分秒 void Set_Rct(unsigned char*ucRct)//unsigned char* ucRtc指向我存放时分秒的数组指针
{unsigned char i;Write_Ds1302_Byte(0x8e,0x00);for(i0;i3;i)Write_Ds1302_Byte(0x84-2*i,ucRct[i]);Write_Ds1302_Byte(0x8e,0x80);
} //读取时钟 void Read_Rct(unsigned char*ucRct)
{unsigned char i;for(i0;i3;i)ucRct[i] Read_Ds1302_Byte(0x85-2*i);
} //头文件 #include STC15F2K60S2.H void Write_Ds1302(unsigned char temp) ; void Write_Ds1302_Byte( unsigned char address,unsigned char dat ); unsigned char Read_Ds1302_Byte ( unsigned char address ); void Set_Rct(unsigned char*ucRct); void Read_Rct(unsigned char*ucRct); 工程主函数内容 1.头文件声明把需要用到的头文件添加进来 //头文件声明区 #include STC15F2K60S2.H//单片机寄存器专用头文件 #include Init.h//初始化底层驱动专用头文件 #include Led.h//Led底层驱动专用头文件 #include Key.h//按键底层驱动专用头文件 #include Seg.h//数码管底层驱动专用头文件 #include ds1302.h//时钟底层驱动专用头文件 #include onewire.h//温度底层驱动专用头文件 2.变量声明把需要用到的所有变量现在这里进行声明 //变量声明区 unsigned char Key_Val,Key_Old,Key_Down,Key_Up;//按键专用变量 unsigned char Key_Slow_Down;//按键减速专用变量 unsigned char Seg_Pos;//数码管扫描专用变量 unsigned char Seg_Slow_Down;//数码管减速专用变量 unsigned char Seg_Buf[8] {10,10,10,10,10,10,10,10};//数码管显示数据存放数组 unsigned char Seg_Point[8] {0,0,0,0,0,0,0,0};//数码管小数点数据存放数组 unsigned char ucLed[8] {0,0,0,0,0,0,0,0};//Led显示数据存放数组 unsigned char Seg_Disp_Mode;//数码管显示模式变量 0-时间相关 1-温度相关 unsigned char Seg_Index;//时间相关显示内容 0-时钟显示 1-时钟设置 2-闹钟设置 unsigned char ucRct[3] {0x23,0x59,0x50};//实时时钟数据数组 上电默认时间23:59:55 unsigned char ucRct_Set[3] {0x23,0x59,0x50};//时钟数据设置数组 unsigned char ucRct_Index;//时钟设置数组指针 unsigned int Timer_500ms;//五百毫秒计时变量 bit Seg_Star_Flag;//数码管闪烁标志位 unsigned char Alarm[3] {0x00,0x00,0x00};//闹钟数据储存数组 unsigned char Alarm_Set[3] {0x00,0x00,0x00};//闹钟数据设置数组 unsigned char* Data_Flag[3] {ucRct,ucRct_Set,Alarm_Set};//简化程序专用指针数组 bit Beep_Flag;//闹钟使能标志位 0-不使能 1-使能 unsigned int Timer_200ms;//两百毫秒计时变量 bit Led_Star_Flag;//Led闪烁标志位 unsigned char Temperature;//实时温度储存变量 3.按键处理函数在这里编写按键控制的函数 //键盘处理函数 void Key_Proc() { unsigned char i;//For循环专用变量 if(Key_Slow_Down)return; Key_Slow_Down 1;//键盘减速程序 Key_Val Key_Read();//实时读取键码值 Key_Down Key_Val (Key_Val ^ Key_Old);//捕捉按键下降沿 Key_Up ~ Key_Val (Key_Val ^ Key_Old);//捕捉按键上升沿 Key_Old Key_Val;//辅助扫描变量 if(Beep_Flag 1)//闹钟使能状态 { if(Key_Down ! 0)//按下任意按键 Beep_Flag 0;//关闭闹钟 return;//跳出按键子程序 避免执行下面的语句 } if(Seg_Index 0)//处于非设置界面 { if(Key_Old 4) Seg_Disp_Mode 1; else Seg_Disp_Mode 0; } switch (Key_Down) { case 7://时钟设置 if(Seg_Disp_Mode 0)//处于时钟相关界面 { if(Seg_Index 0)//处于时钟显示界面 { for(i0;i3;i) ucRct_Set[i] ucRct[i];//读取实时数据 Seg_Index 1;//切换到时钟设置界面 } else if(Seg_Index 1)//处于时钟设置界面 { if(ucRct_Index 3) { Set_Rct(ucRct_Set);//保存时钟数据 ucRct_Index 0;//切换到时钟显示界面 Seg_Index 0;//指针复位 } } } break; case 6://闹钟设置 if(Seg_Disp_Mode 0)//处于时钟相关界面 { if(Seg_Index 0)//处于时钟显示界面 Seg_Index 2;//切换到闹钟设置界面 else if(Seg_Index 2)//处于闹钟设置界面 { if(ucRct_Index 3) { for(i0;i3;i) Alarm[1] Alarm_Set[i];//保存闹钟数据 ucRct_Index 0;//切换到时钟显示界面 Seg_Index 0;//指针复位 } } } break; case 5://参数自加 if(Seg_Disp_Mode 0)//时钟相关 { // if(Seg_Index 1)//设置时钟 // { // ucRct_Set[ucRct_Index]; // if(ucRct_Set[ucRct_Index] % 16 0x0a)//16进制 (91)A // ucRct_Set[ucRct_Index] 6;//16进制(A6)10 // if(ucRct_Set[ucRct_Index] (ucRct_Index?0x60:0x24))//使用BCD码的形式存储用十六进制计算显示 // ucRct_Set[ucRct_Index] (ucRct_Index?0x59:0x23); // } Data_Flag[Seg_Index][ucRct_Index]; if(Data_Flag[Seg_Index][ucRct_Index] % 16 0x0a)//16进制 (91)A //使用BCD码的形式存储用十六进制计算显示 Data_Flag[Seg_Index][ucRct_Index] 6;//16进制(A6)10 if(Data_Flag[Seg_Index][ucRct_Index] (ucRct_Index?0x60:0x24))//设置上限 Data_Flag[Seg_Index][ucRct_Index] (ucRct_Index?0x59:0x23); } break; case 4: if(Seg_Disp_Mode 0)//时钟相关 { // if(Seg_Index 1)//设置时钟 // { // ucRct_Set[ucRct_Index]--; // if(ucRct_Set[ucRct_Index] % 16 0x0f)//16进制 (10-1)F //BCD码需要手动进行十进制进位 // ucRct_Set[ucRct_Index] - 6;//16进制 (F-6)9 // if(ucRct_Set[ucRct_Index] 0xf9)//16进制0-7FFFF FFFF FFFF FFF9 取最后两位 // ucRct_Set[ucRct_Index] 0; // } Data_Flag[Seg_Index][ucRct_Index]--; if(Data_Flag[Seg_Index][ucRct_Index] % 16 0x0f)//16进制 (10-1)F //BCD码需要手动进行十进制进位 Data_Flag[Seg_Index][ucRct_Index] - 6;//16进制 (F-6)9 if(Data_Flag[Seg_Index][ucRct_Index] 0xf9)//16进制0-7FFFF FFFF FFFF FFF9 取最后两位 //设置下限 Data_Flag[Seg_Index][ucRct_Index] 0; } break; } } 4.信息处理函数需要使用到到的函数进行简单的预处理 //信息处理函数 void Seg_Proc() { unsigned char i;//For循环专用变量 if(Seg_Slow_Down)return; Seg_Slow_Down 1;//数码管减速程序 //数据读取区域 Read_Rct(ucRct);//实时读取时钟数据 Temperature Read_Temperature();//实时读取温度数据 //数据显示区域 // if(Seg_Disp_Mode 0)//时钟 // switch (Seg_Index) // { // case 0://时钟显示 // Seg_Buf[2] Seg_Buf[5] 11; // for(i0;i3;i) // { // Seg_Buf[3*i] ucRct[i] / 16; // Seg_Buf[3*i1] ucRct[i] % 16; // } // break; // case 1://时钟设置 // Seg_Buf[2] Seg_Buf[5] 11; // for(i0;i3;i) // { // Seg_Buf[3*i] ucRct_Set[i] / 16; // Seg_Buf[3*i1] ucRct_Set[i] % 16; // } // Seg_Buf[3*ucRct_Index] Seg_Star_Flag?10:ucRct_Set[ucRct_Index] / 16; // Seg_Buf[3*ucRct_Index1] Seg_Star_Flag?10:ucRct_Set[ucRct_Index] % 16; // break; // } /* 遇到在某个状态下显示格式不变 但是显示数据数组需要发生改变时 可以将这些数组按照顺序放入一个指针数组内 然后通过访问指针数组达到简化程序的目的 */ if(Seg_Disp_Mode 0)//时钟 { Seg_Buf[2] Seg_Buf[5] 11; for(i0;i3;i) { Seg_Buf[3*i] Data_Flag[Seg_Index][i] / 16; Seg_Buf[3*i1] Data_Flag[Seg_Index][i] % 16; } if(Seg_Index 0)//闪烁使能 { Seg_Buf[3*ucRct_Index] Seg_Star_Flag?10:Data_Flag[Seg_Index][ucRct_Index] / 16; Seg_Buf[3*ucRct_Index1] Seg_Star_Flag?10:Data_Flag[Seg_Index][ucRct_Index] % 16; } } else//温度 { for(i0;i5;i) Seg_Buf[i] 10; Seg_Buf[5] Temperature / 10; Seg_Buf[6] Temperature % 10; Seg_Buf[7] 12; } } 5.其他函数其他编写的函数在这里书写会比较方便理解 //其他函数 void Led_Prov() { if(Alarm[0] ucRct[0] Alarm[1] ucRct[1] Alarm[2] ucRct[2])//闹钟使能 Beep_Flag 1; if((ucRct[2] % 16) (Alarm[2] % 16 5))//过五秒后 Beep_Flag 0; ucLed[0] Led_Star_Flag Beep_Flag;//只有在闹钟使能条件下闪烁 //char 和bit 不能相乘所以把*改成 } 6.定时器中断初始化函数 这个可以使用STC的定时器计算那里生成c代码后面要自己添加ET0,EA打开中断 //定时器中断初始化函数 void Timer0Init(void) //1毫秒12.000MHz { AUXR 0x7F; //定时器时钟12T模式 TMOD 0xF0; //设置定时器模式 TL0 0x18; //设置定时初值 TH0 0xFC; //设置定时初值 TF0 0; //清除TF0标志 TR0 1; //定时器0开始计时 ET0 1; //定时器中断0打开 EA 1; //总中断打开 } 7.定时器1中断服务函数 为了定时执行特定的任务如此处设置了定时的时间触发了数码管和LED产生特定反应//中断在测试时可以先注释掉但是这里按键状态有延时测试按键时可以解除注释 //定时器中断服务函数 void Timer0server()interrupt 1 { if(Key_Slow_Down 10)Key_Slow_Down 0;//键盘减速专用 if(Seg_Slow_Down 200)Seg_Slow_Down 0;//数码管减速时间过长有时候会影响数码管的刷新有问题的时候减短减速时间 if(Seg_Pos 8)Seg_Pos 0;//数码管显示专用 Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]); Led_Disp(Seg_Pos,ucLed[Seg_Pos]); if(Timer_500ms 500) { Timer_500ms 0; Seg_Star_Flag ^ 1; } if(Timer_200ms 200) { Timer_200ms 0; Led_Star_Flag ^ 1; } } 8.主函数Main调用书写的函数实现所需的相应功能 //Main void main() { Set_Rct(ucRct);//上电初始化实时时钟 Timer0Init(); Sys_Init(); while(1) { Key_Proc(); Seg_Proc(); Led_Prov(); } }