您的位置:首页 > 其它

基于操作系统的键盘板显示程序(LPC2103版本)

2010-12-11 17:04 288 查看
/********************************** "3+1"班专用easyARM2103的uc/OS II模板*********************************
** 程序名称:dis_key_board
** 程序作者:LiuYingzi
** 修改日期: 2010-11-29
** 程序版本:V1.0
** 程序描述:操作系统下的键盘显示板
*********************************************************************************************************/
#include "main.h"
#define KEY 1<<5
uint32 Fpwm=9876;
uint32 i=0; //用于扫描按键
uint32 Witchkeydown=8; //记录哪个键按下
uint32 Move=8; //由于记录当前修改的数据位
uint8 segnumber[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67,0x00};//0~9及黒码
uint8 bitnumber[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码
uint8 data[8]={1,2,3,4,10,10,10,10};
/*********************************************************************************************************
TASK0 任务优先级、堆栈设置及函数声明
*********************************************************************************************************/
#define STACK_SIZE 64 //定义堆栈的长度
OS_STK Disp_STACK[STACK_SIZE]; //定义堆栈
OS_STK Key_STACK[STACK_SIZE];
void TaskDisp(void *pdata);
void TaskKey(void *pdata);
/*********************************************************************************************************
** Function name: main
** Descriptions: 主函数
** Input parameters: None
** output parameters: None
** Created Date: 2010-11-28
*********************************************************************************************************/
int main (void)
{
OSInit();
OSTaskCreate(TaskKey,(void *)0,&Key_STACK[STACK_SIZE-1],6);
OSTaskCreate(TaskDisp,(void *)0,&Disp_STACK[STACK_SIZE-1],10);
OSStart();
return 0;
}
/*******************************************************************************************************
Conver()把数据转换成数字,用于显示,高位的零去掉
*******************************************************************************************************/
void Conver(uint32 value,uint8 *d)
{
uint8 *p=d; //四位数据转化的数字要存放的地方。
uint8 temp1=0,temp2=0,temp3=0;
temp1=value/1000;
if(0==temp1) //千位==0
{
*(p--)=10;
}
else //千位不为0
{
*(p--)=temp1;
}
temp2=value/100-temp1*10;
if((0==temp1)&&(0==temp2)) //temp1,temp2放置的顺序可以减少时间
{
*(p--)=10;
}
else //百位不为0
{
*(p--)=temp2;
}
temp3=value/10-temp1*100-temp2*10;
if((0==temp1)&&(0==temp2)&&(0==temp3)) //temp1,temp2存放的顺序可以减少时间
{
*(p--)=10;
}
else //十位不为0
{
*(p--)=temp3;
}
temp3=value%10;
*p=temp3;
}
/********************************************************************************************************
SPI初始化
*******************************************************************************************************/
void SPIInit(void)
{
SPI_SPCCR=0x08; //设置时钟分频,必须为大于8的偶数
SPI_SPCR=0<<3 | //第一个时钟沿采样
1<<4 | //sclk低电平有效
1<<5 | //设置为主模式
0<<6 | //MSB,高位在前发送
0<<7 ; //禁止中断
}
/********************************************************************************************************
SPI发送数据
*******************************************************************************************************/
uint8 SPISendData(uint8 number)
{
SPI_SPDR=number;
while(0==(SPI_SPSR&0x80));
return SPI_SPDR;
}
/*********************************************************************************************************
** Function name: PINInit
** Descriptions: 引脚的初始化
** Input parameters: None
** output parameters: None
** Created Date: 2006-04-11
*********************************************************************************************************/
void PINInit()
{
PINSEL0=0; //初始化一下,心里比较有底
//p0.17----GPIO
PINSEL1&=~(0x03<<2);
IODIR|=1<<17;
IOSET=1<<17;
//p0.7--勿设置为SSEL功能(不要让ARM作为从机,否则出现模式错误)
//p0.4-->clk,p0.5-->MISO,p0.6-->MOSI
PINSEL0=((PINSEL0&~(0x3f<<8))|(0x15<<8));
}
/*********************************************************************************************************
** Function name: TASK0
** Descriptions: None
** input parameters: None
** output parameters: None
*********************************************************************************************************/
void TaskKey (void *pdata)
{
uint32 modifing=0; //用于标志修改模式,为0 表示为修改模式,为255 非修改模式
pdata = pdata;
TargetInit();
PINInit();
SPIInit();
while(1) {
if((IOPIN&KEY)==0)
{
Witchkeydown=i;
}
else
{
if(Witchkeydown==i)
{
switch(i)
{
case 1: //修改模式键
{
modifing=~modifing;
Move=11;
}
break;
case 2: //移位键
{
if(0==modifing)
{
Move=(Move+1)%4; //Move限于0~3
}
}
break;
case 3: //加法键
{
if(0==modifing)
{
data[Move]=(data[Move]+1)%10;
}
}
break;
case 4: //确定按键
{
if(0==modifing)
{
modifing=~modifing;
Move=8; //清除移位标志
Fpwm=data[3]*1000+data[2]*100+data[1]*10+data[0];
//T1Init();
}
}
break;
default:
break;
}
Witchkeydown=8; //清除按键
}
}
OSTimeDlyHMSM(0,0,0,5); //每个10ms来判断是否有键按下
}
}
/*********************************************************************************************************
** Function name: TASK0
** Descriptions: None
** input parameters: None
** output parameters: None
*********************************************************************************************************/
void TaskDisp(void *pdata)
{
uint32 senddata=0;
uint32 count=0;
pdata = pdata;
Conver(Fpwm,&data[3]);
Move=7;
while (1)
{
if(Move==i)
{
count=(count+1)%2000;
if(count>1000)
{
senddata=segnumber[10];
}
else
{
senddata=segnumber[data[i]];
}
}
else
{
senddata=segnumber[data[i]];
}
IOCLR=1<<17; //使用的芯片为595,因此需要产生上升沿
SPISendData(senddata);
SPISendData(bitnumber[i]);
IOSET=1<<17;
i=(i+1)%8;
OSTimeDlyHMSM(0,0,0,2); //延时2ms,这个时间最为合适,使得不间断看到八个数据
}
}
/*********************************************************************************************************
END FILE
*********************************************************************************************************/
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐