⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 代码.txt

📁 该代码就是本人编写的关于arm9 2410板子上的蜂鸣器的程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:


//main.c
#include "includes.h"              		
#include "def.h"
#include "44b.h"
#include "44blib.h"
#include "lcd.h"
#include "OUR_RTC.h"
#include "8led.h"
#define STACKSIZE 512										
extern RTC_TIME sys_time;
OS_STK Task_ShowTime_Stack[STACKSIZE];
OS_STK Task_ShowMin_Stack[STACKSIZE];
OS_STK Task_Beep_Stack[STACKSIZE];
OS_STK Task_Start_Stack[STACKSIZE];

//这是用于串口打印的信号量
OS_EVENT* uart_sem;

//用于控制蜂鸣器的信号量!!
OS_EVENT* beep_sem;
//用于板子的初始化
void board_init();

//起始任务,用于创建任务~
void Start_Task(void * pdata);
void ShowTime_Task(void* pdata);
void ShowMit_Task(void*pdata);
void Beep_Task(void*pdata);
//时钟滴答中断服务函数要调用这个函数
void RTC_TICKInt(void);
//RTC报警中断服务函数
void ISR_RTC_AlarmInt(void);
void Main()
{
	board_init();
	OSInit();
	OSTimeSet(0);
	uart_sem = OSSemCreate(0);//初始值为0因为中断服务函数中会对该信号量进行
	beep_sem = OSSemCreate(0);//
	
	OSTaskCreate(Start_Task, (void *)0, &Task_Start_Stack[STACKSIZE - 1], 20);
	OSStart();
}
void Start_Task(void*pdata)
{
	pdata=pdata;
	enableInt();//打开时钟中断以及报警中断
	OSTaskCreate(ShowTime_Task,(void*)0,&Task_ShowTime_Stack[STACKSIZE-1],19);
	OSTaskCreate(ShowMit_Task,(void*)0,&Task_ShowMin_Stack[STACKSIZE-1],18);
	OSTaskCreate(Beep_Task,(void*)0,&Task_Beep_Stack[STACKSIZE-1],17);
	
	OSTaskDel(OS_PRIO_SELF);
}
/*
这个任务用来向八段管送数据控制八段管的数据更新
*/
void ShowTime_Task(void *pdata)
{
	pdata = pdata;
	while(1)
	{
		OSTimeDly(OS_TICKS_PER_SEC/2);//每个0.5秒钟就要像LED中写入新的数据
		rtc_read();
		writeTime(sys_time.Hour,sys_time.Min,sys_time.Sec);
	}
	//
}
/*
这个任务用来控制通过串口来打印日期以及时间
*/
void ShowMin_Task(void*pdata)
{
	INT8U error;
	pdata = pdata;
	while(1)
	{
		OSSemPost(uart_sem,0,&error);//等待信号量
		//到了正分因此打印
		rtc_printf();
	}
}
/*
这个任务用来控制蜂鸣器整时报警
*/
void Beep_Task(void *pdata)
{
	INT8U error;
	int times=0;//该变量保存当前小时数,用来控制报名的次数;
	pdata = pdata;
	while(1)
	{
		OSSemPost(beep_sem,0,&error);
		//到了正点因此蜂鸣器报时
		//由于在终端服务函数中已经更新了sys_time中的数据,因此这里的小时数已经是最新的了
		//只用把其读出来即可;
		times =(int) BCDToBin(sys_time.Hour);
		while(times--)
		{
			beep_on();
			OSTimeDly(OS_TICKS_PER_SEC/10);//蜂鸣0.1S
			beep_off();
			OSTimeDly(OS_TICKS_PER_SEC);//等待1 S
		}
	}
}
//其实RTC_TICKInt就是向系统告知滴答,并且清除中断
void RTC_TICKInt(void) 
{
	//清除中断挂起寄存器中的相应位!
	rI_ISPC | = BIT_TICK;
	OSTimeTick();
}
void RTC_AlarmInt(void)
{
	//清除中断挂起寄存器中的相应位!
	rI_ISPC | = BIT_RTC;
	rtc_read();//进行一次读操作将当前的时间以及日期信息放入全局变量sys_time中
	
	OSSemPost(uart_sem);
	if(BCDToBin(sys_time.Min+1)==0)
	{
		OSSemPost(beep_sem);//整点了
	}
	setAlarmMin();
}
/*
进行板子的初始化
由于我们的板子中只有rtc iic,以及uart因此我们只执行这几个函数
*/
//初始化时候要和用户进行交互设置时间以及日期
void board_init()
{
	
	rtc_init();
	uart_init();
	iic_int();
	rtc_set_date();//与用户交互进行日期设置
	rtc_set_time();//与用户进行交互进行时间设置
}
//END OF MAIN.C

//OUR_RTC.h
//在这个文件中我们主要是定义了一些与RTC操作有关的一些函数!
#ifndef __RTC__
#define __RTC__
//定义了用来存放日期以及时间的一个struct结构体
struct RTC_TIME {
    unsigned char Year;
    unsigned char Mon;
    unsigned char Day;
    unsigned char Hour;
    unsigned char Min;
    unsigned char Sec;
};
RTC_TIME sys_time=//全局变量用来存放当前的日期时间以及默认的时间
{                 //默认时间是2008-4-18-0:0:0
	8,
	4,
	18,
	0,
	0,
	0
}
void rtc_init(void);//rtc初始化函数主要用来定义各个寄存器的值以及与用户交互设置时间
void rtc_read();//用来读取RTC时钟的函数,结果放到了sys_time中;
void rtc_write(RTC_TIME*src);//用一个RTC_TIME中的数据来设置日期以及时间
void rtc_printf();//用来打印当前的日期以及时间
void rtc_set_date();//设置日期
void rtc_set_time();//设置时间
int check_date(char*date);//用来检查日期是否合法
int check_time(char*time);//用来检查时间是否合法
//下面这两个函数主要是被其他函数调用
unsigned char BinToBCD(unsigned char bin);//将一个二进制编码的字符转化为BCD编码的字符
unsigned char BCDToBin(unsigned char bcd);//将一个BCD编码的字符转化为二进制编码的字符;

//这两个函数的作用很明白了这里不用解释了
void translate_bin_to_bcd(RTC_TIME* src,RTC_TIME*des);
void translate_bcd_to_bin(RTC_TIME* src,RTC_TIME*des);
void enableInt();//允许RTC_TICK和RTC_Alarm中断
void setAlarmMin();//将AlarmMin设置为下一分钟,这样就可以实现每一分钟都会产生一个alarm

void beep_init();//用来初始化端口E(我们用来控制蜂鸣器的一个端口)
void beep_on();//用来使我们的蜂鸣器报时的函数
void beep_off();//关闭蜂鸣器报时的函数
#endif
//END OF  OUR_RTC.h文件


//BEGIN OUR_RTC.c文件
#include "OUR_RTC.h"
#include "44b.h"
#include "44blib.h"
int dayOfMonth[13]={-1,31,28,31,30,31,30,31,31,30,31,30,31};

extern void ISR_RTC_AlarmInt(void);//在main.c中定义的Alarm中断服务函数
extern void RTCTickHandler(void);//在os_cup_a.s文件中定义的


/*rtc初始化函数
*/
void rtc_init()
{
	rRTCCON  = 0x01;//RTC不复位,组合的BCD计数器,时钟1/2^15,RTC读写允许
	rtc_write(&sys_time);//将默认的数值写入到rtc中
	rRTCCON & = ~0x1;//禁止读写;
	//因为要与用户进行交互因而这个地方先禁止中断
    rINTMSK	= 0x07FFFFFF;
	rRTCALM | = 0x42;//分Alarm允许;其他Alarm都是不允许的因为rRTCALM的默认值是0x0
	rALMMIN = BinToBCD((sys_time.Min+1)%60);////将告警分数据寄存器中的初始值设为初始时间的下一分;
	rTICNT = 7+1<<7;//允许滴答中断,同时将计数器内部值置为7,这个样每秒钟将产生128/(n+1) = 16个时钟滴答中断
	pISR_RTC	= (unsigned) ISR_RTC_AlarmInt;
	pISR_TICK   =  (unsigned) ISRTickHandler;
}

/*
很简单的一个工具函数主要用来允许中断
*/
void enableInt()
{
	rINTMSK &=  (~(BIT_GLOBAL|BIT_RTC));//允许RTC告警中断
	rINTMSK &= (~(BIT_GLOBA|BIT_TICK));//允许时间滴答中断
}

/*
将当前的时间读入到sys_time全局变量中
*/
void rtc_read()
{
	int tmp = 0;
	//打开读写允许位!
	rRTCCON | = 0x1;
	while(tmp<=2)//为了防止一秒偏差的问题,需要这个循环来控制
	{
		sys_time.Year = bcd_to_bin(rBCDYEAR)+2000;
		sys_time.Mon  = bcd_to_bin(rBCDMON);
		sys_time.Day  = bcd_to_bin(rBCDDAY);
		sys_time.Hour = bcd_to_bin(rBCDHOUR);
		sys_time.Min  = bcd_to_bin(rBCDMIN);
		sys_time.Sec  = bcd_to_bin(rBCDSEC);
		if(sys_time.Sec !=0)break;
		tmp ++;
	}
	//禁止读写,为了减小STOP电流
	rRTCCON & = 0xfffffffe;
}

/*
将RTC_TIME中的数据写入到RTC寄存器中

Note:src中的数据是按照8421编码格式的数据!
*/
void rtc_write(RTC_TIME*src)
{
	RTC_TIME des;
	translate_bin_to_bcd(src,&des);
	//开始写了要打开允许位
	rRTCCON | = 0x1;
	rBCDYEAR = des.Year;
	rBCDMON  = des.Mon;
	rBCDDAY  = des.Day;	
	rBCDHOUR = des.Hour;
	rBCDMIN  = des.Min;
	rBCDSEC  = des.Sec;
	rALMMIN  = BinToBCD((src->Min+1)%60);//将rALMMIN中的数据设为下一分
	//禁止读写,为了减小STOP电流
	rRTCCON & = 0xfffffffe;
}

/*
与用户交互设置时间
*/
void rtc_set_date()
{
	char tmp;
	char date[11];//日期格式是YYYY-MM-DD的格式
	unsigned char year;
	unsigned char month;
	unsigned char day;
	int validate = 0;
	uart_printf("Would like to set the date and time?(Y/N)\n");
	delay(10);
	tmp = uart_getch();
	uart_sendbyte(c);//回显
	uart_sendbyte('\n');
	if(tmp!='Y'||tmp!='y')
		return;
	else
	{
		while(1)
		{
			uart_printf("Please input your date in the form of (YYYY-MM-DD);\nNote YYYY must between 2000 and 2099\n");
			uart_getstring(date);
			validate = check_date(date);
			if(validate==1)
			{
				//日期是合法的
				year=(date[0]-'0')*1000+(date[1]-'0')*100+(date[2]-'0')*10+date[3]-'0';
				year = BinToBCD(year);
				month =(date[5]-'0')*10+date[6]-'0';
				month = BinToBCD(month);
				day = BinToBCD(day);
				//因为要开始写了所以允许RTCCON应该允许写

				rRTCCON | = 0x1;
				rBCDYEAR = year;
				rBCDMON = month;
				rBCDDAY = day;
				//禁止读写,为了减小STOP电流
				rRTCCON & = 0xfffffffe;
				break;
			}
			else
			{
				uart_printf("Please check your input, there is something wrong!\n");
				delay(10);
			}
		}
	}
	return;	

}

/*
与用户交互设置时间
*/
void rtc_set_time()
{
	int validate;
	unsigned char hour,min,sec;
	char time[9];
	char choose;
	uart_printf("Would you like to set the time now?(Y/N)");
	choose = uart_getch();
	uart_sendbyte(choose);//回显
	if(choose!='Y'||choose!='y')
		return;
	while(1)
	{
		uart_printf("Please input the time you would like to set int the form of HH-MM-SS\n");
		uart_getstring(time);
		validate = check_time(time);
		if(validate==0)
		{
			uart_printf("There is something wrong,Please check\n");
			delay(10);
		}
		else
		{
				//时间是合法的
			hour = (time[0]-'0')*10+time[1]-'0';
			min = (time[3]-'0')*10+time[4]-'0';
			sec = (time[6]-'0')*10+time[7]-'0';

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -