ARM交通灯万年历
单片机万年历毕业设计
单片机万年历毕业设计单片机万年历是一种集成了日历、时钟、闹钟等功能的电子设备,它可以显示日期、时间,并能够提醒用户重要的日程安排。
在现代社会,随着人们生活节奏的加快和工作压力的增大,一个可靠的万年历设备变得尤为重要。
本文将介绍关于单片机万年历的设计原理、功能以及实现方法。
首先,我们来了解一下单片机万年历的设计原理。
单片机万年历的核心是一块单片机芯片,它可以通过内部的时钟电路来计算日期和时间。
通过与外部的LCD液晶显示屏和按键电路的连接,单片机可以将计算得到的日期和时间显示在屏幕上,并接受用户的输入来设置闹钟等功能。
此外,单片机还可以通过与电源电路的连接来实现长时间的运行。
接下来,我们来讨论一下单片机万年历的功能。
除了基本的日期和时间显示功能外,单片机万年历还可以实现一些实用的功能。
比如,它可以设置多个闹钟,提醒用户重要的会议、约会等事项。
闹钟可以通过按键来设置,并且在到达设定时间时会发出声音或者振动来提醒用户。
此外,单片机万年历还可以实现倒计时功能,用户可以设置一个特定的时间,然后单片机会自动倒计时,并在倒计时结束时发出提醒。
这些功能的实现都依赖于单片机芯片的计算和控制能力。
然后,我们来探讨一下单片机万年历的实现方法。
在设计单片机万年历时,首先需要选择合适的单片机芯片,根据芯片的规格书来了解它的功能和接口。
然后,需要设计电路板,将单片机芯片、LCD液晶显示屏、按键电路和电源电路等元件连接起来。
在电路板设计完成后,需要进行焊接和调试工作,确保各个元件之间的连接正确无误。
最后,需要编写单片机的程序代码,实现各个功能的逻辑控制。
在编写代码时,需要根据芯片的指令集和编程规范来进行,以确保程序的正确性和稳定性。
最后,我们来总结一下单片机万年历的优点和应用前景。
单片机万年历具有体积小、功耗低、功能丰富等优点,适合用于个人和家庭使用。
它可以帮助人们合理安排时间,提醒重要的日程安排,提高生活和工作的效率。
此外,单片机万年历还可以应用于学校、办公室等场所,帮助人们更好地管理时间和任务。
ARM课程设计——可调控万年历时钟
ARM课程设计可调控万年历时钟1.初始化并运行RTC,然后读取时间值通过串口向上位机发送,并把秒的值输出到教学实验开发平台上的LED1~LED4进行显示。
2.分析。
万年历显示时间包括年、月、日、星期、时、分和秒,利用EasyARM.exe仿真软件把结果发送到上位机上显示。
通过按键进行上述的显示调节,其中月是1~12,日是1~31,星期是1~7,时是00~23,分是00~59,秒是00~59。
现在时间显示2012年6月11日星期一15:23:30。
3.4.程序#include "config.h"#include "stdio.h"#include "math.h"uint8 time[4];/*按键 GPIO口*/#define key1 1<<16#define key2 1<<17#define key3 1<<18#define key4 1<<19#define key5 1<<20#define key6 1<<21#define HC595_CS (1 << 29) // P0.29口为74HC595的片选typedef struct UartMode // 定义串口模式设置的数据结构{uint8 datab; // 字长度 5/6/7/8uint8 stopb; // 停止位 1/2uint8 parity; // 奇偶校验 0-无校验, 1-奇校验, 2-偶校验}UARTMODE;uint8 rcv_buf[6]; // UART0数据接收缓冲区volatile uint8 rcv_new; // 接收新数据标志void DelayNS (uint32 dly){uint32 m;for ( ; dly>0; dly--)for (m=0; m<5000; m++);}void MSPI_Init(void){//PINSEL0 = (PINSEL0 & 0xFFFF00FF) | 0x00005500; // 设置管脚连接SPI PINSEL0 = (PINSEL0 & (~(0xFF << 8))) | (0x55 << 8) ;SPCCR = 0x52; // 设置SPI时钟分频SPCR = (0 << 3) | // CPHA = 0, 数据在SCK 的第一个时钟沿采样(1 << 4) | // CPOL = 1, SCK 为低有效(1 << 5) | // MSTR = 1, SPI 处于主模式(0 << 6) | // LSBF = 0, SPI 数据传输MSB (位7)在先(0 << 7); // SPIE = 0, SPI 中断被禁止}uint8 MSPI_SendData(uint8 data){IOCLR = HC595_CS; // 片选74HC595SPI_SPDR = data;while( 0 == (SPI_SPSR & 0x80)); // 等待SPIF置位,即等待数据发送完毕IOSET = HC595_CS;return(SPI_SPDR);}/* 此表为LED0~F以及L、P的字模 */uint8 const DISP_TAB[19] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0x88, 0x83, 0xC6, 0xA1,0x86, 0x8E,};uint8 UART0_Init (uint32 baud, UARTMODE set){uint32 bak;/* 参数过滤*/if ((0 == baud) || (baud > 115200)) return (0);if ((set.datab < 5) || (set.datab > 8)) return (0);if ((0 == set.stopb) || (set.stopb > 2)) return (0);if (set.parity > 4) return (0);/* 设置串口波特率*/U0LCR = 0x80; // DLAB=1bak = (Fpclk >> 4) / baud;U0DLM = bak >> 8;U0DLL = bak & 0xff;/* 设置串口模式*/bak = set.datab - 5;if (2 == set.stopb) bak |= 0x04;if (0 != set.parity){set.parity = set.parity - 1;bak |= 0x08;}bak |= set.parity << 4;U0LCR = bak;return (1);}void SendByte (uint8 data){U0THR = data;while ((U0LSR & 0X20) == 0); // 等待数据发送}void PC_DispChar (uint8 no, uint8 chr){SendByte(0xff);SendByte(0x81);SendByte(no);SendByte(chr);SendByte(0x00);}uint8 const SHOWTABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void SendTimeRtc (void){uint32 datas;uint32 times;uint32 bak;times = CTIME0; // 读取完整的时钟寄存器datas = CTIME1;bak = (datas >> 16) & 0xfff; // 获取年PC_DispChar(0, SHOWTABLE[bak / 1000]);bak = bak % 1000;PC_DispChar(1, SHOWTABLE[bak / 100]);bak = bak % 100;PC_DispChar(2, SHOWTABLE[bak / 10]);PC_DispChar(3, SHOWTABLE[bak % 10]);bak = (datas >> 8) & 0x0f; // 获取月PC_DispChar(4, SHOWTABLE[bak / 10]);PC_DispChar(5, SHOWTABLE[bak % 10]);bak = datas & 0x1f; // 获取日PC_DispChar(6, SHOWTABLE[bak / 10]);PC_DispChar(7, SHOWTABLE[bak % 10]);bak = (times >> 24) & 0x07; // 获取星期PC_DispChar(8, SHOWTABLE[bak]);bak = (times >> 16) & 0x1f; // 获取小时PC_DispChar(9, SHOWTABLE[bak / 10]);PC_DispChar(10, SHOWTABLE[bak % 10]);bak = (times >> 8) & 0x3f; // 获取分钟PC_DispChar(11, SHOWTABLE[bak / 10]);PC_DispChar(12, SHOWTABLE[bak % 10]);bak = times & 0x3f; // 获取秒钟PC_DispChar(13, SHOWTABLE[bak / 10]);PC_DispChar(14, SHOWTABLE[bak % 10]);}void RTCInit (void){PREINT = Fpclk / 32768 - 1; // 设置基准时钟分频器PREFRAC = Fpclk - (Fpclk / 32768) * 32768;CCR = 0x00; // 禁止时间计数器YEAR = 2012; //设置时钟初值MONTH = 6;DOM = 11;DOW = 1;HOUR = 15;MIN = 23;SEC = 30;CIIR = 0x01; // 设置秒值的增量产生一次中断 ILR = 0x03; // 清除RTC增量和报警中断标志 CCR = 0x01; // 启动RTC}void __irq IRQ_UART0 (void){uint8 i;if ((U0IIR & 0x0F) == 0x04)rcv_new = 1; // 设置接收到新的数据标志for (i=0; i<14; i++){rcv_buf[i] = U0RBR; // 读取FIFO的数据,并清除中断}/*再次初始化时钟*/CCR = 0x00; // 禁止时间计数器YEAR=(rcv_buf[0]-0x30)*1000+(rcv_buf[1]-0x30)*100+(rcv_buf[2]-0x30)*10+(rcv_buf[3]-0x30);MONTH =(rcv_buf[4]-0x30)*10+(rcv_buf[5]-0x30);DOM =(rcv_buf[6]-0x30)*10+(rcv_buf[7]-0x30);DOW =(rcv_buf[8]-0x30);HOUR =(rcv_buf[9]-0x30)*10+(rcv_buf[1]-0x30);MIN =(rcv_buf[11]-0x30)*10+(rcv_buf[3]-0x30);SEC =(rcv_buf[13]-0x30)*10+(rcv_buf[5]-0x30);CIIR = 0x01; // 设置秒值的增量产生1次中断CCR = 0x01; // 启动RTCVICVectAddr = 0x00; // 中断处理结束}void SET_TIME (void){while ((IO0PIN & key1) == 0) // 等待发送信号{DelayNS(2);if ((IO0PIN & key1) == 0){YEAR=YEAR+1;time[0,1,2,3]=YEAR;loop1: while ((IO0PIN & key1) != 0);DelayNS(2);if ((IO0PIN & key1) == 0) goto loop1; // 等待按键恢复}}while ((IO0PIN & key2) == 0) // 等待发送信号{DelayNS(2);if ((IO0PIN & key2) == 0){if(MONTH>11)MONTH=1;else MONTH=MONTH+1;time[4,5]=MONTH;loop2: while ((IO0PIN & key2) != 0);DelayNS(1);if ((IO0PIN & key2) == 0) goto loop2; // 等待按键恢复 }}while ((IO0PIN & key3) == 0) // 等待发送信号 {DelayNS(2);if ((IO0PIN & key3) == 0){if(DOM>29)DOM=0;elseDOM=DOM+1;time[6,7]=DOM;loop3: while ((IO0PIN & key3) != 0);DelayNS(1);if ((IO0PIN & key3) == 0) goto loop3; // 等待按键恢复 }}while ((IO0PIN & key4) == 0) // 等待发送信号 {DelayNS(2);if ((IO0PIN & key4) == 0){if(DOW>5)DOW=0;elseDOW=DOW+1;time[8]=DOW;loop4: while ((IO0PIN & key4) != 0);DelayNS(2);if ((IO0PIN & key4) == 0) goto loop4; // 等待按键恢复 }}while ((IO0PIN & key5) == 0) // 等待发送信号 {DelayNS(2);if ((IO0PIN & key5) == 0){if(HOUR>22)HOUR=0;elseHOUR=HOUR+1;time[9,10]=HOUR;loop5: while ((IO0PIN & key5) != 0);DelayNS(2);if ((IO0PIN & key5) == 0) goto loop5; // 等待按键恢复 }}while ((IO0PIN & key6) == 0) // 等待发送信号{DelayNS(2);if ((IO0PIN & key6) == 0){if(MIN>58)MIN=0;elseMIN=MIN+1;time[11,12]=MIN;loop6: while ((IO0PIN & key6) != 0);DelayNS(2);if ((IO0PIN & key6) == 0) goto loop6; // 等待按键恢复 }}}int main (void){ uint8 i;UARTMODE uart0_set;PINSEL0 = 0x00000005; // 连接IO到串口UART0PINSEL1 = 0x00000000;PINSEL2 = PINSEL2 & (~0x08); // P1[25:16]连接GPIO//PINSEL1 = 0x00005500; // 设置SPI管脚连接//PINSEL2 = 0x00000000;IODIR = HC595_CS;uart0_set.datab = 8;uart0_set.stopb = 1;uart0_set.parity = 0;UART0_Init(115200, uart0_set);U0FCR = 0xc1; // 使能FIFO,并设置触发点为8字节U0IER = 0x01; // 允许RBR中断,即接收中断MSPI_Init();RTCInit();IRQEnable(); // 使能IRQ中断/* 使能UART0中断 */VICIntSelect = 0x00000000; // 设置所有的通道为IRQ中断VICVectCntl0 = 0x20 | 0x06; // UART0分配到IRQ slot0,即最高优先级VICVectAddr0 = (uint32)IRQ_UART0; // 设置UART0向量地址VICIntEnable = 1 << 0x06; // 使能UART0中断while (1){ while (0 == (ILR & 0x01)); // 等待RTC增量中断ILR = 0x01;for(i=1; i<8; i++){if(DOW==i)rcv_data = MSPI_SendData(DISP_TAB[i]); // 发送显示数据} // 清除中断标志SET_TIME();SendTimeRtc();}return (0);}。
ARM 万年历程序
ARM 万年历程序
0x2b,0x09,0x9e,0x38,0xb6,0x08,0xec,0x74,0x6c,0x05,0xd4,0x0a,0xe4,0x6a, 0x52,0x05,0x95,0x0a,0x5a,0x42,0x5b,0x04,0xb6,0x04,0xb4,0x22,0x6a,0x05, 0x52,0x75,0xc9,0x0a,0x52,0x05,0x35,0x55,0x4d,0x0a,0x5a,0x02,0x5d,0x31, 0xb5,0x02,0x6a,0x8a,0x68,0x05,0xa9,0x0a,0x8a,0x6a,0x2a,0x05,0x2d,0x09, 0xaa,0x48,0x5a,0x01,0xb5,0x09,0xb0,0x39,0x64,0x05,0x25,0x75,0x95,0x0a, 0x96,0x04,0x4d,0x54,0xad,0x04,0xda,0x04,0xd4,0x44,0xb4,0x05,0x54,0x85, 0x52,0x0d,0x92,0x0a,0x56,0x6a,0x56,0x02,0x6d,0x02,0x6a,0x41,0xda,0x02, 0xb2,0xa1,0xa9,0x05,0x49,0x0d,0x0a,0x6d,0x2a,0x09,0x56,0x01,0xad,0x50, 0x6d,0x01,0xd9,0x02,0xd1,0x3a,0xa8,0x05,0x29,0x85,0xa5,0x0c,0x2a,0x09, 0x96,0x54,0xb6,0x08,0x6c,0x09,0x64,0x45,0xd4,0x0a,0xa4,0x05,0x51,0x25, 0x95,0x0a,0x2a,0x72,0x5b,0x04,0xb6,0x04,0xac,0x52,0x6a,0x05,0xd2,0x0a, 0xa2,0x4a,0x4a,0x05,0x55,0x94,0x2d,0x0a,0x5a,0x02,0x75,0x61,0xb5,0x02, 0x6a,0x03,0x61,0x45,0xa9,0x0a,0x4a,0x05,0x25,0x25,0x2d,0x09,0x9a,0x68, 0xda,0x08,0xb4,0x09,0xa8,0x59,0x54,0x03,0xa5,0x0a,0x91,0x3a,0x96,0x04, 0xad,0xb0,0xad,0x04,0xda,0x04,0xf4,0x62,0xb4,0x05,0x54,0x0b,0x44,0x5d, 0x52,0x0a,0x95,0x04,0x55,0x22,0x6d,0x02,0x5a,0x71,0xda,0x02,0xaa,0x05, 0xb2,0x55,0x49,0x0b,0x4a,0x0a,0x2d,0x39,0x36,0x01,0x6d,0x80,0x6d,0x01, 0xd9,0x02,0xe9,0x6a,0xa8,0x05,0x29,0x0b,0x9a,0x4c,0xaa,0x08,0xb6,0x08, 0xb4,0x38,0x6c,0x09,0x54,0x75,0xd4,0x0a,0xa4,0x05,0x45,0x55,0x95,0x0a, 0x9a,0x04,0x55,0x44,0xb5,0x04,0x6a,0x82,0x6a,0x05,0xd2,0x0a,0x92,0x6a, 0x4a,0x05,0x55,0x0a,0x2a,0x4a,0x5a,0x02,0xb5,0x02,0xb2,0x31,0x69,0x03, 0x31,0x73,0xa9,0x0a,0x4a,0x05,0x2d,0x55,0x2d,0x09,0x5a,0x01,0xd5,0x48, 0xb4,0x09,0x68,0x89,0x54,0x0b,0xa4,0x0a,0xa5,0x6a,0x95,0x04,0xad,0x08, 0x6a,0x44,0xda,0x04,0x74,0x05,0xb0,0x25,0x54,0x03,}; 确定阳历日和阴历日的对应关系的算法: 对于其他任何一个阳历日和阴历日的对应关系,都可以通过以下算法求得结果。具体算法由如下 函数get_lunar_day(void)实现: 说明:函数get_lunar_day(void)的输入变量:gc_solar_calendar_year和 gc_solar_calendar_month 输出变量:gc_lunar_calendar_year、gc_lunar_calendar_month和 gc_lunar_calendar_date void get_lunar_day(void)/*计算出输入阳历年、阳历月,对应该阳历月第一天对应阴历时间,即阴 历年、月、日*/ {unsigned char temp_leap_month; unsigned char temp_flag; unsigned char calculate_temp; unsigned char mc_tpumenus_temp_loop; unsigned char mc_tpumenus_temp_01; temp_leap_month = 0;temp_flag = 1; //条件初始化二次,减少运算数据量. if(gc_solar_calendar_year > 99)
基于单片机控制的电子万年历.
基于单片机控制的电子万年历摘要本设计是一个带温度显示的万年历电路系统,该电路具有年、月、日、星期、时、分、秒、闹钟显示和调整功能,并且还包含显示温度功能。
其中显示部分采用LCD1602显示,时钟部分采用DS1302时钟芯片,温度部分采用DS18B20单线温度传感器。
软件方面我们采用C语言编程,利用Keil uVision3软件编写C语言程序并且生成HEX文件。
先将程序在Proteus 仿真,通过之后再烧录到单片机中。
该设计的优点是充分利用了LCD1602的显示功能完成了万年历应该具有的功能并且还扩展了温度;不足之处是收到LCD1602显示功能的限制没能显示农历日期。
电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。
它可以对年、月、日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能,而且DS1302的使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。
该电路采用AT89S51单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
关键词:万年历;AT89C51;液晶显示(LCD1602);温度传感器(DS18B20);时钟芯片(DS1302);proteus仿真;目录摘要 (1)目录 (1)1引言: (2)2设计方案 (3)2.2模块选择 (4)2.3方案框图 (4)3 软件实现 (5)3.1流程图 (5)3.2程序编写 (6)3.3运行程序生成hex文件 (12)4 proteus仿真 (13)4.1软件简介 (13)4.2 Proteus电路仿真与调试 (14)5 PCB制版 (21)5.1 绘制电路原理图并仿真调试 (21)5.2加载网络表及元件封装 (21)5.3规划电路板并设置相关参数 (23)5.4元件布局及调整 (24)5.5布线并调整 (25)5.6输出及制作PCB (26)总结 (27)参考文献 (28)致谢 (29)1引言:随着微电子技术的高速发展,单片机在国民经济的个人领域得到了广泛的运用。
课程设计(论文)-基于ARM7的电子万年历设计
成绩评定表课程设计任务书目录1 系统设计 (1)1.1电子显示屏特性 (1)1.2 按键控制 (1)1.3LCD显示端 (1)1.4 万年历调控电路 (2)1.5 万年历的实现 (3)1.6 LCD调试电路图 (3)2 软件的具体功能和要求 (4)2.1 基本要求 (4)2.2软件设计平台的介绍及实现方法 (4)2.3 程序设计流程图 (4)3 设计总结 (6)3.1 proteus仿真电路图 (6)3.2 Keil 源代码 (7)3.3 性能分析 (23)[参考文献] (24)1 系统设计1.1电子显示屏特性1>LED由计算机专用设备、显示屏幕、视频输入端口和系统软件等组成。
2>计算机及专用设备直接决定了系统的功能,可根据用户对系统的不同要求选择不同的类型3>提供视频输入端口。
1.2 按键控制1>用于年月日的调控,复位。
2>用于时分秒的置换,清屏。
1.3 LCD显示端LCD显示端如图1所示。
图1 LCD显示端万年历调控电路如图2所示。
图2 万年历调控电路使用调试功能,经过反复的调试终于实现了计时功能,然后通过查询资料,实现了计时过程中时钟实时更新功能及实现LED灯跟节奏闪烁。
再经过程序的改进,实现了实时时钟和闹钟调整功能。
添加了LED灯指示调整时间点(秒、分、时、星期、日、月、年)功能。
1.6 LCD调试电路图调试电路图如图3所示。
图3 调试电路图2 软件的具体功能和要求2.1 基本要求本课题所设计的系统要求:(1)在理解基本实验代码的基础上,掌握万年历的工作原理,基于程序控制方式的驱动设计。
(2)在proteus中使用ARM7的LPC2106芯片并且结合Keil的源代码,实现万年历功能。
(3)编写基于万年历程序,实现代码编译。
2.2软件设计平台的介绍及实现方法本设计中采用可编程逻辑设计环境ARM7进行设计,Keil uVsion5采用C语言进行编程。
2.3 程序设计流程图万年历程序流程图如图4所示。
用单片机做数字万年历
关键词:时钟芯片DS12C887;温度采集DS18B20;单片机AT89S52;液晶显示1602
PDF 文件使用 "pdfFactHale Waihona Puke ry Pro" 试用版本创建
摘要
电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。它可以对年、月、 日、周日、时、分、秒进行计时,还具有闰年补偿等多种功能。本系统选用DALLAS公司 生产的日历时钟芯片DS12C887来作为实时时钟芯片,为本系统提供详细的年、月、日、 星期和小时、分钟等时间信息。数字万年历采用直观数字显示,可以同时显示年、月、日、 周日、时、分、秒和温度等信息,还具有定时和时间校准等功能。该电路采用AT89S52 单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
结束语 ................................................................................................................ 25 致谢词 ................................................................................................................ 26 参考文献 ............................................................................................................ 27 附件 1 ................................................................................................................. 28
单片机万年历设计
单片机万年历设计摘要:电子计时器在现代社会测量仪器越来越普及的时候,得到了广泛的应用。
这是一年来回报你自己。
DS1302的耐用性,相差不大。
数字显示在电子日历中,以及下一年、月、日、时,电路采用AT89S52微处理器设计,工作在低功耗、3V电压下,本项目基于51系列日历元件,可同时实现日期、小时、分钟、时间等,因为我们没有很好的基础知识和实践经验,我们完全准备好了创造整机的理论基础,拓展知识和软件设计,不可能精确地限制任何需要设备的工作,比如程序设计,算法如何执行等等,没有具体的依据,在编程过程中很难找到,写出来的任务也只有掌握了相应的知识才能完成。
日历设计过程与硬件和软件同步,硬件组件主要由AT89C52单片电路组成,LED显示电路和时键7 seg-mpx8-ca监视器,共有八个一般的正二极管,7seg-mpx4-ca带有四个一般性正二极管的监视器。
我使用三个74HC164驱动。
74HC164是一个带有8位边界开关的登记册,它仔细输入数据,然后并行发布数据。
软件包括,除其他外,日历,时间调整程序,日历,显示程序等,以方便设置时间和显示日历后,所有的wave调试程序完成后,由于教师和教师的共同努力,电子日历已经完成。
关键词:动态扫描,单片机时钟电钟,DS1302,DS18B20,一、设计要求与方案论证1.1 设计要求:(1)基本要求1.任务一年,一个月,一周,一小时,分钟,秒;2.日历具有按月控制键和显示功能3.函数校准年、月、日、周、小时、分、秒;( 2 )创新要求1.日历具有按阴历显示功能;② 具有检测室温的功能;1.2系统基本方案选择和论证1.2.1单片机芯片的选择方案和论证:--Flash-ROM采用89C51芯片作为硬件核心,同时采用4kb的ROM内部存储器,但由于缺乏ISPs网络软件,这种技术已经应用到目前的网络中,如果调试器是由于程序错误或附加程序功能引起的,则必须注销。
1.2.2模块论证:表1数字光栅用于显示。
嵌入式智能万年历设计
任务要求:用ARM—M3芯片设计一个智能万年历,要求能够正确显示近100 年时间,星期几,时间格式为****年**月**日(星期**) **:**:**(时:分:秒),能够识别出闰年(计时范围能够从1970年1月1日到2100年左右)。
该程序设计工程里包含有main.c(相关配置、和终端联系,提醒输出初始时间、输出实时时间)/date.c(计算实时时间)/stm32f10x_it.c三个文件,各文件内容如下。
Main.c文件:#include "stm32f10x.h"#include "stdio.h"#include "date.h"__IO uint32_t TimeDisplay = 0;void RCC_Configuration(void);void NVIC_Configuration(void);void GPIO_Configuration(void);void USART_Configuration(void);int fputc(int ch, FILE *f);void RTC_Configuration(void);void Time_Regulate(struct rtc_time *tm);void Time_Adjust(void);void Time_Display(uint32_t TimeVar);void Time_Show(void);u8 USART_Scanf(u32 value);#define RTCClockSource_LSEu8 const *WEEK_STR[] = {"日", "一", "二", "三", "四", "五", "六"};struct rtc_time systmtime;int main(){RCC_Configuration();NVIC_Configuration();GPIO_Configuration();USART_Configuration();/*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5,则需重新配置时间并询问用户调整时间*/printf("\r\n\n RTC not yet configured....");RTC_Configuration();printf("\r\n RTC configured....");Time_Adjust();BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{/*启动无需设置新时钟*//*检查是否掉电重启*/if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET){printf("\r\n\n Power On Reset occurred....");}/*检查是否Reset复位*/else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET){printf("\r\n\n External Reset occurred....");}printf("\r\n No need to configure RTC....");/*等待寄存器同步*/RTC_WaitForSynchro();/*允许RTC秒中断*/RTC_ITConfig(RTC_IT_SEC, ENABLE);/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();}#ifdef RTCClockOutput_EnableRCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); PWR_BackupAccessCmd(ENABLE);BKP_TamperPinCmd(DISABLE);BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);RCC_ClearFlag();Time_Show();}void RCC_Configuration(){SystemInit();RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);}void NVIC_Configuration(){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}void GPIO_Configuration(){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);}void USART_Configuration(){USART_InitTypeDef USART_InitStructure;USART_ART_WordLength = USART_WordLength_8b;USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No ;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);}int fputc(int ch, FILE *f){/* 将Printf内容发往串口 */USART_SendData(USART1, (unsigned char) ch);while (!(USART1->SR & USART_FLAG_TXE));return (ch);}void RTC_Configuration(){/*允许PWR和BKP时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/*允许访问BKP域*/PWR_BackupAccessCmd(ENABLE);/*复位备份域*/BKP_DeInit();#ifdef RTCClockSource_LSI/*允许LSI*/RCC_LSICmd(ENABLE);/*等待LSI准备好*/while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET){}/*选择LSI作为RTC时钟源*/RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);#elif defined RTCClockSource_LSE/*允许LSE*/RCC_LSEConfig(RCC_LSE_ON);/*等待LSE准备好*/while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET){}/*选择LSE作为RTC时钟源*/RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);#endif/* Enable RTC Clock */RCC_RTCCLKCmd(ENABLE);#ifdef RTCClockOutput_Enable/*禁止Tamper引脚*/BKP_TamperPinCmd(DISABLE);/*为了将RTCCLK/64在Tamper引脚输出,Tamper功能必须被禁止*//*允许RTC时钟在Tamper引脚上输出*/BKP_RTCCalibrationClockOutputCmd(ENABLE);#endif/*等待寄存器同步*/RTC_WaitForSynchro();/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();/*允许RTC秒中断*/RTC_ITConfig(RTC_IT_SEC, ENABLE);/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();#ifdef RTCClockSource_LSI/*设置分频系数*/RTC_SetPrescaler(31999); /*RTC周期=RTCCLK/RTC_PR=(32.000kHz/(31999+1))*/#elif defined RTCClockSource_LSERTC_SetPrescaler(32767); /*RTC周期=RTCCLK/RTC_PR=(32.768kHz/(31767+1))*/ #endif/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();}void Time_Regulate(struct rtc_time *tm){u32 Tmp_YY = 0xFF, Tmp_MM = 0xFF, Tmp_DD = 0xFF, Tmp_HH = 0xFF, Tmp_MI = 0xFF, Tmp_SS = 0xFF;printf("\r\n=========================Time Settings==================");printf("\r\n 请输入年份(Please Set Years): 20");while (Tmp_YY == 0xFF){Tmp_YY = USART_Scanf(99);}printf("\n\r 年份被设置为: 20%0.2d\n\r", Tmp_YY);tm->tm_year = Tmp_YY+2000;Tmp_MM = 0xFF;printf("\r\n 请输入月份(Please Set Months): ");while (Tmp_MM == 0xFF){Tmp_MM = USART_Scanf(12);}printf("\n\r 月份被设置为: %d\n\r", Tmp_MM);tm->tm_mon= Tmp_MM;Tmp_DD = 0xFF;printf("\r\n 请输入日期(Please Set Dates): ");while (Tmp_DD == 0xFF){Tmp_DD = USART_Scanf(31);}printf("\n\r 日期被设置为: %d\n\r", Tmp_DD);tm->tm_mday= Tmp_DD;Tmp_HH = 0xFF;printf("\r\n 请输入时钟(Please Set Hours): ");while (Tmp_HH == 0xFF){Tmp_HH = USART_Scanf(23);}printf("\n\r 时钟被设置为: %d\n\r", Tmp_HH );tm->tm_hour= Tmp_HH;Tmp_MI = 0xFF;printf("\r\n 请输入分钟(Please Set Minutes): ");while (Tmp_MI == 0xFF){Tmp_MI = USART_Scanf(59);}printf("\n\r 分钟被设置为: %d\n\r", Tmp_MI);tm->tm_min= Tmp_MI;Tmp_SS = 0xFF;printf("\r\n 请输入秒钟(Please Set Seconds): ");while (Tmp_SS == 0xFF){Tmp_SS = USART_Scanf(59);}printf("\n\r 秒钟被设置为: %d\n\r", Tmp_SS);tm->tm_sec= Tmp_SS;}void Time_Adjust()RTC_WaitForLastTask();Time_Regulate(&systmtime);GregorianDay(&systmtime);RTC_SetCounter(mktimev(&systmtime));RTC_WaitForLastTask();}void Time_Display(uint32_t TimeVar){to_tm(TimeVar, &systmtime);printf("\r 当前时间为: %d年 %d月 %d日 (星期%s) %0.2d:%0.2d:%0.2d", systmtime.tm_year, systmtime.tm_mon, systmtime.tm_mday, WEEK_STR[systmtime.tm_wday], systmtime.tm_hour,systmtime.tm_min, systmtime.tm_sec);}void Time_Show(){printf("\n\r");/* Infinite loop */while (1){/* 每过1s */if (TimeDisplay == 1){Time_Display(RTC_GetCounter());TimeDisplay = 0;}}}u8 USART_Scanf(u32 value){u32 index = 0;u32 tmp[2] = {0, 0};{while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}tmp[index++] = (USART_ReceiveData(USART1));if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)) /*数字0到9的ASCII 码为0x30至0x39*/{if((index == 2) && (tmp[index - 1] == '\r')){tmp[1] = tmp[0];tmp[0] = 0x30;}else{printf("\n\rPlease enter valid number between 0 and 9 -->: ");index--;}}}/* 计算输入字符的相应ASCII值*/index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);/* Checks */if (index > value){printf("\n\rPlease enter valid number between 0 and %d", value);return 0xFF;}return index;}Date.c文件内容如下:#include "date.h"#define FEBRUARY 2#define STARTOFTIME 1970#define SECDAY 86400L#define SECYR (SECDAY * 365)#define leapyear(year) ((year) % 4 == 0)#define days_in_month(a) (month_days[(a) - 1])static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };/*计算公历*/void GregorianDay(struct rtc_time * tm){int leapsToDate;int lastYear;int day;int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };lastYear=tm->tm_year-1;/*计算到计数的前一年之中一共经历了多少个闰年*/leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;/*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/ if((tm->tm_year%4==0) && ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && (tm->tm_mon>2)){day=1;}else{day=0;}day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday; /*计算从计数元年元旦到计数日期一共有多少天*/tm->tm_wday=day%7;}u32 mktimev(struct rtc_time *tm){if (0 >= (int) (tm->tm_mon -= 2)){tm->tm_mon += 12;tm->tm_year -= 1;}return ((((u32) (tm->tm_year/4 - tm->tm_year/100 + tm->tm_year/400 + 367*tm->tm_mon/12 + tm->tm_mday)}void to_tm(u32 tim, struct rtc_time * tm){register u32 i;register long hms, day;day = tim / SECDAY;hms = tim % SECDAY;tm->tm_hour = hms / 3600;tm->tm_min = (hms % 3600) / 60;tm->tm_sec = (hms % 3600) % 60;/*算出当前年份,起始的计数年份为1970年*/for (i = STARTOFTIME; day >= days_in_year(i); i++) {day -= days_in_year(i);}tm->tm_year = i;/*计算当前的月份*/if (leapyear(tm->tm_year)){days_in_month(FEBRUARY) = 29;}for (i = 1; day >= days_in_month(i); i++){day -= days_in_month(i);}days_in_month(FEBRUARY) = 28;tm->tm_mon = i;/*计算当前日期*/tm->tm_mday = day + 1;GregorianDay(tm);}stm32f10x_it.c文件内容:#include "stm32f10x_it.h"extern uint32_t TimeDisplay;void NMI_Handler(void){}/*** @brief This function handles Hard Fault exception.* @param None* @retval : None*/void HardFault_Handler(void){/* Go to infinite loop when Hard Fault exception occurs */while (1){}}/*** @brief This function handles Memory Manage exception.* @param None* @retval : None*/void MemManage_Handler(void){/* Go to infinite loop when Memory Manage exception occurs */ while (1){}}/*** @brief This function handles Bus Fault exception.* @param None* @retval : None*/void BusFault_Handler(void){/* Go to infinite loop when Bus Fault exception occurs */while (1){}}* @brief This function handles Usage Fault exception.* @param None* @retval : None*/void UsageFault_Handler(void){/* Go to infinite loop when Usage Fault exception occurs */ while (1){}}/*** @brief This function handles SVCall exception.* @param None* @retval : None*/void SVC_Handler(void){}/*** @brief This function handles Debug Monitor exception.* @param None* @retval : None*/void DebugMon_Handler(void){}/*** @brief This function handles PendSVC exception.* @param None* @retval : None*/void PendSV_Handler(void){}/*** @brief This function handles SysTick Handler.* @param None* @retval : None*/}void RTC_IRQHandler(void){if (RTC_GetITStatus(RTC_IT_SEC) != RESET){/* Clear the RTC Second interrupt */RTC_ClearITPendingBit(RTC_IT_SEC);/* Enable time update */TimeDisplay = 1;/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();/* Reset RTC Counter when Time is 23:59:59 */if (RTC_GetCounter() == 0x00015180){RTC_SetCounter(0x0);/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();}}}。
ARM7_AD调整万年历和调节LED亮度
实时进行AD转换采样电压,先将采样电压赋值给一个变量,再将当前采样值和该变量实时比较,当采样值比变量大预定值或小预定值时调整万年历各值加减变化即可。
2.AD转换器通过PWM控制调节LED亮度:
通过改变PWM输出波形的占空比,即可控制LED等的明暗变化。实验通过AD转换器实现对PWM输出波形占空比的渐变调节,即可实现对LED亮度的渐变调节。
六.调试过程和心得:
功能虽然简单,但每个功能的实现却是不断失败然后继续调试的过程。
在调试时,貌似KEY4和KEY3按键程序一模一样,可就是出现不一样的结果,当时很郁闷,开始怀疑C语言本身是否有问题。而后认真检查后才发现,原来是ADC_Data变量少了个字母C!从中认识到C语言本身几乎不会有问题,只是自己对C语言的掌握程度有限。
四.实验程序:
1.程序流程图:
.. .
2.实验程序:(见附录)
五.调试结果:
程序烧进LPC2138后,将P0.8、P0.9连接LED7、LED8,BEEP连接P0.15,JP5接Verf端。然后通过按键可实现各个功能。
1按KEY6键可调整万年历。开始时数码管显示0,按KEY6键一次后数码管显示1,此时通过旋转A/D转换模块的电位器(顺时针旋转增大,逆时针减小)可调整万年历分值;按KEY6键两次后数码管显示2,此时通过旋转A/D转换模块的电位器(顺时针旋转增大,逆时针减小)可调整万年历时值;依次类推,可依次调节万年历分、时、星期、日、月、年值,同时数码管从1~6变化。调整过程中,万年历各个调整值每加一或减一同时,LED1闪一次、蜂鸣器蜂鸣一声。当A/D采样电压达到最大或最小值后,蜂鸣器长鸣,同时LED4(采样电压最小时)或LED5(采样电压最大时)长亮。
单片机万年历毕业设计
单片机万年历是一种非常实用的电子设备,它可以准确地显示日期和时间,并且可以自动调整闰年和月份的天数。
在现代社会,随着人们生活水平的提高和科技的发展,电子设备在人们的日常生活中发挥着越来越重要的作用。
在这种背景下,单片机万年历应运而生,它不仅可以帮助人们准确地了解日期和时间,还可以提醒人们重要的日程安排。
单片机万年历的设计原理是通过单片机的控制,实现对时钟芯片的读取和控制,从而实现准确的时间显示。
同时,通过编程控制,还可以实现闰年和月份天数的自动调整功能。
为了实现更加精确的时间显示,可以通过连接网络进行时间同步,从而保证万年历的准确性。
单片机万年历的设计需要考虑多个方面,包括硬件设计和软件设计。
在硬件设计方面,需要选择适合的单片机和时钟芯片,同时还需要设计合适的电路板和显示屏,以及其他必要的外围电路。
在软件设计方面,需要编写相应的程序代码实现对时钟芯片的读取和控制,并实现闰年和月份天数的自动调整功能。
此外,还可以添加一些其他功能,如闹钟、倒计时等,以增加万年历的实用性和娱乐性。
在进行单片机万年历的毕业设计过程中,需要注意以下几个关键点。
首先,要确保硬件电路的正常工作,包括各个元件的连接和供电的稳定性。
其次,要确保编写的软件程序能够准确地读取和显示时间,并能够自动调整闰年和月份天数。
再次,要确保设计的功能实用性和稳定性,如闹钟功能的准点提醒、倒计时功能的精确计算等。
最后,还需要注意外观的美观性和易用性,以增加用户的满意度和使用体验。
综上所述,单片机万年历作为一种实用的电子设备,在现代社会中具有广泛的应用前景。
通过对硬件和软件的设计,可以实现准确的时间显示和自动调整功能,从而方便人们的日常生活和工作。
在进行单片机万年历的毕业设计过程中,需要注重电路的稳定性和软件的功能完善性,并通过实际测试和调试,不断优化设计,以实现更好的效果。
希望通过这篇文献,能够为单片机万年历的毕业设计提供一些参考和帮助。
单片机课程设计--基于51单片机的万年历
单片机课程设计报告万年历的设计基于51单片机的万年历摘要:电子万年历是一种非常广泛日常计时工具,对现代社会越来越流行。
它可以对年、月、日、周日、时、分、秒进行计时,使用寿命长,误差小。
对于数字电子万年历采用直观的数字显示,可以同时显示年、月、日、周日、时、分、秒和温度等信息,还具有时间校准等功能。
该电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。
本设计是基于51系列的单片机进行的电子万年历设计,可以显示年月日时分秒及周信息,具有可调整日期和时间功能。
在设计的同时对单片机的理论基础和外围扩展知识进行了比较全面准备。
万年历的设计过程在硬件与软件方面进行同步设计。
硬件部分主要由AT89C52单片机,LCD显示电路,以及调时按键电路等组成。
在单片机的选择上本人使用了AT89C52单片机,该单片机适合于许多较为复杂控制应用场合。
显示器使用了1602液晶显示,并且使用蜂鸣器实现了整点报警的功能,温度测试的功能实现使用了DS18B20,并实现了温度过高或过低时的温度报警。
软件方面主要包括日历程序、时间调整程序,显示程序等。
程序采用C语言编写。
所有程序编写完成后,在KeilC51软件中进行调试,确定没有问题后,在Proteus软件中嵌入单片机内进行仿真,并最终实现基本要求。
综上所述此万年历具有读取方便、显示直观、功能多样、电路简洁、成本低廉等诸多优点,符合电子仪器仪表的发展趋势,具有广阔的市场前景。
一、设计要求基本要求:1,8 个数码管上显示,显示时间的格式为(假如当前时间是19:32:20)“19-32-20”;2,具有日历功能;③时间可以通过按键调整。
发挥部分:④具有闹钟功能(可以设定多个)。
二:总体设计电路设计框图系统硬件概述本电路是由AT89S52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由单片机定时功能提供;温度的采集由DS18B20构成,它具有独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯,使用时不需要额外的外围电路。
ARM7的万年历的设计
万年历的设计一.项目要求:在ARM7(ARM7TDMI-S)的的核心板上实现“万年历”的的数码管显示。
二.开发工具:1.使用ADS1.2编写硬件程序,并联合AXD进行调试2.H-JTAG烧写程序(笔记本用JLINK烧写调试程序)三.功能要求:基本功能:1.在数码管上显示年,月,日,周,时,分,秒2.整点提示功能3.时间可调(相应闪烁)扩展功能:四,功能分析:1,数码管显示年,月,日,周,时,分,秒a)显示部分,采用数码管的动态扫描,开发板上只有一个4位一体的数码管,所以要实现时间的切换,因开发板上ARM7和74HC595之间进行(SPI)通信,把数据传到数码管上显示。
b)按键处理部分,采用中断的方式,只用当有按键按下时才去扫描按键c)时钟使用RTC模块,2,整点提示功能:a)只需设置ARM7内部的RTC模块的相关Reg即可3,时间可调:在时间的相应位置闪烁,并实现可调功能,采用TIME0五,总体框架:六,程序清单;/*****************************************************文件名:万年历(用数码管显示)*编写人:霍小波*完成时间:2011-3-14-15-00*摘要:在一个四位一体的数码管上能显示年,月,日,周,时,分,秒,具有整点报铃,调时(并在相应的位闪烁)****************************************************/#include"whole.h"#include"delay.h"#include"OFF_Beep.h"#include"RTC.h"//------外部函数的声明----extern void HC595_Init(void);//HC595的初始化extern uint8 HC595_SendData(uint8 data);//发送数据extern void SMG_Init(void);//数码管初始化extern void Display(uint32 data,uint8 i);//数码管的显示extern void Key_Init(void); //按键初始化extern Key_Scan(void); //按键扫描//------变量的声明-------uint8 i;uint32 dat;uint8 num=0; //记录按键按下的次数,来显示不同的时间TIME a,b; //定义时钟结构体uint8 flag8=0;//第1,2个数码管的闪烁;(在显示的地方处理)uint8 flag9=0;//第3,4个数码管的闪烁;uint8 flag7=0;//选择是高位闪烁还是低位闪烁uint8 num1=0; //选择哪个数码管闪uint8 dot=0; //选择数码管的小数点位置uint8 flag5=0; //上电运行分,秒uint8 flag6=0; //有键按下,并一直显示相应的数值uint32 dat; //在数码管上待显示的数据/********************************************************** *名称:void __irq EXINT0_IRQ(void)*功能:外部中断1的中断服务程序,用来扫描按键*入口参数:无*出口参数:无**********************************************************/ void __irq EXINT0_IRQ(void){i=Key_Scan();while((EXTINT & 0x01) != 0){EXTINT = 0x01;}VICV ectAddr = 0;}/********************************************************** *名称:void __irq TIME0_IRQ(void)*功能:定时器0的中断服务程序,用来闪烁相应的位*入口参数:无*出口参数:无**********************************************************/void __irq TIME0_IRQ(void){if(flag7==1) //闪烁第3,4个数码管{flag8=0;flag9=~flag9;}if(flag7==2) //闪烁第1,2个数码管{flag9=0;flag8=~flag8;}T0IR = 0x01;VICV ectAddr = 0;}/*********************************************************名称:void TIME0_Init(void)*功能:定时器0的初始化(并未开启定时器),在调时时才开启,提高CPU的速度*入口参数:无*出口参数:无********************************************************/void TIME0_Init(void){T0TC = 0; //定时计数器设置为0T0PR = 0; //时钟不分频T0MCR = 0x03; //复位,并产生中断T0MR0 = Fpclk*0.4; //时间为1秒T0IR = 0x01; //清除中断标志// T0TCR = 0x01; //启动定时器VICIntSelect = 0x000000; //设置所有中断为IRQ向量中断VICV ectCntl1 = 0x20 | 4; //定时器0的VICV ectAddr1 = (uint32)TIME0_IRQ;VICIntEnable = 0x00004010;}/************************************************名称:void __irq RTC_IRQ(void) //RTC中断服务程序*功能: 整点报铃,当每一次小时加1,报警一次*入口参数:无*出口参数:无***********************************************/void __irq RTC_IRQ(void) //RTC中断服务程序{if((CIIR & 0x04) != 0){Beep_ON();DelayMs(100);Beep_OFF(); //关闭BEEP}while((ILR&0x01) !=0)ILR=0x01; //清除中断标志VICV ectAddr = 0;}/**************************************************名称:void RTC_Init(void) //RTC初始化*功能:RTC的初始化*入口参数:无*出口参数:无*************************************************/void RTC_Init(void) //RTC初始化{PREINT = Fpclk /32768 - 1; //设置基准时钟分频器PREFRAC = Fpclk - (Fpclk /32768) * 32768;AMR=0xff; //屏蔽报警CIIR = 0x04; //设置分增加1产生一次中断ILR = 0x03; //清除中断VICIntSelect = 0x000000; //设置所有中断为IRQ向量中断VICV ectCntl5 = 0x20| 13; //VICV ectCntl0 = 0x20 | 14; //外部中断0VICV ectAddr5 = (uint32)RTC_IRQ; //设置计数器增加中断入口地址VICV ectAddr0 = (uint32)EXINT0_IRQ; //外部中断的地址VICIntEnable = VICIntEnable | (1<<13); //使能中断VICIntEnable = 0x00004000;}/*******************************************************名称:uint32 Show(void)*功能:显示时钟,*入口参数:无*出口参数: 在数码管上待显示的时钟数据******************************************************/uint32 Show(void){if(i==1){flag5=1; //当键按下时,flag5=1;每次显示按键值所对应的数据标志位CCR=0x00; //有键按下,关闭RTCi=0; //num++; //记录按键按下的次数,来显示不同的时间if(num==1){flag6=1;flag7=1;//flag6=1;显示分,秒,flag7=1;调时闪烁后两位标志}else if(num==2){flag6=2;flag7=1;//显示周,小时}else if(num==3){flag6=3;flag7=1;//显示月,日}else if(num==4){flag6=4;flag7=1;//显示年}else if(num==5){flag6=5;flag7=1;//取消闪烁num=0;T0TCR = 0x00; //关闭定时器flag8=0;flag9=0; //取消闪烁}}GetTime(&a);//获得时间的数据if(flag6==1){dat = (a.min*100)+a.sec;dot=3;}if(flag6==2){dat = (a.dow*100)+a.hour;dot=3;}if(flag6==3){dat = (a.mon*100)+a.day;dot=3;}if(flag6==4){dat = a.year;dot=0;}if((flag6==5)||(flag5==0)){CCR=0x01;dat = (a.min*100)+a.sec;dot=3;}else if(i==2){DelayMs(5);if(i==2){i=0;num1++;DelayMs(5);if(num1==1){if(num!=0){flag7=1;T0TCR = 0x01;//启动定时器0,开始闪烁(后两位)}}else if(num1==2){if(num!=0){flag7=2;T0TCR = 0x01;//启动定时器0,开始闪烁(前两位)}}else if(num1==3){num1=0;T0TCR = 0x00; //关闭定时器,停止闪烁flag8=0;flag9=0;}}}else if(i==3) //调时,设置时间(+){DelayMs(10);if(i==3){i=0;if((num==1)&&(num1==1)){GetTime(&a);a.sec++;if(a.sec==60) a.sec=0;Set_Time(&a);}else if((num==1)&&(num1==2)){GetTime(&a);a.min++;if(a.min==60) a.min=0;Set_Time(&a);}else if((num==2)&&(num1==1)){GetTime(&a);a.hour++;if(a.hour==24) a.hour=0;Set_Time(&a);}else if((num==2)&&(num1==2)){GetTime(&a);a.dow++;if(a.dow==8) a.dow=1;Set_Time(&a);}else if((num==3)&&(num1==1)){GetTime(&a);a.day++;if(a.day==32) a.day=1;Set_Time(&a);}else if((num==3)&&(num1==2)){GetTime(&a);a.mon++;if(a.mon==13) a.mon=1;Set_Time(&a);}else if((num==4)&&(num1==1)){GetTime(&a);a.year++;Set_Time(&a);}else if((num==4)&&(num1==2)){GetTime(&a);a.year=a.year+100;Set_Time(&a);}}}else if(i==4) //调时,设置时间(-){DelayMs(10);if(i==4){i=0;if((num==1)&&(num1==1)){GetTime(&a);a.sec--;if(a.sec==-1) a.sec=59;Set_Time(&a);}else if((num==1)&&(num1==2)) {GetTime(&a);a.min--;if(a.min==0) a.min=59;Set_Time(&a);}else if((num==2)&&(num1==1)) {GetTime(&a);a.hour--;if(a.hour==-1) a.hour=23;Set_Time(&a);}else if((num==2)&&(num1==2)) {GetTime(&a);a.dow--;if(a.dow==0) a.dow=7;Set_Time(&a);}else if((num==3)&&(num1==1)) {GetTime(&a);a.day--;if(a.day==0) a.day=31;Set_Time(&a);}else if((num==3)&&(num1==2)) {GetTime(&a);a.mon--;if(a.mon==0) a.mon=12;Set_Time(&a);}else if((num==4)&&(num1==1)) {GetTime(&a);a.year--;if(a.year==0) a.year=99;Set_Time(&a);}else if((num==4)&&(num1==2)){GetTime(&a);a.year=a.year-100;if(a.year==0) a.year=900;Set_Time(&a);}}}return(dat);}int main(void){uint32 data;HC595_Init();SMG_Init();RTC_Init();Key_Init();TIME0_Init();Beep_Init(); //初始化BEEPBeep_OFF(); //关闭BEEPb.year = 2011;b.mon = 3;b.day = 14;b.dow = 1;b.hour = 15;b.min = 59;b.sec = 55;Set_Time(&b); //设置时钟while(1){data=Show(); //取出要显示的数据Display(data,dot); //在数码管上显示时间}return(0);}#include "whole.h"#include"OFF_Beep.h"#define BEEP (1<<24)void Beep_Init(void) //初始化BEEP{PINSEL2=PINSEL2&0xfffffff7;IO1DIR=IO1DIR|BEEP;}void Beep_OFF(void) //关闭BEEP{IO1SET=IO1SET|BEEP;}void Beep_ON(void){IO1CLR=IO1CLR|BEEP;}#include"whole.h"#include"delay.h"void DelayMs(uint32 dly){uint32 i;for(;dly>0;dly--)for(i=0;i<220;i++);}#include"whole.h"//#include"74HC595.h"#define HC595_nCS (1<<28) //HC595的选通信号为P3.28#define HC595_RCK (1<<16) //时钟P1.16/******************************************************* **函数名:HC595_Init()**函数功能:对74HC595及SPI0的初始化**入口参数:无**出口参数:无*******************************************************/void HC595_Init(void){//------------初始化引脚------PINSEL0=(PINSEL0&0xffff00ff)|0x00005500;//设置P0.4 P0.5 P0.6为SPI0引脚PINSEL2=PINSEL2&0xffffff7f; //设置为GPIOPINSEL2=PINSEL2&0xfffffff7; //设置为GPIO//-----------设置引脚为输出------------IO3DIR=IO3DIR|HC595_nCS;IO1DIR=IO1DIR|HC595_RCK;IO3CLR=HC595_nCS; //选中HC595为从机//-------------SPI寄存器的初始化-----------S0PCCR=0x64; //设置SPI时钟的分频值为0x64,即SPI时钟=Fpclk/100S0PCR=0x30; //设置SPI为主模式,CPOL=1,CPHA=1;}/*******************************************************名称:uint8 HC595_SendData(uint8 data)**功能:向74HC595发送一字节数据**入口参数:data**出口参数:S0PDR****************************************************/uint8 HC595_SendData(uint8 data){IO1CLR=HC595_RCK; //先将RCK拉低S0PDR=data; //准备数据,while((S0PSR&0x80)==0); //等待SPIF置位,完成数据的传输IO1SET=HC595_RCK; //控制HC595将数据并行输出return(S0PDR);}#include"whole.h"#include"delay.h"#define smgA1 (1<<22) //P2.22#define smgA2 (1<<23) //P0.23#define smgA3 (1<<19) //P1.19#define smgA4 (1<<24) //P0.24extern uint8 flag8;extern uint8 flag9;extern uint8 HC595_SendData(uint8 data);//发送数据//--------数字0--9的共阳段码-------------uint8 const TAB[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x98};//---------数码管的初始化---------------void SMG_Init(void){IO2DIR=IO2DIR|smgA1;IO0DIR=IO0DIR|smgA2|smgA4;IO1DIR=IO1DIR|smgA3;}void NumbTube_Bit(uint8 data){if((data & 0x01) != 0) IO2CLR = smgA1; // 控制smgA1else IO2SET = smgA1;if((data & 0x02) != 0) IO0CLR = smgA2; // 控制smgA2else IO0SET = smgA2;if((data & 0x04) != 0) IO1CLR = smgA3; // 控制smgA3else IO1SET = smgA3;if((data & 0x08) != 0) IO0CLR = smgA4; // 控制smgA4else IO0SET = smgA4;}//---------数码管的显示------------------/*void Display(uint32 data,uint8 i){uint16 j;uint16 qian,bai,shi,ge;qian=data/1000;bai=data%1000/100;shi=data%100/10;ge=data%10;IO2CLR=IO2CLR|smgA1;IO0SET=IO0SET|smgA2;IO1SET=IO1SET|smgA3;IO0SET=IO0SET|smgA4;if(i==4)HC595_SendData(TAB[qian]&0x0f);elseHC595_SendData(TAB[qian]);//DelayMs(3);for(j=0;j<350;j++);IO2SET=IO2SET|smgA1;IO0CLR=IO0CLR|smgA2;IO2SET=IO2SET|smgA1;IO1SET=IO1SET|smgA3;IO0SET=IO0SET|smgA4;if(i==3)HC595_SendData(TAB[bai] &0x7f);elseHC595_SendData(TAB[bai]);// DelayMs(3);for(j=0;j<350;j++);IO0SET=IO0SET|smgA2;IO1CLR=IO1CLR|smgA3;IO0SET=IO0SET|smgA2;IO2SET=IO2SET|smgA1;IO0SET=IO0SET|smgA4;if(i==2)HC595_SendData(TAB[shi]&0x7f);elseHC595_SendData(TAB[shi]);// DelayMs(3);for(j=0;j<350;j++);IO1SET=IO1SET|smgA3;IO0CLR=IO0CLR|smgA4;IO1SET=IO1SET|smgA3;IO0SET=IO0SET|smgA2;IO2SET=IO2SET|smgA1;HC595_SendData(TAB[ge]);//DelayMs(3);for(j=0;j<350;j++);IO0SET=IO0SET|smgA4;}*/void Display(uint32 data,uint8 radix_point){ uint32 j,one,ten,hundred,thousand; //个,十,百,千,的变量声明thousand = data / 1000; //计算千位if(thousand != 0) data -= thousand*1000;hundred = data / 100; //计算百位if(hundred != 0) data -= hundred*100;ten = data / 10; //计算十位if(ten != 0) data -= ten*10;one = data % 10; //计算个位//-------------------显示千位数据----------------if(radix_point==4) HC595_SendData(TAB[thousand] & 0x7f);else HC595_SendData(TAB[thousand]);if(flag8==0){NumbTube_Bit(0x01); //打开显示千位的位选端for(j=0;j<500;j++); //小段延时NumbTube_Bit(0x00); //关闭显示}//-------------------显示百位数据----------------if(radix_point==3) HC595_SendData(TAB[hundred] & 0x7f);else HC595_SendData(TAB[hundred]);if(flag8==0){NumbTube_Bit(0x02);for(j=0;j<500;j++);NumbTube_Bit(0x00); //关闭显示}//-------------------显示十位数据----------------if(radix_point==2) HC595_SendData(TAB[ten] & 0x7f);else HC595_SendData(TAB[ten]);if(flag9==0){NumbTube_Bit(0x04);for(j=0;j<500;j++);NumbTube_Bit(0x00); //关闭显示}//-------------------显示个位数据----------------HC595_SendData(TAB[one]);if(flag9==0){NumbTube_Bit(0x08);for(j=0;j<500;j++);NumbTube_Bit(0x00); //关闭显示}}#include"whole.h"#include"OFF_Beep.h"#include"delay.h"extern Key_Scan(void);//-------定义一个时间结构体-------typedef struct{uint16 year;//年uint16 mon; //月uint16 day; //日uint16 dow; //星期uint16 hour; //时uint16 min; //分uint16 sec; //秒}TIME;/***********************************************名称:Set_Time(TIME *time)*功能:设置时间(初始化时间)*入口参数:time指针用来指向结构体中的时间*出口参数:无**********************************************/void Set_Time(TIME *time){CCR = 0x00; //时间计数器被禁止,可对时间进行初始化YEAR = time->year;MONTH = time->mon;DOM = time->day;DOW = time->dow;HOUR = time->hour;MIN = time->min;SEC = time->sec;// CCR=0x01; //启动RTC}/************************************************名称:GetTime(TIME *t)*功能:读取RTC时钟值*入口参数:t 保存日期的TIME结构体变量的指针*出口参数:无***********************************************/void GetTime(TIME *t){t->year = YEAR;t->mon = MONTH;t->day = DOM;t->dow = DOW;t->hour = HOUR;t->min = MIN;t->sec = SEC;}#include"whole.h"#include"delay.h"#define ROW1 (1<<21) //P2.21#define ROW2 (1<<20) //P2.20#define ROW3 (1<<19) //P2.19#define ROW4 (1<<18) //P2.18#define COL1 (1<<17) //P2.17#define COL2 (1<<16) //P2.16#define COL3 (1<<21) //P1.21#define COL4 (1<<22) //P1.22void Key_Init(void){//-------定义为GPIO--------// PINSEL2=PINSEL2&0xffffffcf;// PINSEL2=PINSEL2&0xfffffff7;//-------方向-------------IO2DIR=(IO2DIR&(~ROW1)&(~ROW2)&(~ROW3)&(~ROW4)|COL1|COL2);IO1DIR=IO1DIR|COL3|COL4;//IO2CLR=COL1|COL2;//IO1CLR=COL3|COL4;}uint8 Key_Scan(void){uint8 key=0;//--------扫描第一列-------IO2CLR=COL1;IO2SET=COL2;IO1SET=COL3|COL4;if((IO2PIN&ROW1)==0){DelayMs(5);if((IO2PIN&ROW1)==0)key=1;}if((IO2PIN&ROW2)==0){DelayMs(5);if((IO2PIN&ROW2)==0)key=2;}if((IO2PIN&ROW3)==0){DelayMs(5);if((IO2PIN&ROW3)==0)key=3;}if((IO2PIN&ROW4)==0){DelayMs(5);if((IO2PIN&ROW4)==0)key=4;}//--------扫描第二列-------IO2CLR=COL2;IO2SET=COL1;IO1SET=COL3|COL4;if((IO2PIN&ROW1)==0){DelayMs(5);if((IO2PIN&ROW1)==0)key=5;}if((IO2PIN&ROW2)==0){DelayMs(5);if((IO2PIN&ROW2)==0)key=6;}if((IO2PIN&ROW3)==0){DelayMs(5);if((IO2PIN&ROW3)==0)key=7;}if((IO2PIN&ROW4)==0) {DelayMs(5);if((IO2PIN&ROW4)==0)key=8;}//--------扫描第三列-------IO1CLR=COL3;IO2SET=COL1|COL2;IO1SET=COL4;if((IO2PIN&ROW1)==0) {DelayMs(5);if((IO2PIN&ROW1)==0)key=9;}if((IO2PIN&ROW2)==0) {DelayMs(5);if((IO2PIN&ROW2)==0)key=10;}if((IO2PIN&ROW3)==0) {DelayMs(5);if((IO2PIN&ROW3)==0)key=11;}if((IO2PIN&ROW4)==0) {DelayMs(5);if((IO2PIN&ROW4)==0)key=12;}//--------扫描第四列-------IO1CLR=COL4;IO2SET=COL1|COL2;IO1SET=COL3;if((IO2PIN&ROW1)==0){DelayMs(5);if((IO2PIN&ROW1)==0)key=13;}if((IO2PIN&ROW2)==0){DelayMs(5);if((IO2PIN&ROW2)==0)key=14;}if((IO2PIN&ROW3)==0){DelayMs(5);if((IO2PIN&ROW3)==0)key=15;}if((IO2PIN&ROW4)==0){DelayMs(5);if((IO2PIN&ROW4)==0)key=0;}IO1CLR=COL3|COL4;IO2CLR=COL1|COL2;return(key);}#ifndef __RTC_H__#define __RTC_H__typedef struct{uint16 year;//年uint16 mon; //月uint16 day; //日uint16 dow; //星期uint16 hour; //时uint16 min; //分uint16 sec; //秒}TIME;extern void Set_Time(TIME *time);extern void RTC_Init(void); //RTC初始化] extern void GetTime(TIME *t);#endif。
嵌入式系统原理及应用大作业题目
嵌入式系统原理及应用大作业题目1、基于ARM的数字相框以实验箱为基础编程实现多幅图片(4幅以上,按照屏幕的分辨率选择图片即可)的显示。
可以裸机编程,也可建立于uC/osII操作系统平台基础上。
多幅图片换页显示,使用触摸屏进行翻页,手写笔向左滑动实现上一页图片显示,相反,手写笔向右滑动实现下一页图片显示。
扩展功能1,实现图片间切换的动态效果;扩展功能2,实现图片放大缩小的效果。
2、基于ARM的数字式万年历可以显示时、分、秒,倒计时,秒表等功能,显示器可选(数码管或液晶屏);要求使用LPC内部的实时时钟;实现按键调整时间。
扩展功能:用触屏查询。
3、基于ARM+LCD的菜单设计具有3级菜单,每级菜单至少3个菜单项。
扩展功能:每个菜单项设计一个小的演示功能。
4、公交报站显示器用触摸屏点击模拟到站,通过液晶显示提示信息(汉字)。
5、计算器用触摸屏做人机接口,实现软计算器。
6、直流电机控制用7290键盘控制直流电机转速,设置转速阈值,实现超限报警(闪灯)。
7、远程报警指示器通过RS485总线实现远程通信,报警端通过按键触发并蜂鸣,然后通过总线远传到显示端,显示端使用LCD显示报警的主机号,并蜂鸣;显示端实现回传信息撤销报警。
扩展功能:使用CAN总线替换RS485总线实现通信。
8、步进电机控制用LCD显示一个滑块控件,通过触摸屏操作滑块来设置步进电机转动的角度;扩展功能:实现顺、逆时针两个方向的转动;实现多级变速。
9、彩灯显示用触屏控制数码管、单色灯,实现8种以上的动态亮灯方案。
10、交通灯自行设定交通规则,要求在LCD显示器上画出交通灯模型,在数码管上显示交通灯的秒表倒计时数。
基于ARM的万年历(1) 精品
《嵌入式系统》课程设计报告基于ARM的万年历系统院系:机电学院学生姓名:专业:应用电子技术教育班级:指导教师:田丰庆付广春完成时间:2013年3月29日目录1 引言............................................. 错误!未定义书签。
2 STM32芯片RTC时钟介绍........................... 错误!未定义书签。
3 程序运行结果 (2)3.1 STM32管脚介绍.............................. 错误!未定义书签。
3.2 STM32复位电路和时钟设计 (2)4 总体设计框图 (3)5 程序运行结果图示................................. 错误!未定义书签。
6 程序流程图....................................... 错误!未定义书签。
7 总结体会 (5)8 参考文献 (6)附录一:总体电路图 (7)附录二:源程序 (8)基于ARM的万年历系统摘要:本设计选择STM32为核心控制元件,设计了用RTC定时器实现万年历的控制与设计。
程序使用C语言进行编程,能动态显示当前时间,包括年、月、日、时、分、秒,并且用串口助手显示。
关键词:STM32 ARM 时钟1 引言随着科技的发展,嵌入式系统广泛应用于工业控制和商业管理领域,在多媒体手机、袖珍电脑,掌上电脑,车载导航器等方面的应用,更是极大地促进了嵌入式技术深入到生活和工作各个方面。
嵌入式系统主要由嵌入式处理器、相关支撑硬件及嵌入式软件系统组成。
本文介绍基于STM32F103R6T6的嵌入式微处理器的万年历设计,并且在液晶上显示。
2 STM32芯片RTC时钟介绍STM32的实时时钟(RTC)是一个独立的定时器。
RTC模块拥有一组连续计数的计数器,在相应软件配置下,可以提供时钟日历的功能,修改计数器的值可以重新设置系统当前的时间和日期。
基于ARM的万年历
摘要现在是一个知识爆炸的新时代,新产品、新技术层出不穷,电子技术的发展更是日新月异。
可以毫不夸张的说,电子技术的应用无处不在,电子技术正在不断地改变我们的生活,改变着我们的世界。
在这快速发展的年代,时间对人们来说是越来越宝贵,在快节奏的生活时,人们往往忘记了时间,一旦遇到重要的事情而忘记了时间,这将会带来很大的损失。
因此我们需要一个定时系统来提醒这些忙碌的人,而数字化的钟表给人们带来了极大的方便。
电子万年历是一种非常广泛日常计时工作,对现代社会越来越流行。
它可以对年、月、日、周、时、分、秒进行计时。
由于单片机具有灵活性强、成本低、功耗低、保密性好等特点,所以电子日历时钟一般都以单片机为核心,外加一些外围设备来实现,可以显示年月日时分秒和温度信息,具有可调整日期和时间功能。
近些年,随着科技的发展和社会的进步,人们对数字钟的要求也越来越高,传统的时钟已不能满足人们的需求。
多功能数字钟不管在性能还是在样式上都发生了质的变化,有电子闹钟、数字闹钟等等。
单片机在多功能数字钟中的应用已是非常普遍的,人们对数字钟的功能及工作顺序都非常熟悉。
但是却很少知道它的内部结构以及工作原理。
由单片机作为数字钟的核心控制器,可以通过它的时钟信号进行计时实现计时功能,将其时间数据经单片机输出,利用显示器显示出来,通过按键可以进行定时、校时功能。
输出设备显示器可以用液晶显示技术和数码管显示技术。
目录1 ARM Cortex-M简介 (1)2 电子万年历的发展状况 (1)3 万年历硬件系统设计 (2)3.1 单片机内部主电路如图一所示 (2)3.2 时钟电路如图二所示 (2)4 程序流程图 (3)5 程序运行结果如图五所示 (4)6 研究目的与意义 (4)参考文献 (6)附录 (7)源程序 (7)1 ARM Cortex-M简介ARM Cortex-M系列主要用于微控制器单片机(MCU)领域,是为了那些对功耗和成本非常敏感,同时对性能要求不断增加的嵌入式应用(如微控制器系统、汽车电子与车身控制系统、各种家电、工业控制、医疗器械、玩具和无线网络等)所设计与实现的。
嵌入式智能万年历设计
任务要求:用ARM—M3芯片设计一个智能万年历,要求能够正确显示近100 年时间,星期几,时间格式为****年**月**日(星期**) **:**:**(时:分:秒),能够识别出闰年(计时范围能够从1970年1月1日到2100年左右)。
该程序设计工程里包含有main.c(相关配置、和终端联系,提醒输出初始时间、输出实时时间)/date.c(计算实时时间)/stm32f10x_it.c三个文件,各文件内容如下。
Main.c文件:#include "stm32f10x.h"#include "stdio.h"#include "date.h"__IO uint32_t TimeDisplay = 0;void RCC_Configuration(void);void NVIC_Configuration(void);void GPIO_Configuration(void);void USART_Configuration(void);int fputc(int ch, FILE *f);void RTC_Configuration(void);void Time_Regulate(struct rtc_time *tm);void Time_Adjust(void);void Time_Display(uint32_t TimeVar);void Time_Show(void);u8 USART_Scanf(u32 value);#define RTCClockSource_LSEu8 const *WEEK_STR[] = {"日", "一", "二", "三", "四", "五", "六"};struct rtc_time systmtime;int main(){RCC_Configuration();NVIC_Configuration();GPIO_Configuration();USART_Configuration();/*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5,则需重新配置时间并询问用户调整时间*/printf("\r\n\n RTC not yet configured....");RTC_Configuration();printf("\r\n RTC configured....");Time_Adjust();BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);}else{/*启动无需设置新时钟*//*检查是否掉电重启*/if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET){printf("\r\n\n Power On Reset occurred....");}/*检查是否Reset复位*/else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET){printf("\r\n\n External Reset occurred....");}printf("\r\n No need to configure RTC....");/*等待寄存器同步*/RTC_WaitForSynchro();/*允许RTC秒中断*/RTC_ITConfig(RTC_IT_SEC, ENABLE);/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();}#ifdef RTCClockOutput_EnableRCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE); PWR_BackupAccessCmd(ENABLE);BKP_TamperPinCmd(DISABLE);BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);RCC_ClearFlag();Time_Show();}void RCC_Configuration(){SystemInit();RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);}void NVIC_Configuration(){NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}void GPIO_Configuration(){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA, &GPIO_InitStructure);}void USART_Configuration(){USART_InitTypeDef USART_InitStructure;USART_ART_WordLength = USART_WordLength_8b;USART_ART_StopBits = USART_StopBits_1;USART_ART_Parity = USART_Parity_No ;USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(USART1, &USART_InitStructure);USART_Cmd(USART1, ENABLE);}int fputc(int ch, FILE *f){/* 将Printf内容发往串口 */USART_SendData(USART1, (unsigned char) ch);while (!(USART1->SR & USART_FLAG_TXE));return (ch);}void RTC_Configuration(){/*允许PWR和BKP时钟*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);/*允许访问BKP域*/PWR_BackupAccessCmd(ENABLE);/*复位备份域*/BKP_DeInit();#ifdef RTCClockSource_LSI/*允许LSI*/RCC_LSICmd(ENABLE);/*等待LSI准备好*/while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET){}/*选择LSI作为RTC时钟源*/RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);#elif defined RTCClockSource_LSE/*允许LSE*/RCC_LSEConfig(RCC_LSE_ON);/*等待LSE准备好*/while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET){}/*选择LSE作为RTC时钟源*/RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);#endif/* Enable RTC Clock */RCC_RTCCLKCmd(ENABLE);#ifdef RTCClockOutput_Enable/*禁止Tamper引脚*/BKP_TamperPinCmd(DISABLE);/*为了将RTCCLK/64在Tamper引脚输出,Tamper功能必须被禁止*//*允许RTC时钟在Tamper引脚上输出*/BKP_RTCCalibrationClockOutputCmd(ENABLE);#endif/*等待寄存器同步*/RTC_WaitForSynchro();/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();/*允许RTC秒中断*/RTC_ITConfig(RTC_IT_SEC, ENABLE);/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();#ifdef RTCClockSource_LSI/*设置分频系数*/RTC_SetPrescaler(31999); /*RTC周期=RTCCLK/RTC_PR=(32.000kHz/(31999+1))*/#elif defined RTCClockSource_LSERTC_SetPrescaler(32767); /*RTC周期=RTCCLK/RTC_PR=(32.768kHz/(31767+1))*/ #endif/*等待上次RTC寄存器写操作完成*/RTC_WaitForLastTask();}void Time_Regulate(struct rtc_time *tm){u32 Tmp_YY = 0xFF, Tmp_MM = 0xFF, Tmp_DD = 0xFF, Tmp_HH = 0xFF, Tmp_MI = 0xFF, Tmp_SS = 0xFF;printf("\r\n=========================Time Settings==================");printf("\r\n 请输入年份(Please Set Years): 20");while (Tmp_YY == 0xFF){Tmp_YY = USART_Scanf(99);}printf("\n\r 年份被设置为: 20%0.2d\n\r", Tmp_YY);tm->tm_year = Tmp_YY+2000;Tmp_MM = 0xFF;printf("\r\n 请输入月份(Please Set Months): ");while (Tmp_MM == 0xFF){Tmp_MM = USART_Scanf(12);}printf("\n\r 月份被设置为: %d\n\r", Tmp_MM);tm->tm_mon= Tmp_MM;Tmp_DD = 0xFF;printf("\r\n 请输入日期(Please Set Dates): ");while (Tmp_DD == 0xFF){Tmp_DD = USART_Scanf(31);}printf("\n\r 日期被设置为: %d\n\r", Tmp_DD);tm->tm_mday= Tmp_DD;Tmp_HH = 0xFF;printf("\r\n 请输入时钟(Please Set Hours): ");while (Tmp_HH == 0xFF){Tmp_HH = USART_Scanf(23);}printf("\n\r 时钟被设置为: %d\n\r", Tmp_HH );tm->tm_hour= Tmp_HH;Tmp_MI = 0xFF;printf("\r\n 请输入分钟(Please Set Minutes): ");while (Tmp_MI == 0xFF){Tmp_MI = USART_Scanf(59);}printf("\n\r 分钟被设置为: %d\n\r", Tmp_MI);tm->tm_min= Tmp_MI;Tmp_SS = 0xFF;printf("\r\n 请输入秒钟(Please Set Seconds): ");while (Tmp_SS == 0xFF){Tmp_SS = USART_Scanf(59);}printf("\n\r 秒钟被设置为: %d\n\r", Tmp_SS);tm->tm_sec= Tmp_SS;}void Time_Adjust()RTC_WaitForLastTask();Time_Regulate(&systmtime);GregorianDay(&systmtime);RTC_SetCounter(mktimev(&systmtime));RTC_WaitForLastTask();}void Time_Display(uint32_t TimeVar){to_tm(TimeVar, &systmtime);printf("\r 当前时间为: %d年 %d月 %d日 (星期%s) %0.2d:%0.2d:%0.2d", systmtime.tm_year, systmtime.tm_mon, systmtime.tm_mday, WEEK_STR[systmtime.tm_wday], systmtime.tm_hour,systmtime.tm_min, systmtime.tm_sec);}void Time_Show(){printf("\n\r");/* Infinite loop */while (1){/* 每过1s */if (TimeDisplay == 1){Time_Display(RTC_GetCounter());TimeDisplay = 0;}}}u8 USART_Scanf(u32 value){u32 index = 0;u32 tmp[2] = {0, 0};{while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}tmp[index++] = (USART_ReceiveData(USART1));if ((tmp[index - 1] < 0x30) || (tmp[index - 1] > 0x39)) /*数字0到9的ASCII 码为0x30至0x39*/{if((index == 2) && (tmp[index - 1] == '\r')){tmp[1] = tmp[0];tmp[0] = 0x30;}else{printf("\n\rPlease enter valid number between 0 and 9 -->: ");index--;}}}/* 计算输入字符的相应ASCII值*/index = (tmp[1] - 0x30) + ((tmp[0] - 0x30) * 10);/* Checks */if (index > value){printf("\n\rPlease enter valid number between 0 and %d", value);return 0xFF;}return index;}Date.c文件内容如下:#include "date.h"#define FEBRUARY 2#define STARTOFTIME 1970#define SECDAY 86400L#define SECYR (SECDAY * 365)#define leapyear(year) ((year) % 4 == 0)#define days_in_month(a) (month_days[(a) - 1])static int month_days[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };/*计算公历*/void GregorianDay(struct rtc_time * tm){int leapsToDate;int lastYear;int day;int MonthOffset[] = { 0,31,59,90,120,151,181,212,243,273,304,334 };lastYear=tm->tm_year-1;/*计算到计数的前一年之中一共经历了多少个闰年*/leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;/*如若计数的这一年为闰年,且计数的月份在2月之后,则日数加1,否则不加1*/ if((tm->tm_year%4==0) && ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && (tm->tm_mon>2)){day=1;}else{day=0;}day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + tm->tm_mday; /*计算从计数元年元旦到计数日期一共有多少天*/tm->tm_wday=day%7;}u32 mktimev(struct rtc_time *tm){if (0 >= (int) (tm->tm_mon -= 2)){tm->tm_mon += 12;tm->tm_year -= 1;}return ((((u32) (tm->tm_year/4 - tm->tm_year/100 + tm->tm_year/400 + 367*tm->tm_mon/12 + tm->tm_mday)}void to_tm(u32 tim, struct rtc_time * tm){register u32 i;register long hms, day;day = tim / SECDAY;hms = tim % SECDAY;tm->tm_hour = hms / 3600;tm->tm_min = (hms % 3600) / 60;tm->tm_sec = (hms % 3600) % 60;/*算出当前年份,起始的计数年份为1970年*/for (i = STARTOFTIME; day >= days_in_year(i); i++) {day -= days_in_year(i);}tm->tm_year = i;/*计算当前的月份*/if (leapyear(tm->tm_year)){days_in_month(FEBRUARY) = 29;}for (i = 1; day >= days_in_month(i); i++){day -= days_in_month(i);}days_in_month(FEBRUARY) = 28;tm->tm_mon = i;/*计算当前日期*/tm->tm_mday = day + 1;GregorianDay(tm);}stm32f10x_it.c文件内容:#include "stm32f10x_it.h"extern uint32_t TimeDisplay;void NMI_Handler(void){}/*** @brief This function handles Hard Fault exception.* @param None* @retval : None*/void HardFault_Handler(void){/* Go to infinite loop when Hard Fault exception occurs */while (1){}}/*** @brief This function handles Memory Manage exception.* @param None* @retval : None*/void MemManage_Handler(void){/* Go to infinite loop when Memory Manage exception occurs */ while (1){}}/*** @brief This function handles Bus Fault exception.* @param None* @retval : None*/void BusFault_Handler(void){/* Go to infinite loop when Bus Fault exception occurs */while (1){}}* @brief This function handles Usage Fault exception.* @param None* @retval : None*/void UsageFault_Handler(void){/* Go to infinite loop when Usage Fault exception occurs */ while (1){}}/*** @brief This function handles SVCall exception.* @param None* @retval : None*/void SVC_Handler(void){}/*** @brief This function handles Debug Monitor exception.* @param None* @retval : None*/void DebugMon_Handler(void){}/*** @brief This function handles PendSVC exception.* @param None* @retval : None*/void PendSV_Handler(void){}/*** @brief This function handles SysTick Handler.* @param None* @retval : None*/}void RTC_IRQHandler(void){if (RTC_GetITStatus(RTC_IT_SEC) != RESET){/* Clear the RTC Second interrupt */RTC_ClearITPendingBit(RTC_IT_SEC);/* Enable time update */TimeDisplay = 1;/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();/* Reset RTC Counter when Time is 23:59:59 */if (RTC_GetCounter() == 0x00015180){RTC_SetCounter(0x0);/* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask();}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
龙岩学院
实验报告
班级07电本一班学号2007050326 姓名刘桂银同组人实验日期室温大气压成绩
(3)GPIO电路两种应用电路
1.无需上拉电阻的 GPIO
LPC2131 大多数GPIO都属于这种情况,这类GPIO的典型电路如下图所示,采用灌电流方式驱动需加一定阻值(如 470Ω)的限流电阻即可。
但也有例外,如下图所示,当P0 口连接GPIO且用于输入时,例如用于检测按键的时
GPIO输入时,内部无上拉电阻,所以需要加 10K左右的上拉电阻,把I/O 口拉到高电平。
在这种应用中,需要将(相应端口,这里为 P0.0)P0.0 设置为输入状态,然后读取
当按键 S0 按下时,P0.0 端口接地,将会读回 0,若松开按键 S0,P0.0 接高电
.需要上拉电阻的 GPIO
这里所说的上拉电阻是因为 I/O 口自身结构要求的上拉电阻。
LPC2131
口(P0.2-SCL、P0.3-SDA0;P0.11-SCL1、P0.14-SDA1)为开漏输出,
时,需要加 1K~10KΩ的上拉电阻。
用作 I C 总线时的典型电路如所示。
特性:
图一按键电路原理图
图二RTC功能结构图
)使用举例
先假设一个最简单的状况,pclk频率为65.537KHz。
那么:PREINT = int (pclk/32768) ((PREINT+1)×32768) = 1 使用此设定,每秒钟有32767次2个pclk周期计数,。