下面代码是数码管时钟的代码,断断续续学习了好几天
MAIN.C
#include "config.h"
#include "task.h"
#include "io.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
void main(void)
{
Sys_init();
usb_init(); //USB CDC 接口配置
Timer0_Init(); //定时器初始化
IE2|=0x80; //使能USB中断
Init_595(); //595端口的初始化
EA = 1; //开总中断吗?
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
P40=0;
while (1)
{
if (bUsbOutReady) //如果接收到了数据
{
//USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
usb_OUT_done();
}
//下面写代码
Task_Pro_Handler_Callback();
}
}
void Timer0_Isr(void) interrupt 1 //1m秒中断执行一次
{
Task_Marks_Handler_Callback();
}
CONFIG.C
#include "config.h"
void Sys_init(void)
{
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00; //设置为准双向口
P1M1 = 0x00; P1M0 = 0x00; //设置为准双向口
P2M1 = 0x00; P2M0 = 0x00; //设置为准双向口
P3M1 = 0x00; P3M0 = 0x00; //设置为准双向口
P4M1 = 0x00; P4M0 = 0x00; //设置为准双向口
P5M1 = 0x00; P5M0 = 0x00; //设置为准双向口
P6M1 = 0x00; P6M0 = 0x00; //设置为准双向口
P7M1 = 0x00; P7M0 = 0x00; //设置为准双向口
}
void Timer0_Init(void) //1毫秒@24.000MHz
{
TM0PS = 0x00; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初始值
TH0 = 0xF8; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
////////TASK.C
#include "task.h"
#include "io.h"
static TASK_COMPONENTS Task_Comps[]=
{
//状态 计数 周期 函数
// {0, 1, 1, Sample_Display}, /* task 1 Period: 1ms */
// {0, 10, 10, Sample_MatrixKey}, /* task 2 Period: 10ms */
// {0, 10, 10, Sample_adcKey}, /* task 3 Period: 10ms */
// {0, 300, 300, Sample_NTC}, /* task 4 Period: 300ms */
// {0, 500, 500, Sample_RTC}, /* task 5 Period: 500ms */
// /* Add new task here */
// {0,300,300,LED0_Blink},
// {0,600,600,LED1_Blink},
// {0,2000,2000,LED2_Blink},
{0,10,10,Key_Task},
{0,1,1,Seg_Task},
{0,1000,1000,run},
};
u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
u8 i;
for(i=0; i<Tasks_Max; i++) //循环好几次,几个任务几个循环
{
if(Task_Comps[i].TIMCount) /* If the time is not 0 */ //如果计数不为0
{
Task_Comps[i].TIMCount--; /* Time counter decrement */ //计数减减
if(Task_Comps[i].TIMCount == 0) /* If time arrives */ //如果计数减到0
{
/*Resume the timer value and try again */
Task_Comps[i].TIMCount = Task_Comps[i].TRITime; //重装计数
Task_Comps[i].Run = 1; /* The task can be run */ //将run置为1
}
}
}
}
//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
u8 i;
for(i=0; i<Tasks_Max; i++) //循环好几次,几个任务几个循环
{
if(Task_Comps[i].Run) /* If task can be run */ //如果哪个任务的run参数为1
{
Task_Comps[i].Run = 0; /* Flag clear 0 */ //那么就将rin标志清0
Task_Comps[i].TaskHook(); /* Run task */ //并且执行这个任务的任务
}
}
}
////////IO.C
#include "io.h"
u8 SEG_NUM[]=
{
0x3F, /*'0', 0*/
0x06, /*'1', 1*/
0x5B, /*'2', 2*/
0x4F, /*'3', 3*/
0x66, /*'4', 4*/
0x6D, /*'5', 5*/
0x7D, /*'6', 6*/
0x07, /*'7', 7*/
0x7F, /*'8', 8*/
0x6F, /*'9', 9*/
0x77, /*'A', 10*/
0x7C, /*'B', 11*/
0x39, /*'C', 12*/
0x5E, /*'D', 13*/
0x79, /*'E', 14*/
0x71, /*'F', 15*/
0x40, /*'-', 16*/
0x00, /*' ', 17*/
0x80, /*'.', 18*/
};
u8 wei[]=
{
0xfe, /*'0', 0*/
0xfd, /*'1', 1*/
0xfb, /*'2', 2*/
0xf7, /*'3', 3*/
0xef, /*'4', 4*/
0xdf, /*'5', 5*/
0xbf, /*'6', 6*/
0x7f, /*'7', 7*/
};
u8 State0=0; //LED1的初始状态
u8 State1=0; //LED2的初始状态
u8 State2=0; //LED3的初始状态
u16 key_vol=0;
u8 shi=00;
u8 fen=00;
u8 miao=00;
void LED0_Blink(void)
{
State0=!State0;
P00=State0;
}
void LED1_Blink(void)
{
State1=!State1;
P01=State1;
}
void LED2_Blink(void)
{
State2=!State2;
P02=State2;
}
void Key_Task(void)
{
if(P33==0)
{
key_vol++;
if(key_vol==5)
{
//执行按键按下的代码
printf("按键单击\r\n");
shi=0;
fen=0;
miao=0;
}
}
else
{
key_vol=0;
}
}
u8 shishi[]=
{
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
void run(void)
{
miao++;
if(miao>=60)
{
miao=0;
fen++;
if(fen>=60)
{
shi++;
if(shi>=24)
{
shi=0;
}
}
}
shishi[0]=shi/10;
shishi[1]=shi%10;
shishi[2]=16;
shishi[3]=fen/10;
shishi[4]=fen%10;
shishi[5]=16;
shishi[6]=miao/10;
shishi[7]=miao%10;
}
void Init_595(void)
{
HC595_SER=0;
HC595_RCK=0;
HC595_SCK=0;
}
void Send_595(u8 dat)
{
u8 i;
for(i=0;i<8;i++)
{
dat<<=1; //dat左移一位
HC595_SER=CY; //然后给到数据引脚
HC595_SCK=1; //输出上升沿的时钟信号
HC595_SCK=0; //请0以备下次输出
//printf("%d\r\n",HC595_SER);
}
}
void Display_Seg(u8 HC595_1,u8 HC595_2)
{
Send_595(HC595_1); //段码输出,高电平点亮
Send_595(HC595_2); //位码输出,低电平点亮
HC595_RCK=1;
HC595_RCK=0;
}
u8 i=0;
u8 num=0;
void Seg_Task(void)
{
if(i==0)
{
num=shi/10;
}
else if(i==1)
{
num=shi%10;
}
else if(i==2)
{
num=18;
}
else if(i==3)
{
num=fen/10;
}
else if(i==4)
{
num=fen%10;
}
else if(i==5)
{
num=18;
}
else if(i==6)
{
num=miao/10;
}
else if(i==7)
{
num=miao%10;
}
Display_Seg(SEG_NUM[num],wei[i]);
i++;
if(i>=8)
{
i=0;
}
}